async def get_song_raw(self, song_mid: str) -> dict: params = { 'songmid': song_mid, } try: _resp = await self.request('GET', _GET_SONG_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 0: raise exceptions.ResponseError('get song: {}'.format(resp['code'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song: {}'.format(e)) return resp
async def get_playlist_raw(self, playlist_id: typing.Union[int, str]) -> dict: data = { 'id': playlist_id, 'n': 100000, } try: _resp = await self.request('POST', _API_GET_PLAYLIST, data=_weapi(data)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get playlist: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get playlist: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get playlist: {}'.format(e)) return resp
async def get_song_url_raw(self, mid: typing.Union[int, str], br: int = 128) -> dict: params = { 'rid': mid, 'br': '{}kmp3'.format(_bit_rate(br)), } try: _resp = await self.request('GET', _API_GET_SONG_URL, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song url: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get song url: {}'.format(resp.get('msg', 'copyright protection'))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song url: {}'.format(e)) return resp
async def get_song_raw(self, song_id: typing.Union[int, str]) -> dict: params = { 'songId': song_id, } try: _resp = await self.request('GET', _API_GET_SONG, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != '000000': raise exceptions.ResponseError('get song: {}'.format( resp.get('error', resp['info']))) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.ResponseError('get song: {}'.format(e)) return resp
async def get_song_url_raw(self, song_mid: str, media_mid: str) -> dict: params = { 'songmid': song_mid, 'filename': 'M500' + media_mid + '.mp3', } try: _resp = await self.request('GET', _API_GET_SONG_URL, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song url: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 0: raise exceptions.ResponseError('get song url: {}'.format(resp.get('errinfo', 'copyright protection'))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song url: {}'.format(e)) return resp
async def get_songs_url_raw(self, *song_ids: typing.Union[int, str], br: int = 128) -> dict: data = { 'br': _bit_rate(br), 'ids': json.dumps(song_ids), } try: _resp = await self.request('POST', _API_GET_SONGS_URL, data=_weapi(data)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get songs url: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get songs url: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get songs url: {}'.format(e)) return resp
async def get_album_raw(self, album_id: typing.Union[int, str]) -> dict: try: _resp = await self.request( 'POST', _GET_ALBUM_API.format(album_id=album_id), data=_weapi()) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get album: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get album: {}'.format( resp.get('msg', resp['code']))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get album: {}'.format(e)) return resp
async def get_artist_raw(self, singer_mid: str, page: int = 1, page_size: int = 50) -> dict: params = { 'singermid': singer_mid, 'begin': page, 'num': page_size, } try: _resp = await self.request('GET', _API_GET_ARTIST, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get artist: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 0: raise exceptions.ResponseError('get artist: {}'.format(resp['code'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get artist: {}'.format(e)) return resp
async def get_song_pic_raw(self, song_id: typing.Union[int, str]) -> dict: params = { 'songId': song_id, } try: _resp = await self.request('GET', _GET_SONG_PIC_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song pic: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['returnCode'] != '000000': raise exceptions.ResponseError('get song pic: {}'.format( resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song pic: {}'.format(e)) return resp
async def get_album_raw(self, album_id: typing.Union[int, str]) -> dict: params = { 'resourceId': album_id, } try: _resp = await self.request('GET', _API_GET_ALBUM, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get album: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != '000000': raise exceptions.ResponseError('get album: {}'.format( resp.get('error', resp['errcode']))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get album: {}'.format(e)) return resp
async def search_songs_raw(self, keyword: str, page: int = 1, page_size: int = 50) -> dict: params = { 'key': keyword, 'pn': page, 'rn': page_size, } try: _resp = await self.request('GET', _API_SEARCH, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('search songs: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('search songs: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('search songs: {}'.format(e)) return resp
async def get_song_url_raw(self, content_id: str, resource_type: str) -> dict: params = { 'contentId': content_id, 'lowerQualityContentId': content_id, 'resourceType': resource_type, } try: _resp = await self.request('GET', _GET_SONG_URL_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song url: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != '000000': raise exceptions.ResponseError('get song url: {}'.format(resp['info'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song url: {}'.format(e)) return resp
async def get_song_url_raw(self, file_hash: str) -> dict: data = file_hash + 'kgcloudv2' key = hashlib.md5(data.encode('utf-8')).hexdigest() params = { 'hash': file_hash, 'key': key, } try: _resp = await self.request('GET', _GET_SONG_URL_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song url: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['status'] != 1: raise exceptions.ResponseError('get song url: {}'.format(resp.get('error', 'copyright protection'))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song url: {}'.format(e)) return resp
async def get_playlist_raw(self, playlist_id: typing.Union[int, str]) -> dict: params = { 'resourceId': playlist_id, } try: _resp = await self.request('GET', _API_GET_PLAYLIST, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get playlist: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != '000000': raise exceptions.ResponseError('get playlist: {}'.format( resp['info'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get playlist: {}'.format(e)) return resp
async def get_artist__song_raw(self, singer_id: typing.Union[int, str], page: int = 1, page_size: int = 20) -> dict: params = { 'singerId': singer_id, 'pageNo': page, 'pageSize': page_size, } try: resp = await self.request('GET', _GET_ARTIST_SONG_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get artist song: {}'.format(e)) try: resp = await resp.json(content_type=None) if resp['code'] != '000000': raise exceptions.ResponseError('get artist song: {}'.format(resp['info'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get artist song: {}'.format(e)) return resp
async def get_playlist_song_raw(self, special_id: typing.Union[int, str], page: int = 1, page_size: int = -1) -> dict: params = { 'specialid': special_id, 'page': page, 'pagesize': page_size, } try: _resp = await self.request('GET', _GET_PLAYLIST_SONG_API, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get playlist song: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['errcode'] != 0: raise exceptions.ResponseError('get playlist song: {}'.format(resp.get('error', resp['errcode']))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get playlist song: {}'.format(e)) return resp
async def get_playlist_raw(self, playlist_id: typing.Union[int, str], page: int = 1, page_size: int = 9999) -> dict: params = { 'pid': playlist_id, 'pn': page, 'rn': page_size, } try: _resp = await self.request('GET', _API_GET_PLAYLIST, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get playlist: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get playlist: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get playlist: {}'.format(e)) return resp
async def search_songs_raw(self, keyword: str, offset: int = 0, limit: int = 50) -> dict: data = { 's': keyword, 'type': 1, 'offset': offset, 'limit': limit, } try: _resp = await self.request('POST', _API_SEARCH, data=_weapi(data)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('search songs: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('search songs: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('search songs: {}'.format(e)) return resp
async def get_song_lyric_raw(self, mid: typing.Union[int, str]) -> dict: params = { 'musicId': mid, } try: _resp = await self.request('GET', _API_GET_SONG_LYRIC, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song lyric: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['status'] != 200: raise exceptions.ResponseError('get song lyric: {}'.format( resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song lyric: {}'.format(e)) return resp
async def get_song_lyric_raw(self, song_id: typing.Union[int, str]) -> dict: data = { 'method': 'POST', 'url': 'https://music.163.com/api/song/lyric?lv=-1&kv=-1&tv=-1', 'params': { 'id': song_id, } } try: _resp = await self.request('POST', _API_LINUX, data=_linuxapi(data)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get song lyric: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get song lyric: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get song lyric: {}'.format(e)) return resp
async def get_songs_raw(self, *song_ids: typing.Union[int, str]) -> dict: if len(song_ids) > _SONG_REQUEST_LIMIT: song_ids = song_ids[:_SONG_REQUEST_LIMIT] c = [{'id': song_id} for song_id in song_ids] data = { 'c': json.dumps(c), } try: _resp = await self.request('POST', _API_GET_SONGS, data=_weapi(data)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get songs: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get songs: {}'.format(resp['msg'])) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get songs: {}'.format(e)) return resp
async def get_artist_info_raw(self, artist_id: typing.Union[int, str]) -> dict: params = { 'artistid': artist_id, } try: _resp = await self.request('GET', _API_GET_ARTIST_INFO, params=params) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get artist info: {}'.format(e)) try: resp = await _resp.json(content_type=None) if resp['code'] != 200: raise exceptions.ResponseError('get artist info: {}'.format( resp.get('msg', 'no data'))) except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get artist info: {}'.format(e)) return resp
async def get_album_raw(self, album_id: typing.Union[int, str]) -> dict: token = await self._get_token(_API_SEARCH) if token is None: raise exceptions.ClientError("get album: can't get token") model = {} if album_id.isdigit(): model['albumId'] = album_id else: model['albumStringId'] = album_id try: _resp = await self.request('GET', _API_GET_ALBUM, params=_sign_payload(token, model)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get album: {}'.format(e)) try: resp = await _resp.json(content_type=None) _check(resp['ret'], 'get album') except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get album: {}'.format(e)) return resp
async def get_songs_raw(self, *song_ids: typing.Union[int, str]) -> dict: token = await self._get_token(_API_GET_SONGS) if token is None: raise exceptions.ClientError("get songs: can't get token") if len(song_ids) > _SONG_REQUEST_LIMIT: song_ids = song_ids[:_SONG_REQUEST_LIMIT] model = { 'songIds': song_ids, } try: _resp = await self.request('GET', _API_GET_SONGS, params=_sign_payload(token, model)) except (aiohttp.ClientError, asyncio.TimeoutError) as e: raise exceptions.RequestError('get songs: {}'.format(e)) try: resp = await _resp.json(content_type=None) _check(resp['ret'], 'get songs') except (aiohttp.ClientResponseError, json.JSONDecodeError, KeyError) as e: raise exceptions.ResponseError('get songs: {}'.format(e)) return resp
def _check(ret: typing.List[str], msg: str): for s in ret: if s.startswith('FAIL'): raise exceptions.ResponseError('{}: {}'.format(msg, s))