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.

122 lines
4.5 KiB

  1. import itertools
  2. import json
  3. import random
  4. import re
  5. from .common import InfoExtractor
  6. from ..utils import (
  7. ExtractorError,
  8. )
  9. class EightTracksIE(InfoExtractor):
  10. IE_NAME = '8tracks'
  11. _VALID_URL = r'https?://8tracks.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$'
  12. _TEST = {
  13. u"name": u"EightTracks",
  14. u"url": u"http://8tracks.com/ytdl/youtube-dl-test-tracks-a",
  15. u"playlist": [
  16. {
  17. u"file": u"11885610.m4a",
  18. u"md5": u"96ce57f24389fc8734ce47f4c1abcc55",
  19. u"info_dict": {
  20. u"title": u"youtue-dl project<>\"' - youtube-dl test track 1 \"'/\\\u00e4\u21ad",
  21. u"uploader_id": u"ytdl"
  22. }
  23. },
  24. {
  25. u"file": u"11885608.m4a",
  26. u"md5": u"4ab26f05c1f7291ea460a3920be8021f",
  27. u"info_dict": {
  28. u"title": u"youtube-dl project - youtube-dl test track 2 \"'/\\\u00e4\u21ad",
  29. u"uploader_id": u"ytdl"
  30. }
  31. },
  32. {
  33. u"file": u"11885679.m4a",
  34. u"md5": u"d30b5b5f74217410f4689605c35d1fd7",
  35. u"info_dict": {
  36. u"title": u"youtube-dl project as well - youtube-dl test track 3 \"'/\\\u00e4\u21ad",
  37. u"uploader_id": u"ytdl"
  38. }
  39. },
  40. {
  41. u"file": u"11885680.m4a",
  42. u"md5": u"4eb0a669317cd725f6bbd336a29f923a",
  43. u"info_dict": {
  44. u"title": u"youtube-dl project as well - youtube-dl test track 4 \"'/\\\u00e4\u21ad",
  45. u"uploader_id": u"ytdl"
  46. }
  47. },
  48. {
  49. u"file": u"11885682.m4a",
  50. u"md5": u"1893e872e263a2705558d1d319ad19e8",
  51. u"info_dict": {
  52. u"title": u"PH - youtube-dl test track 5 \"'/\\\u00e4\u21ad",
  53. u"uploader_id": u"ytdl"
  54. }
  55. },
  56. {
  57. u"file": u"11885683.m4a",
  58. u"md5": u"b673c46f47a216ab1741ae8836af5899",
  59. u"info_dict": {
  60. u"title": u"PH - youtube-dl test track 6 \"'/\\\u00e4\u21ad",
  61. u"uploader_id": u"ytdl"
  62. }
  63. },
  64. {
  65. u"file": u"11885684.m4a",
  66. u"md5": u"1d74534e95df54986da7f5abf7d842b7",
  67. u"info_dict": {
  68. u"title": u"phihag - youtube-dl test track 7 \"'/\\\u00e4\u21ad",
  69. u"uploader_id": u"ytdl"
  70. }
  71. },
  72. {
  73. u"file": u"11885685.m4a",
  74. u"md5": u"f081f47af8f6ae782ed131d38b9cd1c0",
  75. u"info_dict": {
  76. u"title": u"phihag - youtube-dl test track 8 \"'/\\\u00e4\u21ad",
  77. u"uploader_id": u"ytdl"
  78. }
  79. }
  80. ]
  81. }
  82. def _real_extract(self, url):
  83. mobj = re.match(self._VALID_URL, url)
  84. if mobj is None:
  85. raise ExtractorError(u'Invalid URL: %s' % url)
  86. playlist_id = mobj.group('id')
  87. webpage = self._download_webpage(url, playlist_id)
  88. json_like = self._search_regex(r"PAGE.mix = (.*?);\n", webpage, u'trax information', flags=re.DOTALL)
  89. data = json.loads(json_like)
  90. session = str(random.randint(0, 1000000000))
  91. mix_id = data['id']
  92. track_count = data['tracks_count']
  93. first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)
  94. next_url = first_url
  95. res = []
  96. for i in itertools.count():
  97. api_json = self._download_webpage(next_url, playlist_id,
  98. note=u'Downloading song information %s/%s' % (str(i+1), track_count),
  99. errnote=u'Failed to download song information')
  100. api_data = json.loads(api_json)
  101. track_data = api_data[u'set']['track']
  102. info = {
  103. 'id': track_data['id'],
  104. 'url': track_data['track_file_stream_url'],
  105. 'title': track_data['performer'] + u' - ' + track_data['name'],
  106. 'raw_title': track_data['name'],
  107. 'uploader_id': data['user']['login'],
  108. 'ext': 'm4a',
  109. }
  110. res.append(info)
  111. if api_data['set']['at_last_track']:
  112. break
  113. next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (session, mix_id, track_data['id'])
  114. return res