From 9a4afe4b1fd117d8cc55a84ad3671892c3143ae1 Mon Sep 17 00:00:00 2001 From: Krateng Date: Sat, 2 Feb 2019 18:08:30 +0100 Subject: [PATCH] Expanded start page --- database.py | 30 +++++++++++++++++ server.py | 1 + utilities.py | 15 +++++++++ website/favicon.ico | Bin 0 -> 13982 bytes website/favicon.png | Bin 0 -> 23964 bytes website/start.html | 80 +++++++++++++++++++++++++++++++++++--------- website/start.py | 65 +++++++++++++++++++++++++++-------- 7 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 website/favicon.ico create mode 100644 website/favicon.png diff --git a/database.py b/database.py index 3f49998..83ee0a6 100644 --- a/database.py +++ b/database.py @@ -146,6 +146,16 @@ def get_scrobbles(): return {"list":r} ##json can't be a list apparently??? +@dbserver.route("/numscrobbles") +def get_scrobbles(): + keys = FormsDict.decode(request.query) + + r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),associated=(keys.get("associated")!=None)) + r.reverse() + + return {"amount":len(r)} + + @dbserver.route("/tracks") def get_tracks(): keys = FormsDict.decode(request.query) @@ -168,6 +178,10 @@ def get_artists(): return {"list":ARTISTS} +@dbserver.route("/amounts") +def get_amounts(): + return {"scrobbles":len(SCROBBLES),"tracks":len(TRACKS),"artists":len(ARTISTS)} + @dbserver.route("/charts/artists") def get_charts_artists(): since = request.query.get("since") @@ -733,6 +747,22 @@ def getTimestamps(f,t): if isinstance(t, str) and t.lower() == "today": tod = datetime.datetime.utcnow() t = [tod.year,tod.month,tod.day] + + + if isinstance(f, str) and f.lower() == "month": + tod = datetime.datetime.utcnow() + f = [tod.year,tod.month] + if isinstance(t, str) and t.lower() == "month": + tod = datetime.datetime.utcnow() + t = [tod.year,tod.month] + + + if isinstance(f, str) and f.lower() == "year": + tod = datetime.datetime.utcnow() + f = [tod.year] + if isinstance(t, str) and t.lower() == "year": + tod = datetime.datetime.utcnow() + t = [tod.year] if isinstance(f, str): diff --git a/server.py b/server.py index f3fe41f..b8ca71c 100755 --- a/server.py +++ b/server.py @@ -84,6 +84,7 @@ def static_image(pth): @webserver.route("/") @webserver.route("/") @webserver.route("/") +@webserver.route("/") def static(name): return static_file("website/" + name,root="") diff --git a/utilities.py b/utilities.py index d17d1cf..cea4f92 100644 --- a/utilities.py +++ b/utilities.py @@ -271,6 +271,21 @@ def getArtistInfo(artist): result = apirequest(artist=artist) cachedArtists[artist] = result["image"] return result + +def getTracksInfo(trackobjectlist): + + threads = [] + + for track in trackobjectlist: + t = Thread(target=getTrackInfo,args=(track["artists"],track["title"],)) + t.start() + threads.append(t) + + for t in threads: + t.join() + + + return [getTrackInfo(t["artists"],t["title"]) for t in trackobjectlist] def getArtistsInfo(artistlist): diff --git a/website/favicon.ico b/website/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..03e8803e66c80e247fea01b0142a7e36e872c43d GIT binary patch literal 13982 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 R1lp~WA=LFB)~TT){s$mgX$AlQ literal 0 HcmV?d00001 diff --git a/website/start.html b/website/start.html index bf424ff..ff3cf0d 100644 --- a/website/start.html +++ b/website/start.html @@ -8,39 +8,87 @@ - -

Top Artists

+ + Scrobbles today KEY_SCROBBLES_TODAY +
Scrobbles this month KEY_SCROBBLES_MONTH +
Scrobbles overall KEY_SCROBBLES_TOTAL + +

Top Artists

- + + +
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
- - + + - - + +
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
- - - + + + - - - + + + - - - + + + + +
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
KEY_POSITION_ARTIST KEY_ARTISTLINK
+ +
+ + + + + + +

Top Tracks

