325 lines
7.9 KiB
Python
325 lines
7.9 KiB
Python
#!/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
|