1
0
mirror of https://github.com/krateng/maloja.git synced 2023-08-10 21:12:55 +03:00

Reworked artwork grabbing

This commit is contained in:
Krateng 2018-12-28 18:06:09 +01:00
parent 5fd6810098
commit 39873e9297
9 changed files with 212 additions and 73 deletions

4
images/artists/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.png
*.jpg
*.jpeg
!default.jpg

BIN
images/artists/default.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

4
images/tracks/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.png
*.jpg
*.jpeg
!default.jpg

View File

@ -72,11 +72,11 @@ def graceful_exit(sig=None,frame=None):
sys.exit() sys.exit()
@webserver.route("/info/<pth:re:.*\\.jpeg>") @webserver.route("/images/<pth:re:.*\\.jpeg>")
@webserver.route("/info/<pth:re:.*\\.jpg>") @webserver.route("/images/<pth:re:.*\\.jpg>")
@webserver.route("/info/<pth:re:.*\\.png>") @webserver.route("/images/<pth:re:.*\\.png>")
def static_image(pth): def static_image(pth):
return static_file("info/" + pth,root="") return static_file("images/" + pth,root="")
@webserver.route("/<name:re:.*\\.html>") @webserver.route("/<name:re:.*\\.html>")
@webserver.route("/<name:re:.*\\.js>") @webserver.route("/<name:re:.*\\.js>")

View File