+ + + + +
KEY_POSITION_TRACK KEY_TRACKLINK
+ + + + + + + + + +
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
+
+ + + + + + + + + + + + + + +
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
KEY_POSITION_TRACK KEY_TRACKLINK
diff --git a/website/start.py b/website/start.py index aa89b06..d598f1b 100644 --- a/website/start.py +++ b/website/start.py @@ -3,32 +3,69 @@ import json def replacedict(keys,dbport): - from utilities import getArtistInfo, getArtistsInfo + from utilities import getArtistInfo, getArtistsInfo, getTracksInfo from htmlgenerators import artistLink, artistLinks, trackLink, scrobblesArtistLink, keysToUrl, pickKeys, clean - clean(keys) - timekeys = pickKeys(keys,"since","to","in") - limitkeys = pickKeys(keys) + max_show = 15 + posrange = ["#" + str(i) for i in range(1,max_show)] + + #clean(keys) + #timekeys = pickKeys(keys,"since","to","in") + #limitkeys = pickKeys(keys) # get chart data - response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/charts/artists?" + keysToUrl(timekeys,limitkeys)) + + # artists + response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/charts/artists") db_data = json.loads(response.read()) - charts = db_data["list"][:50] + charts = db_data["list"][:max_show] topartist = charts[0]["artist"] - chartslist = [c["artist"] for c in charts] + artisttitles = [c["artist"] for c in charts] #chartslistimg = [getArtistInfo(a).get("image") for a in chartslist] - chartslistimg = [info.get("image") for info in getArtistsInfo(chartslist)] - chartslistlink = [artistLink(a) for a in chartslist] + artistimages = [info.get("image") for info in getArtistsInfo(artisttitles)] + artistlinks = [artistLink(a) for a in artisttitles] - # get total amount of scrobbles - response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/scrobbles?" + keysToUrl(timekeys,limitkeys)) + # tracks + response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/charts/tracks") db_data = json.loads(response.read()) - scrobblelist = db_data["list"] - scrobbles = len(scrobblelist) + charts = db_data["list"][:max_show] + + trackobjects = [t["track"] for t in charts] + tracktitles = [t["title"] for t in trackobjects] + trackartists = [", ".join(t["artists"]) for t in trackobjects] + trackimages = [info.get("image") for info in getTracksInfo(trackobjects)] + tracklinks = [trackLink(t) for t in trackobjects] + + + # get scrobbles + #response = urllib.request.urlopen("http://localhost:" + str(dbport) + "/scrobbles") + #db_data = json.loads(response.read()) + #scrobblelist = db_data["list"] + + # get stats + response = urllib.request.urlopen("http://localhost:" +str(dbport) + "/numscrobbles?since=today") + stats = json.loads(response.read()) + scrobbles_today = "" + str(stats["amount"]) + "" + + response = urllib.request.urlopen("http://localhost:" +str(dbport) + "/numscrobbles?since=month") + stats = json.loads(response.read()) + scrobbles_month = "" + str(stats["amount"]) + "" + + response = urllib.request.urlopen("http://localhost:" +str(dbport) + "/numscrobbles?since=year") + stats = json.loads(response.read()) + scrobbles_year = "" + str(stats["amount"]) + "" + + response = urllib.request.urlopen("http://localhost:" +str(dbport) + "/numscrobbles") + stats = json.loads(response.read()) + scrobbles_total = "" + str(stats["amount"]) + "" + #stats_tracks = "" + str(stats["tracks"]) + "" + #stats_artists = "" + str(stats["artists"]) + "" - return {"KEY_ARTISTIMAGE":chartslistimg,"KEY_ARTISTNAME":chartslist,"KEY_ARTISTLINK":chartslistlink,"KEY_POSITION":["#" + str(i) for i in range(1,50)]} + return {"KEY_ARTISTIMAGE":artistimages,"KEY_ARTISTNAME":artisttitles,"KEY_ARTISTLINK":artistlinks,"KEY_POSITION_ARTIST":posrange, + "KEY_TRACKIMAGE":trackimages,"KEY_TRACKNAME":tracktitles,"KEY_TRACKLINK":tracklinks,"KEY_POSITION_TRACK":posrange, + "KEY_SCROBBLES_TODAY":scrobbles_today,"KEY_SCROBBLES_MONTH":scrobbles_month,"KEY_SCROBBLES_YEAR":scrobbles_year,"KEY_SCROBBLES_TOTAL":scrobbles_total}