mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Added time selector to scrobbles and fixed bug with multiartist tracks
This commit is contained in:
parent
aa56e11d85
commit
c96103ad28
@ -3,28 +3,28 @@ from bottle import FormsDict
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
def artistLink(name):
|
def artistLink(name):
|
||||||
return "<a href='/artist?artist=" + urllib.parse.quote(name) + "'>" + name + "</a>"
|
return "<a href='/artist?artist=" + urllib.parse.quote(name) + "'>" + name + "</a>"
|
||||||
|
|
||||||
def artistLinks(artists):
|
def artistLinks(artists):
|
||||||
return ", ".join([artistLink(a) for a in artists])
|
return ", ".join([artistLink(a) for a in artists])
|
||||||
|
|
||||||
#def trackLink(artists,title):
|
#def trackLink(artists,title):
|
||||||
def trackLink(track):
|
def trackLink(track):
|
||||||
artists,title = track["artists"],track["title"]
|
artists,title = track["artists"],track["title"]
|
||||||
return "<a href='/track?title=" + urllib.parse.quote(title) + "&" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "'>" + title + "</a>"
|
return "<a href='/track?title=" + urllib.parse.quote(title) + "&" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "'>" + title + "</a>"
|
||||||
|
|
||||||
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
|
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
|
||||||
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
|
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
|
||||||
artists,title = track["artists"],track["title"]
|
artists,title = track["artists"],track["title"]
|
||||||
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
||||||
return "<a href='/scrobbles?" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "&title=" + urllib.parse.quote(title) + "&" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
return "<a href='/scrobbles?" + "&".join(["artist=" + urllib.parse.quote(a) for a in artists]) + "&title=" + urllib.parse.quote(title) + "&" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
||||||
|
|
||||||
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
|
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
|
||||||
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
||||||
askey = "&associated" if associated else ""
|
askey = "&associated" if associated else ""
|
||||||
return "<a href='/scrobbles?artist=" + urllib.parse.quote(artist) + "&" + keysToUrl(timekeys) + askey + "'>" + inner + "</a>"
|
return "<a href='/scrobbles?artist=" + urllib.parse.quote(artist) + "&" + keysToUrl(timekeys) + askey + "'>" + inner + "</a>"
|
||||||
|
|
||||||
def scrobblesLink(timekeys,amount=None,percent=None,artist=None,track=None,associated=False):
|
def scrobblesLink(timekeys,amount=None,percent=None,artist=None,track=None,associated=False):
|
||||||
if track is not None: return scrobblesTrackLink(track,timekeys,amount,percent)
|
if track is not None: return scrobblesTrackLink(track,timekeys,amount,percent)
|
||||||
if artist is not None: return scrobblesArtistLink(artist,timekeys,amount,percent,associated)
|
if artist is not None: return scrobblesArtistLink(artist,timekeys,amount,percent,associated)
|
||||||
@ -32,15 +32,17 @@ def scrobblesLink(timekeys,amount=None,percent=None,artist=None,track=None,assoc
|
|||||||
return "<a href='/scrobbles?" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
return "<a href='/scrobbles?" + keysToUrl(timekeys) + "'>" + inner + "</a>"
|
||||||
|
|
||||||
# necessary because urllib.parse.urlencode doesnt handle multidicts
|
# necessary because urllib.parse.urlencode doesnt handle multidicts
|
||||||
def keysToUrl(*dicts):
|
def keysToUrl(*dicts,exclude=[]):
|
||||||
st = ""
|
st = ""
|
||||||
keys = removeIdentical(*dicts)
|
keys = removeIdentical(*dicts)
|
||||||
for k in keys:
|
for k in keys:
|
||||||
|
if k in exclude: continue
|
||||||
values = keys.getall(k)
|
values = keys.getall(k)
|
||||||
st += "&".join([urllib.parse.urlencode({k:v},safe="/") for v in values])
|
st += "&".join([urllib.parse.urlencode({k:v},safe="/") for v in values])
|
||||||
st += "&"
|
st += "&"
|
||||||
return st
|
return st
|
||||||
|
|
||||||
|
|
||||||
def removeIdentical(*dicts):
|
def removeIdentical(*dicts):
|
||||||
#combine multiple dicts
|
#combine multiple dicts
|
||||||
keys = FormsDict()
|
keys = FormsDict()
|
||||||
@ -52,21 +54,21 @@ def removeIdentical(*dicts):
|
|||||||
except: #normaldicts
|
except: #normaldicts
|
||||||
v = d.get(k)
|
v = d.get(k)
|
||||||
keys.append(k,v)
|
keys.append(k,v)
|
||||||
|
|
||||||
new = FormsDict()
|
new = FormsDict()
|
||||||
for k in keys:
|
for k in keys:
|
||||||
values = set(keys.getall(k))
|
values = set(keys.getall(k))
|
||||||
for v in values:
|
for v in values:
|
||||||
new.append(k,v)
|
new.append(k,v)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
#def getTimeDesc(timestamp,short=False):
|
#def getTimeDesc(timestamp,short=False):
|
||||||
# tim = datetime.datetime.utcfromtimestamp(timestamp)
|
# tim = datetime.datetime.utcfromtimestamp(timestamp)
|
||||||
# if short:
|
# if short:
|
||||||
# now = datetime.datetime.now(tz=datetime.timezone.utc)
|
# now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||||
# difference = int(now.timestamp() - timestamp)
|
# difference = int(now.timestamp() - timestamp)
|
||||||
#
|
#
|
||||||
# if difference < 10: return "just now"
|
# if difference < 10: return "just now"
|
||||||
# if difference < 60: return str(difference) + " seconds ago"
|
# if difference < 60: return str(difference) + " seconds ago"
|
||||||
# difference = int(difference/60)
|
# difference = int(difference/60)
|
||||||
@ -78,16 +80,16 @@ def removeIdentical(*dicts):
|
|||||||
# if difference < 31: return str(difference) + " days ago" if difference>1 else str(difference) + " day ago"
|
# if difference < 31: return str(difference) + " days ago" if difference>1 else str(difference) + " day ago"
|
||||||
# #if difference < 300 and tim.year == now.year: return tim.strftime("%B")
|
# #if difference < 300 and tim.year == now.year: return tim.strftime("%B")
|
||||||
# #if difference < 300: return tim.strftime("%B %Y")
|
# #if difference < 300: return tim.strftime("%B %Y")
|
||||||
#
|
#
|
||||||
# return tim.strftime("%d. %B %Y")
|
# return tim.strftime("%d. %B %Y")
|
||||||
# else:
|
# else:
|
||||||
# return tim.strftime("%d. %b %Y %I:%M %p")
|
# return tim.strftime("%d. %b %Y %I:%M %p")
|
||||||
|
|
||||||
#def getRangeDesc(since=None,to=None,inclusiveB=True):
|
#def getRangeDesc(since=None,to=None,inclusiveB=True):
|
||||||
# # string to list
|
# # string to list
|
||||||
# if isinstance(timeA,str): timeA = timeA.split("/")
|
# if isinstance(timeA,str): timeA = timeA.split("/")
|
||||||
# if isinstance(timeB,str): timeB = timeB.split("/")
|
# if isinstance(timeB,str): timeB = timeB.split("/")
|
||||||
#
|
#
|
||||||
# # if lists, we have it potentially much easier:
|
# # if lists, we have it potentially much easier:
|
||||||
# if isinstance(timeA,list) and isinstance(timeB,list):
|
# if isinstance(timeA,list) and isinstance(timeB,list):
|
||||||
# if timeA == timeB:
|
# if timeA == timeB:
|
||||||
@ -100,14 +102,14 @@ def removeIdentical(*dicts):
|
|||||||
# return dto.strftime("%B %Y")
|
# return dto.strftime("%B %Y")
|
||||||
# if len(timeA) == 1:
|
# if len(timeA) == 1:
|
||||||
# return dto.strftime("%Y")
|
# return dto.strftime("%Y")
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# (timeA, timeB) = getTimestamps(since=timeA, to=timeB)
|
# (timeA, timeB) = getTimestamps(since=timeA, to=timeB)
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# return getTimeDesc(timeA) + " to " + getTimeDesc(timeB)
|
# return getTimeDesc(timeA) + " to " + getTimeDesc(timeB)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# finds out if we want an artist or a track
|
# finds out if we want an artist or a track
|
||||||
@ -116,9 +118,9 @@ def removeIdentical(*dicts):
|
|||||||
# return {"track":{"artists":keys.getall("artist"),"title":keys.get("title")}}
|
# return {"track":{"artists":keys.getall("artist"),"title":keys.get("title")}}
|
||||||
# if "artist" in keys:
|
# if "artist" in keys:
|
||||||
# return {"artist":keys.get("artist")}
|
# return {"artist":keys.get("artist")}
|
||||||
#
|
#
|
||||||
# return {}
|
# return {}
|
||||||
|
|
||||||
# alright this is the last one
|
# alright this is the last one
|
||||||
# one ultimate method to rule them all
|
# one ultimate method to rule them all
|
||||||
# one method to take html keys and convert them into internal keys
|
# one method to take html keys and convert them into internal keys
|
||||||
@ -143,7 +145,7 @@ def KeySplit(keys,forceTrack=False,forceArtist=False):
|
|||||||
if "associated" in keys: resultkeys1["associated"] = True
|
if "associated" in keys: resultkeys1["associated"] = True
|
||||||
else:
|
else:
|
||||||
resultkeys1 = {}
|
resultkeys1 = {}
|
||||||
|
|
||||||
# 2
|
# 2
|
||||||
resultkeys2 = {}
|
resultkeys2 = {}
|
||||||
if "since" in keys: resultkeys2["since"] = keys.get("since")
|
if "since" in keys: resultkeys2["since"] = keys.get("since")
|
||||||
@ -157,23 +159,23 @@ def KeySplit(keys,forceTrack=False,forceArtist=False):
|
|||||||
if "in" in keys: resultkeys2["within"] = keys.get("in")
|
if "in" in keys: resultkeys2["within"] = keys.get("in")
|
||||||
elif "within" in keys: resultkeys2["within"] = keys.get("within")
|
elif "within" in keys: resultkeys2["within"] = keys.get("within")
|
||||||
elif "during" in keys: resultkeys2["within"] = keys.get("during")
|
elif "during" in keys: resultkeys2["within"] = keys.get("during")
|
||||||
|
|
||||||
|
|
||||||
#3
|
#3
|
||||||
resultkeys3 = {}
|
resultkeys3 = {}
|
||||||
if "step" in keys: [resultkeys3["step"],resultkeys3["stepn"]] = (keys["step"].split("-") + [1])[:2]
|
if "step" in keys: [resultkeys3["step"],resultkeys3["stepn"]] = (keys["step"].split("-") + [1])[:2]
|
||||||
if "stepn" in keys: resultkeys3["stepn"] = keys["stepn"] #overwrite if explicitly given
|
if "stepn" in keys: resultkeys3["stepn"] = keys["stepn"] #overwrite if explicitly given
|
||||||
if "stepn" in resultkeys3: resultkeys3["stepn"] = int(resultkeys3["stepn"]) #in both cases, convert it here
|
if "stepn" in resultkeys3: resultkeys3["stepn"] = int(resultkeys3["stepn"]) #in both cases, convert it here
|
||||||
if "trail" in keys: resultkeys3["trail"] = int(keys["trail"])
|
if "trail" in keys: resultkeys3["trail"] = int(keys["trail"])
|
||||||
|
|
||||||
|
|
||||||
#4
|
#4
|
||||||
resultkeys4 = {}
|
resultkeys4 = {}
|
||||||
if "max" in keys: resultkeys4["max_"] = int(keys["max"])
|
if "max" in keys: resultkeys4["max_"] = int(keys["max"])
|
||||||
|
|
||||||
return resultkeys1, resultkeys2, resultkeys3, resultkeys4
|
return resultkeys1, resultkeys2, resultkeys3, resultkeys4
|
||||||
|
|
||||||
|
|
||||||
# limit a multidict to only the specified keys
|
# limit a multidict to only the specified keys
|
||||||
# would be a simple constructor expression, but multidicts apparently don't let me do that
|
# would be a simple constructor expression, but multidicts apparently don't let me do that
|
||||||
def pickKeys(d,*keys):
|
def pickKeys(d,*keys):
|
||||||
@ -187,10 +189,10 @@ def pickKeys(d,*keys):
|
|||||||
for k in newd:
|
for k in newd:
|
||||||
for v in newd.get(k):
|
for v in newd.get(k):
|
||||||
finald.append(k,v)
|
finald.append(k,v)
|
||||||
|
|
||||||
return finald
|
return finald
|
||||||
|
|
||||||
# removes all duplicate keys, except artists when a title is specified
|
# removes all duplicate keys, except artists when a title is specified
|
||||||
#def clean(d):
|
#def clean(d):
|
||||||
# if isinstance(d,dict):
|
# if isinstance(d,dict):
|
||||||
# return
|
# return
|
||||||
|
@ -283,10 +283,10 @@ def module_filterselection(keys,time=True,delimit=False):
|
|||||||
|
|
||||||
html = ""
|
html = ""
|
||||||
|
|
||||||
|
|
||||||
if time:
|
if time:
|
||||||
|
|
||||||
retainkeys = {k:keys[k] for k in keys if k not in ["since","to","in"]}
|
keystr = "?" + keysToUrl(keys,exclude=["since","to","in"])
|
||||||
keystr = "?" + urllib.parse.urlencode(retainkeys)
|
|
||||||
|
|
||||||
|
|
||||||
# wonky selector for precise date range
|
# wonky selector for precise date range
|
||||||
@ -343,8 +343,7 @@ def module_filterselection(keys,time=True,delimit=False):
|
|||||||
|
|
||||||
if delimit:
|
if delimit:
|
||||||
|
|
||||||
retainkeys = {k:keys[k] for k in keys if k not in ["step","stepn"]}
|
keystr = "?" + keysToUrl(keys,exclude=["step","stepn"])
|
||||||
keystr = "?" + urllib.parse.urlencode(retainkeys)
|
|
||||||
|
|
||||||
html += "<div>"
|
html += "<div>"
|
||||||
if keys.get("step") == "day":
|
if keys.get("step") == "day":
|
||||||
@ -367,8 +366,8 @@ def module_filterselection(keys,time=True,delimit=False):
|
|||||||
html += "</div>"
|
html += "</div>"
|
||||||
|
|
||||||
|
|
||||||
retainkeys = {k:keys[k] for k in keys if k not in ["trail"]}
|
|
||||||
keystr = "?" + urllib.parse.urlencode(retainkeys)
|
keystr = "?" + keysToUrl(keys,exclude=["trail"])
|
||||||
|
|
||||||
html += "<div>"
|
html += "<div>"
|
||||||
if keys.get("trail") == "1" or keys.get("trail") is None:
|
if keys.get("trail") == "1" or keys.get("trail") is None:
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
<h1>Scrobbles</h1><br/>
|
<h1>Scrobbles</h1><br/>
|
||||||
<span>KEY_LIMITS</span>
|
<span>KEY_LIMITS</span>
|
||||||
<p class="stats">KEY_SCROBBLES Scrobbles</p>
|
<p class="stats">KEY_SCROBBLES Scrobbles</p>
|
||||||
|
<br/>
|
||||||
|
KEY_FILTERSELECTOR
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -5,7 +5,7 @@ import database
|
|||||||
def instructions(keys):
|
def instructions(keys):
|
||||||
from utilities import getArtistImage, getTrackImage
|
from utilities import getArtistImage, getTrackImage
|
||||||
from htmlgenerators import artistLink, artistLinks, trackLink, KeySplit
|
from htmlgenerators import artistLink, artistLinks, trackLink, KeySplit
|
||||||
from htmlmodules import module_scrobblelist
|
from htmlmodules import module_scrobblelist, module_filterselection
|
||||||
from malojatime import range_desc
|
from malojatime import range_desc
|
||||||
|
|
||||||
|
|
||||||
@ -27,6 +27,8 @@ def instructions(keys):
|
|||||||
|
|
||||||
limitstring += " " + range_desc(**timekeys)
|
limitstring += " " + range_desc(**timekeys)
|
||||||
|
|
||||||
|
html_filterselector = module_filterselection(keys)
|
||||||
|
|
||||||
|
|
||||||
html, amount, rep = module_scrobblelist(**filterkeys,**timekeys,**amountkeys)
|
html, amount, rep = module_scrobblelist(**filterkeys,**timekeys,**amountkeys)
|
||||||
|
|
||||||
@ -44,6 +46,10 @@ def instructions(keys):
|
|||||||
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []
|
||||||
|
|
||||||
|
|
||||||
replace = {"KEY_SCROBBLELIST":html,"KEY_SCROBBLES":str(amount),"KEY_IMAGEURL":imgurl,"KEY_LIMITS":limitstring}
|
replace = {"KEY_SCROBBLELIST":html,
|
||||||
|
"KEY_SCROBBLES":str(amount),
|
||||||
|
"KEY_IMAGEURL":imgurl,
|
||||||
|
"KEY_LIMITS":limitstring,
|
||||||
|
"KEY_FILTERSELECTOR":html_filterselector}
|
||||||
|
|
||||||
return (replace,pushresources)
|
return (replace,pushresources)
|
||||||
|
Loading…
Reference in New Issue
Block a user