From 65d40ecb4b5b4e43cc9b9c96f949f0153a1b23eb Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 12 Nov 2025 11:49:30 +0200 Subject: [PATCH 1/3] [ie/ERRJupiter] Fix tests against live data Apparently when show is gets disabled and re-enabled, its 'release_date' and 'release_timestamp' get updated. --- yt_dlp/extractor/err.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yt_dlp/extractor/err.py b/yt_dlp/extractor/err.py index d4139c6f3c..1378265bf7 100644 --- a/yt_dlp/extractor/err.py +++ b/yt_dlp/extractor/err.py @@ -20,10 +20,10 @@ class ERRJupiterIE(InfoExtractor): 'title': 'Siin me oleme!', 'alt_title': '', 'description': 'md5:1825b795f5f7584241aeb59e5bbb4f70', - 'release_date': '20231226', + 'release_date': '20250623', 'upload_date': '20201217', 'modified_date': '20201217', - 'release_timestamp': 1703577600, + 'release_timestamp': 1750688400, 'timestamp': 1608210000, 'modified_timestamp': 1608220800, 'release_year': 1978, From 1bccaecd0f7780cf3664fe018a6782f3dd6216f1 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 12 Nov 2025 14:26:48 +0200 Subject: [PATCH 2/3] [ie/ERRJupiter] Add playlist fetching support --- yt_dlp/extractor/err.py | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/yt_dlp/extractor/err.py b/yt_dlp/extractor/err.py index 1378265bf7..b0859fe694 100644 --- a/yt_dlp/extractor/err.py +++ b/yt_dlp/extractor/err.py @@ -2,7 +2,9 @@ from .common import InfoExtractor from ..utils import ( clean_html, int_or_none, + smuggle_url, str_or_none, + unsmuggle_url, url_or_none, ) from ..utils.traversal import traverse_obj @@ -174,12 +176,15 @@ class ERRJupiterIE(InfoExtractor): }] def _real_extract(self, url): + url, idata = unsmuggle_url(url, {}) video_id = self._match_id(url) data = self._download_json( 'https://services.err.ee/api/v2/vodContent/getContentPageData', video_id, - query={'contentId': video_id})['data']['mainContent'] + query={'contentId': video_id})['data'] - media_data = traverse_obj(data, ('medias', ..., {dict}), get_all=False) + main_data = data.get('mainContent') + + media_data = traverse_obj(main_data, ('medias', ..., {dict}), get_all=False) if traverse_obj(media_data, ('restrictions', 'drm', {bool})): self.report_drm(video_id) @@ -200,11 +205,11 @@ class ERRJupiterIE(InfoExtractor): 'format_id': 'http', }) - return { + metadata = { 'id': video_id, 'formats': formats, 'subtitles': subtitles, - **traverse_obj(data, { + **traverse_obj(main_data, { 'title': ('heading', {str}), 'alt_title': ('subHeading', {str}), 'description': (('lead', 'body'), {clean_html}, filter), @@ -213,12 +218,34 @@ class ERRJupiterIE(InfoExtractor): 'release_timestamp': (('scheduleStart', 'publicStart'), {int_or_none}), 'release_year': ('year', {int_or_none}), }, get_all=False), - **(traverse_obj(data, { + } + + # Early return for non-episode types ('movies', ...?) + if main_data.get('type') != 'episode': + return metadata + + metadata |= { + **(traverse_obj(main_data, { 'series': ('heading', {str}), 'series_id': ('rootContentId', {str_or_none}), 'episode': ('subHeading', {str}), 'season_number': ('season', {int_or_none}), 'episode_number': ('episode', {int_or_none}), 'episode_id': ('id', {str_or_none}), - }) if data.get('type') == 'episode' else {}), + })), } + + if season_data := data.get('seasonList'): + # XXX: Apparently we need to fill out the playlist_id + if self._yes_playlist('dummy-id', video_id, idata): + playlist_type = season_data.get('type') + if playlist_type in ('seasonal', 'monthly'): + active_season = next(season for season in season_data.get('items') if season.get('contents')) + entries = [ + self.url_result(smuggle_url(episode['url'], {'force_noplaylist': True})) + for episode in active_season.get('contents', []) + ] + return self.playlist_result(entries, video_id, **metadata) + else: + self.report_warning(f'Unhandled playlist type {playlist_type}, skipping playlist...') + return metadata From 7755b3f855ef85b1350f1e5396eaf4e744e24355 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Mon, 24 Nov 2025 19:54:05 +0200 Subject: [PATCH 3/3] [ie/ERRJupiter] Support downloading "shortSeriesList" as well --- yt_dlp/extractor/err.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/extractor/err.py b/yt_dlp/extractor/err.py index b0859fe694..43fb18eb70 100644 --- a/yt_dlp/extractor/err.py +++ b/yt_dlp/extractor/err.py @@ -239,7 +239,7 @@ class ERRJupiterIE(InfoExtractor): # XXX: Apparently we need to fill out the playlist_id if self._yes_playlist('dummy-id', video_id, idata): playlist_type = season_data.get('type') - if playlist_type in ('seasonal', 'monthly'): + if playlist_type in ('seasonal', 'monthly', 'shortSeriesList'): active_season = next(season for season in season_data.get('items') if season.get('contents')) entries = [ self.url_result(smuggle_url(episode['url'], {'force_noplaylist': True}))