[vimeo] improve extraction
- fix review extraction - fix ondemand extraction - make password protected player case as an expected error(closes #22896) - simplify channel based extractors code
This commit is contained in:
		| @@ -15,18 +15,20 @@ from ..compat import ( | |||||||
|     compat_urlparse, |     compat_urlparse, | ||||||
| ) | ) | ||||||
| from ..utils import ( | from ..utils import ( | ||||||
|  |     clean_html, | ||||||
|     determine_ext, |     determine_ext, | ||||||
|  |     dict_get, | ||||||
|     ExtractorError, |     ExtractorError, | ||||||
|     js_to_json, |     js_to_json, | ||||||
|     int_or_none, |     int_or_none, | ||||||
|     merge_dicts, |     merge_dicts, | ||||||
|     NO_DEFAULT, |  | ||||||
|     OnDemandPagedList, |     OnDemandPagedList, | ||||||
|     parse_filesize, |     parse_filesize, | ||||||
|     RegexNotFoundError, |     RegexNotFoundError, | ||||||
|     sanitized_Request, |     sanitized_Request, | ||||||
|     smuggle_url, |     smuggle_url, | ||||||
|     std_headers, |     std_headers, | ||||||
|  |     str_or_none, | ||||||
|     try_get, |     try_get, | ||||||
|     unified_timestamp, |     unified_timestamp, | ||||||
|     unsmuggle_url, |     unsmuggle_url, | ||||||
| @@ -210,7 +212,7 @@ class VimeoBaseInfoExtractor(InfoExtractor): | |||||||
|         video_uploader_url = owner.get('url') |         video_uploader_url = owner.get('url') | ||||||
|  |  | ||||||
|         return { |         return { | ||||||
|             'id': video_id, |             'id': str_or_none(video_data.get('id')) or video_id, | ||||||
|             'title': self._live_title(video_title) if is_live else video_title, |             'title': self._live_title(video_title) if is_live else video_title, | ||||||
|             'uploader': owner.get('name'), |             'uploader': owner.get('name'), | ||||||
|             'uploader_id': video_uploader_url.split('/')[-1] if video_uploader_url else None, |             'uploader_id': video_uploader_url.split('/')[-1] if video_uploader_url else None, | ||||||
| @@ -258,11 +260,11 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                         (?: |                         (?: | ||||||
|                             (?: |                             (?: | ||||||
|                                 www| |                                 www| | ||||||
|                                 (?P<player>player) |                                 player | ||||||
|                             ) |                             ) | ||||||
|                             \. |                             \. | ||||||
|                         )? |                         )? | ||||||
|                         vimeo(?P<pro>pro)?\.com/ |                         vimeo(?:pro)?\.com/ | ||||||
|                         (?!(?:channels|album|showcase)/[^/?#]+/?(?:$|[?#])|[^/]+/review/|ondemand/) |                         (?!(?:channels|album|showcase)/[^/?#]+/?(?:$|[?#])|[^/]+/review/|ondemand/) | ||||||
|                         (?:.*?/)? |                         (?:.*?/)? | ||||||
|                         (?: |                         (?: | ||||||
| @@ -284,7 +286,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'id': '56015672', |                 'id': '56015672', | ||||||
|                 'ext': 'mp4', |                 'ext': 'mp4', | ||||||
|                 'title': "youtube-dl test video - \u2605 \" ' \u5e78 / \\ \u00e4 \u21ad \U0001d550", |                 'title': "youtube-dl test video - \u2605 \" ' \u5e78 / \\ \u00e4 \u21ad \U0001d550", | ||||||
|                 'description': 'md5:509a9ad5c9bf97c60faee9203aca4479', |                 'description': 'md5:2d3305bad981a06ff79f027f19865021', | ||||||
|                 'timestamp': 1355990239, |                 'timestamp': 1355990239, | ||||||
|                 'upload_date': '20121220', |                 'upload_date': '20121220', | ||||||
|                 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/user7108434', |                 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/user7108434', | ||||||
| @@ -293,6 +295,9 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'duration': 10, |                 'duration': 10, | ||||||
|                 'license': 'by-sa', |                 'license': 'by-sa', | ||||||
|             }, |             }, | ||||||
|  |             'params': { | ||||||
|  |                 'format': 'best[protocol=https]', | ||||||
|  |             }, | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             'url': 'http://vimeopro.com/openstreetmapus/state-of-the-map-us-2013/video/68093876', |             'url': 'http://vimeopro.com/openstreetmapus/state-of-the-map-us-2013/video/68093876', | ||||||
| @@ -305,8 +310,13 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'uploader_id': 'openstreetmapus', |                 'uploader_id': 'openstreetmapus', | ||||||
|                 'uploader': 'OpenStreetMap US', |                 'uploader': 'OpenStreetMap US', | ||||||
|                 'title': 'Andy Allan - Putting the Carto into OpenStreetMap Cartography', |                 'title': 'Andy Allan - Putting the Carto into OpenStreetMap Cartography', | ||||||
|                 'description': 'md5:fd69a7b8d8c34a4e1d2ec2e4afd6ec30', |                 'description': 'md5:2c362968038d4499f4d79f88458590c1', | ||||||
|                 'duration': 1595, |                 'duration': 1595, | ||||||
|  |                 'upload_date': '20130610', | ||||||
|  |                 'timestamp': 1370893156, | ||||||
|  |             }, | ||||||
|  |             'params': { | ||||||
|  |                 'format': 'best[protocol=https]', | ||||||
|             }, |             }, | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
| @@ -323,6 +333,10 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'duration': 3610, |                 'duration': 3610, | ||||||
|                 'description': None, |                 'description': None, | ||||||
|             }, |             }, | ||||||
|  |             'params': { | ||||||
|  |                 'format': 'best[protocol=https]', | ||||||
|  |             }, | ||||||
|  |             'expected_warnings': ['Unable to download JSON metadata'], | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             'url': 'http://vimeo.com/68375962', |             'url': 'http://vimeo.com/68375962', | ||||||
| @@ -341,6 +355,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'description': 'md5:dca3ea23adb29ee387127bc4ddfce63f', |                 'description': 'md5:dca3ea23adb29ee387127bc4ddfce63f', | ||||||
|             }, |             }, | ||||||
|             'params': { |             'params': { | ||||||
|  |                 'format': 'best[protocol=https]', | ||||||
|                 'videopassword': 'youtube-dl', |                 'videopassword': 'youtube-dl', | ||||||
|             }, |             }, | ||||||
|         }, |         }, | ||||||
| @@ -441,10 +456,14 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'uploader': '10Ft Films', |                 'uploader': '10Ft Films', | ||||||
|                 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/tenfootfilms', |                 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/tenfootfilms', | ||||||
|                 'uploader_id': 'tenfootfilms', |                 'uploader_id': 'tenfootfilms', | ||||||
|  |                 'description': 'md5:0fa704e05b04f91f40b7f3ca2e801384', | ||||||
|  |                 'upload_date': '20130830', | ||||||
|  |                 'timestamp': 1377853339, | ||||||
|             }, |             }, | ||||||
|             'params': { |             'params': { | ||||||
|                 'skip_download': True, |                 'skip_download': True, | ||||||
|             }, |             }, | ||||||
|  |             'expected_warnings': ['Unable to download JSON metadata'], | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             'url': 'http://player.vimeo.com/video/68375962', |             'url': 'http://player.vimeo.com/video/68375962', | ||||||
| @@ -459,6 +478,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                 'duration': 10, |                 'duration': 10, | ||||||
|             }, |             }, | ||||||
|             'params': { |             'params': { | ||||||
|  |                 'format': 'best[protocol=https]', | ||||||
|                 'videopassword': 'youtube-dl', |                 'videopassword': 'youtube-dl', | ||||||
|             }, |             }, | ||||||
|         }, |         }, | ||||||
| @@ -523,7 +543,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|     def _verify_player_video_password(self, url, video_id, headers): |     def _verify_player_video_password(self, url, video_id, headers): | ||||||
|         password = self._downloader.params.get('videopassword') |         password = self._downloader.params.get('videopassword') | ||||||
|         if password is None: |         if password is None: | ||||||
|             raise ExtractorError('This video is protected by a password, use the --video-password option') |             raise ExtractorError('This video is protected by a password, use the --video-password option', expected=True) | ||||||
|         data = urlencode_postdata({ |         data = urlencode_postdata({ | ||||||
|             'password': base64.b64encode(password.encode()), |             'password': base64.b64encode(password.encode()), | ||||||
|         }) |         }) | ||||||
| @@ -552,28 +572,26 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|             r'vimeo\.com/channels/([^/]+)', url, 'channel id', default=None) |             r'vimeo\.com/channels/([^/]+)', url, 'channel id', default=None) | ||||||
|  |  | ||||||
|         # Extract ID from URL |         # Extract ID from URL | ||||||
|         mobj = re.match(self._VALID_URL, url) |         video_id = self._match_id(url) | ||||||
|         video_id = mobj.group('id') |  | ||||||
|         orig_url = url |         orig_url = url | ||||||
|         if mobj.group('pro'): |         is_pro = 'vimeopro.com/' in url | ||||||
|  |         is_player = '://player.vimeo.com/video/' in url | ||||||
|  |         if is_pro: | ||||||
|             # some videos require portfolio_id to be present in player url |             # some videos require portfolio_id to be present in player url | ||||||
|             # https://github.com/ytdl-org/youtube-dl/issues/20070 |             # https://github.com/ytdl-org/youtube-dl/issues/20070 | ||||||
|             url = self._extract_url(url, self._download_webpage(url, video_id)) |             url = self._extract_url(url, self._download_webpage(url, video_id)) | ||||||
|         elif mobj.group('player'): |             if not url: | ||||||
|  |                 url = 'https://vimeo.com/' + video_id | ||||||
|  |         elif is_player: | ||||||
|             url = 'https://player.vimeo.com/video/' + video_id |             url = 'https://player.vimeo.com/video/' + video_id | ||||||
|         elif any(p in url for p in ('play_redirect_hls', 'moogaloop.swf')): |         elif any(p in url for p in ('play_redirect_hls', 'moogaloop.swf')): | ||||||
|             url = 'https://vimeo.com/' + video_id |             url = 'https://vimeo.com/' + video_id | ||||||
|  |  | ||||||
|         # Retrieve video webpage to extract further information |  | ||||||
|         request = sanitized_Request(url, headers=headers) |  | ||||||
|         try: |         try: | ||||||
|             webpage, urlh = self._download_webpage_handle(request, video_id) |             # Retrieve video webpage to extract further information | ||||||
|  |             webpage, urlh = self._download_webpage_handle( | ||||||
|  |                 url, video_id, headers=headers) | ||||||
|             redirect_url = compat_str(urlh.geturl()) |             redirect_url = compat_str(urlh.geturl()) | ||||||
|             # Some URLs redirect to ondemand can't be extracted with |  | ||||||
|             # this extractor right away thus should be passed through |  | ||||||
|             # ondemand extractor (e.g. https://vimeo.com/73445910) |  | ||||||
|             if VimeoOndemandIE.suitable(redirect_url): |  | ||||||
|                 return self.url_result(redirect_url, VimeoOndemandIE.ie_key()) |  | ||||||
|         except ExtractorError as ee: |         except ExtractorError as ee: | ||||||
|             if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 403: |             if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 403: | ||||||
|                 errmsg = ee.cause.read() |                 errmsg = ee.cause.read() | ||||||
| @@ -600,6 +618,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|  |  | ||||||
|         cc_license = None |         cc_license = None | ||||||
|         timestamp = None |         timestamp = None | ||||||
|  |         video_description = None | ||||||
|  |  | ||||||
|         # Extract the config JSON |         # Extract the config JSON | ||||||
|         try: |         try: | ||||||
| @@ -611,17 +630,17 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                     # Sometimes new react-based page is served instead of old one that require |                     # Sometimes new react-based page is served instead of old one that require | ||||||
|                     # different config URL extraction approach (see |                     # different config URL extraction approach (see | ||||||
|                     # https://github.com/ytdl-org/youtube-dl/pull/7209) |                     # https://github.com/ytdl-org/youtube-dl/pull/7209) | ||||||
|                     vimeo_clip_page_config = self._search_regex( |                     page_config = self._parse_json(self._search_regex( | ||||||
|                         r'vimeo\.clip_page_config\s*=\s*({.+?});', webpage, |                         r'vimeo\.(?:clip|vod_title)_page_config\s*=\s*({.+?});', | ||||||
|                         'vimeo clip page config') |                         webpage, 'page config'), video_id) | ||||||
|                     page_config = self._parse_json(vimeo_clip_page_config, video_id) |  | ||||||
|                     config_url = page_config['player']['config_url'] |                     config_url = page_config['player']['config_url'] | ||||||
|                     cc_license = page_config.get('cc_license') |                     cc_license = page_config.get('cc_license') | ||||||
|                     timestamp = try_get( |                     timestamp = try_get( | ||||||
|                         page_config, lambda x: x['clip']['uploaded_on'], |                         page_config, lambda x: x['clip']['uploaded_on'], | ||||||
|                         compat_str) |                         compat_str) | ||||||
|                 config_json = self._download_webpage(config_url, video_id) |                     video_description = clean_html(dict_get( | ||||||
|                 config = json.loads(config_json) |                         page_config, ('description', 'description_html_escaped'))) | ||||||
|  |                 config = self._download_json(config_url, video_id) | ||||||
|             except RegexNotFoundError: |             except RegexNotFoundError: | ||||||
|                 # For pro videos or player.vimeo.com urls |                 # For pro videos or player.vimeo.com urls | ||||||
|                 # We try to find out to which variable is assigned the config dic |                 # We try to find out to which variable is assigned the config dic | ||||||
| @@ -675,14 +694,14 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|                     {'force_feature_id': True}), 'Vimeo') |                     {'force_feature_id': True}), 'Vimeo') | ||||||
|  |  | ||||||
|         # Extract video description |         # Extract video description | ||||||
|  |         if not video_description: | ||||||
|         video_description = self._html_search_regex( |             video_description = self._html_search_regex( | ||||||
|             r'(?s)<div\s+class="[^"]*description[^"]*"[^>]*>(.*?)</div>', |                 r'(?s)<div\s+class="[^"]*description[^"]*"[^>]*>(.*?)</div>', | ||||||
|             webpage, 'description', default=None) |                 webpage, 'description', default=None) | ||||||
|         if not video_description: |         if not video_description: | ||||||
|             video_description = self._html_search_meta( |             video_description = self._html_search_meta( | ||||||
|                 'description', webpage, default=None) |                 'description', webpage, default=None) | ||||||
|         if not video_description and mobj.group('pro'): |         if not video_description and is_pro: | ||||||
|             orig_webpage = self._download_webpage( |             orig_webpage = self._download_webpage( | ||||||
|                 orig_url, video_id, |                 orig_url, video_id, | ||||||
|                 note='Downloading webpage for description', |                 note='Downloading webpage for description', | ||||||
| @@ -690,7 +709,7 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|             if orig_webpage: |             if orig_webpage: | ||||||
|                 video_description = self._html_search_meta( |                 video_description = self._html_search_meta( | ||||||
|                     'description', orig_webpage, default=None) |                     'description', orig_webpage, default=None) | ||||||
|         if not video_description and not mobj.group('player'): |         if not video_description and not is_player: | ||||||
|             self._downloader.report_warning('Cannot find video description') |             self._downloader.report_warning('Cannot find video description') | ||||||
|  |  | ||||||
|         # Extract upload date |         # Extract upload date | ||||||
| @@ -747,9 +766,9 @@ class VimeoIE(VimeoBaseInfoExtractor): | |||||||
|         return info_dict |         return info_dict | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoOndemandIE(VimeoBaseInfoExtractor): | class VimeoOndemandIE(VimeoIE): | ||||||
|     IE_NAME = 'vimeo:ondemand' |     IE_NAME = 'vimeo:ondemand' | ||||||
|     _VALID_URL = r'https?://(?:www\.)?vimeo\.com/ondemand/(?P<id>[^/?#&]+)' |     _VALID_URL = r'https?://(?:www\.)?vimeo\.com/ondemand/([^/]+/)?(?P<id>[^/?#&]+)' | ||||||
|     _TESTS = [{ |     _TESTS = [{ | ||||||
|         # ondemand video not available via https://vimeo.com/id |         # ondemand video not available via https://vimeo.com/id | ||||||
|         'url': 'https://vimeo.com/ondemand/20704', |         'url': 'https://vimeo.com/ondemand/20704', | ||||||
| @@ -761,24 +780,32 @@ class VimeoOndemandIE(VimeoBaseInfoExtractor): | |||||||
|             'uploader': 'גם סרטים', |             'uploader': 'גם סרטים', | ||||||
|             'uploader_url': r're:https?://(?:www\.)?vimeo\.com/gumfilms', |             'uploader_url': r're:https?://(?:www\.)?vimeo\.com/gumfilms', | ||||||
|             'uploader_id': 'gumfilms', |             'uploader_id': 'gumfilms', | ||||||
|  |             'description': 'md5:4c027c965e439de4baab621e48b60791', | ||||||
|  |             'upload_date': '20140906', | ||||||
|  |             'timestamp': 1410032453, | ||||||
|         }, |         }, | ||||||
|         'params': { |         'params': { | ||||||
|             'format': 'best[protocol=https]', |             'format': 'best[protocol=https]', | ||||||
|         }, |         }, | ||||||
|  |         'expected_warnings': ['Unable to download JSON metadata'], | ||||||
|     }, { |     }, { | ||||||
|         # requires Referer to be passed along with og:video:url |         # requires Referer to be passed along with og:video:url | ||||||
|         'url': 'https://vimeo.com/ondemand/36938/126682985', |         'url': 'https://vimeo.com/ondemand/36938/126682985', | ||||||
|         'info_dict': { |         'info_dict': { | ||||||
|             'id': '126682985', |             'id': '126584684', | ||||||
|             'ext': 'mp4', |             'ext': 'mp4', | ||||||
|             'title': 'Rävlock, rätt läte på rätt plats', |             'title': 'Rävlock, rätt läte på rätt plats', | ||||||
|             'uploader': 'Lindroth & Norin', |             'uploader': 'Lindroth & Norin', | ||||||
|             'uploader_url': r're:https?://(?:www\.)?vimeo\.com/user14430847', |             'uploader_url': r're:https?://(?:www\.)?vimeo\.com/lindrothnorin', | ||||||
|             'uploader_id': 'user14430847', |             'uploader_id': 'lindrothnorin', | ||||||
|  |             'description': 'md5:c3c46a90529612c8279fb6af803fc0df', | ||||||
|  |             'upload_date': '20150502', | ||||||
|  |             'timestamp': 1430586422, | ||||||
|         }, |         }, | ||||||
|         'params': { |         'params': { | ||||||
|             'skip_download': True, |             'skip_download': True, | ||||||
|         }, |         }, | ||||||
|  |         'expected_warnings': ['Unable to download JSON metadata'], | ||||||
|     }, { |     }, { | ||||||
|         'url': 'https://vimeo.com/ondemand/nazmaalik', |         'url': 'https://vimeo.com/ondemand/nazmaalik', | ||||||
|         'only_matching': True, |         'only_matching': True, | ||||||
| @@ -790,16 +817,6 @@ class VimeoOndemandIE(VimeoBaseInfoExtractor): | |||||||
|         'only_matching': True, |         'only_matching': True, | ||||||
|     }] |     }] | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |  | ||||||
|         video_id = self._match_id(url) |  | ||||||
|         webpage = self._download_webpage(url, video_id) |  | ||||||
|         return self.url_result( |  | ||||||
|             # Some videos require Referer to be passed along with og:video:url |  | ||||||
|             # similarly to generic vimeo embeds (e.g. |  | ||||||
|             # https://vimeo.com/ondemand/36938/126682985). |  | ||||||
|             VimeoIE._smuggle_referrer(self._og_search_video_url(webpage), url), |  | ||||||
|             VimeoIE.ie_key()) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoChannelIE(VimeoBaseInfoExtractor): | class VimeoChannelIE(VimeoBaseInfoExtractor): | ||||||
|     IE_NAME = 'vimeo:channel' |     IE_NAME = 'vimeo:channel' | ||||||
| @@ -815,6 +832,7 @@ class VimeoChannelIE(VimeoBaseInfoExtractor): | |||||||
|         }, |         }, | ||||||
|         'playlist_mincount': 25, |         'playlist_mincount': 25, | ||||||
|     }] |     }] | ||||||
|  |     _BASE_URL_TEMPL = 'https://vimeo.com/channels/%s' | ||||||
|  |  | ||||||
|     def _page_url(self, base_url, pagenum): |     def _page_url(self, base_url, pagenum): | ||||||
|         return '%s/videos/page:%d/' % (base_url, pagenum) |         return '%s/videos/page:%d/' % (base_url, pagenum) | ||||||
| @@ -886,14 +904,13 @@ class VimeoChannelIE(VimeoBaseInfoExtractor): | |||||||
|         return self.playlist_result(title_and_entries, list_id, list_title) |         return self.playlist_result(title_and_entries, list_id, list_title) | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |     def _real_extract(self, url): | ||||||
|         mobj = re.match(self._VALID_URL, url) |         channel_id = self._match_id(url) | ||||||
|         channel_id = mobj.group('id') |         return self._extract_videos(channel_id, self._BASE_URL_TEMPL % channel_id) | ||||||
|         return self._extract_videos(channel_id, 'https://vimeo.com/channels/%s' % channel_id) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoUserIE(VimeoChannelIE): | class VimeoUserIE(VimeoChannelIE): | ||||||
|     IE_NAME = 'vimeo:user' |     IE_NAME = 'vimeo:user' | ||||||
|     _VALID_URL = r'https://vimeo\.com/(?!(?:[0-9]+|watchlater)(?:$|[?#/]))(?P<name>[^/]+)(?:/videos|[#?]|$)' |     _VALID_URL = r'https://vimeo\.com/(?!(?:[0-9]+|watchlater)(?:$|[?#/]))(?P<id>[^/]+)(?:/videos|[#?]|$)' | ||||||
|     _TITLE_RE = r'<a[^>]+?class="user">([^<>]+?)</a>' |     _TITLE_RE = r'<a[^>]+?class="user">([^<>]+?)</a>' | ||||||
|     _TESTS = [{ |     _TESTS = [{ | ||||||
|         'url': 'https://vimeo.com/nkistudio/videos', |         'url': 'https://vimeo.com/nkistudio/videos', | ||||||
| @@ -903,11 +920,7 @@ class VimeoUserIE(VimeoChannelIE): | |||||||
|         }, |         }, | ||||||
|         'playlist_mincount': 66, |         'playlist_mincount': 66, | ||||||
|     }] |     }] | ||||||
|  |     _BASE_URL_TEMPL = 'https://vimeo.com/%s' | ||||||
|     def _real_extract(self, url): |  | ||||||
|         mobj = re.match(self._VALID_URL, url) |  | ||||||
|         name = mobj.group('name') |  | ||||||
|         return self._extract_videos(name, 'https://vimeo.com/%s' % name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoAlbumIE(VimeoChannelIE): | class VimeoAlbumIE(VimeoChannelIE): | ||||||
| @@ -969,25 +982,18 @@ class VimeoAlbumIE(VimeoChannelIE): | |||||||
|             r'<title>\s*(.+?)(?:\s+on Vimeo)?</title>', webpage, 'title', fatal=False)) |             r'<title>\s*(.+?)(?:\s+on Vimeo)?</title>', webpage, 'title', fatal=False)) | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoGroupsIE(VimeoAlbumIE): | class VimeoGroupsIE(VimeoChannelIE): | ||||||
|     IE_NAME = 'vimeo:group' |     IE_NAME = 'vimeo:group' | ||||||
|     _VALID_URL = r'https://vimeo\.com/groups/(?P<name>[^/]+)(?:/(?!videos?/\d+)|$)' |     _VALID_URL = r'https://vimeo\.com/groups/(?P<id>[^/]+)(?:/(?!videos?/\d+)|$)' | ||||||
|     _TESTS = [{ |     _TESTS = [{ | ||||||
|         'url': 'https://vimeo.com/groups/rolexawards', |         'url': 'https://vimeo.com/groups/kattykay', | ||||||
|         'info_dict': { |         'info_dict': { | ||||||
|             'id': 'rolexawards', |             'id': 'kattykay', | ||||||
|             'title': 'Rolex Awards for Enterprise', |             'title': 'Katty Kay', | ||||||
|         }, |         }, | ||||||
|         'playlist_mincount': 73, |         'playlist_mincount': 27, | ||||||
|     }] |     }] | ||||||
|  |     _BASE_URL_TEMPL = 'https://vimeo.com/groups/%s' | ||||||
|     def _extract_list_title(self, webpage): |  | ||||||
|         return self._og_search_title(webpage, fatal=False) |  | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |  | ||||||
|         mobj = re.match(self._VALID_URL, url) |  | ||||||
|         name = mobj.group('name') |  | ||||||
|         return self._extract_videos(name, 'https://vimeo.com/groups/%s' % name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class VimeoReviewIE(VimeoBaseInfoExtractor): | class VimeoReviewIE(VimeoBaseInfoExtractor): | ||||||
| @@ -1003,7 +1009,9 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): | |||||||
|             'title': "DICK HARDWICK 'Comedian'", |             'title': "DICK HARDWICK 'Comedian'", | ||||||
|             'uploader': 'Richard Hardwick', |             'uploader': 'Richard Hardwick', | ||||||
|             'uploader_id': 'user21297594', |             'uploader_id': 'user21297594', | ||||||
|         } |             'description': "Comedian Dick Hardwick's five minute demo filmed in front of a live theater audience.\nEdit by Doug Mattocks", | ||||||
|  |         }, | ||||||
|  |         'expected_warnings': ['Unable to download JSON metadata'], | ||||||
|     }, { |     }, { | ||||||
|         'note': 'video player needs Referer', |         'note': 'video player needs Referer', | ||||||
|         'url': 'https://vimeo.com/user22258446/review/91613211/13f927e053', |         'url': 'https://vimeo.com/user22258446/review/91613211/13f927e053', | ||||||
| @@ -1016,7 +1024,8 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): | |||||||
|             'duration': 2773, |             'duration': 2773, | ||||||
|             'thumbnail': r're:^https?://.*\.jpg$', |             'thumbnail': r're:^https?://.*\.jpg$', | ||||||
|             'uploader_id': 'user22258446', |             'uploader_id': 'user22258446', | ||||||
|         } |         }, | ||||||
|  |         'skip': 'video gone', | ||||||
|     }, { |     }, { | ||||||
|         'note': 'Password protected', |         'note': 'Password protected', | ||||||
|         'url': 'https://vimeo.com/user37284429/review/138823582/c4d865efde', |         'url': 'https://vimeo.com/user37284429/review/138823582/c4d865efde', | ||||||
| @@ -1036,32 +1045,20 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): | |||||||
|     def _real_initialize(self): |     def _real_initialize(self): | ||||||
|         self._login() |         self._login() | ||||||
|  |  | ||||||
|     def _get_config_url(self, webpage_url, video_id, video_password_verified=False): |  | ||||||
|         webpage = self._download_webpage(webpage_url, video_id) |  | ||||||
|         config_url = self._html_search_regex( |  | ||||||
|             r'data-config-url=(["\'])(?P<url>(?:(?!\1).)+)\1', webpage, |  | ||||||
|             'config URL', default=None, group='url') |  | ||||||
|         if not config_url: |  | ||||||
|             data = self._parse_json(self._search_regex( |  | ||||||
|                 r'window\s*=\s*_extend\(window,\s*({.+?})\);', webpage, 'data', |  | ||||||
|                 default=NO_DEFAULT if video_password_verified else '{}'), video_id) |  | ||||||
|             config = data.get('vimeo_esi', {}).get('config', {}) |  | ||||||
|             config_url = config.get('configUrl') or try_get(config, lambda x: x['clipData']['configUrl']) |  | ||||||
|         if config_url is None: |  | ||||||
|             self._verify_video_password(webpage_url, video_id, webpage) |  | ||||||
|             config_url = self._get_config_url( |  | ||||||
|                 webpage_url, video_id, video_password_verified=True) |  | ||||||
|         return config_url |  | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |     def _real_extract(self, url): | ||||||
|         page_url, video_id = re.match(self._VALID_URL, url).groups() |         page_url, video_id = re.match(self._VALID_URL, url).groups() | ||||||
|         config_url = self._get_config_url(url, video_id) |         clip_data = self._download_json( | ||||||
|  |             page_url.replace('/review/', '/review/data/'), | ||||||
|  |             video_id)['clipData'] | ||||||
|  |         config_url = clip_data['configUrl'] | ||||||
|         config = self._download_json(config_url, video_id) |         config = self._download_json(config_url, video_id) | ||||||
|         info_dict = self._parse_config(config, video_id) |         info_dict = self._parse_config(config, video_id) | ||||||
|         source_format = self._extract_original_format(page_url, video_id) |         source_format = self._extract_original_format( | ||||||
|  |             page_url + '/action', video_id) | ||||||
|         if source_format: |         if source_format: | ||||||
|             info_dict['formats'].append(source_format) |             info_dict['formats'].append(source_format) | ||||||
|         self._vimeo_sort_formats(info_dict['formats']) |         self._vimeo_sort_formats(info_dict['formats']) | ||||||
|  |         info_dict['description'] = clean_html(clip_data.get('description')) | ||||||
|         return info_dict |         return info_dict | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Remita Amine
					Remita Amine