#!/usr/bin/python3 from requests import Session from deezspot.deezloader.deezer_settings import qualities from deezspot.deezloader.__download_utils__ import md5hex from deezspot.exceptions import ( BadCredentials, TrackNotFound, NoRightOnMedia, ) from requests import ( get as req_get, post as req_post, ) from deezspot.libutils.logging_utils import logger class API_GW: @classmethod def __init__( cls, arl = None, email = None, password = None ): cls.__req = Session() cls.__arl = arl cls.__email = email cls.__password = password cls.__token = "null" cls.__client_id = 172365 cls.__client_secret = "fb0bec7ccc063dab0417eb7b0d847f34" cls.__try_link = "https://api.deezer.com/platform/generic/track/3135556" cls.__get_lyric = "song.getLyrics" cls.__get_song_data = "song.getData" cls.__get_user_getArl = "user.getArl" cls.__get_page_track = "deezer.pageTrack" cls.__get_user_data = "deezer.getUserData" cls.__get_album_data = "song.getListByAlbum" cls.__get_playlist_data = "playlist.getSongs" cls.__get_episode_data = "episode.getData" cls.__get_media_url = "https://media.deezer.com/v1/get_url" cls.__get_auth_token_url = "https://api.deezer.com/auth/token" cls.__private_api_link = "https://www.deezer.com/ajax/gw-light.php" cls.__song_server = "https://e-cdns-proxy-{}.dzcdn.net/mobile/1/{}" cls.__refresh_token() @classmethod def __login(cls): if ( (not cls.__arl) and (not cls.__email) and (not cls.__password) ): msg = f"NO LOGIN STUFF INSERTED :)))" raise BadCredentials(msg = msg) if cls.__arl: cls.__req.cookies['arl'] = cls.__arl else: cls.__set_arl() @classmethod def __set_arl(cls): access_token = cls.__get_access_token() c_headers = { "Authorization": f"Bearer {access_token}" } cls.__req.get(cls.__try_link, headers = c_headers).json() cls.__arl = cls.__get_api(cls.__get_user_getArl) @classmethod def __get_access_token(cls): password = md5hex(cls.__password) to_hash = ( f"{cls.__client_id}{cls.__email}{password}{cls.__client_secret}" ) request_hash = md5hex(to_hash) params = { "app_id": cls.__client_id, "login": cls.__email, "password": password, "hash": request_hash } results = req_get(cls.__get_auth_token_url, params = params).json() if "error" in results: raise BadCredentials( email = cls.__email, password = cls.__password ) access_token = results['access_token'] return access_token def __cool_api(cls): guest_sid = cls.__req.cookies.get("sid") url = "https://api.deezer.com/1.0/gateway.php" params = { 'api_key': "4VCYIJUCDLOUELGD1V8WBVYBNVDYOXEWSLLZDONGBBDFVXTZJRXPR29JRLQFO6ZE", 'sid': guest_sid, 'input': '3', 'output': '3', 'method': 'song_getData' } json = {'sng_id': 302127} json = req_post(url, params = params, json = json).json() print(json) @classmethod def __get_api( cls, method, json_data = None, repeats = 4 ): params = { "api_version": "1.0", "api_token": cls.__token, "input": "3", "method": method } results = cls.__req.post( cls.__private_api_link, params = params, json = json_data ).json()['results'] if not results and repeats != 0: cls.__refresh_token() cls.__get_api( method, json_data, repeats = repeats - 1 ) return results @classmethod def get_user(cls): data = cls.__get_api(cls.__get_user_data) return data @classmethod def __refresh_token(cls): cls.__req.cookies.clear_session_cookies() if not cls.amIlog(): cls.__login() cls.am_I_log() data = cls.get_user() cls.__token = data['checkForm'] cls.__license_token = cls.__get_license_token() @classmethod def __get_license_token(cls): data = cls.get_user() license_token = data['USER']['OPTIONS']['license_token'] return license_token @classmethod def amIlog(cls): data = cls.get_user() user_id = data['USER']['USER_ID'] is_logged = False if user_id != 0: is_logged = True return is_logged @classmethod def am_I_log(cls): if not cls.amIlog(): raise BadCredentials(arl = cls.__arl) @classmethod def get_song_data(cls, ids): json_data = { "sng_id" : ids } infos = cls.__get_api(cls.__get_song_data, json_data) return infos @classmethod def get_album_data(cls, ids): json_data = { "alb_id": ids, "nb": -1 } infos = cls.__get_api(cls.__get_album_data, json_data) return infos @classmethod def get_lyric(cls, ids): json_data = { "sng_id": ids } infos = cls.__get_api(cls.__get_lyric, json_data) return infos @classmethod def get_playlist_data(cls, ids): json_data = { "playlist_id": ids, "nb": -1 } infos = cls.__get_api(cls.__get_playlist_data, json_data) return infos @classmethod def get_page_track(cls, ids): json_data = { "sng_id" : ids } infos = cls.__get_api(cls.__get_page_track, json_data) return infos @classmethod def get_episode_data(cls, ids): json_data = { "episode_id": ids } infos = cls.__get_api(cls.__get_episode_data, json_data) if infos: infos['MEDIA_VERSION'] = '1' infos['SNG_ID'] = infos.get('EPISODE_ID') if 'EPISODE_DIRECT_STREAM_URL' in infos: infos['MD5_ORIGIN'] = 'episode' return infos @classmethod def get_song_url(cls, n, song_hash): song_url = cls.__song_server.format(n, song_hash) return song_url @classmethod def song_exist(cls, song_link): if song_link and 'spreaker.com' in song_link: return req_get(song_link, stream=True) crypted_audio = req_get(song_link) if len(crypted_audio.content) == 0: raise TrackNotFound return crypted_audio @classmethod def get_medias_url(cls, tracks_token, quality): others_qualities = [] for c_quality in qualities: if c_quality == quality: continue c_quality_set = { "cipher": "BF_CBC_STRIPE", "format": c_quality } others_qualities.append(c_quality_set) json_data = { "license_token": cls.__license_token, "media": [ { "type": "FULL", "formats": [ { "cipher": "BF_CBC_STRIPE", "format": quality } ] + others_qualities } ], "track_tokens": tracks_token } infos = req_post( cls.__get_media_url, json = json_data ).json() if "errors" in infos: msg = infos['errors'][0]['message'] raise NoRightOnMedia(msg) medias = infos['data'] return medias