steam.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. from __future__ import unicode_literals
  2. import re
  3. from .common import InfoExtractor
  4. from ..utils import (
  5. extract_attributes,
  6. ExtractorError,
  7. get_element_by_class,
  8. js_to_json,
  9. )
  10. class SteamIE(InfoExtractor):
  11. _VALID_URL = r"""(?x)
  12. https?://store\.steampowered\.com/
  13. (agecheck/)?
  14. (?P<urltype>video|app)/ #If the page is only for videos or for a game
  15. (?P<gameID>\d+)/?
  16. (?P<videoID>\d*)(?P<extra>\??) # For urltype == video we sometimes get the videoID
  17. |
  18. https?://(?:www\.)?steamcommunity\.com/sharedfiles/filedetails/\?id=(?P<fileID>[0-9]+)
  19. """
  20. _VIDEO_PAGE_TEMPLATE = 'http://store.steampowered.com/video/%s/'
  21. _AGECHECK_TEMPLATE = 'http://store.steampowered.com/agecheck/video/%s/?snr=1_agecheck_agecheck__age-gate&ageDay=1&ageMonth=January&ageYear=1970'
  22. _TESTS = [{
  23. 'url': 'http://store.steampowered.com/video/105600/',
  24. 'playlist': [
  25. {
  26. 'md5': '6a294ee0c4b1f47f5bb76a65e31e3592',
  27. 'info_dict': {
  28. 'id': '2040428',
  29. 'ext': 'mp4',
  30. 'title': 'Terraria 1.3 Trailer',
  31. 'playlist_index': 1,
  32. }
  33. },
  34. {
  35. 'md5': '911672b20064ca3263fa89650ba5a7aa',
  36. 'info_dict': {
  37. 'id': '2029566',
  38. 'ext': 'mp4',
  39. 'title': 'Terraria 1.2 Trailer',
  40. 'playlist_index': 2,
  41. }
  42. }
  43. ],
  44. 'info_dict': {
  45. 'id': '105600',
  46. 'title': 'Terraria',
  47. },
  48. 'params': {
  49. 'playlistend': 2,
  50. }
  51. }, {
  52. 'url': 'http://steamcommunity.com/sharedfiles/filedetails/?id=242472205',
  53. 'info_dict': {
  54. 'id': 'X8kpJBlzD2E',
  55. 'ext': 'mp4',
  56. 'upload_date': '20140617',
  57. 'title': 'FRONTIERS - Trapping',
  58. 'description': 'md5:bf6f7f773def614054089e5769c12a6e',
  59. 'uploader': 'AAD Productions',
  60. 'uploader_id': 'AtomicAgeDogGames',
  61. }
  62. }]
  63. def _real_extract(self, url):
  64. m = re.match(self._VALID_URL, url)
  65. fileID = m.group('fileID')
  66. if fileID:
  67. videourl = url
  68. playlist_id = fileID
  69. else:
  70. gameID = m.group('gameID')
  71. playlist_id = gameID
  72. videourl = self._VIDEO_PAGE_TEMPLATE % playlist_id
  73. webpage = self._download_webpage(videourl, playlist_id)
  74. if re.search('<h2>Please enter your birth date to continue:</h2>', webpage) is not None:
  75. videourl = self._AGECHECK_TEMPLATE % playlist_id
  76. self.report_age_confirmation()
  77. webpage = self._download_webpage(videourl, playlist_id)
  78. flash_vars = self._parse_json(self._search_regex(
  79. r'(?s)rgMovieFlashvars\s*=\s*({.+?});', webpage,
  80. 'flash vars'), playlist_id, js_to_json)
  81. playlist_title = None
  82. entries = []
  83. if fileID:
  84. playlist_title = get_element_by_class('workshopItemTitle', webpage)
  85. for movie in flash_vars.values():
  86. if not movie:
  87. continue
  88. youtube_id = movie.get('YOUTUBE_VIDEO_ID')
  89. if not youtube_id:
  90. continue
  91. entries.append({
  92. '_type': 'url',
  93. 'url': youtube_id,
  94. 'ie_key': 'Youtube',
  95. })
  96. else:
  97. playlist_title = get_element_by_class('apphub_AppName', webpage)
  98. for movie_id, movie in flash_vars.items():
  99. if not movie:
  100. continue
  101. video_id = self._search_regex(r'movie_(\d+)', movie_id, 'video id', fatal=False)
  102. title = movie.get('MOVIE_NAME')
  103. if not title or not video_id:
  104. continue
  105. entry = {
  106. 'id': video_id,
  107. 'title': title.replace('+', ' '),
  108. }
  109. formats = []
  110. flv_url = movie.get('FILENAME')
  111. if flv_url:
  112. formats.append({
  113. 'format_id': 'flv',
  114. 'url': flv_url,
  115. })
  116. highlight_element = self._search_regex(
  117. r'(<div[^>]+id="highlight_movie_%s"[^>]+>)' % video_id,
  118. webpage, 'highlight element', fatal=False)
  119. if highlight_element:
  120. highlight_attribs = extract_attributes(highlight_element)
  121. if highlight_attribs:
  122. entry['thumbnail'] = highlight_attribs.get('data-poster')
  123. for quality in ('', '-hd'):
  124. for ext in ('webm', 'mp4'):
  125. video_url = highlight_attribs.get('data-%s%s-source' % (ext, quality))
  126. if video_url:
  127. formats.append({
  128. 'format_id': ext + quality,
  129. 'url': video_url,
  130. })
  131. if not formats:
  132. continue
  133. entry['formats'] = formats
  134. entries.append(entry)
  135. if not entries:
  136. raise ExtractorError('Could not find any videos')
  137. return self.playlist_result(entries, playlist_id, playlist_title)