]>
 
 
Raphaël G. Git Repositories - youtubedl/blob - youtube_dl/extractor/vimeo.py 
 
 
 
 
 
 
 
 
   2  from  __future__ 
import  unicode_literals
 
   8  from  . common 
import  InfoExtractor
 
  12      compat_urllib_request
,  
  28  class  VimeoBaseInfoExtractor ( InfoExtractor
):  
  29      _NETRC_MACHINE 
=  'vimeo'  
  30      _LOGIN_REQUIRED 
=  False  
  33          ( username
,  password
) =  self
._ get
_l ogin
_ info
()  
  35              if  self
._L OGIN
_ REQUIRED
:  
  36                  raise  ExtractorError ( 'No login info available, needed for using  %s .'  %  self
. IE_NAME
,  expected
= True )  
  39          login_url 
=  'https://vimeo.com/log_in'  
  40          webpage 
=  self
._ download
_ webpage
( login_url
,  None ,  False )  
  41          token 
=  self
._ search
_ regex
( r
'xsrft":"(.*?)"' ,  webpage
,  'login token' )  
  42          data 
=  urlencode_postdata ({  
  49          login_request 
=  compat_urllib_request
. Request ( login_url
,  data
)  
  50          login_request
. add_header ( 'Content-Type' ,  'application/x-www-form-urlencoded' )  
  51          login_request
. add_header ( 'Cookie' ,  'xsrft= %s '  %  token
)  
  52          self
._ download
_ webpage
( login_request
,  None ,  False ,  'Wrong login info' )  
  55  class  VimeoIE ( VimeoBaseInfoExtractor
):  
  56      """Information extractor for vimeo.com."""  
  58      # _VALID_URL matches Vimeo URLs  
  61          (?:(?:www|(?P<player>player))\.)?  
  62          vimeo(?P<pro>pro)?\.com/  
  63          (?!channels/[^/?#]+/?(?:$|[?#])|album/)  
  65          (?:(?:play_redirect_hls|moogaloop\.swf)\?clip_id=)?  
  68          /?(?:[?&].*)?(?:[#].*)?$'''  
  72              'url' :  'http://vimeo.com/56015672#at=0' ,  
  73              'md5' :  '8879b6cc097e987f02484baf890129e5' ,  
  77                  "upload_date" :  "20121220" ,  
  78                  "description" :  "This is a test case for youtube-dl. \n For more information, see github.com/rg3/youtube-dl \n Test chars: \u2605  \"  ' \u5e78 /  \\  \u00e4 \u21ad \U0001d550" ,  
  79                  "uploader_id" :  "user7108434" ,  
  80                  "uploader" :  "Filippo Valsorda" ,  
  81                  "title" :  "youtube-dl test video - \u2605  \"  ' \u5e78 /  \\  \u00e4 \u21ad \U0001d550" ,  
  86              'url' :  'http://vimeopro.com/openstreetmapus/state-of-the-map-us-2013/video/68093876' ,  
  87              'md5' :  '3b5ca6aa22b60dfeeadf50b72e44ed82' ,  
  88              'note' :  'Vimeo Pro video (#1197)' ,  
  92                  'uploader_id' :  'openstreetmapus' ,  
  93                  'uploader' :  'OpenStreetMap US' ,  
  94                  'title' :  'Andy Allan - Putting the Carto into OpenStreetMap Cartography' ,  
  95                  'description' :  'md5:380943ec71b89736ff4bf27183233d09' ,  
 100              'url' :  'http://player.vimeo.com/video/54469442' ,  
 101              'md5' :  '619b811a4417aa4abe78dc653becf511' ,  
 102              'note' :  'Videos that embed the url in the player page' ,  
 106                  'title' :  'Kathy Sierra: Building the minimum Badass User, Business of Software 2012' ,  
 107                  'uploader' :  'The BLN & Business of Software' ,  
 108                  'uploader_id' :  'theblnbusinessofsoftware' ,  
 114              'url' :  'http://vimeo.com/68375962' ,  
 115              'md5' :  'aaf896bdb7ddd6476df50007a0ac0ae7' ,  
 116              'note' :  'Video protected with password' ,  
 120                  'title' :  'youtube-dl password protected test video' ,  
 121                  'upload_date' :  '20130614' ,  
 122                  'uploader_id' :  'user18948128' ,  
 123                  'uploader' :  'Jaime Marquínez Ferrándiz' ,  
 125                  'description' :  'This is "youtube-dl password protected test video" by Jaime Marquínez Ferrándiz on Vimeo, the home for high quality videos and the people who love them.' ,  
 128                  'videopassword' :  'youtube-dl' ,  
 132              'url' :  'http://vimeo.com/channels/keypeele/75629013' ,  
 133              'md5' :  '2f86a05afe9d7abc0b9126d229bbe15d' ,  
 134              'note' :  'Video is freely available via original URL '  
 135                      'and protected with password when accessed via http://vimeo.com/75629013' ,  
 139                  'title' :  'Key & Peele: Terrorist Interrogation' ,  
 140                  'description' :  'md5:8678b246399b070816b12313e8b4eb5c' ,  
 141                  'uploader_id' :  'atencio' ,  
 142                  'uploader' :  'Peter Atencio' ,  
 143                  'upload_date' :  '20130927' ,  
 148              'url' :  'http://vimeo.com/76979871' ,  
 149              'md5' :  '3363dd6ffebe3784d56f4132317fd446' ,  
 150              'note' :  'Video with subtitles' ,  
 154                  'title' :  'The New Vimeo Player (You Know, For Videos)' ,  
 155                  'description' :  'md5:2ec900bf97c3f389378a96aee11260ea' ,  
 156                  'upload_date' :  '20131015' ,  
 157                  'uploader_id' :  'staff' ,  
 158                  'uploader' :  'Vimeo Staff' ,  
 163              # from https://www.ouya.tv/game/Pier-Solar-and-the-Great-Architects/  
 164              'url' :  'https://player.vimeo.com/video/98044508' ,  
 165              'note' :  'The js code contains assignments to the same variable as the config' ,  
 169                  'title' :  'Pier Solar OUYA Official Trailer' ,  
 170                  'uploader' :  'Tulio Gonçalves' ,  
 171                  'uploader_id' :  'user28849593' ,  
 176      def  _verify_video_password ( self
,  url
,  video_id
,  webpage
):  
 177          password 
=  self
._ downloader
. params
. get ( 'videopassword' ,  None )  
 179              raise  ExtractorError ( 'This video is protected by a password, use the --video-password option' ,  expected
= True )  
 180          token 
=  self
._ search
_ regex
( r
'xsrft[\s=:"\' ]+([ ^
" \' ]+)', webpage, 'login token')  
 181          data = urlencode_postdata({  
 182              'password': password,  
 185          if url.startswith('http://'):  
 186              # vimeo only supports https now, but the user can give an http url  
 187              url = url.replace('http://', 'https://')  
 188          password_request = compat_urllib_request.Request(url + '/password', data)  
 189          password_request.add_header('Content-Type', 'application/x-www-form-urlencoded')  
 190          password_request.add_header('Cookie', 'xsrft= %s ' % token)  
 191          return self._download_webpage(  
 192              password_request, video_id,  
 193              'Verifying the password', 'Wrong password')  
 195      def _verify_player_video_password(self, url, video_id):  
 196          password = self._downloader.params.get('videopassword', None)  
 198              raise ExtractorError('This video is protected by a password, use the --video-password option')  
 199          data = compat_urllib_parse.urlencode({'password': password})  
 200          pass_url = url + '/check-password'  
 201          password_request = compat_urllib_request.Request(pass_url, data)  
 202          password_request.add_header('Content-Type', 'application/x-www-form-urlencoded')  
 203          return self._download_json(  
 204              password_request, video_id,  
 205              'Verifying the password',  
 208      def _real_initialize(self):  
 211      def _real_extract(self, url):  
 212          url, data = unsmuggle_url(url)  
 213          headers = std_headers  
 215              headers = headers.copy()  
 217          if 'Referer' not in headers:  
 218              headers['Referer'] = url  
 220          # Extract ID from URL  
 221          mobj = re.match(self._VALID_URL, url)  
 222          video_id = mobj.group('id')  
 224          if mobj.group('pro') or mobj.group('player'):  
 225              url = 'https://player.vimeo.com/video/' + video_id  
 227              url = 'https://vimeo.com/' + video_id  
 229          # Retrieve video webpage to extract further information  
 230          request = compat_urllib_request.Request(url, None, headers)  
 232              webpage = self._download_webpage(request, video_id)  
 233          except ExtractorError as ee:  
 234              if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 403:  
 235                  errmsg = ee.cause.read()  
 236                  if b'Because of its privacy settings, this video cannot be played here' in errmsg:  
 237                      raise ExtractorError(  
 238                          'Cannot download embed-only video without embedding '  
 239                          'URL. Please call youtube-dl with the URL of the page '  
 240                          'that embeds this video.',  
 244          # Now we begin extracting as much information as we can from what we  
 245          # retrieved. First we extract the information common to all extractors,  
 246          # and latter we extract those that are Vimeo specific.  
 247          self.report_extraction(video_id)  
 249          vimeo_config = self._search_regex(  
 250              r'vimeo\.config\s*=\s*({.+?});', webpage,  
 251              'vimeo config', default=None)  
 253              seed_status = self._parse_json(vimeo_config, video_id).get('seed_status', {})  
 254              if seed_status.get('state') == 'failed':  
 255                  raise ExtractorError(  
 256                      ' %s  returned error:  %s ' % (self.IE_NAME, seed_status['title']),  
 259          # Extract the config JSON  
 262                  config_url = self._html_search_regex(  
 263                      r' data-config-url=" (.+ ?
) "', webpage, 'config URL')  
 264                  config_json = self._download_webpage(config_url, video_id)  
 265                  config = json.loads(config_json)  
 266              except RegexNotFoundError:  
 267                  # For pro videos or player.vimeo.com urls  
 268                  # We try to find out to which variable is assigned the config dic  
 269                  m_variable_name = re.search('(\w)\.video\.id', webpage)  
 270                  if m_variable_name is not None:  
 271                      config_re = r' %s =({[^}].+?});' % re.escape(m_variable_name.group(1))  
 273                      config_re = [r' = {config:({.+?}),assets:', r'(?:[abc])=({.+?});']  
 274                  config = self._search_regex(config_re, webpage, 'info section',  
 276                  config = json.loads(config)  
 277          except Exception as e:  
 278              if re.search('The creator of this video has not given you permission to embed it on this domain.', webpage):  
 279                  raise ExtractorError('The author has restricted the access to this video, try with the " -- referer
" option')  
 281              if re.search(r'<form[^>]+?id=" pw_form
"', webpage) is not None:  
 282                  if data and '_video_password_verified' in data:  
 283                      raise ExtractorError('video password verification failed!')  
 284                  self._verify_video_password(url, video_id, webpage)  
 285                  return self._real_extract(  
 286                      smuggle_url(url, {'_video_password_verified': 'verified'}))  
 288                  raise ExtractorError('Unable to extract info section',  
 291              if config.get('view') == 4:  
 292                  config = self._verify_player_video_password(url, video_id)  
 295          video_title = config[" video
"][" title
"]  
 297          # Extract uploader and uploader_id  
 298          video_uploader = config[" video
"][" owner
"][" name
"]  
 299          video_uploader_id = config[" video
"][" owner
"][" url
"].split('/')[-1] if config[" video
"][" owner
"][" url
"] else None  
 301          # Extract video thumbnail  
 302          video_thumbnail = config[" video
"].get(" thumbnail
")  
 303          if video_thumbnail is None:  
 304              video_thumbs = config[" video
"].get(" thumbs
")  
 305              if video_thumbs and isinstance(video_thumbs, dict):  
 306                  _, video_thumbnail = sorted((int(width if width.isdigit() else 0), t_url) for (width, t_url) in video_thumbs.items())[-1]  
 308          # Extract video description  
 310          video_description = self._html_search_regex(  
 311              r'(?s)<div\s+class=" [ ^
"]*description[^" ]* "[^>]*>(.*?)</div>',  
 312              webpage, 'description', default=None)  
 313          if not video_description:  
 314              video_description = self._html_search_meta(  
 315                  'description', webpage, default=None)  
 316          if not video_description and mobj.group('pro'):  
 317              orig_webpage = self._download_webpage(  
 319                  note='Downloading webpage for description',  
 322                  video_description = self._html_search_meta(  
 323                      'description', orig_webpage, default=None)  
 324          if not video_description and not mobj.group('player'):  
 325              self._downloader.report_warning('Cannot find video description')  
 327          # Extract video duration  
 328          video_duration = int_or_none(config[" video
"].get(" duration
"))  
 330          # Extract upload date  
 331          video_upload_date = None  
 332          mobj = re.search(r'<time[^>]+datetime=" ([ ^
"]+)" ', webpage)  
 334              video_upload_date = unified_strdate(mobj.group(1))  
 337              view_count = int(self._search_regex(r' UserPlays
:( \d
+) ', webpage, ' view count
'))  
 338              like_count = int(self._search_regex(r' UserLikes
:( \d
+) ', webpage, ' like count
'))  
 339              comment_count = int(self._search_regex(r' UserComments
:( \d
+) ', webpage, ' comment count
'))  
 340          except RegexNotFoundError:  
 341              # This info is only available in vimeo.com/ {id}  urls  
 346          # Vimeo specific: extract request signature and timestamp  
 347          sig = config[' request
'][' signature
']  
 348          timestamp = config[' request
'][' timestamp
']  
 350          # Vimeo specific: extract video codec and quality information  
 351          # First consider quality, then codecs, then take everything  
 352          codecs = [(' vp6
', ' flv
'), (' vp8
', ' flv
'), (' h264
', ' mp4
')]  
 353          files = {' hd
': [], ' sd
': [], ' other
': []}  
 354          config_files = config["video"].get("files") or config["request"].get("files")  
 355          for codec_name, codec_extension in codecs:  
 356              for quality in config_files.get(codec_name, []):  
 357                  format_id = ' - '.join((codec_name, quality)).lower()  
 358                  key = quality if quality in files else ' other
'  
 360                  if isinstance(config_files[codec_name], dict):  
 361                      file_info = config_files[codec_name][quality]  
 362                      video_url = file_info.get(' url
')  
 365                  if video_url is None:  
 366                      video_url = "http://player.vimeo.com/play_redirect?clip_id= %s &sig= %s &time= %s &quality= %s &codecs= %s &type=moogaloop_local&embed_location=" \  
 367                          % (video_id, sig, timestamp, quality, codec_name.upper())  
 370                      ' ext
': codec_extension,  
 372                      ' format_id
': format_id,  
 373                      ' width
': file_info.get(' width
'),  
 374                      ' height
': file_info.get(' height
'),  
 377          for key in (' other
', ' sd
', ' hd
'):  
 378              formats += files[key]  
 379          if len(formats) == 0:  
 380              raise ExtractorError(' No known codec found
')  
 383          text_tracks = config[' request
'].get(' text_tracks
')  
 385              for tt in text_tracks:  
 386                  subtitles[tt[' lang
']] = [{  
 388                      ' url
': ' https
:// vimeo
. com
' + tt[' url
'],  
 393              ' uploader
': video_uploader,  
 394              ' uploader_id
': video_uploader_id,  
 395              ' upload_date
': video_upload_date,  
 396              ' title
': video_title,  
 397              ' thumbnail
': video_thumbnail,  
 398              ' description
': video_description,  
 399              ' duration
': video_duration,  
 402              ' view_count
': view_count,  
 403              ' like_count
': like_count,  
 404              ' comment_count
': comment_count,  
 405              ' subtitles
': subtitles,  
 409  class VimeoChannelIE(InfoExtractor):  
 410      IE_NAME = ' vimeo
: channel
'  
 411      _VALID_URL = r' https
:// vimeo\
. com
/ channels
/( ?P
< id >[ ^
/ ?
#]+)/?(?:$|[?#])'  
 412      _MORE_PAGES_INDICATOR 
=  r
'<a.+?rel="next"'  
 413      _TITLE_RE 
=  r
'<link rel="alternate"[^>]+?title="(.*?)"'  
 415          'url' :  'https://vimeo.com/channels/tributes' ,  
 418              'title' :  'Vimeo Tributes' ,  
 420          'playlist_mincount' :  25 ,  
 423      def  _page_url ( self
,  base_url
,  pagenum
):  
 424          return  ' %s /videos/page: %d /'  % ( base_url
,  pagenum
)  
 426      def  _extract_list_title ( self
,  webpage
):  
 427          return  self
._ html
_ search
_ regex
( self
._ TITLE
_ RE
,  webpage
,  'list title' )  
 429      def  _login_list_password ( self
,  page_url
,  list_id
,  webpage
):  
 430          login_form 
=  self
._ search
_ regex
(  
 431              r
'(?s)<form[^>]+?id="pw_form"(.*?)</form>' ,  
 432              webpage
,  'login form' ,  default
= None )  
 436          password 
=  self
._ downloader
. params
. get ( 'videopassword' ,  None )  
 438              raise  ExtractorError ( 'This album is protected by a password, use the --video-password option' ,  expected
= True )  
 439          fields 
=  dict ( re
. findall ( r
'''(?x)<input\s+  
 444          token 
=  self
._ search
_ regex
( r
'xsrft[\s=:"\' ]+([ ^
" \' ]+)', webpage, 'login token')  
 445          fields['token'] = token  
 446          fields['password'] = password  
 447          post = urlencode_postdata(fields)  
 448          password_path = self._search_regex(  
 449              r'action=" ([ ^
"]+)" ', login_form, ' password URL
')  
 450          password_url = compat_urlparse.urljoin(page_url, password_path)  
 451          password_request = compat_urllib_request.Request(password_url, post)  
 452          password_request.add_header(' Content
- type ', ' application
/ x
- www
- form
- urlencoded
')  
 453          self._set_cookie(' vimeo
. com
', ' xsrft
', token)  
 455          return self._download_webpage(  
 456              password_request, list_id,  
 457              ' Verifying the password
', ' Wrong password
')  
 459      def _extract_videos(self, list_id, base_url):  
 461          for pagenum in itertools.count(1):  
 462              page_url = self._page_url(base_url, pagenum)  
 463              webpage = self._download_webpage(  
 465                  ' Downloading page 
%s ' % pagenum)  
 468                  webpage = self._login_list_password(page_url, list_id, webpage)  
 470              video_ids.extend(re.findall(r' id = "clip_(\d+?)" ', webpage))  
 471              if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None:  
 474          entries = [self.url_result(' https
:// vimeo
. com
/ %s ' % video_id, ' Vimeo
')  
 475                     for video_id in video_ids]  
 476          return {' _type
': ' playlist
',  
 478                  ' title
': self._extract_list_title(webpage),  
 482      def _real_extract(self, url):  
 483          mobj = re.match(self._VALID_URL, url)  
 484          channel_id = mobj.group(' id ')  
 485          return self._extract_videos(channel_id, ' https
:// vimeo
. com
/ channels
/ %s ' % channel_id)  
 488  class VimeoUserIE(VimeoChannelIE):  
 489      IE_NAME = ' vimeo
: user
'  
 490      _VALID_URL = r' https
:// vimeo\
. com
/( ?
![ 0 - 9 ]+( ?
: $|
[ ?
#/]))(?P<name>[^/]+)(?:/videos|[#?]|$)'  
 491      _TITLE_RE 
=  r
'<a[^>]+?class="user">([^<>]+?)</a>'  
 493          'url' :  'https://vimeo.com/nkistudio/videos' ,  
 498          'playlist_mincount' :  66 ,  
 501      def  _real_extract ( self
,  url
):  
 502          mobj 
=  re
. match ( self
._ VALID
_U RL
,  url
)  
 503          name 
=  mobj
. group ( 'name' )  
 504          return  self
._ extract
_ videos
( name
,  'https://vimeo.com/ %s '  %  name
)  
 507  class  VimeoAlbumIE ( VimeoChannelIE
):  
 508      IE_NAME 
=  'vimeo:album'  
 509      _VALID_URL 
=  r
'https://vimeo\.com/album/(?P<id>\d+)'  
 510      _TITLE_RE 
=  r
'<header id="page_header">\n\s*<h1>(.*?)</h1>'  
 512          'url' :  'https://vimeo.com/album/2632481' ,  
 515              'title' :  'Staff Favorites: November 2013' ,  
 517          'playlist_mincount' :  13 ,  
 519          'note' :  'Password-protected album' ,  
 520          'url' :  'https://vimeo.com/album/3253534' ,  
 527              'videopassword' :  'youtube-dl' ,  
 531      def  _page_url ( self
,  base_url
,  pagenum
):  
 532          return  ' %s /page: %d /'  % ( base_url
,  pagenum
)  
 534      def  _real_extract ( self
,  url
):  
 535          album_id 
=  self
._ match
_ id
( url
)  
 536          return  self
._ extract
_ videos
( album_id
,  'https://vimeo.com/album/ %s '  %  album_id
)  
 539  class  VimeoGroupsIE ( VimeoAlbumIE
):  
 540      IE_NAME 
=  'vimeo:group'  
 541      _VALID_URL 
=  r
'https://vimeo\.com/groups/(?P<name>[^/]+)'  
 543          'url' :  'https://vimeo.com/groups/rolexawards' ,  
 546              'title' :  'Rolex Awards for Enterprise' ,  
 548          'playlist_mincount' :  73 ,  
 551      def  _extract_list_title ( self
,  webpage
):  
 552          return  self
._ og
_ search
_ title
( webpage
)  
 554      def  _real_extract ( self
,  url
):  
 555          mobj 
=  re
. match ( self
._ VALID
_U RL
,  url
)  
 556          name 
=  mobj
. group ( 'name' )  
 557          return  self
._ extract
_ videos
( name
,  'https://vimeo.com/groups/ %s '  %  name
)  
 560  class  VimeoReviewIE ( InfoExtractor
):  
 561      IE_NAME 
=  'vimeo:review'  
 562      IE_DESC 
=  'Review pages on vimeo'  
 563      _VALID_URL 
=  r
'https://vimeo\.com/[^/]+/review/(?P<id>[^/]+)'  
 565          'url' :  'https://vimeo.com/user21297594/review/75524534/3c257a1b5d' ,  
 566          'md5' :  'c507a72f780cacc12b2248bb4006d253' ,  
 570              'title' :  "DICK HARDWICK 'Comedian'" ,  
 571              'uploader' :  'Richard Hardwick' ,  
 574          'note' :  'video player needs Referer' ,  
 575          'url' :  'https://vimeo.com/user22258446/review/91613211/13f927e053' ,  
 576          'md5' :  '6295fdab8f4bf6a002d058b2c6dce276' ,  
 580              'title' :  're:(?i)^Death by dogma versus assembling agile . Sander Hoogendoorn' ,  
 581              'uploader' :  'DevWeek Events' ,  
 583              'thumbnail' :  're:^https?://.*\.jpg$' ,  
 587      def  _real_extract ( self
,  url
):  
 588          mobj 
=  re
. match ( self
._ VALID
_U RL
,  url
)  
 589          video_id 
=  mobj
. group ( 'id' )  
 590          player_url 
=  'https://player.vimeo.com/player/'  +  video_id
 
 591          return  self
. url_result ( player_url
,  'Vimeo' ,  video_id
)  
 594  class  VimeoWatchLaterIE ( VimeoBaseInfoExtractor
,  VimeoChannelIE
):  
 595      IE_NAME 
=  'vimeo:watchlater'  
 596      IE_DESC 
=  'Vimeo watch later list, "vimeowatchlater" keyword (requires authentication)'  
 597      _VALID_URL 
=  r
'https://vimeo\.com/home/watchlater|:vimeowatchlater'  
 598      _LOGIN_REQUIRED 
=  True  
 599      _TITLE_RE 
=  r
'href="/home/watchlater".*?>(.*?)<'  
 601          'url' :  'https://vimeo.com/home/watchlater' ,  
 602          'only_matching' :  True ,  
 605      def  _real_initialize ( self
):  
 608      def  _page_url ( self
,  base_url
,  pagenum
):  
 609          url 
=  ' %s /page: %d /'  % ( base_url
,  pagenum
)  
 610          request 
=  compat_urllib_request
. Request ( url
)  
 611          # Set the header to get a partial html page with the ids,  
 612          # the normal page doesn't contain them.  
 613          request
. add_header ( 'X-Requested-With' ,  'XMLHttpRequest' )  
 616      def  _real_extract ( self
,  url
):  
 617          return  self
._ extract
_ videos
( 'watchlater' ,  'https://vimeo.com/home/watchlater' )  
 620  class  VimeoLikesIE ( InfoExtractor
):  
 621      _VALID_URL 
=  r
'https://(?:www\.)?vimeo\.com/user(?P<id>[0-9]+)/likes/?(?:$|[?#]|sort:)'  
 622      IE_NAME 
=  'vimeo:likes'  
 623      IE_DESC 
=  'Vimeo user likes'  
 625          'url' :  'https://vimeo.com/user755559/likes/' ,  
 626          'playlist_mincount' :  293 ,  
 628              'id' :  'user755559_likes' ,  
 629              "description" :  "See all the videos urza likes" ,  
 630              "title" :  'Videos urza likes' ,  
 634      def  _real_extract ( self
,  url
):  
 635          user_id 
=  self
._ match
_ id
( url
)  
 636          webpage 
=  self
._ download
_ webpage
( url
,  user_id
)  
 637          page_count 
=  self
._ int
(  
 639                  r
'''(?x)<li><a\s+href="[^"]+"\s+data-page="([0-9]+)">  
 640                      .*?</a></li>\s*<li\s+class="pagination_next">  
 641                  ''' ,  webpage
,  'page count' ),  
 642              'page count' ,  fatal
= True )  
 644          title 
=  self
._ html
_ search
_ regex
(  
 645              r
'(?s)<h1>(.+?)</h1>' ,  webpage
,  'title' ,  fatal
= False )  
 646          description 
=  self
._ html
_ search
_ meta
( 'description' ,  webpage
)  
 649              page_url 
=  'https://vimeo.com/user %s /likes/page: %d /sort:date'  % (  
 651              webpage 
=  self
._ download
_ webpage
(  
 653                  note
= 'Downloading page  %d / %d '  % ( idx 
+  1 ,  page_count
))  
 654              video_list 
=  self
._ search
_ regex
(  
 655                  r
'(?s)<ol class="js-browse_list[^"]+"[^>]*>(.*?)</ol>' ,  
 656                  webpage
,  'video content' )  
 658                  r
'<li[^>]*>\s*<a\s+href="([^"]+)"' ,  video_list
)  
 662                      'url' :  compat_urlparse
. urljoin ( page_url
,  path
),  
 665          pl 
=  InAdvancePagedList ( _get_page
,  page_count
,  PAGE_SIZE
)  
 669              'id' :  'user %s _likes'  %  user_id
,  
 671              'description' :  description
,