]>
Commit | Line | Data |
---|---|---|
2e1fa03b JMF |
1 | import re |
2 | import json | |
2e1fa03b JMF |
3 | |
4 | from .common import InfoExtractor | |
5 | from ..utils import ( | |
6 | compat_urlparse, | |
7 | compat_urllib_parse, | |
8 | determine_ext, | |
9 | unified_strdate, | |
10 | ) | |
11 | ||
12 | ||
91dbaef4 JMF |
13 | class NHLBaseInfoExtractor(InfoExtractor): |
14 | @staticmethod | |
15 | def _fix_json(json_string): | |
16 | return json_string.replace('\\\'', '\'') | |
17 | ||
18 | def _extract_video(self, info): | |
19 | video_id = info['id'] | |
20 | self.report_extraction(video_id) | |
21 | ||
22 | initial_video_url = info['publishPoint'] | |
23 | data = compat_urllib_parse.urlencode({ | |
24 | 'type': 'fvod', | |
25 | 'path': initial_video_url.replace('.mp4', '_sd.mp4'), | |
26 | }) | |
27 | path_url = 'http://video.nhl.com/videocenter/servlets/encryptvideopath?' + data | |
e26f8712 | 28 | path_doc = self._download_xml(path_url, video_id, |
91dbaef4 | 29 | u'Downloading final video url') |
91dbaef4 JMF |
30 | video_url = path_doc.find('path').text |
31 | ||
32 | join = compat_urlparse.urljoin | |
33 | return { | |
34 | 'id': video_id, | |
35 | 'title': info['name'], | |
36 | 'url': video_url, | |
37 | 'ext': determine_ext(video_url), | |
38 | 'description': info['description'], | |
39 | 'duration': int(info['duration']), | |
40 | 'thumbnail': join(join(video_url, '/u/'), info['bigImage']), | |
41 | 'upload_date': unified_strdate(info['releaseDate'].split('.')[0]), | |
42 | } | |
43 | ||
44 | ||
45 | class NHLIE(NHLBaseInfoExtractor): | |
2e1fa03b JMF |
46 | IE_NAME = u'nhl.com' |
47 | _VALID_URL = r'https?://video(?P<team>\.[^.]*)?\.nhl\.com/videocenter/console\?.*?(?<=[?&])id=(?P<id>\d+)' | |
48 | ||
49 | _TEST = { | |
50 | u'url': u'http://video.canucks.nhl.com/videocenter/console?catid=6?id=453614', | |
51 | u'file': u'453614.mp4', | |
52 | u'info_dict': { | |
53 | u'title': u'Quick clip: Weise 4-3 goal vs Flames', | |
54 | u'description': u'Dale Weise scores his first of the season to put the Canucks up 4-3.', | |
55 | u'duration': 18, | |
56 | u'upload_date': u'20131006', | |
57 | }, | |
58 | } | |
59 | ||
60 | def _real_extract(self, url): | |
61 | mobj = re.match(self._VALID_URL, url) | |
62 | video_id = mobj.group('id') | |
63 | json_url = 'http://video.nhl.com/videocenter/servlets/playlist?ids=%s&format=json' % video_id | |
64 | info_json = self._download_webpage(json_url, video_id, | |
65 | u'Downloading info json') | |
91dbaef4 | 66 | info_json = self._fix_json(info_json) |
2e1fa03b | 67 | info = json.loads(info_json)[0] |
91dbaef4 JMF |
68 | return self._extract_video(info) |
69 | ||
70 | ||
71 | class NHLVideocenterIE(NHLBaseInfoExtractor): | |
72 | IE_NAME = u'nhl.com:videocenter' | |
0190eecc | 73 | IE_DESC = u'NHL videocenter category' |
91dbaef4 JMF |
74 | _VALID_URL = r'https?://video\.(?P<team>[^.]*)\.nhl\.com/videocenter/(console\?.*?catid=(?P<catid>[^&]+))?' |
75 | ||
76 | @classmethod | |
77 | def suitable(cls, url): | |
78 | if NHLIE.suitable(url): | |
79 | return False | |
80 | return super(NHLVideocenterIE, cls).suitable(url) | |
81 | ||
82 | def _real_extract(self, url): | |
83 | mobj = re.match(self._VALID_URL, url) | |
84 | team = mobj.group('team') | |
85 | webpage = self._download_webpage(url, team) | |
86 | cat_id = self._search_regex( | |
87 | [r'var defaultCatId = "(.+?)";', | |
88 | r'{statusIndex:0,index:0,.*?id:(.*?),'], | |
89 | webpage, u'category id') | |
90 | playlist_title = self._html_search_regex( | |
ce68b590 JMF |
91 | r'tab0"[^>]*?>(.*?)</td>', |
92 | webpage, u'playlist title', flags=re.DOTALL).lower().capitalize() | |
2e1fa03b | 93 | |
2e1fa03b | 94 | data = compat_urllib_parse.urlencode({ |
91dbaef4 JMF |
95 | 'cid': cat_id, |
96 | # This is the default value | |
97 | 'count': 12, | |
98 | 'ptrs': 3, | |
99 | 'format': 'json', | |
2e1fa03b | 100 | }) |
91dbaef4 JMF |
101 | path = '/videocenter/servlets/browse?' + data |
102 | request_url = compat_urlparse.urljoin(url, path) | |
103 | response = self._download_webpage(request_url, playlist_title) | |
104 | response = self._fix_json(response) | |
105 | if not response.strip(): | |
106 | self._downloader.report_warning(u'Got an empty reponse, trying ' | |
107 | u'adding the "newvideos" parameter') | |
108 | response = self._download_webpage(request_url + '&newvideos=true', | |
109 | playlist_title) | |
110 | response = self._fix_json(response) | |
111 | videos = json.loads(response) | |
2e1fa03b | 112 | |
2e1fa03b | 113 | return { |
91dbaef4 JMF |
114 | '_type': 'playlist', |
115 | 'title': playlist_title, | |
116 | 'id': cat_id, | |
117 | 'entries': [self._extract_video(i) for i in videos], | |
2e1fa03b | 118 | } |