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.

168 lines
5.5 KiB

10 years ago
10 years ago
  1. from __future__ import unicode_literals
  2. import re
  3. from .common import InfoExtractor
  4. from ..utils import (
  5. extract_attributes,
  6. int_or_none,
  7. parse_duration,
  8. parse_filesize,
  9. unified_timestamp,
  10. )
  11. class NewgroundsIE(InfoExtractor):
  12. _VALID_URL = r'https?://(?:www\.)?newgrounds\.com/(?:audio/listen|portal/view)/(?P<id>[0-9]+)'
  13. _TESTS = [{
  14. 'url': 'https://www.newgrounds.com/audio/listen/549479',
  15. 'md5': 'fe6033d297591288fa1c1f780386f07a',
  16. 'info_dict': {
  17. 'id': '549479',
  18. 'ext': 'mp3',
  19. 'title': 'B7 - BusMode',
  20. 'uploader': 'Burn7',
  21. 'timestamp': 1378878540,
  22. 'upload_date': '20130911',
  23. 'duration': 143,
  24. },
  25. }, {
  26. 'url': 'https://www.newgrounds.com/portal/view/673111',
  27. 'md5': '3394735822aab2478c31b1004fe5e5bc',
  28. 'info_dict': {
  29. 'id': '673111',
  30. 'ext': 'mp4',
  31. 'title': 'Dancin',
  32. 'uploader': 'Squirrelman82',
  33. 'timestamp': 1460256780,
  34. 'upload_date': '20160410',
  35. },
  36. }, {
  37. # source format unavailable, additional mp4 formats
  38. 'url': 'http://www.newgrounds.com/portal/view/689400',
  39. 'info_dict': {
  40. 'id': '689400',
  41. 'ext': 'mp4',
  42. 'title': 'ZTV News Episode 8',
  43. 'uploader': 'BennettTheSage',
  44. 'timestamp': 1487965140,
  45. 'upload_date': '20170224',
  46. },
  47. 'params': {
  48. 'skip_download': True,
  49. },
  50. }]
  51. def _real_extract(self, url):
  52. media_id = self._match_id(url)
  53. webpage = self._download_webpage(url, media_id)
  54. title = self._html_search_regex(
  55. r'<title>([^>]+)</title>', webpage, 'title')
  56. media_url = self._parse_json(self._search_regex(
  57. r'"url"\s*:\s*("[^"]+"),', webpage, ''), media_id)
  58. formats = [{
  59. 'url': media_url,
  60. 'format_id': 'source',
  61. 'quality': 1,
  62. }]
  63. max_resolution = int_or_none(self._search_regex(
  64. r'max_resolution["\']\s*:\s*(\d+)', webpage, 'max resolution',
  65. default=None))
  66. if max_resolution:
  67. url_base = media_url.rpartition('.')[0]
  68. for resolution in (360, 720, 1080):
  69. if resolution > max_resolution:
  70. break
  71. formats.append({
  72. 'url': '%s.%dp.mp4' % (url_base, resolution),
  73. 'format_id': '%dp' % resolution,
  74. 'height': resolution,
  75. })
  76. self._check_formats(formats, media_id)
  77. self._sort_formats(formats)
  78. uploader = self._html_search_regex(
  79. (r'(?s)<h4[^>]*>(.+?)</h4>.*?<em>\s*Author\s*</em>',
  80. r'(?:Author|Writer)\s*<a[^>]+>([^<]+)'), webpage, 'uploader',
  81. fatal=False)
  82. timestamp = unified_timestamp(self._html_search_regex(
  83. (r'<dt>\s*Uploaded\s*</dt>\s*<dd>([^<]+</dd>\s*<dd>[^<]+)',
  84. r'<dt>\s*Uploaded\s*</dt>\s*<dd>([^<]+)'), webpage, 'timestamp',
  85. default=None))
  86. duration = parse_duration(self._search_regex(
  87. r'(?s)<dd>\s*Song\s*</dd>\s*<dd>.+?</dd>\s*<dd>([^<]+)', webpage,
  88. 'duration', default=None))
  89. filesize_approx = parse_filesize(self._html_search_regex(
  90. r'(?s)<dd>\s*Song\s*</dd>\s*<dd>(.+?)</dd>', webpage, 'filesize',
  91. default=None))
  92. if len(formats) == 1:
  93. formats[0]['filesize_approx'] = filesize_approx
  94. if '<dd>Song' in webpage:
  95. formats[0]['vcodec'] = 'none'
  96. return {
  97. 'id': media_id,
  98. 'title': title,
  99. 'uploader': uploader,
  100. 'timestamp': timestamp,
  101. 'duration': duration,
  102. 'formats': formats,
  103. }
  104. class NewgroundsPlaylistIE(InfoExtractor):
  105. _VALID_URL = r'https?://(?:www\.)?newgrounds\.com/(?:collection|[^/]+/search/[^/]+)/(?P<id>[^/?#&]+)'
  106. _TESTS = [{
  107. 'url': 'https://www.newgrounds.com/collection/cats',
  108. 'info_dict': {
  109. 'id': 'cats',
  110. 'title': 'Cats',
  111. },
  112. 'playlist_mincount': 46,
  113. }, {
  114. 'url': 'http://www.newgrounds.com/portal/search/author/ZONE-SAMA',
  115. 'info_dict': {
  116. 'id': 'ZONE-SAMA',
  117. 'title': 'Portal Search: ZONE-SAMA',
  118. },
  119. 'playlist_mincount': 47,
  120. }, {
  121. 'url': 'http://www.newgrounds.com/audio/search/title/cats',
  122. 'only_matching': True,
  123. }]
  124. def _real_extract(self, url):
  125. playlist_id = self._match_id(url)
  126. webpage = self._download_webpage(url, playlist_id)
  127. title = self._search_regex(
  128. r'<title>([^>]+)</title>', webpage, 'title', default=None)
  129. # cut left menu
  130. webpage = self._search_regex(
  131. r'(?s)<div[^>]+\bclass=["\']column wide(.+)',
  132. webpage, 'wide column', default=webpage)
  133. entries = []
  134. for a, path, media_id in re.findall(
  135. r'(<a[^>]+\bhref=["\']/?((?:portal/view|audio/listen)/(\d+))[^>]+>)',
  136. webpage):
  137. a_class = extract_attributes(a).get('class')
  138. if a_class not in ('item-portalsubmission', 'item-audiosubmission'):
  139. continue
  140. entries.append(
  141. self.url_result(
  142. 'https://www.newgrounds.com/%s' % path,
  143. ie=NewgroundsIE.ie_key(), video_id=media_id))
  144. return self.playlist_result(entries, playlist_id, title)