summaryrefslogtreecommitdiff
path: root/youtube_dl/extractor/vine.py
blob: 46950d3a1499b20bec50a9482d47a0ebdbbfb8b3 (plain)
    1 # coding: utf-8
    2 from __future__ import unicode_literals
    3 
    4 import re
    5 import itertools
    6 
    7 from .common import InfoExtractor
    8 from ..utils import (
    9     determine_ext,
   10     int_or_none,
   11     unified_timestamp,
   12 )
   13 
   14 
   15 class VineIE(InfoExtractor):
   16     _VALID_URL = r'https?://(?:www\.)?vine\.co/(?:v|oembed)/(?P<id>\w+)'
   17     _TESTS = [{
   18         'url': 'https://vine.co/v/b9KOOWX7HUx',
   19         'md5': '2f36fed6235b16da96ce9b4dc890940d',
   20         'info_dict': {
   21             'id': 'b9KOOWX7HUx',
   22             'ext': 'mp4',
   23             'title': 'Chicken.',
   24             'alt_title': 'Vine by Jack',
   25             'timestamp': 1368997951,
   26             'upload_date': '20130519',
   27             'uploader': 'Jack',
   28             'uploader_id': '76',
   29             'view_count': int,
   30             'like_count': int,
   31             'comment_count': int,
   32             'repost_count': int,
   33         },
   34     }, {
   35         'url': 'https://vine.co/v/e192BnZnZ9V',
   36         'info_dict': {
   37             'id': 'e192BnZnZ9V',
   38             'ext': 'mp4',
   39             'title': 'ยิ้ม~ เขิน~ อาย~ น่าร้ากอ้ะ >//< @n_whitewo @orlameena #lovesicktheseries  #lovesickseason2',
   40             'alt_title': 'Vine by Pimry_zaa',
   41             'timestamp': 1436057405,
   42             'upload_date': '20150705',
   43             'uploader': 'Pimry_zaa',
   44             'uploader_id': '1135760698325307392',
   45             'view_count': int,
   46             'like_count': int,
   47             'comment_count': int,
   48             'repost_count': int,
   49         },
   50         'params': {
   51             'skip_download': True,
   52         },
   53     }, {
   54         'url': 'https://vine.co/v/MYxVapFvz2z',
   55         'only_matching': True,
   56     }, {
   57         'url': 'https://vine.co/v/bxVjBbZlPUH',
   58         'only_matching': True,
   59     }, {
   60         'url': 'https://vine.co/oembed/MYxVapFvz2z.json',
   61         'only_matching': True,
   62     }]
   63 
   64     def _real_extract(self, url):
   65         video_id = self._match_id(url)
   66 
   67         data = self._download_json(
   68             'https://archive.vine.co/posts/%s.json' % video_id, video_id)
   69 
   70         def video_url(kind):
   71             for url_suffix in ('Url', 'URL'):
   72                 format_url = data.get('video%s%s' % (kind, url_suffix))
   73                 if format_url:
   74                     return format_url
   75 
   76         formats = []
   77         for quality, format_id in enumerate(('low', '', 'dash')):
   78             format_url = video_url(format_id.capitalize())
   79             if not format_url:
   80                 continue
   81             # DASH link returns plain mp4
   82             if format_id == 'dash' and determine_ext(format_url) == 'mpd':
   83                 formats.extend(self._extract_mpd_formats(
   84                     format_url, video_id, mpd_id='dash', fatal=False))
   85             else:
   86                 formats.append({
   87                     'url': format_url,
   88                     'format_id': format_id or 'standard',
   89                     'quality': quality,
   90                 })
   91         self._sort_formats(formats)
   92 
   93         username = data.get('username')
   94 
   95         alt_title = 'Vine by %s' % username if username else None
   96 
   97         return {
   98             'id': video_id,
   99             'title': data.get('description') or alt_title or 'Vine video',
  100             'alt_title': alt_title,
  101             'thumbnail': data.get('thumbnailUrl'),
  102             'timestamp': unified_timestamp(data.get('created')),
  103             'uploader': username,
  104             'uploader_id': data.get('userIdStr'),
  105             'view_count': int_or_none(data.get('loops')),
  106             'like_count': int_or_none(data.get('likes')),
  107             'comment_count': int_or_none(data.get('comments')),
  108             'repost_count': int_or_none(data.get('reposts')),
  109             'formats': formats,
  110         }
  111 
  112 
  113 class VineUserIE(InfoExtractor):
  114     IE_NAME = 'vine:user'
  115     _VALID_URL = r'(?:https?://)?vine\.co/(?P<u>u/)?(?P<user>[^/]+)/?(\?.*)?$'
  116     _VINE_BASE_URL = 'https://vine.co/'
  117     _TESTS = [
  118         {
  119             'url': 'https://vine.co/Visa',
  120             'info_dict': {
  121                 'id': 'Visa',
  122             },
  123             'playlist_mincount': 46,
  124         },
  125         {
  126             'url': 'https://vine.co/u/941705360593584128',
  127             'only_matching': True,
  128         },
  129     ]
  130 
  131     def _real_extract(self, url):
  132         mobj = re.match(self._VALID_URL, url)
  133         user = mobj.group('user')
  134         u = mobj.group('u')
  135 
  136         profile_url = '%sapi/users/profiles/%s%s' % (
  137             self._VINE_BASE_URL, 'vanity/' if not u else '', user)
  138         profile_data = self._download_json(
  139             profile_url, user, note='Downloading user profile data')
  140 
  141         user_id = profile_data['data']['userId']
  142         timeline_data = []
  143         for pagenum in itertools.count(1):
  144             timeline_url = '%sapi/timelines/users/%s?page=%s&size=100' % (
  145                 self._VINE_BASE_URL, user_id, pagenum)
  146             timeline_page = self._download_json(
  147                 timeline_url, user, note='Downloading page %d' % pagenum)
  148             timeline_data.extend(timeline_page['data']['records'])
  149             if timeline_page['data']['nextPage'] is None:
  150                 break
  151 
  152         entries = [
  153             self.url_result(e['permalinkUrl'], 'Vine') for e in timeline_data]
  154         return self.playlist_result(entries, user)

Generated by cgit