mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Basic artist overview webpage
This commit is contained in:
parent
159313ad0a
commit
1643eafc71
111
database.py
111
database.py
@ -166,34 +166,27 @@ def get_pulse():
|
|||||||
since = request.query.get("since")
|
since = request.query.get("since")
|
||||||
to = request.query.get("to")
|
to = request.query.get("to")
|
||||||
(ts_start,ts_end) = getTimestamps(since,to)
|
(ts_start,ts_end) = getTimestamps(since,to)
|
||||||
date_start = datetime.datetime.utcfromtimestamp(ts_start)
|
step = request.query.get("step","month")
|
||||||
date_end = datetime.datetime.utcfromtimestamp(ts_end)
|
trail = int(request.query.get("trail",3))
|
||||||
#date_start = datetime.datetime.utcfromtimestamp(min(timestamps))
|
|
||||||
#date_end = datetime.datetime.utcnow()
|
|
||||||
d_end = [date_end.year,date_end.month,date_end.day]
|
|
||||||
|
|
||||||
step = request.query.get("step")
|
|
||||||
if (step == None):
|
|
||||||
step = "month"
|
|
||||||
|
|
||||||
[step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned
|
[step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned
|
||||||
|
stepn = int(stepn)
|
||||||
|
|
||||||
if step == "year":
|
d_start = getStartOf(ts_start,step)
|
||||||
d_start = [date_start.year,1,1]
|
d_end = getStartOf(ts_end,step)
|
||||||
elif step == "month":
|
|
||||||
d_start = [date_start.year,date_start.month,1]
|
|
||||||
|
|
||||||
inc = [i*int(stepn) for i in {"year":[1,0,0],"month":[0,1,0]}[step]]
|
|
||||||
|
|
||||||
|
d_start = getNext(d_start,step,stepn) # first range should end right after the first active scrobbling week / month / whatever relevant step
|
||||||
|
d_start = getNext(d_start,step,stepn * trail * -1) # go one range back to begin
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
|
|
||||||
d_current = d_start
|
d_current = d_start
|
||||||
while True:
|
while True:
|
||||||
d_current_end = addDate(d_current,inc)
|
d_current_end = getNext(d_current,step,stepn * trail)
|
||||||
|
#print("Checking from " + str(d_current[0]) + "-" + str(d_current[1]) + "-" + str(d_current[2]) + " to " + str(d_current_end[0]) + "-" + str(d_current_end[1]) + "-" + str(d_current_end[2]))
|
||||||
res = db_aggregate(since=d_current,to=d_current_end)
|
res = db_aggregate(since=d_current,to=d_current_end)
|
||||||
results.append({"from":d_current,"to":d_current_end,"scrobbles":res})
|
results.append({"from":d_current,"to":d_current_end,"scrobbles":res})
|
||||||
d_current = d_current_end
|
d_current = getNext(d_current,step,stepn)
|
||||||
if isPast(d_current_end,d_end):
|
if isPast(d_current_end,d_end):
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -205,33 +198,17 @@ def get_top_artists():
|
|||||||
since = request.query.get("since")
|
since = request.query.get("since")
|
||||||
to = request.query.get("to")
|
to = request.query.get("to")
|
||||||
(ts_start,ts_end) = getTimestamps(since,to)
|
(ts_start,ts_end) = getTimestamps(since,to)
|
||||||
#date_start = datetime.datetime.utcfromtimestamp(ts_start)
|
|
||||||
#date_end = datetime.datetime.utcfromtimestamp(ts_end)
|
|
||||||
#d_end = [date_end.year,date_end.month,date_end.day]
|
|
||||||
|
|
||||||
# We use a trailing multiplier instead of a separate argument for time and step to avoid weirdness
|
|
||||||
# e.g. if our steps are weeks, but the time is a month, should the value for 3/31 go back to 2/28?
|
|
||||||
step = request.query.get("step","month")
|
step = request.query.get("step","month")
|
||||||
trail = int(request.query.get("trail","3"))
|
trail = int(request.query.get("trail",3))
|
||||||
|
|
||||||
[step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned
|
[step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned
|
||||||
#[time,timen] = (time.split("-") + [1])[:2]
|
|
||||||
stepn = int(stepn)
|
stepn = int(stepn)
|
||||||
|
|
||||||
d_start = getStartOf(ts_start,step)
|
d_start = getStartOf(ts_start,step)
|
||||||
d_end = getStartOf(ts_end,step)
|
d_end = getStartOf(ts_end,step)
|
||||||
#if step == "year":
|
|
||||||
# d_start = [date_start.year,1,1]
|
|
||||||
#elif step == "month":
|
|
||||||
# d_start = [date_start.year,date_start.month,1]
|
|
||||||
|
|
||||||
#inc = [i*int(stepn) for i in {"year":[1,0,0],"month":[0,1,0]}[step]]
|
d_start = getNext(d_start,step,stepn) # first range should end right after the first active scrobbling week / month / whatever relevant step
|
||||||
#ran = [i*int(timen) for i in {"year":[1,0,0],"month":[0,1,0]}[time]]
|
d_start = getNext(d_start,step,stepn * trail * -1) # go one range back to begin
|
||||||
|
|
||||||
#d_start = addDate(d_start,inc) # first range should end right after the first active scrobbling week / month / whatever relevant step
|
|
||||||
#d_start = addDate(d_start,[-i for i in ran]) # go one range back to begin
|
|
||||||
d_start = getNext(d_start,step,stepn)
|
|
||||||
d_start = getNext(d_start,step,stepn * trail * -1)
|
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
|
|
||||||
@ -239,14 +216,46 @@ def get_top_artists():
|
|||||||
while True:
|
while True:
|
||||||
d_current_end = getNext(d_current,step,stepn * trail)
|
d_current_end = getNext(d_current,step,stepn * trail)
|
||||||
#print("Checking from " + str(d_current[0]) + "-" + str(d_current[1]) + "-" + str(d_current[2]) + " to " + str(d_current_end[0]) + "-" + str(d_current_end[1]) + "-" + str(d_current_end[2]))
|
#print("Checking from " + str(d_current[0]) + "-" + str(d_current[1]) + "-" + str(d_current[2]) + " to " + str(d_current_end[0]) + "-" + str(d_current_end[1]) + "-" + str(d_current_end[2]))
|
||||||
#d_current_end = addDate(d_current,ran)
|
|
||||||
try:
|
try:
|
||||||
res = db_aggregate(since=d_current,to=d_current_end,by="ARTIST")[0]
|
res = db_aggregate(since=d_current,to=d_current_end,by="ARTIST")[0]
|
||||||
results.append({"from":d_current,"to":d_current_end,"artist":res["artist"],"scrobbles":res["scrobbles"]})
|
results.append({"from":d_current,"to":d_current_end,"artist":res["artist"],"scrobbles":res["scrobbles"]})
|
||||||
except:
|
except:
|
||||||
results.append({"from":d_current,"to":d_current_end,"artist":None,"scrobbles":0})
|
results.append({"from":d_current,"to":d_current_end,"artist":None,"scrobbles":0})
|
||||||
d_current = getNext(d_current,step,stepn)
|
d_current = getNext(d_current,step,stepn)
|
||||||
#d_current = addDate(d_current,inc)
|
if isPast(d_current_end,d_end):
|
||||||
|
break
|
||||||
|
|
||||||
|
return {"list":results}
|
||||||
|
|
||||||
|
@route("/top/tracks")
|
||||||
|
def get_top_tracks():
|
||||||
|
since = request.query.get("since")
|
||||||
|
to = request.query.get("to")
|
||||||
|
(ts_start,ts_end) = getTimestamps(since,to)
|
||||||
|
step = request.query.get("step","month")
|
||||||
|
trail = int(request.query.get("trail",3))
|
||||||
|
|
||||||
|
[step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned
|
||||||
|
stepn = int(stepn)
|
||||||
|
|
||||||
|
d_start = getStartOf(ts_start,step)
|
||||||
|
d_end = getStartOf(ts_end,step)
|
||||||
|
|
||||||
|
d_start = getNext(d_start,step,stepn) # first range should end right after the first active scrobbling week / month / whatever relevant step
|
||||||
|
d_start = getNext(d_start,step,stepn * trail * -1) # go one range back to begin
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
d_current = d_start
|
||||||
|
while True:
|
||||||
|
d_current_end = getNext(d_current,step,stepn * trail)
|
||||||
|
#print("Checking from " + str(d_current[0]) + "-" + str(d_current[1]) + "-" + str(d_current[2]) + " to " + str(d_current_end[0]) + "-" + str(d_current_end[1]) + "-" + str(d_current_end[2]))
|
||||||
|
try:
|
||||||
|
res = db_aggregate(since=d_current,to=d_current_end,by="TRACK")[0]
|
||||||
|
results.append({"from":d_current,"to":d_current_end,"track":res["track"],"scrobbles":res["scrobbles"]})
|
||||||
|
except:
|
||||||
|
results.append({"from":d_current,"to":d_current_end,"track":None,"scrobbles":0})
|
||||||
|
d_current = getNext(d_current,step,stepn)
|
||||||
if isPast(d_current_end,d_end):
|
if isPast(d_current_end,d_end):
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -288,20 +297,20 @@ def getNext(time,unit,step=1):
|
|||||||
elif unit == "week":
|
elif unit == "week":
|
||||||
return getNext(time,"day",step * 7)
|
return getNext(time,"day",step * 7)
|
||||||
|
|
||||||
# DEPRECATED
|
|
||||||
def addDate(date,inc):
|
|
||||||
newdate = [1,1,1]
|
|
||||||
newdate[0] = date[0] + inc[0]
|
|
||||||
newdate[1] = date[1] + inc[1]
|
|
||||||
newdate[2] = date[2] + inc[2]
|
|
||||||
while (newdate[1] > 12):
|
|
||||||
newdate[1] -= 12
|
|
||||||
newdate[0] += 1
|
|
||||||
while (newdate[1] < 1):
|
|
||||||
newdate[1] += 12
|
|
||||||
newdate[0] -= 1
|
|
||||||
|
|
||||||
return newdate
|
#def addDate(date,inc):
|
||||||
|
# newdate = [1,1,1]
|
||||||
|
# newdate[0] = date[0] + inc[0]
|
||||||
|
# newdate[1] = date[1] + inc[1]
|
||||||
|
# newdate[2] = date[2] + inc[2]
|
||||||
|
# while (newdate[1] > 12):
|
||||||
|
# newdate[1] -= 12
|
||||||
|
# newdate[0] += 1
|
||||||
|
# while (newdate[1] < 1):
|
||||||
|
# newdate[1] += 12
|
||||||
|
# newdate[0] -= 1
|
||||||
|
#
|
||||||
|
# return newdate
|
||||||
|
|
||||||
def isPast(date,limit):
|
def isPast(date,limit):
|
||||||
if not date[0] == limit[0]:
|
if not date[0] == limit[0]:
|
||||||
|
@ -9,6 +9,7 @@ import urllib.parse
|
|||||||
from urllib.error import *
|
from urllib.error import *
|
||||||
import sys
|
import sys
|
||||||
import signal
|
import signal
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
MAIN_PORT = 42010
|
MAIN_PORT = 42010
|
||||||
@ -80,6 +81,8 @@ def static(name):
|
|||||||
|
|
||||||
@route("/<name>")
|
@route("/<name>")
|
||||||
def static_html(name):
|
def static_html(name):
|
||||||
|
if os.path.exists("website/" + name + ".py"):
|
||||||
|
return SourceFileLoader(name,"website/" + name + ".py").load_module().page(FormsDict.decode(request.query))
|
||||||
|
|
||||||
return static_file("website/" + name + ".html",root="")
|
return static_file("website/" + name + ".html",root="")
|
||||||
|
|
||||||
|
2
website/.gitignore
vendored
Normal file
2
website/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__pycache__
|
||||||
|
apikey
|
29
website/artist.html
Normal file
29
website/artist.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Maloja</title>
|
||||||
|
<link rel="stylesheet" href="maloja.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table class="top_info">
|
||||||
|
<tr>
|
||||||
|
<td class="image">
|
||||||
|
<img src="KEY_IMAGEURL" />
|
||||||
|
</td>
|
||||||
|
<td class="text">
|
||||||
|
<h1>KEY_ARTISTNAME</h1>
|
||||||
|
<p class="stats">2342 Scrobbles / 23th all time / 12th this month</p>
|
||||||
|
|
||||||
|
KEY_DESCRIPTION
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Tracks</h2>
|
||||||
|
KEY_TRACKLIST
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
48
website/artist.py
Normal file
48
website/artist.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import urllib
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def page(keys):
|
||||||
|
|
||||||
|
txt_keys = replace(keys)
|
||||||
|
|
||||||
|
|
||||||
|
with open("website/artist.html","r") as htmlfile:
|
||||||
|
html = htmlfile.read()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for k in txt_keys:
|
||||||
|
html = html.replace(k,txt_keys[k])
|
||||||
|
|
||||||
|
return html
|
||||||
|
|
||||||
|
def replace(keys):
|
||||||
|
with open("website/apikey","r") as keyfile:
|
||||||
|
apikey = keyfile.read().replace("\n","")
|
||||||
|
url = "https://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=" + keys["artist"] + "&api_key=" + apikey + "&format=json"
|
||||||
|
response = urllib.request.urlopen(url)
|
||||||
|
lastfm_data = json.loads(response.read())
|
||||||
|
imgurl = lastfm_data["artist"]["image"][2]["#text"]
|
||||||
|
desc = lastfm_data["artist"]["bio"]["summary"]
|
||||||
|
|
||||||
|
response = urllib.request.urlopen("http://localhost:42010/db/tracks?artist=" + urllib.parse.quote(keys["artist"]))
|
||||||
|
db_data = json.loads(response.read())
|
||||||
|
tracks = []
|
||||||
|
for e in db_data["list"]:
|
||||||
|
html = "<td>"
|
||||||
|
for a in e["artists"]:
|
||||||
|
html += "<a href=/artist?artist=" + urllib.parse.quote(a) + ">" + a + "</a> "
|
||||||
|
html += "</td><td>" + e["title"] + "</td>"
|
||||||
|
tracks.append(html)
|
||||||
|
|
||||||
|
trackshtml = "<table>"
|
||||||
|
for t in tracks:
|
||||||
|
trackshtml += "<tr>"
|
||||||
|
trackshtml += t
|
||||||
|
trackshtml += "</tr>"
|
||||||
|
trackshtml += "</table>"
|
||||||
|
|
||||||
|
|
||||||
|
return {"KEY_ARTISTNAME":keys["artist"],"KEY_IMAGEURL":imgurl,"KEY_DESCRIPTION":desc,"KEY_TRACKLIST":trackshtml}
|
@ -1,8 +1,30 @@
|
|||||||
@import url('https://fonts.googleapis.com/css?family=Ubuntu');
|
@import url('https://fonts.googleapis.com/css?family=Ubuntu');
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color:#111114;
|
background-color:#333337;
|
||||||
color:beige;
|
color:beige;
|
||||||
font-family:"Ubuntu";
|
font-family:"Ubuntu";
|
||||||
padding:15px;
|
padding:15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color:lightgray;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.top_info td.image {
|
||||||
|
padding:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.top_info td.text {
|
||||||
|
vertical-align: top;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.top_info td.text p.stats {
|
||||||
|
color:grey;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user