1
0
mirror of https://github.com/krateng/maloja.git synced 2023-08-10 21:12:55 +03:00
maloja/database.py

208 lines
5.6 KiB
Python
Raw Normal View History

2018-11-24 18:29:24 +03:00
from bottle import route, run, template, static_file, request, response
from importlib.machinery import SourceFileLoader
import waitress
import os
import datetime
DATABASE = []
ARTISTS = []
TRACKS = []
@route("/scrobbles")
def get_scrobbles():
keys = request.query
r = db_query(artist=keys.get("artist"))
#print(r)
2018-11-25 16:49:53 +03:00
response.content_type = "application/json; charset=UTF-8"
#response.charset = 'UTF-8'
return {"list":r} ##json can't be a list apparently???
2018-11-24 18:29:24 +03:00
#r = db_query(artist=keys.get("artist"))
#text = ""
#for e in r:
# entry = ""
# for a in e["artists"]:
# entry += a + "/"
# entry += " " + e["title"] + "\n"
# text += entry
#return text
@route("/tracks")
def get_tracks():
artist = request.query.get("artist")
2018-11-25 16:49:53 +03:00
# turn the tupel of frozensets into a jsonable object
tracklist = [{"artists":list(a[0]),"title":a[1]} for a in TRACKS]
ls = [t for t in tracklist if (artist in t["artists"]) or (artist==None)]
return {"list":ls}
@route("/artists")
def get_artists():
response.content_type = "application/json; charset=UTF-8"
#response.charset = "utf-8"
return {"list":ARTISTS}
@route("/charts")
def get_charts():
since = request.query.get("since")
to = request.query.get("to")
results = db_query(since=since,to=to)
return {"list":results}
2018-11-24 18:29:24 +03:00
# Starts the server
def runserver(DATABASE_PORT):
reload()
buildh()
run(host='0.0.0.0', port=DATABASE_PORT, server='waitress')
# builds database of artists and tracks
# UNUSED as it is very resource-heavy, use buildh() instead
def build():
global ARTISTS
global TRACKS
artistlist = []
tracklist = []
for t in DATABASE:
for a in t["artists"]:
if a in artistlist:
continue
artistlist.append(a)
# first check if the title exists at all to quickly rule out most titles
if (t["title"] in [tr["title"] for tr in tracklist]):
#only it same title actually exists do we need to check if the song is the same
if not (set(t["artists"]) in [set(tr["artists"]) for tr in tracklist if tr["title"] == t["title"]]): #wut
tracklist.append({"artists":t["artists"],"title":t["title"]})
### ALRIGHT
#foundexisting = False
#for track in [tr for tr in tracklist if tr["title"] == t["title"]]: #wtf did I just write
# #print("Check duplicate: " + str(track) + " AND " + str(t))
# if (set(track["artists"]) == set(t["artists"])):
# foundexisting = True
# #print("MATCH!")
# break
# #else:
# #print("NO MATCH!")
2018-11-25 16:49:53 +03:00
#
2018-11-24 18:29:24 +03:00
#if not foundexisting:
# tracklist.append({"artists":t["artists"],"title":t["title"]})
else:
tracklist.append({"artists":t["artists"],"title":t["title"]})
ARTISTS = artistlist
TRACKS = tracklist
# builds database of artists and tracks
# uses better data types to quickly find all unique tracks
def buildh():
global ARTISTS
global TRACKS
artistset = set()
trackset = set()
for t in DATABASE:
for a in t["artists"]:
2018-11-25 16:49:53 +03:00
#if a not in artistset:
artistset.add(a)
2018-11-24 18:29:24 +03:00
# we list the tracks as tupels of frozenset(artists) and track
# this way they're hashable and easily comparable, but we need to change them back after we have the list
2018-11-25 16:49:53 +03:00
#if ((frozenset(t["artists"]),t["title"])) not in trackset:
trackset.add((frozenset(t["artists"]),t["title"]))
2018-11-24 18:29:24 +03:00
print("Done, now converting back!")
ARTISTS = list(artistset)
2018-11-25 16:49:53 +03:00
#TRACKS = [{"artists":list(a[0]),"title":a[1]} for a in trackset]
#actually lets only convert this once we need it, kinda makes sense to store it in the tuple frozenset form
TRACKS = list(trackset)
2018-11-24 18:29:24 +03:00
# Rebuilds the database from disk, keeps cached entries
def reload():
newdb = [t for t in DATABASE if not t["saved"]]
for f in os.listdir("logs/"):
#print(f)
if not (".csv" in f):
continue
logfile = open("logs/" + f)
for l in logfile:
l = l.replace("\n","")
data = l.split(",")
#print(l)
2018-11-25 16:49:53 +03:00
## saving album in the scrobbles is supported, but for now we don't use it. It shouldn't be a defining part of the track (same song from Album or EP), but derived information
2018-11-24 18:29:24 +03:00
artists = data[1].split("/")
#album = data[3]
title = data[2]
time = int(data[0])
DATABASE.append({"artists":artists,"title":title,"time":time,"saved":True})
# Saves all cached entries to disk
def flush():
for t in DATABASE:
if not t["saved"]:
artistss = "/".join(t["artists"])
timestamp = datetime.date.fromtimestamp(t["time"])
entry = ",".join([str(t["time"]),artistss,t["title"]])
monthfile = open("logs/" + str(timestamp.year) + "_" + str(timestamp.month) + ".csv","a")
monthfile.write(entry)
monthfile.write("\n")
monthfile.close()
t["saved"] = True
# Queries the database
def db_query(artist=None,title=None,since=0,to=9999999999):
if isinstance(since, str):
sdate = [int(x) for x in since.split("/")]
date = [1970,1,1,0,0]
date[:len(sdate)] = sdate
since = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
if isinstance(to, str):
sdate = [int(x) for x in to.split("/")]
date = [1970,1,1,0,0]
date[:len(sdate)] = sdate
to = int(datetime.datetime(date[0],date[1],date[2],date[3],date[4],tzinfo=datetime.timezone.utc).timestamp())
thingsweneed = ["artists","title","time"]
return [{key:t[key] for key in thingsweneed} for t in DATABASE if (artist in t["artists"] or artist==None) and (t["title"]==title or title==None) and (since < t["time"] < to)]
# Search for strings
def db_search(query,type=None):
if type=="ARTIST":
results = []
for a in ARTISTS:
if query.lower() in a.lower():
results.append(a)
if type=="TRACK":
results = []
for t in TRACKS:
if query.lower() in t[1].lower():
results.append(t)
return results