@ -144,88 +144,206 @@ def log(msg):
### Media info ### Media info
def getArtistInfo(artist): def apirequest(artists=None,artist=None,title=None):
import urllib.parse, urllib.request
import json
with open("apikey","r") as keyfile:
apikey = keyfile.read().replace("\n","")
sites = [
{
"name":"lastfm",
"artisturl":"https://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist={artist}&api_key=" + apikey + "&format=json",
"trackurl":"https://ws.audioscrobbler.com/2.0/?method=track.getinfo&track={title}&artist={artist}&api_key=" + apikey + "&format=json",
"result_artist_imgurl":lambda data:data["artist"]["image"][2]["#text"],
"result_track_imgurl":lambda data:data["track"]["album"]["image"][2]["#text"]
#"result_artist_desc":lambda data:data["artist"]["bio"]["summary"],
#"result_track_desc":lambda data:None
}
]
# TRACKS
if title is not None:
for s in sites:
try:
artiststr = urllib.parse.quote(", ".join(artists))
titlestr = urllib.parse.quote(title)
response = urllib.request.urlopen(s["trackurl"].format(artist=artiststr,title=titlestr))
data = json.loads(response.read())
if s["result_track_imgurl"](data) != "":
return {"image":s["result_track_imgurl"](data)}
except:
pass
# if nothing worked, just return the artist image
if len(artists) == 1:
return {"image":apirequest(artist=artists[0])["image"]}
#return {"image":None,"desc":None}
# try the same track with every single artist
for a in artists:
rec = apirequest(artists=[a],title=title)
if rec["image"] is not None:
return rec
# ARTISTS
else:
for s in sites:
try:
response = urllib.request.urlopen(s["artisturl"].format(artist=urllib.parse.quote(artist)))
data = json.loads(response.read())
if s["result_artist_imgurl"](data) != "":
return {"image":s["result_artist_imgurl"](data)}
except:
pass
return {"image":None}
cachedTracks = {}
cachedArtists = {}
def getTrackInfo(artists,title):
import re import re
import os import os
import urllib
import json
import _thread
obj = (frozenset(artists),title)
filename = re.sub("[^a-zA-Z0-9]","",artist) filename = "-".join([re.sub("[^a-zA-Z0-9]","",artist) for artist in artists]) + "_" + re.sub("[^a-zA-Z0-9]","",title)
filepath = "info/artists/" + filename if filename = "": filename = str(hash(obj))
filepath_cache = "info/artists_cache/" + filename filepath = "images/tracks/" + filename
# check if custom image exists # check if custom image exists
if os.path.exists(filepath + ".png"): if os.path.exists(filepath + ".png"):
imgurl = "/" + filepath + ".png" imgurl = "/" + filepath + ".png"
return {"image":imgurl}
elif os.path.exists(filepath + ".jpg"): elif os.path.exists(filepath + ".jpg"):
imgurl = "/" + filepath + ".jpg" imgurl = "/" + filepath + ".jpg"
return {"image":imgurl}
elif os.path.exists(filepath + ".jpeg"): elif os.path.exists(filepath + ".jpeg"):
imgurl = "/" + filepath + ".jpeg" imgurl = "/" + filepath + ".jpeg"
return {"image":imgurl}
try:
return {"image":cachedTracks[(frozenset(artists),title)]}
except:
pass
result = apirequest(artists=artists,title=title)
cachedTracks[(frozenset(artists),title)] = result["image"]
return result
# with open("apikey","r") as keyfile:
# apikey = keyfile.read().replace("\n","")
#
#
# for a in artists:
# try:
# url = "https://ws.audioscrobbler.com/2.0/?method=track.getinfo&track=" + urllib.parse.quote(title) + "&artist=" + urllib.parse.quote(a) + "&api_key=" + apikey + "&format=json"
# response = urllib.request.urlopen(url)
# lastfm_data = json.loads(response.read())
# imgurl = lastfm_data["track"]["album"]["image"][2]["#text"]
# break
# except:
# pass
#
# try:
# return {"image":imgurl}
# except:
# for a in artists:
# try:
# return {"image":getArtistInfo(a)["image"]}
# except:
# pass
#
# return {"image":""}
def getArtistInfo(artist):
import re
import os
obj = artist
filename = re.sub("[^a-zA-Z0-9]","",artist)
if filename = "": filename = str(hash(obj))
filepath = "images/artists/" + filename
#filepath_cache = "info/artists_cache/" + filename
# check if custom image exists
if os.path.exists(filepath + ".png"):
imgurl = "/" + filepath + ".png"
return {"image":imgurl}
elif os.path.exists(filepath + ".jpg"):
imgurl = "/" + filepath + ".jpg"
return {"image":imgurl}
elif os.path.exists(filepath + ".jpeg"):
imgurl = "/" + filepath + ".jpeg"
return {"image":imgurl}
#check if cached image exists #check if cached image exists
elif os.path.exists(filepath_cache + ".png"): # elif os.path.exists(filepath_cache + ".png"):
imgurl = "/" + filepath_cache + ".png" # imgurl = "/" + filepath_cache + ".png"
elif os.path.exists(filepath_cache + ".jpg"): # elif os.path.exists(filepath_cache + ".jpg"):
imgurl = "/" + filepath_cache + ".jpg" # imgurl = "/" + filepath_cache + ".jpg"
elif os.path.exists(filepath_cache + ".jpeg"): # elif os.path.exists(filepath_cache + ".jpeg"):
imgurl = "/" + filepath_cache + ".jpeg" # imgurl = "/" + filepath_cache + ".jpeg"
# check if custom desc exists # check if custom desc exists
if os.path.exists(filepath + ".txt"): # if os.path.exists(filepath + ".txt"):
with open(filepath + ".txt","r") as descfile: # with open(filepath + ".txt","r") as descfile:
desc = descfile.read().replace("\n","") # desc = descfile.read().replace("\n","")
#
#check if cached desc exists # #check if cached desc exists
elif os.path.exists(filepath_cache + ".txt"): # elif os.path.exists(filepath_cache + ".txt"):
with open(filepath_cache + ".txt","r") as descfile: # with open(filepath_cache + ".txt","r") as descfile:
desc = descfile.read().replace("\n","") # desc = descfile.read().replace("\n","")
try: try:
return {"image":imgurl,"info":desc} return {"image":cachedArtists[artist]}
except NameError:
pass
#is this pythonic?
# if we neither have a custom image nor a cached version, we return the address from lastfm, but cache that image for later use
with open("apikey","r") as keyfile:
apikey = keyfile.read().replace("\n","")
try:
url = "https://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=" + urllib.parse.quote(artist) + "&api_key=" + apikey + "&format=json"
response = urllib.request.urlopen(url)
lastfm_data = json.loads(response.read())
try:
imgurl
except NameError:
imgurl = lastfm_data["artist"]["image"][2]["#text"]
if imgurl == "":
imgurl = "/info/artists/default.jpg"
else:
_thread.start_new_thread(cacheImage,(imgurl,"info/artists_cache",filename))
try:
desc
except NameError:
desc = lastfm_data["artist"]["bio"]["summary"].split("(1) ")[-1]
with open(filepath_cache + ".txt","w") as descfile:
descfile.write(desc)
# this feels so dirty
return {"image":imgurl,"info":desc}
except: except:
return {"image":"/info/artists/default.jpg","info":"No information available"} pass
result = apirequest(artist=artist)
cachedArtists[artist] = result["image"]
return result
# # if we neither have a custom image nor a cached version, we return the address from lastfm, but cache that image for later use
# with open("apikey","r") as keyfile:
# apikey = keyfile.read().replace("\n","")
#
#
# try:
# url = "https://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=" + urllib.parse.quote(artist) + "&api_key=" + apikey + "&format=json"
# response = urllib.request.urlopen(url)
# lastfm_data = json.loads(response.read())
# try:
# imgurl
# except NameError:
# imgurl = lastfm_data["artist"]["image"][2]["#text"]
# if imgurl == "":
# imgurl = "/info/artists/default.jpg"
# else:
# _thread.start_new_thread(cacheImage,(imgurl,"info/artists_cache",filename))
# try:
# desc
# except NameError:
# desc = lastfm_data["artist"]["bio"]["summary"].split("(1) ")[-1]
# with open(filepath_cache + ".txt","w") as descfile:
# descfile.write(desc)
# # this feels so dirty
#
#
# return {"image":imgurl,"info":desc}
# except:
# return {"image":"/info/artists/default.jpg","info":"No information available"}
def cacheImage(url,path,filename): #def cacheImage(url,path,filename):
import urllib.request # import urllib.request
response = urllib.request.urlopen(url) # response = urllib.request.urlopen(url)
target = path + "/" + filename + "." + response.info().get_content_subtype() # target = path + "/" + filename + "." + response.info().get_content_subtype()
urllib.request.urlretrieve(url,target) # urllib.request.urlretrieve(url,target)

