diff options
| -rw-r--r-- | youtube_dl/extractor/extractors.py | 1 | ||||
| -rw-r--r-- | youtube_dl/extractor/tvnow.py | 73 | 
2 files changed, 58 insertions, 16 deletions
| diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index de48a37ad..e3a67cc5b 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -1136,6 +1136,7 @@ from .tvnoe import TVNoeIE  from .tvnow import (      TVNowIE,      TVNowListIE, +    TVNowListChannelIE,  )  from .tvp import (      TVPEmbedIE, diff --git a/youtube_dl/extractor/tvnow.py b/youtube_dl/extractor/tvnow.py index 1bf472444..8e0ac6be5 100644 --- a/youtube_dl/extractor/tvnow.py +++ b/youtube_dl/extractor/tvnow.py @@ -19,7 +19,7 @@ class TVNowBaseIE(InfoExtractor):          'id', 'title', 'free', 'geoblocked', 'articleLong', 'articleShort',          'broadcastStartDate', 'isDrm', 'duration', 'season', 'episode',          'manifest.dashclear', 'format.title', 'format.defaultImage169Format', -        'format.defaultImage169Logo') +        'format.defaultImage169Logo', 'replaceMovieInformation')      def _call_api(self, path, video_id, query):          return self._download_json( @@ -58,7 +58,7 @@ class TVNowBaseIE(InfoExtractor):          duration = parse_duration(info.get('duration'))          f = info.get('format', {}) -        thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo') +        thumbnail = ('https://aistvnow-a.akamaihd.net/tvnow/movie/%s' % info.get('replaceMovieInformation')) or f.get('defaultImage169Format') or f.get('defaultImage169Logo')          return {              'id': video_id, @@ -133,7 +133,27 @@ class TVNowIE(TVNowBaseIE):          return self._extract_video(info, display_id) -class TVNowListIE(TVNowBaseIE): +class TVNowListBaseIE(TVNowBaseIE): +    def _extend_query(self, show, season, video=None): +        fields = [] +        fields.extend(show) +        fields.extend('formatTabs.%s' % field for field in season) +        if video: +            fields.extend( +                'formatTabs.formatTabPages.container.movies.%s' % field +                for field in video) + +        return fields + +    def _tvnow_list_info(self, list_id, show_id, fields): +        return self._call_api( +            'formats/seo', list_id, query={ +                'fields': ','.join(fields), +                'name': show_id + '.php' +            }) + + +class TVNowListIE(TVNowListBaseIE):      _VALID_URL = r'(?P<base_url>https?://(?:www\.)?tvnow\.(?:de|at|ch)/(?:rtl(?:2|plus)?|nitro|superrtl|ntv|vox)/(?P<show_id>[^/]+)/)list/(?P<id>[^?/#&]+)$'      _SHOW_FIELDS = ('title', ) @@ -152,18 +172,7 @@ class TVNowListIE(TVNowBaseIE):      def _real_extract(self, url):          base_url, show_id, season_id = re.match(self._VALID_URL, url).groups() -        fields = [] -        fields.extend(self._SHOW_FIELDS) -        fields.extend('formatTabs.%s' % field for field in self._SEASON_FIELDS) -        fields.extend( -            'formatTabs.formatTabPages.container.movies.%s' % field -            for field in self._VIDEO_FIELDS) - -        list_info = self._call_api( -            'formats/seo', season_id, query={ -                'fields': ','.join(fields), -                'name': show_id + '.php' -            }) +        list_info = self._tvnow_list_info(season_id, show_id, self._extend_query(self._SHOW_FIELDS, self._SEASON_FIELDS, self._VIDEO_FIELDS))          season = next(              season for season in list_info['formatTabs']['items'] @@ -177,8 +186,40 @@ class TVNowListIE(TVNowBaseIE):                  seo_url = info.get('seoUrl')                  if not seo_url:                      continue +                  entries.append(self.url_result( -                    base_url + seo_url + '/player', 'TVNow', info.get('id'))) +                    base_url + seo_url + '/player', 'TVNow', str(info.get('id', seo_url))))          return self.playlist_result(              entries, compat_str(season.get('id') or season_id), title) + + +class TVNowListChannelIE(TVNowListBaseIE): +    _VALID_URL = r'(?P<base_url>https?://(?:www\.)?tvnow\.(?:de|at|ch)/(?:rtl(?:2|plus)?|nitro|superrtl|ntv|vox)/(?P<show_id>[^/]+))' + +    _SHOW_FIELDS = ('id', 'title', ) +    _SEASON_FIELDS = ('id', 'headline', 'seoheadline', ) + +    _TESTS = [{ +        'url': 'https://www.tvnow.at/vox/ab-ins-beet', +        'only_matching': 'True', +    }] + +    @classmethod +    def suitable(cls, url): +        return False if TVNowIE.suitable(url) or TVNowListIE.suitable(url) else super(TVNowListChannelIE, cls).suitable(url) + +    def _real_extract(self, url): +        base_url, show_id = re.match(self._VALID_URL, url).groups() + +        list_info = self._tvnow_list_info(show_id, show_id, self._extend_query(self._SHOW_FIELDS, self._SEASON_FIELDS)) + +        entries = [] +        for season_info in list_info['formatTabs']['items']: +            season_url = season_info.get('seoheadline') +            if not season_url: +                continue +            entries.append(self.url_result( +                base_url + "/list/" + season_url, 'TVNowList', compat_str(season_info.get('id')), season_info.get('headline'))) + +        return self.playlist_result(entries) | 
