b655a750304e8aff1c61cb2a11b158f51dc5af56
[youtube-dl] / youtube_dl / extractor / twentytwotracks.py
1 from __future__ import unicode_literals
2
3 import re
4
5 from .common import InfoExtractor
6
7 # 22Tracks regularly replace the audio tracks that can be streamed on their
8 # site. The tracks usually expire after 1 months, so we can't add tests.
9
10
11 class TwentyTwoTracksIE(InfoExtractor):
12     _VALID_URL = r'http://22tracks\.com/([a-z]+)/([a-z]+[2]*)/(\d+)'
13     IE_NAME = 'TwentyTwoTracks:Tracks'
14
15     def _extract_info(self, city, genre, track=''):
16         self._base_url = "http://22tracks.com/api/"
17
18         if track == '':
19             itemid = genre
20         else:
21             itemid = track
22
23         cities = self._download_json(
24             self._base_url + 'cities', itemid,
25             'Downloading city info', 'Cannot download city info')
26         city_id = [x['id'] for x in cities if x['slug'] == city]
27
28         genres = self._download_json(
29             self._base_url + 'genres/' + str(city_id[0]), itemid,
30             'Downloading genre info', 'Cannot download genre info')
31         genre_id = [x['id'] for x in genres if x['slug'] == genre]
32
33         tracks = self._download_json(
34             self._base_url + 'tracks/' + str(genre_id[0]),
35             itemid, 'Downloading track info', 'Cannot download track info')
36
37         if track == '':
38             return [[x['title'] for x in genres if x['slug'] == genre][0],
39                     tracks]
40         else:
41             return [x for x in tracks if x['id'] == itemid][0]
42
43     def _get_token(self, filename, track_id):
44         token = self._download_json(
45             'http://22tracks.com/token.php?desktop=true&u=%2F128%2f{0}'.format(
46                 filename), track_id, 'Finding download link...')
47
48         down_url = 'http://audio.22tracks.com{0}?st={1}&e={2}'.format(
49             token['filename'],
50             token['st'],
51             token['e'])
52
53         return down_url
54
55     def _real_extract(self, url):
56         mobj = re.match(self._VALID_URL, url)
57
58         city_id = mobj.group(1)
59         genre_id = mobj.group(2)
60         track_id = mobj.group(3)
61
62         self.to_screen(':: Track ID found! - Downloading single track')
63
64         track_info = self._extract_info(city_id, genre_id, track_id)
65
66         download_url = self._get_token(track_info['filename'], track_id)
67         title = '{0}-{1}'.format(
68             track_info['artist'].strip(), track_info['title'].strip())
69
70         return {
71             'id': track_id,
72             'url': download_url,
73             'ext': 'mp3',
74             'title': title,
75             'duration': track_info['duration']
76         }
77
78
79 class TwentyTwoTracksGenreIE(TwentyTwoTracksIE):
80     _VALID_URL = r'http://22tracks\.com/([a-z]+)/([a-z]+[2]*)/?'
81     IE_NAME = 'TwentyTwoTracks:Genre'
82
83     def _real_extract(self, url):
84         mobj = re.match(self._VALID_URL, url)
85
86         city_id = mobj.group(1)
87         genre_id = mobj.group(2)
88
89         self.to_screen(':: Track ID not found! - Downloading entire genre')
90
91         playlist_info = self._extract_info(city_id, genre_id)
92
93         entries = []
94         for track in playlist_info[1]:
95             title = '{0}-{1}'.format(
96                 track['artist'].strip(), track['title'].strip())
97             entries.append({
98                 'id': track['id'],
99                 'url': self._get_token(track['filename'], track['id']),
100                 'ext': 'mp3',
101                 'title': title
102             })
103
104         self.to_screen(':: Links found - Downloading Playlist')
105
106         return {
107             '_type': 'playlist',
108             'id': genre_id,
109             'title': playlist_info[0],
110             'entries': entries
111         }