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.

86 lines
3.1 KiB

  1. from __future__ import unicode_literals
  2. import re
  3. from .common import InfoExtractor
  4. from ..utils import int_or_none
  5. # 22Tracks regularly replace the audio tracks that can be streamed on their
  6. # site. The tracks usually expire after 1 months, so we can't add tests.
  7. class TwentyTwoTracksIE(InfoExtractor):
  8. _VALID_URL = r'https?://22tracks\.com/(?P<city>[a-z]+)/(?P<genre>[\da-z]+)/(?P<id>\d+)'
  9. IE_NAME = '22tracks:track'
  10. _API_BASE = 'http://22tracks.com/api'
  11. def _extract_info(self, city, genre_name, track_id=None):
  12. item_id = track_id if track_id else genre_name
  13. cities = self._download_json(
  14. '%s/cities' % self._API_BASE, item_id,
  15. 'Downloading cities info',
  16. 'Unable to download cities info')
  17. city_id = [x['id'] for x in cities if x['slug'] == city][0]
  18. genres = self._download_json(
  19. '%s/genres/%s' % (self._API_BASE, city_id), item_id,
  20. 'Downloading %s genres info' % city,
  21. 'Unable to download %s genres info' % city)
  22. genre = [x for x in genres if x['slug'] == genre_name][0]
  23. genre_id = genre['id']
  24. tracks = self._download_json(
  25. '%s/tracks/%s' % (self._API_BASE, genre_id), item_id,
  26. 'Downloading %s genre tracks info' % genre_name,
  27. 'Unable to download track info')
  28. return [x for x in tracks if x['id'] == item_id][0] if track_id else [genre['title'], tracks]
  29. def _get_track_url(self, filename, track_id):
  30. token = self._download_json(
  31. 'http://22tracks.com/token.php?desktop=true&u=/128/%s' % filename,
  32. track_id, 'Downloading token', 'Unable to download token')
  33. return 'http://audio.22tracks.com%s?st=%s&e=%d' % (token['filename'], token['st'], token['e'])
  34. def _extract_track_info(self, track_info, track_id):
  35. download_url = self._get_track_url(track_info['filename'], track_id)
  36. title = '%s - %s' % (track_info['artist'].strip(), track_info['title'].strip())
  37. return {
  38. 'id': track_id,
  39. 'url': download_url,
  40. 'ext': 'mp3',
  41. 'title': title,
  42. 'duration': int_or_none(track_info.get('duration')),
  43. 'timestamp': int_or_none(track_info.get('published_at') or track_info.get('created'))
  44. }
  45. def _real_extract(self, url):
  46. mobj = re.match(self._VALID_URL, url)
  47. city = mobj.group('city')
  48. genre = mobj.group('genre')
  49. track_id = mobj.group('id')
  50. track_info = self._extract_info(city, genre, track_id)
  51. return self._extract_track_info(track_info, track_id)
  52. class TwentyTwoTracksGenreIE(TwentyTwoTracksIE):
  53. _VALID_URL = r'https?://22tracks\.com/(?P<city>[a-z]+)/(?P<genre>[\da-z]+)/?$'
  54. IE_NAME = '22tracks:genre'
  55. def _real_extract(self, url):
  56. mobj = re.match(self._VALID_URL, url)
  57. city = mobj.group('city')
  58. genre = mobj.group('genre')
  59. genre_title, tracks = self._extract_info(city, genre)
  60. entries = [
  61. self._extract_track_info(track_info, track_info['id'])
  62. for track_info in tracks]
  63. return self.playlist_result(entries, genre, genre_title)