Merge branch 'remitamine-nowness'

This commit is contained in:
Sergey M․ 2015-09-13 19:19:13 +06:00
commit 25cd56a715
2 changed files with 111 additions and 51 deletions

View file

@ -405,7 +405,11 @@
from .nosvideo import NosVideoIE from .nosvideo import NosVideoIE
from .nova import NovaIE from .nova import NovaIE
from .novamov import NovaMovIE from .novamov import NovaMovIE
from .nowness import NownessIE from .nowness import (
NownessIE,
NownessPlaylistIE,
NownessSeriesIE,
)
from .nowtv import NowTVIE from .nowtv import NowTVIE
from .nowvideo import NowVideoIE from .nowvideo import NowVideoIE
from .npo import ( from .npo import (

View file

@ -1,64 +1,120 @@
# encoding: utf-8 # encoding: utf-8
from __future__ import unicode_literals from __future__ import unicode_literals
import re
from .brightcove import BrightcoveIE from .brightcove import BrightcoveIE
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import ExtractorError from ..utils import ExtractorError
from ..compat import (
compat_str,
compat_urllib_request,
)
class NownessIE(InfoExtractor): class NownessBaseIE(InfoExtractor):
_VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/[^?#]*?/(?P<id>[0-9]+)/(?P<slug>[^/]+?)(?:$|[?#])' def _extract_url_result(self, post):
if post['type'] == 'video':
for media in post['media']:
if media['type'] == 'video':
video_id = media['content']
source = media['source']
if source == 'brightcove':
player_code = self._download_webpage(
'http://www.nowness.com/iframe?id=%s' % video_id, video_id,
note='Downloading player JavaScript',
errnote='Unable to download player JavaScript')
bc_url = BrightcoveIE._extract_brightcove_url(player_code)
if bc_url is None:
raise ExtractorError('Could not find player definition')
return self.url_result(bc_url, 'Brightcove')
elif source == 'vimeo':
return self.url_result('http://vimeo.com/%s' % video_id, 'Vimeo')
elif source == 'youtube':
return self.url_result(video_id, 'Youtube')
elif source == 'cinematique':
# youtube-dl currently doesn't support cinematique
# return self.url_result('http://cinematique.com/embed/%s' % video_id, 'Cinematique')
pass
_TESTS = [ def _api_request(self, url, request_path):
{ display_id = self._match_id(url)
'url': 'http://www.nowness.com/day/2013/6/27/3131/candor--the-art-of-gesticulation', request = compat_urllib_request.Request(
'md5': '068bc0202558c2e391924cb8cc470676', 'http://api.nowness.com/api/' + request_path % display_id,
'info_dict': { headers={
'id': '2520295746001', 'X-Nowness-Language': 'zh-cn' if 'cn.nowness.com' in url else 'en-us',
'ext': 'mp4', })
'title': 'Candor: The Art of Gesticulation', return display_id, self._download_json(request, display_id)
'description': 'Candor: The Art of Gesticulation',
'thumbnail': 're:^https?://.*\.jpg',
'uploader': 'Nowness', class NownessIE(NownessBaseIE):
} IE_NAME = 'nowness'
}, _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/(?:story|(?:series|category)/[^/]+)/(?P<id>[^/]+?)(?:$|[?#])'
{ _TESTS = [{
'url': 'http://cn.nowness.com/day/2014/8/7/4069/kasper-bj-rke-ft-jaakko-eino-kalevi--tnr', 'url': 'https://www.nowness.com/story/candor-the-art-of-gesticulation',
'md5': 'e79cf125e387216f86b2e0a5b5c63aa3', 'md5': '068bc0202558c2e391924cb8cc470676',
'info_dict': { 'info_dict': {
'id': '3716354522001', 'id': '2520295746001',
'ext': 'mp4', 'ext': 'mp4',
'title': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR', 'title': 'Candor: The Art of Gesticulation',
'description': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR', 'description': 'Candor: The Art of Gesticulation',
'thumbnail': 're:^https?://.*\.jpg', 'thumbnail': 're:^https?://.*\.jpg',
'uploader': 'Nowness', 'uploader': 'Nowness',
} }
}, }, {
] 'url': 'https://cn.nowness.com/story/kasper-bjorke-ft-jaakko-eino-kalevi-tnr',
'md5': 'e79cf125e387216f86b2e0a5b5c63aa3',
'info_dict': {
'id': '3716354522001',
'ext': 'mp4',
'title': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
'description': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
'thumbnail': 're:^https?://.*\.jpg',
'uploader': 'Nowness',
}
}]
def _real_extract(self, url): def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url) _, post = self._api_request(url, 'post/getBySlug/%s')
video_id = mobj.group('slug') return self._extract_url_result(post)
webpage = self._download_webpage(url, video_id)
player_url = self._search_regex(
r'"([^"]+/content/issue-[0-9.]+.js)"', webpage, 'player URL')
real_id = self._search_regex(
r'\sdata-videoId="([0-9]+)"', webpage, 'internal video ID')
player_code = self._download_webpage( class NownessPlaylistIE(NownessBaseIE):
player_url, video_id, IE_NAME = 'nowness:playlist'
note='Downloading player JavaScript', _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/playlist/(?P<id>\d+)'
errnote='Player download failed') _TEST = {
player_code = player_code.replace("'+d+'", real_id) 'url': 'https://www.nowness.com/playlist/3286/i-guess-thats-why-they-call-it-the-blues',
'info_dict': {
'id': '3286',
},
'playlist_mincount': 8,
}
bc_url = BrightcoveIE._extract_brightcove_url(player_code) def _real_extract(self, url):
if bc_url is None: playlist_id, playlist = self._api_request(url, 'post?PlaylistId=%s')
raise ExtractorError('Could not find player definition') entries = [self._extract_url_result(item) for item in playlist['items']]
return { return self.playlist_result(entries, playlist_id)
'_type': 'url',
'url': bc_url,
'ie_key': 'Brightcove', class NownessSeriesIE(NownessBaseIE):
} IE_NAME = 'nowness:series'
_VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/series/(?P<id>[^/]+?)(?:$|[?#])'
_TEST = {
'url': 'https://www.nowness.com/series/60-seconds',
'info_dict': {
'id': '60',
'title': '60 Seconds',
'description': 'One-minute wisdom in a new NOWNESS series',
},
'playlist_mincount': 4,
}
def _real_extract(self, url):
display_id, series = self._api_request(url, 'series/getBySlug/%s')
entries = [self._extract_url_result(post) for post in series['posts']]
series_title = None
series_description = None
translations = series.get('translations', [])
if translations:
series_title = translations[0].get('title') or translations[0]['seoTitle']
series_description = translations[0].get('seoDescription')
return self.playlist_result(
entries, compat_str(series['id']), series_title, series_description)