import urllib
from bottle import FormsDict
import datetime
from malojatime import uri_to_internal, internal_to_uri
# returns the proper column(s) for an artist or track
def entity_column(element,counting=[],image=None):
html = ""
if image is not None:
html += """
| """
if "artists" in element:
# track
html += "" + artistLinks(element["artists"]) + " | "
html += "" + trackLink({"artists":element["artists"],"title":element["title"]}) + " | "
else:
# artist
html += "" + artistLink(element)
if (counting != []):
html += " "
html += " | "
return html
def artistLink(name):
return "" + name + ""
def artistLinks(artists):
return ", ".join([artistLink(a) for a in artists])
#def trackLink(artists,title):
def trackLink(track):
artists,title = track["artists"],track["title"]
return "" + title + ""
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
artists,title = track["artists"],track["title"]
inner = str(amount) if amount is not None else ""
return "" + inner + ""
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
inner = str(amount) if amount is not None else ""
askey = "&associated" if associated else ""
return "" + inner + ""
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 artist is not None: return scrobblesArtistLink(artist,timekeys,amount,percent,associated)
inner = str(amount) if amount is not None else ""
return "" + inner + ""
# necessary because urllib.parse.urlencode doesnt handle multidicts
def keysToUrl(*dicts,exclude=[]):
for dict in dicts:
for key in dict:
dict[key] = internal_to_uri(dict[key])
st = ""
keys = removeIdentical(*dicts)
for k in keys:
if k in exclude: continue
values = keys.getall(k)
st += "&".join([urllib.parse.urlencode({k:v},safe="/") for v in values])
st += "&"
return st
def removeIdentical(*dicts):
#combine multiple dicts
keys = FormsDict()
for d in dicts:
for k in d:
try: #multidicts
for v in d.getall(k):
keys.append(k,v)
except: #normaldicts
v = d.get(k)
keys.append(k,v)
new = FormsDict()
for k in keys:
values = set(keys.getall(k))
for v in values:
new.append(k,v)
return new
#def getTimeDesc(timestamp,short=False):
# tim = datetime.datetime.utcfromtimestamp(timestamp)
# if short:
# now = datetime.datetime.now(tz=datetime.timezone.utc)
# difference = int(now.timestamp() - timestamp)
#
# if difference < 10: return "just now"
# if difference < 60: return str(difference) + " seconds ago"
# difference = int(difference/60)
# if difference < 60: return str(difference) + " minutes ago" if difference>1 else str(difference) + " minute ago"
# difference = int(difference/60)
# if difference < 24: return str(difference) + " hours ago" if difference>1 else str(difference) + " hour ago"
# difference = int(difference/24)
# if difference < 5: return tim.strftime("%A")
# 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: return tim.strftime("%B %Y")
#
# return tim.strftime("%d. %B %Y")
# else:
# return tim.strftime("%d. %b %Y %I:%M %p")
#def getRangeDesc(since=None,to=None,inclusiveB=True):
# # string to list
# if isinstance(timeA,str): timeA = timeA.split("/")
# if isinstance(timeB,str): timeB = timeB.split("/")
#
# # if lists, we have it potentially much easier:
# if isinstance(timeA,list) and isinstance(timeB,list):
# if timeA == timeB:
# date = [1970,1,1]
# date[:len(timeA)] = timeA
# dto = datetime.datetime(date[0],date[1],date[2],tzinfo=datetime.timezone.utc)
# if len(timeA) == 3:
# return dto.strftime("%d. %b %Y")
# if len(timeA) == 2:
# return dto.strftime("%B %Y")
# if len(timeA) == 1:
# return dto.strftime("%Y")
#
#
#
# (timeA, timeB) = getTimestamps(since=timeA, to=timeB)
#
#
# return getTimeDesc(timeA) + " to " + getTimeDesc(timeB)
# finds out if we want an artist or a track
#def interpretURLKeys(keys):
# if "title" in keys:
# return {"track":{"artists":keys.getall("artist"),"title":keys.get("title")}}
# if "artist" in keys:
# return {"artist":keys.get("artist")}
#
# return {}
# alright this is the last one
# one ultimate method to rule them all
# one method to take html keys and convert them into internal keys
# it renames them, interprets what's being asked, removes duplicates
# it gets rid of multidicts
# it does fecking everything
# it's the best
# fantastic
def KeySplit(keys,forceTrack=False,forceArtist=False):
# output:
# 1 keys that define the filtered object like artist or track
# 2 keys that define time limits of the whole thing
# 3 keys that define interal time ranges
# 4 keys that define amount limits
# 1
if "title" in keys and not forceArtist:
resultkeys1 = {"track":{"artists":keys.getall("artist"),"title":keys.get("title")}}
elif "artist" in keys and not forceTrack:
resultkeys1 = {"artist":keys.get("artist")}
if "associated" in keys: resultkeys1["associated"] = True
else:
resultkeys1 = {}
# 2
resultkeys2 = {}
if "since" in keys: resultkeys2["since"] = uri_to_internal(keys.get("since"))
elif "from" in keys: resultkeys2["since"] = uri_to_internal(keys.get("from"))
elif "start" in keys: resultkeys2["since"] = uri_to_internal(keys.get("start"))
#
if "to" in keys: resultkeys2["to"] = uri_to_internal(keys.get("to"))
elif "until" in keys: resultkeys2["to"] = uri_to_internal(keys.get("until"))
elif "end" in keys: resultkeys2["to"] = uri_to_internal(keys.get("end"))
#
if "since" in resultkeys2 and "to" in resultkeys2 and resultkeys2["since"] == resultkeys2["to"]:
resultkeys2["within"] = resultkeys2["since"]
del resultkeys2["since"]
del resultkeys2["to"]
#
if "in" in keys: resultkeys2["within"] = uri_to_internal(keys.get("in"))
elif "within" in keys: resultkeys2["within"] = uri_to_internal(keys.get("within"))
elif "during" in keys: resultkeys2["within"] = uri_to_internal(keys.get("during"))
if "within" in resultkeys2:
del resultkeys2["since"]
del resultkeys2["to"]
#3
resultkeys3 = {}
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 resultkeys3: resultkeys3["stepn"] = int(resultkeys3["stepn"]) #in both cases, convert it here
if "trail" in keys: resultkeys3["trail"] = int(keys["trail"])
#4
resultkeys4 = {}
if "max" in keys: resultkeys4["max_"] = int(keys["max"])
return resultkeys1, resultkeys2, resultkeys3, resultkeys4
# limit a multidict to only the specified keys
# would be a simple constructor expression, but multidicts apparently don't let me do that
def pickKeys(d,*keys):
if isinstance(d,dict):
return {k:d.get(k) for k in d if k in keys}
else:
# create a normal dictionary of lists
newd = {k:d.getall(k) for k in d if k in keys}
# one by one add the list entries to the formsdict
finald = FormsDict()
for k in newd:
for v in newd.get(k):
finald.append(k,v)
return finald
# removes all duplicate keys, except artists when a title is specified
#def clean(d):
# if isinstance(d,dict):
# return
# else:
# for k in d:
# if (k != "artist") or "title" not in d:
# d[k] = d.pop(k)