Skip to content

Commit

Permalink
if If wait_for_subscription_confirm is true, unsubscribe_all will now…
Browse files Browse the repository at this point in the history
… wait for the subscriptions to be confirmed unsubscribed
  • Loading branch information
Teekeks committed Oct 16, 2020
1 parent 259d5d1 commit 2181497
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
12 changes: 12 additions & 0 deletions twitchAPI/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@
from dateutil import parser as du_parser
from enum import Enum
from .types import AuthScope
from urllib.parse import urlparse, parse_qs


TWITCH_API_BASE_URL = "https://api.twitch.tv/helix/"
TWITCH_AUTH_BASE_URL = "https://id.twitch.tv/"


def extract_uuid_str_from_url(url: str) -> Union[str, None]:
"""Extracts a UUID string from a URL
:param str url: The URL to parse
:return: UUID string extracted from given URL or None if no UUID found
:rtype: Union[str, None]
"""
uuids = parse_qs(urlparse(url).query).get('uuid', [])
return uuids[0] if len(uuids) > 0 else None


def build_url(url: str, params: dict, remove_none=False, split_lists=False) -> str:
"""Build a valid url string
Expand Down
35 changes: 28 additions & 7 deletions twitchAPI/webhook.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) 2020. Lena "Teekeks" During <info@teawork.de>
from typing import Union, Tuple, Callable
from .helper import build_url, TWITCH_API_BASE_URL, get_uuid, get_json, make_fields_datetime, fields_to_enum
from .helper import extract_uuid_str_from_url
from .types import *
import requests
from aiohttp import web
Expand Down Expand Up @@ -248,17 +249,33 @@ def _generic_handle_callback(self, request: 'web.Request', data: Union[dict, lis
# SUBSCRIPTION HELPER
# ==================================================================================================================

__unsubscribe_all_helper = {}

def unsubscribe_all(self,
twitch: 'twitchAPI.twitch.Twitch') -> None:
"""Unsubscribe from all active Webhooks
twitch: Twitch) -> bool:
"""Unsubscribe from all Webhooks that use the callback URL set in :param:`callback_url`\n
**If `wait_for_subscription_confirm` is False, the response might be
True even tho the unsubscribe action failed.**
:param twitch: App authorized instance of twitchAPI.twitch.Twitch
:rtype: None
:param ~twitchAPI.twitch.Twitch twitch: App authorized instance of :class:`~twitchAPI.twitch.Twitch`
:rtype: bool
:returns: True if all webhooks could be unsubscribed, otherwise False.
"""
from pprint import pprint
self.__unsubscribe_all_helper = {}
data = twitch.get_webhook_subscriptions()
sub_responses = []
for d in data.get('data', []):
pprint(self._generic_unsubscribe(d.get('callback'), d.get('topic'), callback_full=False))
uuid = extract_uuid_str_from_url(d.get('callback'))
if uuid is not None and d.get('callback').startswith(self.callback_url):
self.__unsubscribe_all_helper[uuid] = False
sub_responses.append(self._generic_unsubscribe(d.get('callback'), d.get('topic'), callback_full=False))
if self.wait_for_subscription_confirm:
timeout = time.time() + self.wait_for_subscription_confirm_timeout
while timeout > time.time() and not all(self.__unsubscribe_all_helper.values()):
time.sleep(0.05)
return all(self.__unsubscribe_all_helper.values()) and all(sub_responses)
else:
return all(sub_responses)

def renew_subscription(self,
uuid: UUID) -> bool:
Expand Down Expand Up @@ -514,12 +531,16 @@ async def __handle_challenge(self, request: 'web.Request'):
self.__active_webhooks.get(UUID(request.rel_url.query.get('uuid')))['active'] = True
self.__active_webhooks.get(UUID(request.rel_url.query.get('uuid')))['confirmed_subscribe'] = True
if request.rel_url.query.get('hub.mode') == 'unsubscribe':
if UUID(request.rel_url.query.get('uuid')) in self.__active_webhooks.keys():
uuid_str = request.rel_url.query.get('uuid')
if uuid_str in self.__unsubscribe_all_helper.keys():
self.__unsubscribe_all_helper[uuid_str] = True
if UUID(uuid_str) in self.__active_webhooks.keys():
# we treat this as invalid as soon as we answer the challenge
if self.wait_for_subscription_confirm:
self.__active_webhooks.get(UUID(request.rel_url.query.get('uuid')))['confirmed_unsubscribe'] = True
else:
self.__active_webhooks.pop(UUID(request.rel_url.query.get('uuid')))

return web.Response(text=challenge)
return web.Response(status=500)

Expand Down

0 comments on commit 2181497

Please sign in to comment.