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