From 42833c8d09610a81ec5f21254db7d7217c027b4e Mon Sep 17 00:00:00 2001 From: Krateng Date: Fri, 15 Feb 2019 18:11:40 +0100 Subject: [PATCH 1/5] First test separation of API get and actual function --- database.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/database.py b/database.py index 58d2074..184eeab 100644 --- a/database.py +++ b/database.py @@ -138,10 +138,12 @@ def test_server(): # 403 Database server is up, but provided API key is not valid @dbserver.route("/scrobbles") -def get_scrobbles(): +def get_scrobbles_external(): keys = FormsDict.decode(request.query) - - r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None)) + return get_scrobbles(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None),max=keys.get("max")) + +def get_scrobbles(**keys): + r = db_query(**{k:keys[k] for k in keys if k in ["artists","title","since","to","within","associated"]}) r.reverse() if keys.get("max") is not None: @@ -150,7 +152,7 @@ def get_scrobbles(): return {"list":r} ##json can't be a list apparently??? @dbserver.route("/numscrobbles") -def get_scrobbles(): +def get_scrobbles_num(): keys = FormsDict.decode(request.query) r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None)) From 464e2890ebd7a434fda4db6ef24182acfce74148 Mon Sep 17 00:00:00 2001 From: Krateng Date: Fri, 15 Feb 2019 19:39:19 +0100 Subject: [PATCH 2/5] Expanded HTTP / function separation to more requests --- database.py | 152 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 39 deletions(-) diff --git a/database.py b/database.py index 184eeab..bddb2d0 100644 --- a/database.py +++ b/database.py @@ -114,9 +114,20 @@ def getTrackID(artists,title): return i -#### -## HTTP requests -#### + + + + + + +######## +######## +## HTTP requests and their associated functions +######## +######## + + + @dbserver.route("/test") def test_server(): @@ -137,81 +148,144 @@ def test_server(): # 205 Database server is up, but DB is not fully built or is inconsistent # 403 Database server is up, but provided API key is not valid + +## All database functions are separated - the external wrapper only reads the request keys, converts them into lists and renames them where necessary, and puts the end result in a dict if not already so it can be returned as json + @dbserver.route("/scrobbles") def get_scrobbles_external(): keys = FormsDict.decode(request.query) - return get_scrobbles(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None),max=keys.get("max")) + ckeys["artists"], ckeys["title"] = keys.getall("artist"), keys.get("title") + ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["associated"] = (keys.get("associated")!=None) + ckeys["max"] = keys.get("max") + + result = get_scrobbles(ckeys) + return {"list":result} def get_scrobbles(**keys): r = db_query(**{k:keys[k] for k in keys if k in ["artists","title","since","to","within","associated"]}) r.reverse() if keys.get("max") is not None: - return {"list":r[:int(keys.get("max"))]} + return r[:int(keys.get("max"))] else: - return {"list":r} ##json can't be a list apparently??? + return r + + + @dbserver.route("/numscrobbles") -def get_scrobbles_num(): +def get_scrobbles_num_external(): keys = FormsDict.decode(request.query) + ckeys["artists"], ckeys["title"] = keys.getall("artist"), keys.get("title") + ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["associated"] = (keys.get("associated")!=None) - r = db_query(artists=keys.getall("artist"),title=keys.get("title"),since=keys.get("since"),to=keys.get("to"),within=keys.get("in"),associated=(keys.get("associated")!=None)) - r.reverse() + result = get_scrobbles_num(ckeys) + return {"amount":result} + +def get_scrobbles_num(**keys): + r = db_query(**{k:keys[k] for k in keys if k in ["artists","title","since","to","within","associated"]}) + return len(r) + + - return {"amount":len(r)} @dbserver.route("/tracks") -def get_tracks(): +def get_tracks_external(): keys = FormsDict.decode(request.query) + ckeys["artists"] = keys.get("artist") + + result = get_tracks(ckeys) + return {"list":result} + +def get_tracks(**keys): + artist = keys.get("artist") if artist is not None: - artistid = ARTISTS.index(artist) - + artistid = ARTISTS.index(artist) + # Option 1 - ls = [getTrackObject(t) for t in TRACKS if (artistid in t[0]) or (artistid==None)] + return [getTrackObject(t) for t in TRACKS if (artistid in t[0]) or (artistid==None)] # Option 2 is a bit more elegant but much slower #tracklist = [getTrackObject(t) for t in TRACKS] #ls = [t for t in tracklist if (artist in t["artists"]) or (artist==None)] - - return {"list":ls} - + + @dbserver.route("/artists") +def get_artists_external(): + result = get_artists() + return {"list":result} + def get_artists(): + return ARTISTS #well - return {"list":ARTISTS} - + + @dbserver.route("/amounts") +get_amounts_external = get_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") - to = request.query.get("to") - within=request.query.get("in") - - return {"list":db_aggregate(by="ARTIST",since=since,to=to,within=within)} - -@dbserver.route("/charts/tracks") -def get_charts_tracks(): +def get_charts_artists_external(): keys = FormsDict.decode(request.query) - since = keys.get("since") - to = keys.get("to") - within=request.query.get("in") - artist = keys.get("artist") + ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + + result = get_charts_artists(ckeys) + return {"list":result} + +def get_charts_artists(**keys): + return db_aggregate(by="ARTIST",**{k:keys[k] for k in keys if k in ["since","to","within"]}) + + + + + + +@dbserver.route("/charts/tracks") +def get_charts_tracks_external(): + keys = FormsDict.decode(request.query) + ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["artist"] = keys.get("artist") + + result = get_charts_tracks(ckeys) + return {"list":result} + +def get_charts_tracks(**keys): + return db_aggregate(by="TRACK",**{k:keys[k] for k in keys if k in ["since","to","within","artist"]}) + + + + + - return {"list":db_aggregate(by="TRACK",since=since,to=to,within=within,artist=artist)} @dbserver.route("/charts") -def get_charts(): - since = request.query.get("since") - to = request.query.get("to") - within=request.query.get("in") +def get_charts_external(): + keys = FormsDict.decode(request.query) + ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") - return {"number":db_aggregate(since=since,to=to,within=within)} + result = get_charts(ckeys) + return {"number":result} + +def get_charts(**keys): + return db_aggregate(**{k:keys[k] for k in keys if k in ["since","to","within"]}) + + + + + + + @dbserver.route("/pulse") def get_pulse(): @@ -700,7 +774,7 @@ def db_query(artists=None,title=None,track=None,since=None,to=None,within=None,a # Queries that... well... aggregate -def db_aggregate(by=None,since=None,to=None,withinin=None,artist=None): +def db_aggregate(by=None,since=None,to=None,within=None,artist=None): (since, to) = getTimestamps(since,to,within) if isinstance(artist, str): From 208d059743018c715af84e980b642fa27d373b86 Mon Sep 17 00:00:00 2001 From: Krateng Date: Fri, 15 Feb 2019 21:07:08 +0100 Subject: [PATCH 3/5] Expanded on separation, fixed some tech debt and bugs --- database.py | 166 ++++++++++++++++++++++++++++++++------------------- utilities.py | 18 ++++++ 2 files changed, 123 insertions(+), 61 deletions(-) diff --git a/database.py b/database.py index bddb2d0..a050352 100644 --- a/database.py +++ b/database.py @@ -154,12 +154,13 @@ def test_server(): @dbserver.route("/scrobbles") def get_scrobbles_external(): keys = FormsDict.decode(request.query) + ckeys = {} ckeys["artists"], ckeys["title"] = keys.getall("artist"), keys.get("title") - ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") ckeys["associated"] = (keys.get("associated")!=None) ckeys["max"] = keys.get("max") - result = get_scrobbles(ckeys) + result = get_scrobbles(**ckeys) return {"list":result} def get_scrobbles(**keys): @@ -173,15 +174,16 @@ def get_scrobbles(**keys): - +# DEPRECATED, merge with /amounts @dbserver.route("/numscrobbles") def get_scrobbles_num_external(): keys = FormsDict.decode(request.query) + ckeys = {} ckeys["artists"], ckeys["title"] = keys.getall("artist"), keys.get("title") - ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") ckeys["associated"] = (keys.get("associated")!=None) - result = get_scrobbles_num(ckeys) + result = get_scrobbles_num(**ckeys) return {"amount":result} def get_scrobbles_num(**keys): @@ -195,17 +197,19 @@ def get_scrobbles_num(**keys): @dbserver.route("/tracks") def get_tracks_external(): keys = FormsDict.decode(request.query) - ckeys["artists"] = keys.get("artist") + ckeys = {} + ckeys["artist"] = keys.get("artist") - result = get_tracks(ckeys) + result = get_tracks(**ckeys) return {"list":result} -def get_tracks(**keys): +def get_tracks(artist=None): - artist = keys.get("artist") if artist is not None: - artistid = ARTISTS.index(artist) + artistid = ARTISTS.index(artist) + else: + artistid = None # Option 1 return [getTrackObject(t) for t in TRACKS if (artistid in t[0]) or (artistid==None)] @@ -226,7 +230,8 @@ def get_artists(): @dbserver.route("/amounts") -get_amounts_external = get_amounts +def get_amounts_external(): + return get_amounts() #really now def get_amounts(): return {"scrobbles":len(SCROBBLES),"tracks":len(TRACKS),"artists":len(ARTISTS)} @@ -238,9 +243,10 @@ def get_amounts(): @dbserver.route("/charts/artists") def get_charts_artists_external(): keys = FormsDict.decode(request.query) - ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") - result = get_charts_artists(ckeys) + result = get_charts_artists(**ckeys) return {"list":result} def get_charts_artists(**keys): @@ -254,10 +260,11 @@ def get_charts_artists(**keys): @dbserver.route("/charts/tracks") def get_charts_tracks_external(): keys = FormsDict.decode(request.query) - ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") ckeys["artist"] = keys.get("artist") - result = get_charts_tracks(ckeys) + result = get_charts_tracks(**ckeys) return {"list":result} def get_charts_tracks(**keys): @@ -268,13 +275,14 @@ def get_charts_tracks(**keys): - +# DEPRECATED, merge with /amounts @dbserver.route("/charts") def get_charts_external(): keys = FormsDict.decode(request.query) - ckeys["since"],ckeys["to"],ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") - result = get_charts(ckeys) + result = get_charts(**ckeys) return {"number":result} def get_charts(**keys): @@ -288,20 +296,23 @@ def get_charts(**keys): @dbserver.route("/pulse") -def get_pulse(): - since = request.query.get("since") - to = request.query.get("to") - within=request.query.get("in") - (ts_start,ts_end) = getTimestamps(since,to,within) - 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) +def get_pulse_external(): + keys = FormsDict.decode(request.query) + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["step"], ckeys["trail"] = keys.get("step"), int_or_none(keys.get("trail")) + if ckeys["step"] is not None: [ckeys["step"],ckeys["stepn"]] = (ckeys["step"].split("-") + [1])[:2] # makes the multiplier 1 if not assigned + if "stepn" in ckeys: ckeys["stepn"] = int(ckeys["stepn"]) + cleandict(ckeys) + results = get_pulse(**ckeys) + return {"list":results} + +def get_pulse(step="month",stepn=1,trail=3,**keys): + + (ts_start,ts_end) = getTimestamps(**{k:keys[k] for k in keys if k in ["since","to","within"]}) 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 @@ -310,31 +321,40 @@ def get_pulse(): 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])) res = db_aggregate(since=d_current,to=d_current_end) results.append({"from":d_current,"to":d_current_end,"scrobbles":res}) d_current = getNext(d_current,step,stepn) if isPast(d_current_end,d_end): break - return {"list":results} + return results + + + + + + @dbserver.route("/top/artists") -def get_top_artists(): - since = request.query.get("since") - to = request.query.get("to") - within=request.query.get("in") - (ts_start,ts_end) = getTimestamps(since,to,within) - step = request.query.get("step","month") - trail = int(request.query.get("trail",3)) +def get_top_artists_external(): + + keys = FormsDict.decode(request.query) + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["step"], ckeys["trail"] = keys.get("step"), int_or_none(keys.get("trail")) + if ckeys["step"] is not None: [ckeys["step"],ckeys["stepn"]] = (ckeys["step"].split("-") + [1])[:2] # makes the multiplier 1 if not assigned + if "stepn" in ckeys: ckeys["stepn"] = int(ckeys["stepn"]) - [step,stepn] = (step.split("-") + [1])[:2] # makes the multiplier 1 if not assigned - stepn = int(stepn) + cleandict(ckeys) + results = get_top_artists(**ckeys) + return {"list":results} +def get_top_artists(step="month",stepn=1,trail=3,**keys): + + (ts_start,ts_end) = getTimestamps(**{k:keys[k] for k in keys if k in ["since","to","within"]}) d_start = getStartOf(ts_start,step) - d_end = getStartOf(ts_end,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 @@ -343,7 +363,6 @@ def get_top_artists(): 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="ARTIST")[0] results.append({"from":d_current,"to":d_current_end,"artist":res["artist"],"scrobbles":res["scrobbles"]}) @@ -353,32 +372,44 @@ def get_top_artists(): if isPast(d_current_end,d_end): break - return {"list":results} - + return results + + + + + + + + + + @dbserver.route("/top/tracks") -def get_top_tracks(): - since = request.query.get("since") - to = request.query.get("to") - within=request.query.get("in") - (ts_start,ts_end) = getTimestamps(since,to,within) - 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) +def get_top_tracks_external(): + keys = FormsDict.decode(request.query) + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + ckeys["step"], ckeys["trail"] = keys.get("step"), int_or_none(keys.get("trail")) + if ckeys["step"] is not None: [ckeys["step"],ckeys["stepn"]] = (ckeys["step"].split("-") + [1])[:2] # makes the multiplier 1 if not assigned + if "stepn" in ckeys: ckeys["stepn"] = int(ckeys["stepn"]) + cleandict(ckeys) + results = get_top_tracks(**ckeys) + return {"list":results} + +def get_top_tracks(step="month",stepn=1,trail=3,**keys): + + (ts_start,ts_end) = getTimestamps(**{k:keys[k] for k in keys if k in ["since","to","within"]}) d_start = getStartOf(ts_start,step) - d_end = getStartOf(ts_end,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"]}) @@ -388,7 +419,18 @@ def get_top_tracks(): if isPast(d_current_end,d_end): break - return {"list":results} + return results + + + + + + + + + + + def getStartOf(timestamp,unit): @@ -836,7 +878,9 @@ def db_search(query,type=None): # Takes user inputs like YYYY/MM and returns the timestamps. Returns timestamp if timestamp was already given. # to dates are interpreted differently (from 2010 and to 2010 both include all of 2010) -def getTimestamps(f=None,t=None,i=None): +def getTimestamps(since=None,to=None,within=None): + + f,t,i = since,to,within if i is not None: f = i diff --git a/utilities.py b/utilities.py index ba652f0..577af6c 100644 --- a/utilities.py +++ b/utilities.py @@ -134,6 +134,24 @@ def addEntries(filename,al): for a in al: line = "\t".join(a) f.write(line + "\n") + + + +### Useful functions + +def int_or_none(input_): + try: + return int(input_) + except: + return None + +def cleandict(d): + newdict = {k:d[k] for k in d if d[k] is not None} + d.clear() + d.update(newdict) + + + ### Logging From 8f2ea10be296f406de3af4116c9b2300141643ea Mon Sep 17 00:00:00 2001 From: Krateng Date: Sat, 16 Feb 2019 16:28:32 +0100 Subject: [PATCH 4/5] Organizing --- database.py | 55 ++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/database.py b/database.py index a050352..59e8e5c 100644 --- a/database.py +++ b/database.py @@ -174,7 +174,18 @@ def get_scrobbles(**keys): -# DEPRECATED, merge with /amounts + + +# DEPRECATED +# UNUSED +@dbserver.route("/amounts") +def get_amounts_external(): + return get_amounts() #really now + +def get_amounts(): + return {"scrobbles":len(SCROBBLES),"tracks":len(TRACKS),"artists":len(ARTISTS)} + + @dbserver.route("/numscrobbles") def get_scrobbles_num_external(): keys = FormsDict.decode(request.query) @@ -190,6 +201,22 @@ def get_scrobbles_num(**keys): r = db_query(**{k:keys[k] for k in keys if k in ["artists","title","since","to","within","associated"]}) return len(r) +# DEPRECATED +# UNUSED +@dbserver.route("/charts") +def get_charts_external(): + keys = FormsDict.decode(request.query) + ckeys = {} + ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") + + result = get_scrobbles_num(**ckeys) + return {"number":result} + +#def get_charts(**keys): +# return db_aggregate(**{k:keys[k] for k in keys if k in ["since","to","within"]}) + + + @@ -199,7 +226,7 @@ def get_tracks_external(): keys = FormsDict.decode(request.query) ckeys = {} ckeys["artist"] = keys.get("artist") - + result = get_tracks(**ckeys) return {"list":result} @@ -229,13 +256,6 @@ def get_artists(): -@dbserver.route("/amounts") -def get_amounts_external(): - return get_amounts() #really now - -def get_amounts(): - return {"scrobbles":len(SCROBBLES),"tracks":len(TRACKS),"artists":len(ARTISTS)} - @@ -272,23 +292,6 @@ def get_charts_tracks(**keys): - - - -# DEPRECATED, merge with /amounts -@dbserver.route("/charts") -def get_charts_external(): - keys = FormsDict.decode(request.query) - ckeys = {} - ckeys["since"], ckeys["to"], ckeys["within"] = keys.get("since"), keys.get("to"), keys.get("in") - - result = get_charts(**ckeys) - return {"number":result} - -def get_charts(**keys): - return db_aggregate(**{k:keys[k] for k in keys if k in ["since","to","within"]}) - - From e4b9ca1d81fd95e324475efee2d0bf859c528684 Mon Sep 17 00:00:00 2001 From: Krateng Date: Sun, 17 Feb 2019 15:02:27 +0100 Subject: [PATCH 5/5] Separation now on all relevant functions --- database.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/database.py b/database.py index b812bca..21c1183 100644 --- a/database.py +++ b/database.py @@ -477,10 +477,16 @@ def getNext(time,unit="auto",step=1): elif unit == "week": return getNext(time,"day",step * 7) -@dbserver.route("/artistinfo") -def artistInfo(): +@dbserver.route("/artistinfo") +def artistInfo_external(): keys = FormsDict.decode(request.query) - artist = keys.get("artist") + ckeys = {} + ckeys["artist"] = keys.get("artist") + + results = artistInfo(**ckeys) + return results + +def artistInfo(artist): charts = db_aggregate(by="ARTIST") scrobbles = len(db_query(artists=[artist])) #we cant take the scrobble number from the charts because that includes all countas scrobbles @@ -493,19 +499,28 @@ def artistInfo(): artist = coa.getCredited(artist) c = [e for e in charts if e["artist"] == artist][0] return {"replace":artist,"scrobbles":scrobbles,"position":charts.index(c) + 1} + + + + @dbserver.route("/trackinfo") -def trackInfo(): +def trackInfo_external(): keys = FormsDict.decode(request.query) - artists = keys.getall("artist") - title = keys.get("title") + ckeys = {} + ckeys["artists"],ckeys["title"] = keys.getall("artist"), keys.get("title") + results = trackInfo(**ckeys) + return results + +def trackInfo(artists,title): charts = db_aggregate(by="TRACK") scrobbles = len(db_query(artists=artists,title=title)) #we cant take the scrobble number from the charts because that includes all countas scrobbles - c = [e for e in charts if set(e["track"]["artists"]) == set(artists) and e["track"]["title"] == title][0] return {"scrobbles":scrobbles,"position":charts.index(c) + 1} + + def isPast(date,limit): if not date[0] == limit[0]: @@ -514,6 +529,12 @@ def isPast(date,limit): return date[1] > limit[1] return (date[2] > limit[2]) + + + + + + @dbserver.get("/newscrobble") def pseudo_post_scrobble(): keys = FormsDict.decode(request.query) # The Dal★Shabet handler