summaryrefslogtreecommitdiff
path: root/youtube_dl/extractor/nowness.py
blob: f26dafb8f03db4c937ace6607f2ddc795fb245de (plain)
    1 # coding: utf-8
    2 from __future__ import unicode_literals
    3 
    4 from .brightcove import (
    5     BrightcoveLegacyIE,
    6     BrightcoveNewIE,
    7 )
    8 from .common import InfoExtractor
    9 from ..compat import compat_str
   10 from ..utils import (
   11     ExtractorError,
   12     sanitized_Request,
   13 )
   14 
   15 
   16 class NownessBaseIE(InfoExtractor):
   17     def _extract_url_result(self, post):
   18         if post['type'] == 'video':
   19             for media in post['media']:
   20                 if media['type'] == 'video':
   21                     video_id = media['content']
   22                     source = media['source']
   23                     if source == 'brightcove':
   24                         player_code = self._download_webpage(
   25                             'http://www.nowness.com/iframe?id=%s' % video_id, video_id,
   26                             note='Downloading player JavaScript',
   27                             errnote='Unable to download player JavaScript')
   28                         bc_url = BrightcoveLegacyIE._extract_brightcove_url(player_code)
   29                         if bc_url:
   30                             return self.url_result(bc_url, BrightcoveLegacyIE.ie_key())
   31                         bc_url = BrightcoveNewIE._extract_url(self, player_code)
   32                         if bc_url:
   33                             return self.url_result(bc_url, BrightcoveNewIE.ie_key())
   34                         raise ExtractorError('Could not find player definition')
   35                     elif source == 'vimeo':
   36                         return self.url_result('http://vimeo.com/%s' % video_id, 'Vimeo')
   37                     elif source == 'youtube':
   38                         return self.url_result(video_id, 'Youtube')
   39                     elif source == 'cinematique':
   40                         # youtube-dl currently doesn't support cinematique
   41                         # return self.url_result('http://cinematique.com/embed/%s' % video_id, 'Cinematique')
   42                         pass
   43 
   44     def _api_request(self, url, request_path):
   45         display_id = self._match_id(url)
   46         request = sanitized_Request(
   47             'http://api.nowness.com/api/' + request_path % display_id,
   48             headers={
   49                 'X-Nowness-Language': 'zh-cn' if 'cn.nowness.com' in url else 'en-us',
   50             })
   51         return display_id, self._download_json(request, display_id)
   52 
   53 
   54 class NownessIE(NownessBaseIE):
   55     IE_NAME = 'nowness'
   56     _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/(?:story|(?:series|category)/[^/]+)/(?P<id>[^/]+?)(?:$|[?#])'
   57     _TESTS = [{
   58         'url': 'https://www.nowness.com/story/candor-the-art-of-gesticulation',
   59         'md5': '068bc0202558c2e391924cb8cc470676',
   60         'info_dict': {
   61             'id': '2520295746001',
   62             'ext': 'mp4',
   63             'title': 'Candor: The Art of Gesticulation',
   64             'description': 'Candor: The Art of Gesticulation',
   65             'thumbnail': r're:^https?://.*\.jpg',
   66             'timestamp': 1446745676,
   67             'upload_date': '20151105',
   68             'uploader_id': '2385340575001',
   69         },
   70         'add_ie': ['BrightcoveNew'],
   71     }, {
   72         'url': 'https://cn.nowness.com/story/kasper-bjorke-ft-jaakko-eino-kalevi-tnr',
   73         'md5': 'e79cf125e387216f86b2e0a5b5c63aa3',
   74         'info_dict': {
   75             'id': '3716354522001',
   76             'ext': 'mp4',
   77             'title': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
   78             'description': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
   79             'thumbnail': r're:^https?://.*\.jpg',
   80             'timestamp': 1407315371,
   81             'upload_date': '20140806',
   82             'uploader_id': '2385340575001',
   83         },
   84         'add_ie': ['BrightcoveNew'],
   85     }, {
   86         # vimeo
   87         'url': 'https://www.nowness.com/series/nowness-picks/jean-luc-godard-supercut',
   88         'md5': '9a5a6a8edf806407e411296ab6bc2a49',
   89         'info_dict': {
   90             'id': '130020913',
   91             'ext': 'mp4',
   92             'title': 'Bleu, Blanc, Rouge - A Godard Supercut',
   93             'description': 'md5:f0ea5f1857dffca02dbd37875d742cec',
   94             'thumbnail': r're:^https?://.*\.jpg',
   95             'upload_date': '20150607',
   96             'uploader': 'Cinema Sem Lei',
   97             'uploader_id': 'cinemasemlei',
   98         },
   99         'add_ie': ['Vimeo'],
  100     }]
  101 
  102     def _real_extract(self, url):
  103         _, post = self._api_request(url, 'post/getBySlug/%s')
  104         return self._extract_url_result(post)
  105 
  106 
  107 class NownessPlaylistIE(NownessBaseIE):
  108     IE_NAME = 'nowness:playlist'
  109     _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/playlist/(?P<id>\d+)'
  110     _TEST = {
  111         'url': 'https://www.nowness.com/playlist/3286/i-guess-thats-why-they-call-it-the-blues',
  112         'info_dict': {
  113             'id': '3286',
  114         },
  115         'playlist_mincount': 8,
  116     }
  117 
  118     def _real_extract(self, url):
  119         playlist_id, playlist = self._api_request(url, 'post?PlaylistId=%s')
  120         entries = [self._extract_url_result(item) for item in playlist['items']]
  121         return self.playlist_result(entries, playlist_id)
  122 
  123 
  124 class NownessSeriesIE(NownessBaseIE):
  125     IE_NAME = 'nowness:series'
  126     _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/series/(?P<id>[^/]+?)(?:$|[?#])'
  127     _TEST = {
  128         'url': 'https://www.nowness.com/series/60-seconds',
  129         'info_dict': {
  130             'id': '60',
  131             'title': '60 Seconds',
  132             'description': 'One-minute wisdom in a new NOWNESS series',
  133         },
  134         'playlist_mincount': 4,
  135     }
  136 
  137     def _real_extract(self, url):
  138         display_id, series = self._api_request(url, 'series/getBySlug/%s')
  139         entries = [self._extract_url_result(post) for post in series['posts']]
  140         series_title = None
  141         series_description = None
  142         translations = series.get('translations', [])
  143         if translations:
  144             series_title = translations[0].get('title') or translations[0]['seoTitle']
  145             series_description = translations[0].get('seoDescription')
  146         return self.playlist_result(
  147             entries, compat_str(series['id']), series_title, series_description)

Generated by cgit