deezer-py/deezer/api.py

295 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import requests
from time import sleep
import json
from deezer.errors import ItemsLimitExceededException, PermissionException, InvalidTokenException, \
WrongParameterException, MissingParameterException, InvalidQueryException, DataException, \
IndividualAccountChangedNotAllowedException, APIError
class SearchOrder():
"""Possible values for order parameter in search"""
RANKING = "RANKING"
TRACK_ASC = "TRACK_ASC"
TRACK_DESC = "TRACK_DESC"
ARTIST_ASC = "ARTIST_ASC"
ARTIST_DESC = "ARTIST_DESC"
ALBUM_ASC = "ALBUM_ASC"
ALBUM_DESC = "ALBUM_DESC"
RATING_ASC = "RATING_ASC"
RATING_DESC = "RATING_DESC"
DURATION_ASC = "DURATION_ASC"
DURATION_DESC = "DURATION_DESC"
class API:
def __init__(self, session, headers):
self.http_headers = headers
self.session = session
self.access_token = None
def api_call(self, method, args=None):
if args is None:
args = {}
if self.access_token: args['access_token'] = self.access_token
try:
result_json = self.session.get(
"https://api.deezer.com/" + method,
params=args,
headers=self.http_headers,
timeout=30
).json()
except:
sleep(2)
return self.api_call(method, args)
if 'error' in result_json.keys():
if 'code' in result_json['error']:
if result_json['error']['code'] in [4, 700]:
sleep(5)
return self.api_call(method, args)
if result_json['error']['code'] == 100: raise ItemsLimitExceededException(f"ItemsLimitExceededException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 200: raise PermissionException(f"PermissionException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 300: raise InvalidTokenException(f"InvalidTokenException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 500: raise WrongParameterException(f"ParameterException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 501: raise MissingParameterException(f"MissingParameterException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 600: raise InvalidQueryException(f"InvalidQueryException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 800: raise DataException(f"DataException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
if result_json['error']['code'] == 901: raise IndividualAccountChangedNotAllowedException(f"IndividualAccountChangedNotAllowedException: {method} {result_json['error']['message'] if 'message' in result_json['error'] else ''}")
raise APIError(json.dumps(result_json['error']))
return result_json
def get_album(self, album_id):
return self.api_call(f'album/{str(album_id)}')
def get_album_by_UPC(self, upc):
return self.get_album(f'upc:{upc}')
def get_album_comments(self, album_id, index=0, limit=10):
return self.api_call(f'album/{str(album_id)}/comments', {'index': index, 'limit': limit})
def get_album_fans(self, album_id, index=0, limit=100):
return self.api_call(f'album/{str(album_id)}/fans', {'index': index, 'limit': limit})
def get_album_tracks(self, album_id, index=0, limit=-1):
return self.api_call(f'album/{str(album_id)}/tracks', {'index': index, 'limit': limit})
def get_artist(self, artist_id):
return self.api_call(f'artist/{str(artist_id)}')
def get_artist_top(self, artist_id, index=0, limit=10):
return self.api_call(f'artist/{str(artist_id)}/top', {'index': index, 'limit': limit})
def get_artist_albums(self, artist_id, index=0, limit=-1):
return self.api_call(f'artist/{str(artist_id)}/albums', {'index': index, 'limit': limit})
def get_artist_comments(self, artist_id, index=0, limit=10):
return self.api_call(f'artist/{str(artist_id)}/comments', {'index': index, 'limit': limit})
def get_artist_fans(self, artist_id, index=0, limit=100):
return self.api_call(f'artist/{str(artist_id)}/fans', {'index': index, 'limit': limit})
def get_artist_related(self, artist_id, index=0, limit=20):
return self.api_call(f'artist/{str(artist_id)}/related', {'index': index, 'limit': limit})
def get_artist_radio(self, artist_id, index=0, limit=25):
return self.api_call(f'artist/{str(artist_id)}/radio', {'index': index, 'limit': limit})
def get_artist_playlists(self, artist_id, index=0, limit=-1):
return self.api_call(f'artist/{str(artist_id)}/playlists', {'index': index, 'limit': limit})
def get_chart(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}', {'index': index, 'limit': limit})
def get_chart_tracks(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}/tracks', {'index': index, 'limit': limit})
def get_chart_albums(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}/albums', {'index': index, 'limit': limit})
def get_chart_artists(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}/artists', {'index': index, 'limit': limit})
def get_chart_playlists(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}/playlists', {'index': index, 'limit': limit})
def get_chart_podcasts(self, genre_id=0, index=0, limit=10):
return self.api_call(f'chart/{str(genre_id)}/podcasts', {'index': index, 'limit': limit})
def get_comment(self, comment_id):
return self.api_call(f'comment/{str(comment_id)}')
def get_editorials(self, index=0, limit=10):
return self.api_call('editorial', {'index': index, 'limit': limit})
def get_editorial(self, genre_id=0):
return self.api_call(f'editorial/{str(genre_id)}')
def get_editorial_selection(self, genre_id=0, index=0, limit=10):
return self.api_call(f'editorial/{str(genre_id)}/selection', {'index': index, 'limit': limit})
def get_editorial_charts(self, genre_id=0, index=0, limit=10):
return self.api_call(f'editorial/{str(genre_id)}/charts', {'index': index, 'limit': limit})
def get_editorial_releases(self, genre_id=0, index=0, limit=10):
return self.api_call(f'editorial/{str(genre_id)}/releases', {'index': index, 'limit': limit})
def get_genres(self, index=0, limit=10):
return self.api_call('genre', {'index': index, 'limit': limit})
def get_genre(self, genre_id=0):
return self.api_call(f'genre/{str(genre_id)}')
def get_genre_artists(self, genre_id=0, index=0, limit=10):
return self.api_call(f'genre/{str(genre_id)}/artists', {'index': index, 'limit': limit})
def get_genre_radios(self, genre_id=0, index=0, limit=10):
return self.api_call(f'genre/{str(genre_id)}/radios', {'index': index, 'limit': limit})
def get_infos(self):
return self.api_call('infos')
def get_options(self):
return self.api_call('options')
def get_playlist(self, playlist_id):
return self.api_call(f'playlist/{str(playlist_id)}')
def get_playlist_comments(self, album_id, index=0, limit=10):
return self.api_call(f'playlist/{str(album_id)}/comments', {'index': index, 'limit': limit})
def get_playlist_fans(self, album_id, index=0, limit=100):
return self.api_call(f'playlist/{str(album_id)}/fans', {'index': index, 'limit': limit})
def get_playlist_tracks(self, album_id, index=0, limit=-1):
return self.api_call(f'playlist/{str(album_id)}/tracks', {'index': index, 'limit': limit})
def get_playlist_radio(self, album_id, index=0, limit=100):
return self.api_call(f'playlist/{str(album_id)}/radio', {'index': index, 'limit': limit})
def get_radios(self, index=0, limit=10):
return self.api_call('radio', {'index': index, 'limit': limit})
def get_radios_genres(self, index=0, limit=25):
return self.api_call('radio/genres', {'index': index, 'limit': limit})
def get_radios_top(self, index=0, limit=50):
return self.api_call('radio/top', {'index': index, 'limit': limit})
def get_radios_lists(self, index=0, limit=25):
return self.api_call('radio/lists', {'index': index, 'limit': limit})
def get_radio(self, radio_id):
return self.api_call(f'radio/{str(radio_id)}')
def get_radio_tracks(self, radio_id, index=0, limit=40):
return self.api_call(f'radio/{str(radio_id)}/tracks', {'index': index, 'limit': limit})
def _generate_search_advanced_query(self, artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0):
query = ""
if artist: query += f'artist:"{artist}" '
if album: query += f'album:"{album}" '
if track: query += f'track:"{track}" '
if label: query += f'label:"{label}" '
if dur_min: query += f'dur_min:"{str(dur_min)}" '
if dur_max: query += f'dur_max:"{str(dur_max)}" '
if bpm_min: query += f'bpm_min:"{str(bpm_min)}" '
if bpm_max: query += f'bpm_max:"{str(bpm_max)}" '
return query.strip()
def _generate_search_args(self, query, strict=False, order=None, index=0, limit=25):
args = {'q': query, 'index': index, 'limit': limit}
if strict: args['strict'] = 'on'
if order: args['order'] = order
return args
def search(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search', args)
def advanced_search(self, artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0, strict=False, order=None, index=0, limit=25):
query = self._generate_search_advanced_query(artist, album, track, label, dur_min, dur_max, bpm_min, bpm_max)
return self.search(query, strict, order, index, limit)
def search_album(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/album', args)
def search_artist(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/artist', args)
def search_playlist(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/playlist', args)
def search_radio(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/radio', args)
def search_track(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/track', args)
def search_user(self, query, strict=False, order=None, index=0, limit=25):
args = self._generate_search_args(query, strict, order, index, limit)
return self.api_call('search/user', args)
def get_track(self, song_id):
return self.api_call(f'track/{str(song_id)}')
def get_track_by_ISRC(self, isrc):
return self.get_track(f'isrc:{isrc}')
def get_user(self, user_id):
return self.api_call(f'user/{str(user_id)}')
def get_user_albums(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/albums', {'index': index, 'limit': limit})
def get_user_artists(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/artists', {'index': index, 'limit': limit})
def get_user_flow(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/flow', {'index': index, 'limit': limit})
def get_user_following(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/followings', {'index': index, 'limit': limit})
def get_user_followers(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/followers', {'index': index, 'limit': limit})
def get_user_playlists(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/playlists', {'index': index, 'limit': limit})
def get_user_radios(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/radios', {'index': index, 'limit': limit})
def get_user_tracks(self, user_id, index=0, limit=25):
return self.api_call(f'user/{str(user_id)}/tracks', {'index': index, 'limit': limit})
# Extra calls
def get_countries_charts(self):
temp = self.get_user_playlists('637006841', limit=-1)['data']
result = sorted(temp, key=lambda k: k['title']) # Sort all playlists
if not result[0]['title'].startswith('Top'): result = result[1:] # Remove loved tracks playlist
return result
def get_track_id_from_metadata(self, artist, track, album):
artist = artist.replace("", "-").replace("", "'")
track = track.replace("", "-").replace("", "'")
album = album.replace("", "-").replace("", "'")
resp = self.advanced_search(artist=artist, track=track, album=album, limit=1)
if len(resp['data']) > 0: return resp['data'][0]['id']
resp = self.advanced_search(artist=artist, track=track, limit=1)
if len(resp['data']) > 0: return resp['data'][0]['id']
# Try removing version
if "(" in track and ")" in track and track.find("(") < track.find(")"):
resp = self.advanced_search(artist=artist, track=track[:track.find("(")], limit=1)
if len(resp['data']) > 0: return resp['data'][0]['id']
elif " - " in track:
resp = self.advanced_search(artist=artist, track=track[:track.find(" - ")], limit=1)
if len(resp['data']) > 0: return resp['data'][0]['id']
return "0"