2019-02-18 02:34:25 +03:00
|
|
|
|
import urllib
|
|
|
|
|
from bottle import FormsDict
|
|
|
|
|
import datetime
|
2019-04-08 14:04:31 +03:00
|
|
|
|
from urihandler import compose_querystring
|
2019-08-21 23:19:01 +03:00
|
|
|
|
import urllib.parse
|
|
|
|
|
from doreah.settings import get_settings
|
2018-12-26 19:42:55 +03:00
|
|
|
|
|
|
|
|
|
|
2019-04-07 15:07:50 +03:00
|
|
|
|
# returns the proper column(s) for an artist or track
|
|
|
|
|
def entity_column(element,counting=[],image=None):
|
|
|
|
|
|
|
|
|
|
html = ""
|
|
|
|
|
|
|
|
|
|
if image is not None:
|
|
|
|
|
html += """<td class='icon'><div style="background-image:url('""" + image + """')"></div></td>"""
|
|
|
|
|
|
|
|
|
|
if "artists" in element:
|
|
|
|
|
# track
|
2019-06-10 18:42:08 +03:00
|
|
|
|
# html += "<td class='artists'>" + html_links(element["artists"]) + "</td>"
|
|
|
|
|
# html += "<td class='title'>" + html_link(element) + "</td>"
|
2019-08-21 23:19:01 +03:00
|
|
|
|
html += "<td class='track'><span class='artist_in_trackcolumn'>"
|
2019-08-22 23:17:04 +03:00
|
|
|
|
html += trackSearchLink(element)
|
2019-08-21 23:19:01 +03:00
|
|
|
|
html += html_links(element["artists"]) + "</span> – " + html_link(element) + "</td>"
|
2019-04-07 15:07:50 +03:00
|
|
|
|
else:
|
|
|
|
|
# artist
|
2019-04-09 12:35:02 +03:00
|
|
|
|
html += "<td class='artist'>" + html_link(element)
|
2019-04-07 15:07:50 +03:00
|
|
|
|
if (counting != []):
|
2019-04-09 12:35:02 +03:00
|
|
|
|
html += " <span class='extra'>incl. " + html_links(counting) + "</span>"
|
2019-04-07 15:07:50 +03:00
|
|
|
|
html += "</td>"
|
|
|
|
|
|
|
|
|
|
return html
|
|
|
|
|
|
2019-04-09 12:35:02 +03:00
|
|
|
|
def uri_query(entity):
|
|
|
|
|
if "artists" in entity:
|
|
|
|
|
#track
|
|
|
|
|
return "title=" + urllib.parse.quote(entity["title"]) \
|
|
|
|
|
+ "&" + "&".join(["artist=" + urllib.parse.quote(a) for a in entity["artists"]])
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
#artist
|
|
|
|
|
return "artist=" + urllib.parse.quote(entity)
|
|
|
|
|
|
|
|
|
|
# returns the address of the track / artist page
|
|
|
|
|
def link_address(entity):
|
|
|
|
|
if "artists" in entity:
|
|
|
|
|
#track
|
|
|
|
|
return "/track?" + uri_query(entity)
|
|
|
|
|
else:
|
|
|
|
|
#artist
|
|
|
|
|
return "/artist?" + uri_query(entity)
|
|
|
|
|
|
|
|
|
|
#returns linked name
|
|
|
|
|
def html_link(entity):
|
|
|
|
|
if "artists" in entity:
|
|
|
|
|
#track
|
|
|
|
|
name = entity["title"]
|
|
|
|
|
else:
|
|
|
|
|
#artist
|
|
|
|
|
name = entity
|
|
|
|
|
return "<a href='" + link_address(entity) + "'>" + name + "</a>"
|
|
|
|
|
|
|
|
|
|
def html_links(entities):
|
|
|
|
|
return ", ".join([html_link(e) for e in entities])
|
|
|
|
|
|
|
|
|
|
# DEPRECATED
|
2019-04-02 13:59:42 +03:00
|
|
|
|
def artistLink(name):
|
2019-04-09 12:35:02 +03:00
|
|
|
|
return html_link(name)
|
|
|
|
|
#return "<a href='/artist?artist=" + urllib.parse.quote(name) + "'>" + name + "</a>"
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2019-04-09 12:35:02 +03:00
|
|
|
|
# DEPRECATED
|
2018-12-26 21:20:26 +03:00
|
|
|
|
def artistLinks(artists):
|
|
|
|
|
return ", ".join([artistLink(a) for a in artists])
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2018-12-26 21:20:26 +03:00
|
|
|
|
#def trackLink(artists,title):
|
2019-04-09 12:35:02 +03:00
|
|
|
|
# DEPRECATED
|
2018-12-26 21:20:26 +03:00
|
|
|
|
def trackLink(track):
|
2019-04-09 12:35:02 +03:00
|
|
|
|
return html_link(track)
|
|
|
|
|
#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>"
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2019-08-21 23:19:01 +03:00
|
|
|
|
def trackSearchLink(track):
|
|
|
|
|
searchProvider = get_settings("TRACK_SEARCH_PROVIDER")
|
2019-08-22 23:17:04 +03:00
|
|
|
|
if searchProvider is None: return ""
|
|
|
|
|
|
2019-08-21 23:19:01 +03:00
|
|
|
|
link = "<a class='trackProviderSearch' href='"
|
|
|
|
|
if searchProvider == "YouTube":
|
|
|
|
|
link += "https://www.youtube.com/results?search_query="
|
|
|
|
|
elif searchProvider == "YouTube Music":
|
|
|
|
|
link += "https://music.youtube.com/search?q="
|
|
|
|
|
elif searchProvider == "Google Play Music":
|
|
|
|
|
link += "https://play.google.com/music/listen#/srs/"
|
|
|
|
|
elif searchProvider == "Spotify":
|
|
|
|
|
link += "https://open.spotify.com/search/results/"
|
|
|
|
|
elif searchProvider == "Tidal":
|
|
|
|
|
link += "https://listen.tidal.com/search/tracks?q="
|
|
|
|
|
elif searchProvider == "SoundCloud":
|
|
|
|
|
link += "https://soundcloud.com/search?q="
|
|
|
|
|
elif searchProvider == "Amazon Music":
|
|
|
|
|
link += "https://music.amazon.com/search/"
|
|
|
|
|
elif searchProvider == "Deezer":
|
|
|
|
|
link += "https://www.deezer.com/search/"
|
|
|
|
|
else:
|
|
|
|
|
link += "https://www.google.com/search?q=" # ¯\_(ツ)_/¯
|
|
|
|
|
|
2019-08-22 23:17:04 +03:00
|
|
|
|
link += urllib.parse.quote(", ".join(track["artists"]) + " " + track["title"]) + "'>🎵</a>"
|
2019-08-21 23:19:01 +03:00
|
|
|
|
return link
|
|
|
|
|
|
2018-12-26 21:20:26 +03:00
|
|
|
|
#def scrobblesTrackLink(artists,title,timekeys,amount=None,pixels=None):
|
2018-12-27 05:09:29 +03:00
|
|
|
|
def scrobblesTrackLink(track,timekeys,amount=None,percent=None):
|
2018-12-26 21:20:26 +03:00
|
|
|
|
artists,title = track["artists"],track["title"]
|
2018-12-27 16:57:25 +03:00
|
|
|
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
2019-04-09 12:35:02 +03:00
|
|
|
|
return "<a href='/scrobbles?" + uri_query(track) + "&" + compose_querystring(timekeys) + "'>" + inner + "</a>"
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2018-12-27 05:09:29 +03:00
|
|
|
|
def scrobblesArtistLink(artist,timekeys,amount=None,percent=None,associated=False):
|
2018-12-27 16:57:25 +03:00
|
|
|
|
inner = str(amount) if amount is not None else "<div style='width:" + str(percent) + "%;'></div>"
|
2018-12-26 21:20:26 +03:00
|
|
|
|
askey = "&associated" if associated else ""
|
2019-04-09 12:35:02 +03:00
|
|
|
|
return "<a href='/scrobbles?" + uri_query(artist) + "&" + compose_querystring(timekeys) + askey + "'>" + inner + "</a>"
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2019-02-18 17:52:08 +03:00
|
|
|
|
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 "<div style='width:" + str(percent) + "%;'></div>"
|
2019-04-08 14:04:31 +03:00
|
|
|
|
return "<a href='/scrobbles?" + compose_querystring(timekeys) + "'>" + inner + "</a>"
|
|
|
|
|
|
2019-02-20 20:22:45 +03:00
|
|
|
|
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2019-04-09 14:34:06 +03:00
|
|
|
|
def rankTrackLink(track,timekeys,rank=None,percent=None,medal=None):
|
|
|
|
|
cl = ""
|
|
|
|
|
if medal == 1: cl = "class='gold'"
|
|
|
|
|
if medal == 2: cl = "class='silver'"
|
|
|
|
|
if medal == 3: cl = "class='bronze'"
|
|
|
|
|
inner = str(rank) if rank is not None else "<div " + cl + " style='width:" + str(percent) + "%;'></div>"
|
|
|
|
|
|
|
|
|
|
return "<a href='/charts_tracks?" + compose_querystring(timekeys) + "'>" + inner + "</a>"
|
|
|
|
|
|
|
|
|
|
def rankArtistLink(artist,timekeys,rank=None,percent=None,medal=None):
|
|
|
|
|
cl = ""
|
|
|
|
|
if medal == 1: cl = "class='gold'"
|
|
|
|
|
if medal == 2: cl = "class='silver'"
|
|
|
|
|
if medal == 3: cl = "class='bronze'"
|
|
|
|
|
inner = str(rank) if rank is not None else "<div " + cl + " style='width:" + str(percent) + "%;'></div>"
|
2019-04-30 18:56:27 +03:00
|
|
|
|
return "<a href='/charts_artists?" + compose_querystring(timekeys) + "'>" + inner + "</a>"
|
2019-04-09 14:34:06 +03:00
|
|
|
|
|
|
|
|
|
def rankLink(timekeys,rank=None,percent=None,artist=None,track=None,medal=None):
|
|
|
|
|
if track is not None: return rankTrackLink(track,timekeys,rank,percent,medal)
|
|
|
|
|
if artist is not None: return rankArtistLink(artist,timekeys,rank,percent,medal)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-12-26 19:42:55 +03:00
|
|
|
|
# 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):
|
2018-12-26 21:20:26 +03:00
|
|
|
|
if isinstance(d,dict):
|
2018-12-26 19:42:55 +03:00
|
|
|
|
return {k:d.get(k) for k in d if k in keys}
|
|
|
|
|
else:
|
|
|
|
|
# create a normal dictionary of lists
|
2018-12-26 21:20:26 +03:00
|
|
|
|
newd = {k:d.getall(k) for k in d if k in keys}
|
2018-12-26 19:42:55 +03:00
|
|
|
|
# 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)
|
2019-04-02 13:59:42 +03:00
|
|
|
|
|
2018-12-26 19:42:55 +03:00
|
|
|
|
return finald
|