]>
Commit | Line | Data |
---|---|---|
e7c14660 | 1 | # coding: utf-8 |
4c603938 MA |
2 | from __future__ import unicode_literals |
3 | ||
4 | import re | |
5 | import hashlib | |
4c603938 MA |
6 | |
7 | from .common import InfoExtractor | |
47fe42e1 S |
8 | from ..compat import compat_str |
9 | from ..utils import ( | |
10 | int_or_none, | |
11 | float_or_none, | |
12 | ) | |
4c603938 | 13 | |
4c603938 | 14 | |
e4df2f98 S |
15 | class YandexMusicTrackIE(InfoExtractor): |
16 | IE_NAME = 'yandexmusic:track' | |
17 | IE_DESC = 'Яндекс.Музыка - Трек' | |
18 | _VALID_URL = r'https?://music\.yandex\.(?:ru|kz|ua|by)/album/(?P<album_id>\d+)/track/(?P<id>\d+)' | |
19 | ||
20 | _TEST = { | |
21 | 'url': 'http://music.yandex.ru/album/540508/track/4878838', | |
22 | 'md5': 'f496818aa2f60b6c0062980d2e00dc20', | |
23 | 'info_dict': { | |
24 | 'id': '4878838', | |
25 | 'ext': 'mp3', | |
26 | 'title': 'Carlo Ambrosio - Gypsy Eyes 1', | |
27 | 'filesize': 4628061, | |
28 | 'duration': 193.04, | |
29 | } | |
30 | } | |
31 | ||
4c603938 | 32 | def _get_track_url(self, storage_dir, track_id): |
47fe42e1 S |
33 | data = self._download_json( |
34 | 'http://music.yandex.ru/api/v1.5/handlers/api-jsonp.jsx?action=getTrackSrc&p=download-info/%s' | |
35 | % storage_dir, | |
36 | track_id, 'Downloading track location JSON') | |
4c603938 | 37 | |
47fe42e1 | 38 | key = hashlib.md5(('XGRlBW9FXlekgbPrRHuSiA' + data['path'][1:] + data['s']).encode('utf-8')).hexdigest() |
4c603938 MA |
39 | storage = storage_dir.split('.') |
40 | ||
47fe42e1 S |
41 | return ('http://%s/get-mp3/%s/%s?track-id=%s&from=service-10-track&similarities-experiment=default' |
42 | % (data['host'], key, data['ts'] + data['path'], storage[1])) | |
4c603938 | 43 | |
47fe42e1 S |
44 | def _get_track_info(self, track): |
45 | return { | |
46 | 'id': track['id'], | |
47 | 'ext': 'mp3', | |
48 | 'url': self._get_track_url(track['storageDir'], track['id']), | |
49 | 'title': '%s - %s' % (track['artists'][0]['name'], track['title']), | |
50 | 'filesize': int_or_none(track.get('fileSize')), | |
51 | 'duration': float_or_none(track.get('durationMs'), 1000), | |
52 | } | |
4c603938 | 53 | |
4c603938 | 54 | def _real_extract(self, url): |
47fe42e1 S |
55 | mobj = re.match(self._VALID_URL, url) |
56 | album_id, track_id = mobj.group('album_id'), mobj.group('id') | |
4c603938 | 57 | |
47fe42e1 S |
58 | track = self._download_json( |
59 | 'http://music.yandex.ru/handlers/track.jsx?track=%s:%s' % (track_id, album_id), | |
60 | track_id, 'Downloading track JSON')['track'] | |
4c603938 | 61 | |
47fe42e1 | 62 | return self._get_track_info(track) |
4c603938 | 63 | |
4c603938 | 64 | |
e7c14660 S |
65 | class YandexMusicPlaylistBaseIE(InfoExtractor): |
66 | def _build_playlist(self, tracks): | |
67 | return [ | |
68 | self.url_result( | |
69 | 'http://music.yandex.ru/album/%s/track/%s' % (track['albums'][0]['id'], track['id'])) | |
70 | for track in tracks] | |
71 | ||
72 | ||
73 | class YandexMusicAlbumIE(YandexMusicPlaylistBaseIE): | |
47fe42e1 S |
74 | IE_NAME = 'yandexmusic:album' |
75 | IE_DESC = 'Яндекс.Музыка - Альбом' | |
29171bc2 | 76 | _VALID_URL = r'https?://music\.yandex\.(?:ru|kz|ua|by)/album/(?P<id>\d+)/?(\?|$)' |
4c603938 | 77 | |
47fe42e1 S |
78 | _TEST = { |
79 | 'url': 'http://music.yandex.ru/album/540508', | |
80 | 'info_dict': { | |
81 | 'id': '540508', | |
82 | 'title': 'Carlo Ambrosio - Gypsy Soul (2009)', | |
83 | }, | |
84 | 'playlist_count': 50, | |
85 | } | |
4c603938 MA |
86 | |
87 | def _real_extract(self, url): | |
47fe42e1 | 88 | album_id = self._match_id(url) |
4c603938 | 89 | |
47fe42e1 S |
90 | album = self._download_json( |
91 | 'http://music.yandex.ru/handlers/album.jsx?album=%s' % album_id, | |
92 | album_id, 'Downloading album JSON') | |
4c603938 | 93 | |
e7c14660 | 94 | entries = self._build_playlist(album['volumes'][0]) |
47fe42e1 S |
95 | |
96 | title = '%s - %s' % (album['artists'][0]['name'], album['title']) | |
97 | year = album.get('year') | |
98 | if year: | |
99 | title += ' (%s)' % year | |
100 | ||
101 | return self.playlist_result(entries, compat_str(album['id']), title) | |
4c603938 | 102 | |
4c603938 | 103 | |
e7c14660 | 104 | class YandexMusicPlaylistIE(YandexMusicPlaylistBaseIE): |
47fe42e1 S |
105 | IE_NAME = 'yandexmusic:playlist' |
106 | IE_DESC = 'Яндекс.Музыка - Плейлист' | |
29171bc2 | 107 | _VALID_URL = r'https?://music\.yandex\.(?:ru|kz|ua|by)/users/[^/]+/playlists/(?P<id>\d+)' |
47fe42e1 | 108 | |
4c603938 | 109 | _TEST = { |
47fe42e1 | 110 | 'url': 'http://music.yandex.ru/users/music.partners/playlists/1245', |
4c603938 | 111 | 'info_dict': { |
47fe42e1 S |
112 | 'id': '1245', |
113 | 'title': 'Что слушают Enter Shikari', | |
114 | 'description': 'md5:3b9f27b0efbe53f2ee1e844d07155cc9', | |
115 | }, | |
116 | 'playlist_count': 6, | |
4c603938 MA |
117 | } |
118 | ||
119 | def _real_extract(self, url): | |
47fe42e1 | 120 | playlist_id = self._match_id(url) |
4c603938 | 121 | |
47fe42e1 | 122 | webpage = self._download_webpage(url, playlist_id) |
4c603938 | 123 | |
47fe42e1 S |
124 | playlist = self._parse_json( |
125 | self._search_regex( | |
126 | r'var\s+Mu\s*=\s*({.+?});\s*</script>', webpage, 'player'), | |
127 | playlist_id)['pageData']['playlist'] | |
128 | ||
47fe42e1 | 129 | return self.playlist_result( |
e7c14660 S |
130 | self._build_playlist(playlist['tracks']), |
131 | compat_str(playlist_id), | |
47fe42e1 | 132 | playlist['title'], playlist.get('description')) |