+
+
+class DRTVSeasonIE(InfoExtractor):
+ IE_NAME = 'drtv:season'
+ _VALID_URL = r'https?://(?:www\.)?(?:dr\.dk|dr-massive\.com)/drtv/saeson/(?P<display_id>[\w-]+)_(?P<id>\d+)'
+ _GEO_COUNTRIES = ['DK']
+ _TESTS = [{
+ 'url': 'https://www.dr.dk/drtv/saeson/frank-and-kastaniegaarden_9008',
+ 'info_dict': {
+ 'id': '9008',
+ 'display_id': 'frank-and-kastaniegaarden',
+ 'title': 'Frank & Kastaniegaarden',
+ 'series': 'Frank & Kastaniegaarden',
+ },
+ 'playlist_mincount': 8
+ }, {
+ 'url': 'https://www.dr.dk/drtv/saeson/frank-and-kastaniegaarden_8761',
+ 'info_dict': {
+ 'id': '8761',
+ 'display_id': 'frank-and-kastaniegaarden',
+ 'title': 'Frank & Kastaniegaarden',
+ 'series': 'Frank & Kastaniegaarden',
+ },
+ 'playlist_mincount': 19
+ }]
+
+ def _real_extract(self, url):
+ display_id, season_id = self._match_valid_url(url).group('display_id', 'id')
+ data = self._download_json(SERIES_API % f'/saeson/{display_id}_{season_id}', display_id)
+
+ entries = [{
+ '_type': 'url',
+ 'url': f'https://www.dr.dk/drtv{episode["path"]}',
+ 'ie_key': DRTVIE.ie_key(),
+ 'title': episode.get('title'),
+ 'episode': episode.get('episodeName'),
+ 'description': episode.get('shortDescription'),
+ 'series': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'season_number': traverse_obj(data, ('entries', 0, 'item', 'seasonNumber')),
+ 'episode_number': episode.get('episodeNumber'),
+ } for episode in traverse_obj(data, ('entries', 0, 'item', 'episodes', 'items'))]
+
+ return {
+ '_type': 'playlist',
+ 'id': season_id,
+ 'display_id': display_id,
+ 'title': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'series': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'entries': entries,
+ 'season_number': traverse_obj(data, ('entries', 0, 'item', 'seasonNumber'))
+ }
+
+
+class DRTVSeriesIE(InfoExtractor):
+ IE_NAME = 'drtv:series'
+ _VALID_URL = r'https?://(?:www\.)?(?:dr\.dk|dr-massive\.com)/drtv/serie/(?P<display_id>[\w-]+)_(?P<id>\d+)'
+ _GEO_COUNTRIES = ['DK']
+ _TESTS = [{
+ 'url': 'https://www.dr.dk/drtv/serie/frank-and-kastaniegaarden_6954',
+ 'info_dict': {
+ 'id': '6954',
+ 'display_id': 'frank-and-kastaniegaarden',
+ 'title': 'Frank & Kastaniegaarden',
+ 'series': 'Frank & Kastaniegaarden',
+ },
+ 'playlist_mincount': 15
+ }]
+
+ def _real_extract(self, url):
+ display_id, series_id = self._match_valid_url(url).group('display_id', 'id')
+ data = self._download_json(SERIES_API % f'/serie/{display_id}_{series_id}', display_id)
+
+ entries = [{
+ '_type': 'url',
+ 'url': f'https://www.dr.dk/drtv{season.get("path")}',
+ 'ie_key': DRTVSeasonIE.ie_key(),
+ 'title': season.get('title'),
+ 'series': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'season_number': traverse_obj(data, ('entries', 0, 'item', 'seasonNumber'))
+ } for season in traverse_obj(data, ('entries', 0, 'item', 'show', 'seasons', 'items'))]
+
+ return {
+ '_type': 'playlist',
+ 'id': series_id,
+ 'display_id': display_id,
+ 'title': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'series': traverse_obj(data, ('entries', 0, 'item', 'title')),
+ 'entries': entries
+ }