]>
Commit | Line | Data |
---|---|---|
b1742275 T |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
e452345f RA |
4 | import hashlib |
5 | import random | |
b1742275 | 6 | |
e452345f | 7 | from ..compat import compat_str |
b1742275 | 8 | from .common import InfoExtractor |
e452345f RA |
9 | from ..utils import ( |
10 | clean_html, | |
11 | int_or_none, | |
12 | try_get, | |
13 | ) | |
14 | ||
15 | ||
16 | class JamendoIE(InfoExtractor): | |
3c7da54c S |
17 | _VALID_URL = r'''(?x) |
18 | https?:// | |
19 | (?: | |
20 | licensing\.jamendo\.com/[^/]+| | |
21 | (?:www\.)?jamendo\.com | |
22 | ) | |
e452345f | 23 | /track/(?P<id>[0-9]+)(?:/(?P<display_id>[^/?#&]+))? |
3c7da54c S |
24 | ''' |
25 | _TESTS = [{ | |
b1742275 T |
26 | 'url': 'https://www.jamendo.com/track/196219/stories-from-emona-i', |
27 | 'md5': '6e9e82ed6db98678f171c25a8ed09ffd', | |
28 | 'info_dict': { | |
29 | 'id': '196219', | |
30 | 'display_id': 'stories-from-emona-i', | |
31 | 'ext': 'flac', | |
f7ad7160 | 32 | # 'title': 'Maya Filipič - Stories from Emona I', |
33 | 'title': 'Stories from Emona I', | |
34 | # 'artist': 'Maya Filipič', | |
3cbecdd1 S |
35 | 'track': 'Stories from Emona I', |
36 | 'duration': 210, | |
e452345f RA |
37 | 'thumbnail': r're:^https?://.*\.jpg', |
38 | 'timestamp': 1217438117, | |
39 | 'upload_date': '20080730', | |
f7ad7160 | 40 | 'license': 'by-nc-nd', |
41 | 'view_count': int, | |
42 | 'like_count': int, | |
43 | 'average_rating': int, | |
44 | 'tags': ['piano', 'peaceful', 'newage', 'strings', 'upbeat'], | |
b1742275 | 45 | } |
3c7da54c S |
46 | }, { |
47 | 'url': 'https://licensing.jamendo.com/en/track/1496667/energetic-rock', | |
48 | 'only_matching': True, | |
49 | }] | |
b1742275 | 50 | |
f7ad7160 | 51 | def _call_api(self, resource, resource_id): |
52 | path = '/api/%ss' % resource | |
53 | rand = compat_str(random.random()) | |
54 | return self._download_json( | |
55 | 'https://www.jamendo.com' + path, resource_id, query={ | |
56 | 'id[]': resource_id, | |
57 | }, headers={ | |
58 | 'X-Jam-Call': '$%s*%s~' % (hashlib.sha1((path + rand).encode()).hexdigest(), rand) | |
59 | })[0] | |
60 | ||
b1742275 | 61 | def _real_extract(self, url): |
bdbafb39 | 62 | track_id, display_id = self._match_valid_url(url).groups() |
f7ad7160 | 63 | # webpage = self._download_webpage( |
64 | # 'https://www.jamendo.com/track/' + track_id, track_id) | |
65 | # models = self._parse_json(self._html_search_regex( | |
66 | # r"data-bundled-models='([^']+)", | |
67 | # webpage, 'bundled models'), track_id) | |
68 | # track = models['track']['models'][0] | |
69 | track = self._call_api('track', track_id) | |
e452345f | 70 | title = track_name = track['name'] |
f7ad7160 | 71 | # get_model = lambda x: try_get(models, lambda y: y[x]['models'][0], dict) or {} |
72 | # artist = get_model('artist') | |
73 | # artist_name = artist.get('name') | |
74 | # if artist_name: | |
75 | # title = '%s - %s' % (artist_name, title) | |
76 | # album = get_model('album') | |
d3b6b3b9 S |
77 | |
78 | formats = [{ | |
79 | 'url': 'https://%s.jamendo.com/?trackid=%s&format=%s&from=app-97dab294' | |
80 | % (sub_domain, track_id, format_id), | |
81 | 'format_id': format_id, | |
82 | 'ext': ext, | |
83 | 'quality': quality, | |
84 | } for quality, (format_id, sub_domain, ext) in enumerate(( | |
85 | ('mp31', 'mp3l', 'mp3'), | |
86 | ('mp32', 'mp3d', 'mp3'), | |
87 | ('ogg1', 'ogg', 'ogg'), | |
88 | ('flac', 'flac', 'flac'), | |
89 | ))] | |
90 | self._sort_formats(formats) | |
91 | ||
e452345f RA |
92 | urls = [] |
93 | thumbnails = [] | |
f7ad7160 | 94 | for covers in (track.get('cover') or {}).values(): |
e452345f RA |
95 | for cover_id, cover_url in covers.items(): |
96 | if not cover_url or cover_url in urls: | |
97 | continue | |
98 | urls.append(cover_url) | |
99 | size = int_or_none(cover_id.lstrip('size')) | |
100 | thumbnails.append({ | |
101 | 'id': cover_id, | |
102 | 'url': cover_url, | |
103 | 'width': size, | |
104 | 'height': size, | |
105 | }) | |
106 | ||
107 | tags = [] | |
f7ad7160 | 108 | for tag in (track.get('tags') or []): |
e452345f RA |
109 | tag_name = tag.get('name') |
110 | if not tag_name: | |
111 | continue | |
112 | tags.append(tag_name) | |
113 | ||
114 | stats = track.get('stats') or {} | |
f7ad7160 | 115 | license = track.get('licenseCC') or [] |
b1742275 | 116 | |
b1742275 T |
117 | return { |
118 | 'id': track_id, | |
119 | 'display_id': display_id, | |
e452345f | 120 | 'thumbnails': thumbnails, |
b1742275 | 121 | 'title': title, |
e452345f RA |
122 | 'description': track.get('description'), |
123 | 'duration': int_or_none(track.get('duration')), | |
f7ad7160 | 124 | # 'artist': artist_name, |
e452345f | 125 | 'track': track_name, |
f7ad7160 | 126 | # 'album': album.get('name'), |
e452345f | 127 | 'formats': formats, |
f7ad7160 | 128 | 'license': '-'.join(license) if license else None, |
e452345f RA |
129 | 'timestamp': int_or_none(track.get('dateCreated')), |
130 | 'view_count': int_or_none(stats.get('listenedAll')), | |
131 | 'like_count': int_or_none(stats.get('favorited')), | |
132 | 'average_rating': int_or_none(stats.get('averageNote')), | |
133 | 'tags': tags, | |
b1742275 T |
134 | } |
135 | ||
136 | ||
f7ad7160 | 137 | class JamendoAlbumIE(JamendoIE): |
e452345f | 138 | _VALID_URL = r'https?://(?:www\.)?jamendo\.com/album/(?P<id>[0-9]+)' |
f7ad7160 | 139 | _TESTS = [{ |
b1742275 T |
140 | 'url': 'https://www.jamendo.com/album/121486/duck-on-cover', |
141 | 'info_dict': { | |
142 | 'id': '121486', | |
e452345f RA |
143 | 'title': 'Duck On Cover', |
144 | 'description': 'md5:c2920eaeef07d7af5b96d7c64daf1239', | |
b1742275 | 145 | }, |
d3b6b3b9 S |
146 | 'playlist': [{ |
147 | 'md5': 'e1a2fcb42bda30dfac990212924149a8', | |
148 | 'info_dict': { | |
149 | 'id': '1032333', | |
150 | 'ext': 'flac', | |
3cbecdd1 S |
151 | 'title': 'Shearer - Warmachine', |
152 | 'artist': 'Shearer', | |
153 | 'track': 'Warmachine', | |
e452345f RA |
154 | 'timestamp': 1368089771, |
155 | 'upload_date': '20130509', | |
d3b6b3b9 S |
156 | } |
157 | }, { | |
158 | 'md5': '1f358d7b2f98edfe90fd55dac0799d50', | |
159 | 'info_dict': { | |
160 | 'id': '1032330', | |
161 | 'ext': 'flac', | |
3cbecdd1 S |
162 | 'title': 'Shearer - Without Your Ghost', |
163 | 'artist': 'Shearer', | |
164 | 'track': 'Without Your Ghost', | |
e452345f RA |
165 | 'timestamp': 1368089771, |
166 | 'upload_date': '20130509', | |
b1742275 | 167 | } |
d3b6b3b9 | 168 | }], |
b1742275 T |
169 | 'params': { |
170 | 'playlistend': 2 | |
171 | } | |
f7ad7160 | 172 | }] |
e452345f | 173 | |
b1742275 | 174 | def _real_extract(self, url): |
e452345f RA |
175 | album_id = self._match_id(url) |
176 | album = self._call_api('album', album_id) | |
177 | album_name = album.get('name') | |
178 | ||
179 | entries = [] | |
f7ad7160 | 180 | for track in (album.get('tracks') or []): |
e452345f RA |
181 | track_id = track.get('id') |
182 | if not track_id: | |
183 | continue | |
184 | track_id = compat_str(track_id) | |
185 | entries.append({ | |
186 | '_type': 'url_transparent', | |
187 | 'url': 'https://www.jamendo.com/track/' + track_id, | |
188 | 'ie_key': JamendoIE.ie_key(), | |
189 | 'id': track_id, | |
190 | 'album': album_name, | |
191 | }) | |
192 | ||
193 | return self.playlist_result( | |
194 | entries, album_id, album_name, | |
195 | clean_html(try_get(album, lambda x: x['description']['en'], compat_str))) |