From 244ef307be6816465af3c3b189c883235bf0c5d0 Mon Sep 17 00:00:00 2001 From: Krateng Date: Fri, 10 May 2019 13:15:40 +0200 Subject: [PATCH] Added Spotify API --- external.py | 63 ++++++++++++++++++++++++++++++++++++-------- maloja | 42 +++++++++++++---------------- settings/default.ini | 4 ++- 3 files changed, 74 insertions(+), 35 deletions(-) diff --git a/external.py b/external.py index b0c1c3f..eac30e5 100644 --- a/external.py +++ b/external.py @@ -1,5 +1,6 @@ import urllib.parse, urllib.request import json +import base64 from doreah.settings import get_settings from doreah.logging import log @@ -9,11 +10,21 @@ apis_artists = [ "name":"LastFM + Fanart.tv", "check":get_settings("LASTFM_API_KEY") not in [None,"ASK"] and get_settings("FANARTTV_API_KEY") not in [None,"ASK"], "steps":[ - ("url","http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist={artiststring}&api_key=" + get_settings("LASTFM_API_KEY") + "&format=json"), + ("get","http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist={artiststring}&api_key=" + get_settings("LASTFM_API_KEY") + "&format=json"), ("parse",["artist","mbid"]), - ("url","http://webservice.fanart.tv/v3/music/{var}?api_key=" + get_settings("FANARTTV_API_KEY")), + ("get","http://webservice.fanart.tv/v3/music/{var}?api_key=" + get_settings("FANARTTV_API_KEY")), ("parse",["artistthumb",0,"url"]) ] + }, + { + "name":"Spotify", + "check":get_settings("SPOTIFY_API_ID") not in [None,"ASK"] and get_settings("SPOTIFY_API_SECRET") not in [None,"ASK"], + "steps":[ + ("post","https://accounts.spotify.com/api/token",{"Authorization":"Basic " + base64.b64encode(bytes(get_settings("SPOTIFY_API_ID") + ":" + get_settings("SPOTIFY_API_SECRET"),encoding="utf-8")).decode("utf-8")},{"grant_type":"client_credentials"}), + ("parse",["access_token"]), + ("get","https://api.spotify.com/v1/search?q={artiststring}&type=artist&access_token={var}"), + ("parse",["artists","items",0,"images",0,"url"]) + ] } ] @@ -22,9 +33,19 @@ apis_tracks = [ "name":"LastFM", "check":get_settings("LASTFM_API_KEY") not in [None,"ASK"], "steps":[ - ("url","https://ws.audioscrobbler.com/2.0/?method=track.getinfo&track={titlestring}&artist={artiststring}&api_key=" + get_settings("LASTFM_API_KEY") + "&format=json"), + ("get","https://ws.audioscrobbler.com/2.0/?method=track.getinfo&track={titlestring}&artist={artiststring}&api_key=" + get_settings("LASTFM_API_KEY") + "&format=json"), ("parse",["track","album","image",3,"#text"]) ] + }, + { + "name":"Spotify", + "check":get_settings("SPOTIFY_API_ID") not in [None,"ASK"] and get_settings("SPOTIFY_API_SECRET") not in [None,"ASK"], + "steps":[ + ("post","https://accounts.spotify.com/api/token",{"Authorization":"Basic " + base64.b64encode(bytes(get_settings("SPOTIFY_API_ID") + ":" + get_settings("SPOTIFY_API_SECRET"),encoding="utf-8")).decode("utf-8")},{"grant_type":"client_credentials"}), + ("parse",["access_token"]), + ("get","https://api.spotify.com/v1/search?q={artiststring}%20{titlestring}&type=track&access_token={var}"), + ("parse",["tracks","items",0,"album","images",0,"url"]) + ] } ] @@ -36,9 +57,19 @@ def api_request_artist(artist): artiststring = urllib.parse.quote(artist) var = artiststring for step in api["steps"]: - if step[0] == "url": + if step[0] == "get": response = urllib.request.urlopen(step[1].format(artiststring=artiststring,var=var)) var = json.loads(response.read()) + elif step[0] == "post": + keys = { + "url":step[1].format(artiststring=artiststring,var=var), + "method":"POST", + "headers":step[2], + "data":bytes(urllib.parse.urlencode(step[3]),encoding="utf-8") + } + req = urllib.request.Request(**keys) + response = urllib.request.urlopen(req) + var = json.loads(response.read()) elif step[0] == "parse": for node in step[1]: var = var[node] @@ -61,20 +92,30 @@ def api_request_track(track): titlestring = urllib.parse.quote(title) var = artiststring + titlestring for step in api["steps"]: - if step[0] == "url": + if step[0] == "get": response = urllib.request.urlopen(step[1].format(artiststring=artiststring,titlestring=titlestring,var=var)) var = json.loads(response.read()) + elif step[0] == "post": + keys = { + "url":step[1].format(artiststring=artiststring,titlestring=titlestring,var=var), + "method":"POST", + "headers":step[2], + "data":bytes(urllib.parse.urlencode(step[3]),encoding="utf-8") + } + req = urllib.request.Request(**keys) + response = urllib.request.urlopen(req) + var = json.loads(response.read()) elif step[0] == "parse": for node in step[1]: var = var[node] assert isinstance(var,str) and var != "" except: - if len(artists) == 1: return None - # try the same track with every single artist - for a in artists: - result = api_request_track(([a],title)) - if result is not None: - return result + if len(artists) != 1: + # try the same track with every single artist + for a in artists: + result = api_request_track(([a],title)) + if result is not None: + return result continue return var diff --git a/maloja b/maloja index 27d269c..37bf120 100755 --- a/maloja +++ b/maloja @@ -52,31 +52,27 @@ def setup(): from doreah import settings - # LASTFM API KEY - key = settings.get_settings("LASTFM_API_KEY") - if key is None: - print("Currently not using a Last.fm API key for image display. Only local images will be used.") - elif key == "ASK": - print("Please enter your Last.FM API key. If you do not want to display artist and track images, simply leave this empty and press Enter.") - key = input() - if key == "": key = None - settings.update_settings("settings/settings.ini",{"LASTFM_API_KEY":key},create_new=True) + # EXTERNAL API KEYS + apikeys = { + "LASTFM_API_KEY":"Last.fm API Key", + "FANARTTV_API_KEY":"Fanart.tv API Key", + "SPOTIFY_API_ID":"Spotify Client ID", + "SPOTIFY_API_SECRET":"Spotify Client Secret" + } - else: - print("Last.FM API key found.") + print("Various external services can be used to display images. If not enough of them are set up, only local images will be used.") + for k in apikeys: + key = settings.get_settings(k) + if key is None: + print("Currently not using a " + apikeys[k] + " for image display.") + elif key == "ASK": + print("Please enter your " + apikeys[k] + ". If you do not want to use one at this moment, simply leave this empty and press Enter.") + key = input() + if key == "": key = None + settings.update_settings("settings/settings.ini",{k:key},create_new=True) + else: + print(apikeys[k] + " found.") - # FANART.TV API KEY - key = settings.get_settings("FANARTTV_API_KEY") - if key is None: - print("Currently not using a Fanart.tv API key for image display. Only local images will be used for artists.") - elif key == "ASK": - print("Please enter your Fanart.tv API key. If you do not want to display artist and track images, simply leave this empty and press Enter.") - key = input() - if key == "": key = None - settings.update_settings("settings/settings.ini",{"FANARTTV_API_KEY":key},create_new=True) - - else: - print("Fanart.tv API key found.") # OWN API KEY if os.path.exists("./clients/authenticated_machines.tsv"): diff --git a/settings/default.ini b/settings/default.ini index ecf76f7..f1ed7ee 100644 --- a/settings/default.ini +++ b/settings/default.ini @@ -5,8 +5,10 @@ API_PORT = 42011 [Third Party Services] -LASTFM_API_KEY = "ASK" # "ASK" signifies that the user has not yet indicated to not use any key at all. +LASTFM_API_KEY = "ASK" # 'ASK' signifies that the user has not yet indicated to not use any key at all. FANARTTV_API_KEY = "ASK" +SPOTIFY_API_ID = "ASK" +SPOTIFY_API_SECRET = "ASK" CACHE_EXPIRE_NEGATIVE = 30 # after how many days negative results should be tried again CACHE_EXPIRE_POSITIVE = 300 # after how many days positive results should be refreshed