]>
Commit | Line | Data |
---|---|---|
4e0c0c15 | 1 | # coding: utf-8 |
89c0dc9a B |
2 | from __future__ import unicode_literals |
3 | ||
4 | from .common import InfoExtractor | |
89c0dc9a | 5 | from ..compat import compat_urllib_parse_unquote |
4e0c0c15 | 6 | from ..utils import int_or_none |
89c0dc9a B |
7 | |
8 | ||
9 | class XiamiBaseIE(InfoExtractor): | |
4e0c0c15 S |
10 | _API_BASE_URL = 'http://www.xiami.com/song/playlist/cat/json/id' |
11 | ||
7759be38 YCH |
12 | def _download_webpage(self, *args, **kwargs): |
13 | webpage = super(XiamiBaseIE, self)._download_webpage(*args, **kwargs) | |
14 | if '>Xiami is currently not available in your country.<' in webpage: | |
15 | self.raise_geo_restricted('Xiami is currently not available in your country') | |
16 | ||
4e0c0c15 S |
17 | def _extract_track(self, track, track_id=None): |
18 | title = track['title'] | |
19 | track_url = self._decrypt(track['location']) | |
20 | ||
21 | subtitles = {} | |
22 | lyrics_url = track.get('lyric_url') or track.get('lyric') | |
23 | if lyrics_url and lyrics_url.startswith('http'): | |
24 | subtitles['origin'] = [{'url': lyrics_url}] | |
25 | ||
26 | return { | |
27 | 'id': track.get('song_id') or track_id, | |
28 | 'url': track_url, | |
29 | 'title': title, | |
30 | 'thumbnail': track.get('pic') or track.get('album_pic'), | |
31 | 'duration': int_or_none(track.get('length')), | |
32 | 'creator': track.get('artist', '').split(';')[0], | |
33 | 'track': title, | |
34 | 'album': track.get('album_name'), | |
35 | 'artist': track.get('artist'), | |
36 | 'subtitles': subtitles, | |
89c0dc9a B |
37 | } |
38 | ||
4e0c0c15 S |
39 | def _extract_tracks(self, item_id, typ=None): |
40 | playlist = self._download_json( | |
41 | '%s/%s%s' % (self._API_BASE_URL, item_id, '/type/%s' % typ if typ else ''), item_id) | |
42 | return [ | |
43 | self._extract_track(track, item_id) | |
44 | for track in playlist['data']['trackList']] | |
89c0dc9a B |
45 | |
46 | @staticmethod | |
47 | def _decrypt(origin): | |
48 | n = int(origin[0]) | |
49 | origin = origin[1:] | |
50 | short_lenth = len(origin) // n | |
51 | long_num = len(origin) - short_lenth * n | |
52 | l = tuple() | |
53 | for i in range(0, n): | |
54 | length = short_lenth | |
55 | if i < long_num: | |
56 | length += 1 | |
57 | l += (origin[0:length], ) | |
58 | origin = origin[length:] | |
59 | ans = '' | |
60 | for i in range(0, short_lenth + 1): | |
61 | for j in range(0, n): | |
4e0c0c15 | 62 | if len(l[j]) > i: |
89c0dc9a B |
63 | ans += l[j][i] |
64 | return compat_urllib_parse_unquote(ans).replace('^', '0') | |
65 | ||
66 | ||
4e0c0c15 | 67 | class XiamiSongIE(XiamiBaseIE): |
89c0dc9a B |
68 | IE_NAME = 'xiami:song' |
69 | IE_DESC = '虾米音乐' | |
4e0c0c15 S |
70 | _VALID_URL = r'https?://(?:www\.)?xiami\.com/song/(?P<id>[0-9]+)' |
71 | _TESTS = [{ | |
72 | 'url': 'http://www.xiami.com/song/1775610518', | |
73 | 'md5': '521dd6bea40fd5c9c69f913c232cb57e', | |
74 | 'info_dict': { | |
75 | 'id': '1775610518', | |
76 | 'ext': 'mp3', | |
77 | 'title': 'Woman', | |
78 | 'thumbnail': r're:http://img\.xiami\.net/images/album/.*\.jpg', | |
79 | 'duration': 265, | |
80 | 'creator': 'HONNE', | |
81 | 'track': 'Woman', | |
82 | 'album': 'Woman', | |
83 | 'artist': 'HONNE', | |
84 | 'subtitles': { | |
85 | 'origin': [{ | |
86 | 'ext': 'lrc', | |
87 | }], | |
88 | }, | |
7759be38 YCH |
89 | }, |
90 | 'skip': 'Georestricted', | |
4e0c0c15 S |
91 | }, { |
92 | 'url': 'http://www.xiami.com/song/1775256504', | |
93 | 'md5': '932a3abd45c6aa2b1fdbe028fcb4c4fc', | |
94 | 'info_dict': { | |
95 | 'id': '1775256504', | |
96 | 'ext': 'mp3', | |
97 | 'title': '悟空', | |
98 | 'thumbnail': r're:http://img\.xiami\.net/images/album/.*\.jpg', | |
99 | 'duration': 200, | |
100 | 'creator': '戴荃', | |
101 | 'track': '悟空', | |
102 | 'album': '悟空', | |
103 | 'artist': '戴荃', | |
104 | 'subtitles': { | |
105 | 'origin': [{ | |
106 | 'ext': 'lrc', | |
107 | }], | |
108 | }, | |
7759be38 YCH |
109 | }, |
110 | 'skip': 'Georestricted', | |
4e0c0c15 | 111 | }] |
89c0dc9a B |
112 | |
113 | def _real_extract(self, url): | |
4e0c0c15 | 114 | return self._extract_tracks(self._match_id(url))[0] |
89c0dc9a B |
115 | |
116 | ||
4e0c0c15 S |
117 | class XiamiPlaylistBaseIE(XiamiBaseIE): |
118 | def _real_extract(self, url): | |
119 | item_id = self._match_id(url) | |
120 | return self.playlist_result(self._extract_tracks(item_id, self._TYPE), item_id) | |
121 | ||
122 | ||
123 | class XiamiAlbumIE(XiamiPlaylistBaseIE): | |
89c0dc9a B |
124 | IE_NAME = 'xiami:album' |
125 | IE_DESC = '虾米音乐 - 专辑' | |
4e0c0c15 S |
126 | _VALID_URL = r'https?://(?:www\.)?xiami\.com/album/(?P<id>[0-9]+)' |
127 | _TYPE = '1' | |
128 | _TESTS = [{ | |
129 | 'url': 'http://www.xiami.com/album/2100300444', | |
130 | 'info_dict': { | |
131 | 'id': '2100300444', | |
89c0dc9a | 132 | }, |
4e0c0c15 | 133 | 'playlist_count': 10, |
7759be38 | 134 | 'skip': 'Georestricted', |
4e0c0c15 S |
135 | }, { |
136 | 'url': 'http://www.xiami.com/album/512288?spm=a1z1s.6843761.1110925389.6.hhE9p9', | |
137 | 'only_matching': True, | |
138 | }] | |
89c0dc9a B |
139 | |
140 | ||
4e0c0c15 | 141 | class XiamiArtistIE(XiamiPlaylistBaseIE): |
89c0dc9a B |
142 | IE_NAME = 'xiami:artist' |
143 | IE_DESC = '虾米音乐 - 歌手' | |
4e0c0c15 S |
144 | _VALID_URL = r'https?://(?:www\.)?xiami\.com/artist/(?P<id>[0-9]+)' |
145 | _TYPE = '2' | |
89c0dc9a B |
146 | _TEST = { |
147 | 'url': 'http://www.xiami.com/artist/2132?spm=0.0.0.0.dKaScp', | |
148 | 'info_dict': { | |
149 | 'id': '2132', | |
150 | }, | |
151 | 'playlist_count': 20, | |
7759be38 | 152 | 'skip': 'Georestricted', |
89c0dc9a B |
153 | } |
154 | ||
89c0dc9a | 155 | |
4e0c0c15 | 156 | class XiamiCollectionIE(XiamiPlaylistBaseIE): |
89c0dc9a B |
157 | IE_NAME = 'xiami:collection' |
158 | IE_DESC = '虾米音乐 - 精选集' | |
4e0c0c15 S |
159 | _VALID_URL = r'https?://(?:www\.)?xiami\.com/collect/(?P<id>[0-9]+)' |
160 | _TYPE = '3' | |
89c0dc9a B |
161 | _TEST = { |
162 | 'url': 'http://www.xiami.com/collect/156527391?spm=a1z1s.2943601.6856193.12.4jpBnr', | |
163 | 'info_dict': { | |
164 | 'id': '156527391', | |
165 | }, | |
4e0c0c15 | 166 | 'playlist_mincount': 29, |
7759be38 | 167 | 'skip': 'Georestricted', |
89c0dc9a | 168 | } |