View File

@ -9,7 +9,7 @@ def replacedict(keys,dbport):
clean(keys) clean(keys)
info = getArtistInfo(keys["artist"]) info = getArtistInfo(keys["artist"])
imgurl = info.get("image") imgurl = info.get("image")
desc = info.get("info") #desc = info.get("info")
response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/artistinfo?artist=" + urllib.parse.quote(keys["artist"])) response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/artistinfo?artist=" + urllib.parse.quote(keys["artist"]))
db_data = json.loads(response.read()) db_data = json.loads(response.read())
@ -39,9 +39,9 @@ def replacedict(keys,dbport):
html += "<td class='artists'>" + artistLinks(e["track"]["artists"]) + "</td>" html += "<td class='artists'>" + artistLinks(e["track"]["artists"]) + "</td>"
html += "<td>" + trackLink(e["track"]) + "</td>" html += "<td>" + trackLink(e["track"]) + "</td>"
html += "<td class='amount'>" + scrobblesTrackLink(e["track"],{},amount=e["scrobbles"]) + "</td>" html += "<td class='amount'>" + scrobblesTrackLink(e["track"],{},amount=e["scrobbles"]) + "</td>"
html += "<td class='bar'>" + scrobblesTrackLink(e["track"],{},pixels=e["scrobbles"]*100/maxbar) + "</td>" html += "<td class='bar'>" + scrobblesTrackLink(e["track"],{},percent=e["scrobbles"]*100/maxbar) + "</td>"
html += "</tr>" html += "</tr>"
html += "</table>" html += "</table>"
return {"KEY_ARTISTNAME":keys["artist"],"KEY_ENC_ARTISTNAME":urllib.parse.quote(keys["artist"]),"KEY_IMAGEURL":imgurl, "KEY_DESCRIPTION":desc,"KEY_TRACKLIST":html,"KEY_SCROBBLES":scrobbles,"KEY_POSITION":pos,"KEY_ASSOCIATED":includestr} return {"KEY_ARTISTNAME":keys["artist"],"KEY_ENC_ARTISTNAME":urllib.parse.quote(keys["artist"]),"KEY_IMAGEURL":imgurl, "KEY_DESCRIPTION":"","KEY_TRACKLIST":html,"KEY_SCROBBLES":scrobbles,"KEY_POSITION":pos,"KEY_ASSOCIATED":includestr}

View File

@ -79,19 +79,31 @@ table.list tr td {
} }
table tr:nth-child(even) { table.list tr:nth-child(even) {
background-color:#37373B; background-color:#37373B;
} }
table tr:nth-child(5n) td { table.list tr:nth-child(5n) td {
border-color:rgba(120,120,120,0.2); border-color:rgba(120,120,120,0.2);
} }
table.list tr:hover {
background-color:#404044;
}
table td.time { table td.time {
width:200px; width:180px;
color:gray; color:gray;
} }
table td.icon {
width:20px;
height:20px;
background-size:cover;
background-position:center;
}
table td.artists,td.artist,td.title { table td.artists,td.artist,td.title {
width:500px; width:500px;
white-space:nowrap; white-space:nowrap;

View File

@ -45,6 +45,7 @@ def replacedict(keys,dbport):
for s in scrobbles: for s in scrobbles:
html += "<tr>" html += "<tr>"
html += "<td class='time'>" + getTimeDesc(s["time"]) + "</td>" html += "<td class='time'>" + getTimeDesc(s["time"]) + "</td>"
#html += """<td class='icon' style="background-image:url('""" + getArtistInfo(s["artists"][0]).get("image") + """')" /></td>"""
html += "<td class='artists'>" + artistLinks(s["artists"]) + "</td>" html += "<td class='artists'>" + artistLinks(s["artists"]) + "</td>"
html += "<td class='title'>" + trackLink({"artists":s["artists"],"title":s["title"]}) + "</td>" html += "<td class='title'>" + trackLink({"artists":s["artists"],"title":s["title"]}) + "</td>"
html += "</tr>" html += "</tr>"

View File

@ -3,12 +3,12 @@ import json
def replacedict(keys,dbport): def replacedict(keys,dbport):
from utilities import getArtistInfo from utilities import getArtistInfo, getTrackInfo
from htmlgenerators import clean, artistLink, artistLinks, trackLink, scrobblesTrackLink, keysToUrl, pickKeys, getTimeDesc from htmlgenerators import clean, artistLink, artistLinks, trackLink, scrobblesTrackLink, keysToUrl, pickKeys, getTimeDesc
clean(keys) clean(keys)
limitkeys = pickKeys(keys,"artist","title") limitkeys = pickKeys(keys,"artist","title")
info = getArtistInfo(keys["artist"]) info = getTrackInfo(keys.getall("artist"),keys.get("title"))
imgurl = info.get("image") imgurl = info.get("image")
desc = info.get("info") desc = info.get("info")