From 22acb019567a63a4a620ad32ad3cc9683981fed0 Mon Sep 17 00:00:00 2001 From: rasmus Date: Sun, 24 Mar 2024 14:01:20 +0100 Subject: [PATCH 1/9] [ie/Boosty] include auth token in API call if available --- yt_dlp/extractor/boosty.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index fb14ca146..1f0f41e89 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -1,3 +1,5 @@ +import json + from .common import InfoExtractor from .youtube import YoutubeIE from ..utils import ( @@ -8,6 +10,7 @@ from ..utils import ( url_or_none, ) from ..utils.traversal import traverse_obj +from ..compat import compat_urllib_parse_unquote class BoostyIE(InfoExtractor): @@ -162,9 +165,22 @@ class BoostyIE(InfoExtractor): def _real_extract(self, url): user, post_id = self._match_valid_url(url).group('user', 'post_id') + + auth_cookie = self._get_cookies('https://api.boosty.to/').get('auth') + auth_headers = {} + if auth_cookie is not None: + try: + auth_data = json.loads(compat_urllib_parse_unquote(auth_cookie.value)) + auth_headers['Authorization'] = f'Bearer {auth_data.get("accessToken")}' + except (json.JSONDecodeError, KeyError): + self.report_warning('Failed to extract token from auth cookie.') + post = self._download_json( f'https://api.boosty.to/v1/blog/{user}/post/{post_id}', post_id, - note='Downloading post data', errnote='Unable to download post data') + note='Downloading post data', errnote='Unable to download post data', headers=auth_headers) + + if not post.get('hasAccess'): + self.report_warning('This post requires a subscription, make sure to include your browser cookies.') post_title = post.get('title') if not post_title: From 3cf701bc59cae92e6039265f7b590ec076c98952 Mon Sep 17 00:00:00 2001 From: Rasmus Antons Date: Fri, 29 Mar 2024 02:15:46 +0100 Subject: [PATCH 2/9] [ie/Boosty] improve error handling during auth cookie parsing --- yt_dlp/extractor/boosty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index 1f0f41e89..025b65334 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -171,7 +171,7 @@ class BoostyIE(InfoExtractor): if auth_cookie is not None: try: auth_data = json.loads(compat_urllib_parse_unquote(auth_cookie.value)) - auth_headers['Authorization'] = f'Bearer {auth_data.get("accessToken")}' + auth_headers['Authorization'] = f'Bearer {auth_data["accessToken"]}' except (json.JSONDecodeError, KeyError): self.report_warning('Failed to extract token from auth cookie.') From 3d66274d7f1b149a6bfc18e86190da42e2d2d8ca Mon Sep 17 00:00:00 2001 From: rasmus Date: Wed, 17 Apr 2024 18:41:57 +0200 Subject: [PATCH 3/9] [ie/Boosty] use base domain to get cookies --- yt_dlp/extractor/boosty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index 025b65334..5381fdaee 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -166,7 +166,7 @@ class BoostyIE(InfoExtractor): def _real_extract(self, url): user, post_id = self._match_valid_url(url).group('user', 'post_id') - auth_cookie = self._get_cookies('https://api.boosty.to/').get('auth') + auth_cookie = self._get_cookies('https://boosty.to/').get('auth') auth_headers = {} if auth_cookie is not None: try: From 2fae8c33630de3c08ae9c3a0ebc382402fbc0f43 Mon Sep 17 00:00:00 2001 From: rasmus Date: Wed, 17 Apr 2024 18:43:38 +0200 Subject: [PATCH 4/9] [ie/Boosty] call raise_login_required if subscription required --- yt_dlp/extractor/boosty.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index 5381fdaee..b60c98bdd 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -179,9 +179,6 @@ class BoostyIE(InfoExtractor): f'https://api.boosty.to/v1/blog/{user}/post/{post_id}', post_id, note='Downloading post data', errnote='Unable to download post data', headers=auth_headers) - if not post.get('hasAccess'): - self.report_warning('This post requires a subscription, make sure to include your browser cookies.') - post_title = post.get('title') if not post_title: self.report_warning('Unable to extract post title. Falling back to parsing html page') @@ -218,6 +215,8 @@ class BoostyIE(InfoExtractor): 'thumbnail': (('previewUrl', 'defaultPreview'), {url_or_none}), }, get_all=False)}) + if not post.get('hasAccess'): + self.raise_login_required('This post requires a subscription', True, method='cookies') if not entries: raise ExtractorError('No videos found', expected=True) if len(entries) == 1: From 4304bac2727d33d6825351de54eeb6419ef526b0 Mon Sep 17 00:00:00 2001 From: rasmus Date: Mon, 6 May 2024 22:18:39 +0200 Subject: [PATCH 5/9] [ie/Boosty] use urllib.parse.unquote directly --- yt_dlp/extractor/boosty.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index b60c98bdd..402c0ba0a 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -1,4 +1,5 @@ import json +import urllib from .common import InfoExtractor from .youtube import YoutubeIE @@ -10,7 +11,6 @@ from ..utils import ( url_or_none, ) from ..utils.traversal import traverse_obj -from ..compat import compat_urllib_parse_unquote class BoostyIE(InfoExtractor): @@ -170,7 +170,7 @@ class BoostyIE(InfoExtractor): auth_headers = {} if auth_cookie is not None: try: - auth_data = json.loads(compat_urllib_parse_unquote(auth_cookie.value)) + auth_data = json.loads(urllib.parse.unquote(auth_cookie.value)) auth_headers['Authorization'] = f'Bearer {auth_data["accessToken"]}' except (json.JSONDecodeError, KeyError): self.report_warning('Failed to extract token from auth cookie.') From e4a9322c48a7f707f18ac337e56c4d5573389487 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Tue, 7 May 2024 02:34:30 +0530 Subject: [PATCH 6/9] Update yt_dlp/extractor/boosty.py --- yt_dlp/extractor/boosty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index 402c0ba0a..fa244159c 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -1,5 +1,5 @@ import json -import urllib +import urllib.parse from .common import InfoExtractor from .youtube import YoutubeIE From 6bb36792171ec97b0eb792715b137fff7abaacbf Mon Sep 17 00:00:00 2001 From: rasmus Date: Tue, 7 May 2024 01:20:44 +0200 Subject: [PATCH 7/9] [ie/Boosty] show bug_reports_message if auth cookie parse fails --- yt_dlp/extractor/boosty.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index fa244159c..bcb7379e0 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -9,6 +9,7 @@ from ..utils import ( qualities, str_or_none, url_or_none, + bug_reports_message, ) from ..utils.traversal import traverse_obj @@ -173,7 +174,7 @@ class BoostyIE(InfoExtractor): auth_data = json.loads(urllib.parse.unquote(auth_cookie.value)) auth_headers['Authorization'] = f'Bearer {auth_data["accessToken"]}' except (json.JSONDecodeError, KeyError): - self.report_warning('Failed to extract token from auth cookie.') + self.report_warning(f'Failed to extract token from auth cookie{bug_reports_message()}') post = self._download_json( f'https://api.boosty.to/v1/blog/{user}/post/{post_id}', post_id, From 7027b79160babc1efea8ac7e80f8c9d665f566c0 Mon Sep 17 00:00:00 2001 From: rasmus Date: Tue, 7 May 2024 01:21:49 +0200 Subject: [PATCH 8/9] [ie/Boosty] don't fail if hasAccess is not set but videos are available --- yt_dlp/extractor/boosty.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index bcb7379e0..671f84a4e 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -216,9 +216,9 @@ class BoostyIE(InfoExtractor): 'thumbnail': (('previewUrl', 'defaultPreview'), {url_or_none}), }, get_all=False)}) - if not post.get('hasAccess'): - self.raise_login_required('This post requires a subscription', True, method='cookies') - if not entries: + if not entries and not post.get('hasAccess'): + self.raise_login_required('This post requires a subscription', metadata_available=True, method='cookies') + elif not entries: raise ExtractorError('No videos found', expected=True) if len(entries) == 1: return entries[0] From c7a1260a8aaaaa4c98fb183ad113ba2f753b2382 Mon Sep 17 00:00:00 2001 From: rasmus Date: Tue, 7 May 2024 01:35:26 +0200 Subject: [PATCH 9/9] [ie/Boosty] remove method parameter in raise_login_required because it is the default value --- yt_dlp/extractor/boosty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/boosty.py b/yt_dlp/extractor/boosty.py index 671f84a4e..2956311d0 100644 --- a/yt_dlp/extractor/boosty.py +++ b/yt_dlp/extractor/boosty.py @@ -217,7 +217,7 @@ class BoostyIE(InfoExtractor): }, get_all=False)}) if not entries and not post.get('hasAccess'): - self.raise_login_required('This post requires a subscription', metadata_available=True, method='cookies') + self.raise_login_required('This post requires a subscription', metadata_available=True) elif not entries: raise ExtractorError('No videos found', expected=True) if len(entries) == 1: