async def get_artist(self, singer_id: typing.Union[int, str]) -> api.Artist: artist_info = await self.get_artist_info_raw(singer_id) artist_song = await self.get_artist_songs_raw(singer_id) try: artist = artist_info['resource'][0] item_list = artist_song['data']['contentItemList'][0]['itemList'] except (KeyError, IndexError): raise exceptions.DataError('get artist: no data') if not item_list: raise exceptions.DataError('get artist: no data') _songs = [v['song'] for i, v in enumerate(item_list) if i % 2 == 0] await self._patch_song_lyric(*_songs) _patch_song_url(*_songs) _patch_song_info(*_songs) songs = _resolve(*_songs) return api.Artist( artist_id=artist['singerId'], name=artist['singer'].strip(), pic_url=_get_pic_url(artist['imgs']), count=len(songs), songs=songs, )
async def get_song(self, copyright_id: typing.Union[int, str]) -> api.Song: song_id = await self.get_song_id(copyright_id) if song_id is None: raise exceptions.DataError('get song: no data') resp = await self.get_song_raw(song_id) try: _song = resp['resource'][0] except (KeyError, IndexError): raise exceptions.DataError('get song: no data') await self._patch_song_lyric(_song) _patch_song_url(_song) _patch_song_info(_song) songs = _resolve(_song) return songs[0]
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_detail_raw(playlist_id) try: playlist = resp['data']['data']['collectDetail'] total = int(playlist['songCount']) tracks = playlist['songs'] track_ids = playlist['allSongs'] except (KeyError, ValueError): raise exceptions.DataError('get playlist: no data') if total == 0: raise exceptions.DataError('get playlist: no data') if total > _SONG_REQUEST_LIMIT: async def patch_tracks(*ids: typing.Union[int, str]): return await self.get_songs_raw(*ids) tasks = [] for i in range(_SONG_REQUEST_LIMIT, total, _SONG_REQUEST_LIMIT): song_ids = track_ids[i:min(i + _SONG_REQUEST_LIMIT, total)] tasks.append(asyncio.ensure_future(patch_tracks(*song_ids))) await asyncio.gather(*tasks) for task in tasks: if not task.exception(): try: data = task.result()['data']['data'] _songs = data.get('songs', []) tracks.extend(_songs) except KeyError: continue await self._patch_song_lyric(*tracks) songs = _resolve(*tracks) return api.Playlist( playlist_id=playlist['listId'], name=playlist['collectName'].strip(), pic_url=playlist.get('collectLogo', ''), count=len(songs), songs=songs, )
async def get_artist(self, ting_uid: typing.Union[int, str]) -> api.Artist: resp = await self.get_artist_raw(ting_uid) try: artist = resp['artistinfo'] _songs = resp['songlist'] except KeyError: raise exceptions.DataError('get artist: no data') if not _songs: raise exceptions.DataError('get artist: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist(name=artist['name'].strip(), pic_url=artist.get('avatar_big', '').split('@')[0], count=len(songs), songs=songs)
async def search_song(self, keyword: str) -> api.SearchResult: resp = await self.search_song_raw(keyword) try: songs = resp['result']['songs'] except KeyError: raise exceptions.DataError('search song: no data') if not songs: raise exceptions.DataError('search song: no data') songs = [ api.SearchSongData( song_id=song['id'], name=song['name'].strip(), artist='/'.join([a['name'].strip() for a in song['artists']]), album=song['album']['name'].strip(), ) for song in songs ] return api.SearchResult(keyword=keyword, count=len(songs), songs=songs)
async def get_song(self, song_id: typing.Union[int, str]) -> api.Song: resp = await self.get_song_detail_raw(song_id) try: _song = resp['data']['data']['songDetail'] except KeyError: raise exceptions.DataError('get song: no data') await self._patch_song_lyric(_song) songs = _resolve(_song) return songs[0]
async def get_album(self, album_id: typing.Union[int, str]) -> api.Album: resp = await self.get_album_raw(album_id) try: _songs = resp['songs'] except KeyError: raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Album( name=resp['album']['name'].strip(), pic_url=resp['album']['picUrl'], count=len(songs), songs=songs, )
async def get_album(self, album_mid: str) -> api.Album: resp = await self.get_album_raw(album_mid) try: album = resp['data']['getAlbumInfo'] _songs = resp['data']['getSongInfo'] except KeyError: raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Album( name=album['Falbum_name'].strip(), pic_url=_ALBUM_PIC_URL.format(album_mid=album['Falbum_mid']), count=len(songs), songs=songs)
async def get_album(self, album_id: typing.Union[int, str]) -> api.Album: resp = await self.get_album_raw(album_id) try: album = resp['data'] _songs = album['musicList'] except KeyError: raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Album(name=album['album'].strip(), pic_url=album.get('pic', ''), count=len(songs), songs=songs)
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_raw(playlist_id) try: playlist = resp['data']['cdlist'][0] _songs = playlist['songlist'] except (KeyError, IndexError): raise exceptions.DataError('get playlist: no data') if not _songs: raise exceptions.DataError('get playlist: no data') await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Playlist(name=playlist['dissname'], pic_url=playlist.get('dir_pic_url2', ''), count=len(songs), songs=songs)
async def search_song(self, keyword: str) -> api.SearchResult: resp = await self.search_song_raw(keyword) try: _songs = resp['data']['info'] except KeyError: raise exceptions.DataError('search song: no data') if not _songs: raise exceptions.DataError('search song: no data') songs = [ api.SearchSongData( song_id=_song['hash'], name=_song['songname'].strip(), artist=_song['singername'].replace('、', '/').strip(), album=_song['album_name'].strip(), ) for _song in _songs ] return api.SearchResult(keyword=keyword, count=len(songs), songs=songs)
async def search_songs(self, keyword: str) -> api.SearchSongsResult: resp = await self.search_songs_raw(keyword) try: _songs = resp['data']['list'] except KeyError: raise exceptions.DataError('search songs: no data') if not _songs: raise exceptions.DataError('search songs: no data') songs = [ api.SearchSongsData( song_id=_song['rid'], name=_song['name'].strip(), artist=_song['artist'].replace('&', '/').strip(), album=_song['album'].strip(), ) for _song in _songs ] return api.SearchSongsResult(keyword=keyword, count=len(songs), songs=songs)
async def search_song(self, keyword: str) -> api.SearchResult: resp = await self.search_song_raw(keyword) try: _songs = resp['songResultData']['result'] except KeyError: raise exceptions.DataError('search song: no data') if not _songs: raise exceptions.DataError('search song: no data') songs = [ api.SearchSongData( song_id=_song['copyrightId'], name=_song['name'].strip(), artist='/'.join([s['name'].strip() for s in _song['singers']]), album='/'.join([a['name'].strip() for a in _song['albums']]) ) for _song in _songs ] return api.SearchResult(keyword=keyword, count=len(songs), songs=songs)
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_raw(playlist_id) try: total = resp['playlist']['trackCount'] tracks = resp['playlist']['tracks'] track_ids = resp['playlist']['trackIds'] except KeyError: raise exceptions.DataError('get playlist: no data') if total == 0: raise exceptions.DataError('get playlist: no data') if total > _SONG_REQUEST_LIMIT: song_ids = [ track_ids[i]['id'] for i in range(_SONG_REQUEST_LIMIT, total) ] async def patch_tracks(*ids: typing.Union[int, str]): return await self.get_songs_raw(*ids) extra = total - _SONG_REQUEST_LIMIT tasks = [] for i in range(0, extra, _SONG_REQUEST_LIMIT): _ids = song_ids[i:min(i + _SONG_REQUEST_LIMIT, extra)] tasks.append(asyncio.ensure_future(patch_tracks(*_ids))) await asyncio.gather(*tasks) for task in tasks: if not task.exception(): tracks.extend(task.result().get('songs', [])) await self._patch_song_url(*tracks) await self._patch_song_lyric(*tracks) songs = _resolve(*tracks) return api.Playlist( playlist_id=resp['playlist']['id'], name=resp['playlist']['name'].strip(), pic_url=resp['playlist']['coverImgUrl'], count=len(songs), songs=songs, )
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_raw(playlist_id) try: playlist = resp['data'] _songs = playlist['musicList'] except KeyError: raise exceptions.DataError('get playlist: no data') if not _songs: raise exceptions.DataError('get playlist: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Playlist(name=playlist['name'].strip(), pic_url=playlist.get('img700', ''), count=len(songs), songs=songs)
async def get_artist(self, singer_mid: str) -> api.Artist: resp = await self.get_artist_raw(singer_mid) try: artist = resp['data'] items = artist['list'] except KeyError: raise exceptions.DataError('get artist: no data') if not items: raise exceptions.DataError('get artist: no data') _songs = [i['musicData'] for i in items] await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist( name=artist['singer_name'].strip(), pic_url=_ARTIST_PIC_URL.format(singer_mid=artist['singer_mid']), count=len(songs), songs=songs)
async def get_artist(self, artist_id: typing.Union[int, str]) -> api.Artist: resp = await self.get_artist_raw(artist_id) try: _songs = resp['hotSongs'] except KeyError: raise exceptions.DataError('get artist: no data') if not _songs: raise exceptions.DataError('get artist: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist( artist_id=resp['artist']['id'], name=resp['artist']['name'].strip(), pic_url=resp['artist']['picUrl'], count=len(songs), songs=songs, )
async def get_album(self, album_id: typing.Union[int, str]) -> api.Album: resp = await self.get_album_raw(album_id) try: album = resp['resource'][0] _songs = album['songItems'] except (KeyError, IndexError): raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self._patch_song_lyric(*_songs) _patch_song_url(*_songs) _patch_song_info(*_songs) songs = _resolve(*_songs) return api.Album(name=album['title'].strip(), pic_url=_get_pic_url(album['imgItems']), count=len(songs), songs=songs)
async def get_song(self, song_id: typing.Union[int, str]) -> api.Song: resp = await self.get_song_raw(song_id) try: _song = resp['songs'][0] except (KeyError, IndexError): raise exceptions.DataError('get song: no data') await self._patch_song_url(_song) await self._patch_song_lyric(_song) songs = _resolve(_song) return songs[0]
async def get_artist(self, singer_id: typing.Union[int, str]) -> api.Artist: artist_info = await self.get_artist_info_raw(singer_id) artist_song = await self.get_artist_songs_raw(singer_id) try: artist = artist_info['data'] _songs = artist_song['data']['list'] except KeyError: raise exceptions.DataError('get artist: no data') if not _songs: raise exceptions.DataError('get artist: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist(name=artist['name'].strip(), pic_url=artist.get('pic300', ''), count=len(songs), songs=songs)
async def get_song(self, mid: typing.Union[int, str]) -> api.Song: if mid.isdigit(): mid = str(mid) if len(str(mid)) > 10 and mid.startswith('6'): song_id = await self.get_song_id(mid) if song_id is None: raise exceptions.DataError('get song: no data') else: song_id = mid resp = await self.get_song_raw(song_id) try: _song = resp['resource'][0] except (KeyError, IndexError): raise exceptions.DataError('get song: no data') await self._patch_song_lyric(_song) _patch_song_url(_song) _patch_song_info(_song) songs = _resolve(_song) return songs[0]
async def get_album(self, album_id: typing.Union[int, str]) -> api.Album: album_info = await self.get_album_info_raw(album_id) album_song = await self.get_album_song_raw(album_id) try: _songs = album_song['data']['info'] except KeyError: raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self.patch_song_info(*_songs) await self.patch_album_info(*_songs) await self.patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Album(name=album_info['data']['albumname'].strip(), pic_url=album_info['data']['imgurl'].replace( '{size}', '480'), count=len(songs), songs=songs)
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_raw(playlist_id) try: playlist = resp['resource'][0] _songs = playlist['songItems'] except (KeyError, IndexError): raise exceptions.DataError('get playlist: no data') if not _songs: raise exceptions.DataError('get playlist: no data') await self._patch_song_lyric(*_songs) _patch_song_url(*_songs) _patch_song_info(*_songs) songs = _resolve(*_songs) return api.Playlist(name=playlist['title'].strip(), pic_url=playlist['imgItem']['img'], count=len(songs), songs=songs)
async def get_album(self, album_id: typing.Union[int, str]) -> api.Album: resp = await self.get_album_raw(album_id) try: album = resp['albumInfo'] _songs = resp['songlist'] except KeyError: raise exceptions.DataError('get album: no data') if not _songs: raise exceptions.DataError('get album: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Album( album_id=album['album_id'], name=album['title'].strip(), pic_url=album.get('pic_big', '').split('@', 1)[0], count=len(songs), songs=songs, )
async def get_playlist(self, special_id: typing.Union[int, str]) -> api.Playlist: playlist_info = await self.get_playlist_info_raw(special_id) playlist_song = await self.get_playlist_song_raw(special_id) try: _songs = playlist_song['data']['info'] except KeyError: raise exceptions.DataError('get playlist: no data') if not _songs: raise exceptions.DataError('get playlist: no data') await self.patch_song_info(*_songs) await self.patch_album_info(*_songs) await self.patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Playlist( name=playlist_info['data']['specialname'].strip(), pic_url=playlist_info['data']['imgurl'].replace('{size}', '480'), count=len(songs), songs=songs )
async def get_artist(self, artist_id: typing.Union[int, str]) -> api.Artist: artist_info = await self.get_artist_info_raw(artist_id) artist_song = await self.get_artist_songs_raw(artist_id) try: artist = artist_info['data']['data']['artistDetailVO'] _songs = artist_song['data']['data']['songs'] except KeyError: raise exceptions.DataError('get artist: no data') if not _songs: raise exceptions.DataError('get artist: no data') await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist( artist_id=artist['artistId'], name=artist['artistName'].strip(), pic_url=artist.get('artistLogo', ''), count=len(songs), songs=songs, )
async def get_playlist( self, playlist_id: typing.Union[int, str]) -> api.Playlist: resp = await self.get_playlist_raw(playlist_id) try: playlist = resp['result']['info'] _songs = resp['result']['songlist'] except KeyError: raise exceptions.DataError('get playlist: no data') if not _songs: raise exceptions.DataError('get playlist: no data') await self._patch_song_url(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Playlist( playlist_id=playlist['list_id'], name=playlist['list_title'].strip(), pic_url=playlist.get('list_pic', ''), count=len(songs), songs=songs, )
async def get_artist(self, singer_id: typing.Union[int, str]) -> api.Artist: artist_info = await self.get_artist_info_raw(singer_id) artist_song = await self.get_artist_songs_raw(singer_id) try: _songs = artist_song['data']['info'] except KeyError: raise exceptions.DataError('get artist: no data') if not _songs: raise exceptions.DataError('get artist: no data') await self._patch_song_info(*_songs) await self._patch_album_info(*_songs) await self._patch_song_lyric(*_songs) songs = _resolve(*_songs) return api.Artist( artist_id=artist_info['data']['singerid'], name=artist_info['data']['singername'].strip(), pic_url=artist_info['data']['imgurl'].replace('{size}', '480'), count=len(songs), songs=songs, )