You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
5.7 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. from __future__ import unicode_literals
  2. import re
  3. import json
  4. import os
  5. from .common import InfoExtractor
  6. from ..compat import (
  7. compat_urlparse,
  8. compat_urllib_parse,
  9. compat_urllib_parse_urlparse
  10. )
  11. from ..utils import (
  12. unified_strdate,
  13. )
  14. class NHLBaseInfoExtractor(InfoExtractor):
  15. @staticmethod
  16. def _fix_json(json_string):
  17. return json_string.replace('\\\'', '\'')
  18. def _extract_video(self, info):
  19. video_id = info['id']
  20. self.report_extraction(video_id)
  21. initial_video_url = info['publishPoint']
  22. if info['formats'] == '1':
  23. parsed_url = compat_urllib_parse_urlparse(initial_video_url)
  24. filename, ext = os.path.splitext(parsed_url.path)
  25. path = '%s_sd%s' % (filename, ext)
  26. data = compat_urllib_parse.urlencode({
  27. 'type': 'fvod',
  28. 'path': compat_urlparse.urlunparse(parsed_url[:2] + (path,) + parsed_url[3:])
  29. })
  30. path_url = 'http://video.nhl.com/videocenter/servlets/encryptvideopath?' + data
  31. path_doc = self._download_xml(
  32. path_url, video_id, 'Downloading final video url')
  33. video_url = path_doc.find('path').text
  34. else:
  35. video_url = initial_video_url
  36. join = compat_urlparse.urljoin
  37. return {
  38. 'id': video_id,
  39. 'title': info['name'],
  40. 'url': video_url,
  41. 'description': info['description'],
  42. 'duration': int(info['duration']),
  43. 'thumbnail': join(join(video_url, '/u/'), info['bigImage']),
  44. 'upload_date': unified_strdate(info['releaseDate'].split('.')[0]),
  45. }
  46. class NHLIE(NHLBaseInfoExtractor):
  47. IE_NAME = 'nhl.com'
  48. _VALID_URL = r'https?://video(?P<team>\.[^.]*)?\.nhl\.com/videocenter/console(?:\?(?:.*?[?&])?)id=(?P<id>[0-9a-z-]+)'
  49. _TESTS = [{
  50. 'url': 'http://video.canucks.nhl.com/videocenter/console?catid=6?id=453614',
  51. 'md5': 'db704a4ea09e8d3988c85e36cc892d09',
  52. 'info_dict': {
  53. 'id': '453614',
  54. 'ext': 'mp4',
  55. 'title': 'Quick clip: Weise 4-3 goal vs Flames',
  56. 'description': 'Dale Weise scores his first of the season to put the Canucks up 4-3.',
  57. 'duration': 18,
  58. 'upload_date': '20131006',
  59. },
  60. }, {
  61. 'url': 'http://video.nhl.com/videocenter/console?id=2014020024-628-h',
  62. 'md5': 'd22e82bc592f52d37d24b03531ee9696',
  63. 'info_dict': {
  64. 'id': '2014020024-628-h',
  65. 'ext': 'mp4',
  66. 'title': 'Alex Galchenyuk Goal on Ray Emery (14:40/3rd)',
  67. 'description': 'Home broadcast - Montreal Canadiens at Philadelphia Flyers - October 11, 2014',
  68. 'duration': 0,
  69. 'upload_date': '20141011',
  70. },
  71. }, {
  72. 'url': 'http://video.mapleleafs.nhl.com/videocenter/console?id=58665&catid=802',
  73. 'md5': 'c78fc64ea01777e426cfc202b746c825',
  74. 'info_dict': {
  75. 'id': '58665',
  76. 'ext': 'flv',
  77. 'title': 'Classic Game In Six - April 22, 1979',
  78. 'description': 'It was the last playoff game for the Leafs in the decade, and the last time the Leafs and Habs played in the playoffs. Great game, not a great ending.',
  79. 'duration': 400,
  80. 'upload_date': '20100129'
  81. },
  82. }, {
  83. 'url': 'http://video.flames.nhl.com/videocenter/console?id=630616',
  84. 'only_matching': True,
  85. }]
  86. def _real_extract(self, url):
  87. mobj = re.match(self._VALID_URL, url)
  88. video_id = mobj.group('id')
  89. json_url = 'http://video.nhl.com/videocenter/servlets/playlist?ids=%s&format=json' % video_id
  90. data = self._download_json(
  91. json_url, video_id, transform_source=self._fix_json)
  92. return self._extract_video(data[0])
  93. class NHLVideocenterIE(NHLBaseInfoExtractor):
  94. IE_NAME = 'nhl.com:videocenter'
  95. IE_DESC = 'NHL videocenter category'
  96. _VALID_URL = r'https?://video\.(?P<team>[^.]*)\.nhl\.com/videocenter/(console\?[^(id=)]*catid=(?P<catid>[0-9]+)(?![&?]id=).*?)?$'
  97. _TEST = {
  98. 'url': 'http://video.canucks.nhl.com/videocenter/console?catid=999',
  99. 'info_dict': {
  100. 'id': '999',
  101. 'title': 'Highlights',
  102. },
  103. 'playlist_count': 12,
  104. }
  105. def _real_extract(self, url):
  106. mobj = re.match(self._VALID_URL, url)
  107. team = mobj.group('team')
  108. webpage = self._download_webpage(url, team)
  109. cat_id = self._search_regex(
  110. [r'var defaultCatId = "(.+?)";',
  111. r'{statusIndex:0,index:0,.*?id:(.*?),'],
  112. webpage, 'category id')
  113. playlist_title = self._html_search_regex(
  114. r'tab0"[^>]*?>(.*?)</td>',
  115. webpage, 'playlist title', flags=re.DOTALL).lower().capitalize()
  116. data = compat_urllib_parse.urlencode({
  117. 'cid': cat_id,
  118. # This is the default value
  119. 'count': 12,
  120. 'ptrs': 3,
  121. 'format': 'json',
  122. })
  123. path = '/videocenter/servlets/browse?' + data
  124. request_url = compat_urlparse.urljoin(url, path)
  125. response = self._download_webpage(request_url, playlist_title)
  126. response = self._fix_json(response)
  127. if not response.strip():
  128. self._downloader.report_warning('Got an empty reponse, trying '
  129. 'adding the "newvideos" parameter')
  130. response = self._download_webpage(request_url + '&newvideos=true',
  131. playlist_title)
  132. response = self._fix_json(response)
  133. videos = json.loads(response)
  134. return {
  135. '_type': 'playlist',
  136. 'title': playlist_title,
  137. 'id': cat_id,
  138. 'entries': [self._extract_video(v) for v in videos],
  139. }