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:
parent
5fd6810098
commit
39873e9297
4
images/artists/.gitignore
vendored
Normal file
4
images/artists/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.png
|
||||||
|
*.jpg
|
||||||
|
*.jpeg
|
||||||
|
!default.jpg
|
BIN
images/artists/default.jpg
Normal file
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
4
images/tracks/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.png
|
||||||
|
*.jpg
|
||||||
|
*.jpeg
|
||||||
|
!default.jpg
|
@ -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>")
|
||||||
|
240
utilities.py
240
utilities.py
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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}
|
||||||
|
@ -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;
|
||||||
|
@ -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>"
|
||||||
|
@ -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")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user