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

Properly separated servers

This commit is contained in:
Krateng 2018-12-19 15:28:10 +01:00
parent 08de19459c
commit dace8f1c44
6 changed files with 80 additions and 45 deletions

View File

@ -1,4 +1,4 @@
from bottle import route, get, post, run, template, static_file, request, response, FormsDict from bottle import Bottle, route, get, post, run, template, static_file, request, response, FormsDict
from importlib.machinery import SourceFileLoader from importlib.machinery import SourceFileLoader
import urllib import urllib
import waitress import waitress
@ -8,6 +8,8 @@ from cleanup import *
from utilities import * from utilities import *
import sys import sys
dbserver = Bottle()
SCROBBLES = [] # Format: tuple(track_ref,timestamp,saved) SCROBBLES = [] # Format: tuple(track_ref,timestamp,saved)
ARTISTS = [] # Format: artist ARTISTS = [] # Format: artist
@ -15,8 +17,8 @@ TRACKS = [] # Format: tuple(frozenset(artist_ref,...),title)
timestamps = set() timestamps = set()
c = CleanerAgent() cla = CleanerAgent()
sovereign = CollectorAgent() coa = CollectorAgent()
clients = [] clients = []
lastsync = 0 lastsync = 0
@ -100,7 +102,7 @@ def getTrackID(artists,title):
## HTTP requests ## HTTP requests
#### ####
@route("/test") @dbserver.route("/test")
def test_server(): def test_server():
apikey = request.query.get("key") apikey = request.query.get("key")
response.set_header("Access-Control-Allow-Origin","*") response.set_header("Access-Control-Allow-Origin","*")
@ -112,14 +114,14 @@ def test_server():
response.status = 204 response.status = 204
return return
@route("/scrobbles") @dbserver.route("/scrobbles")
def get_scrobbles(): def get_scrobbles():
keys = request.query keys = request.query
r = db_query(artist=keys.get("artist"),track=keys.get("track"),since=keys.get("since"),to=keys.get("to")) r = db_query(artist=keys.get("artist"),track=keys.get("track"),since=keys.get("since"),to=keys.get("to"))
return {"list":r} ##json can't be a list apparently??? return {"list":r} ##json can't be a list apparently???
@route("/tracks") @dbserver.route("/tracks")
def get_tracks(): def get_tracks():
keys = FormsDict.decode(request.query) keys = FormsDict.decode(request.query)
artist = keys.get("artist") artist = keys.get("artist")
@ -136,33 +138,33 @@ def get_tracks():
return {"list":ls} return {"list":ls}
@route("/artists") @dbserver.route("/artists")
def get_artists(): def get_artists():
return {"list":ARTISTS} return {"list":ARTISTS}
@route("/charts/artists") @dbserver.route("/charts/artists")
def get_charts_artists(): def get_charts_artists():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
return {"list":db_aggregate(by="ARTIST",since=since,to=to)} return {"list":db_aggregate(by="ARTIST",since=since,to=to)}
@route("/charts/tracks") @dbserver.route("/charts/tracks")
def get_charts_tracks(): def get_charts_tracks():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
return {"list":db_aggregate(by="TRACK",since=since,to=to)} return {"list":db_aggregate(by="TRACK",since=since,to=to)}
@route("/charts") @dbserver.route("/charts")
def get_charts(): def get_charts():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
return {"number":db_aggregate(since=since,to=to)} return {"number":db_aggregate(since=since,to=to)}
@route("/pulse") @dbserver.route("/pulse")
def get_pulse(): def get_pulse():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
@ -194,7 +196,7 @@ def get_pulse():
return {"list":results} return {"list":results}
@route("/top/artists") @dbserver.route("/top/artists")
def get_top_artists(): def get_top_artists():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
@ -228,7 +230,7 @@ def get_top_artists():
return {"list":results} return {"list":results}
@route("/top/tracks") @dbserver.route("/top/tracks")
def get_top_tracks(): def get_top_tracks():
since = request.query.get("since") since = request.query.get("since")
to = request.query.get("to") to = request.query.get("to")
@ -298,7 +300,7 @@ def getNext(time,unit,step=1):
elif unit == "week": elif unit == "week":
return getNext(time,"day",step * 7) return getNext(time,"day",step * 7)
@route("/artistinfo") @dbserver.route("/artistinfo")
def artistInfo(): def artistInfo():
keys = FormsDict.decode(request.query) keys = FormsDict.decode(request.query)
artist = keys.get("artist") artist = keys.get("artist")
@ -307,11 +309,11 @@ def artistInfo():
scrobbles = len(db_query(artist=artist)) #we cant take the scrobble number from the charts because that includes all countas scrobbles scrobbles = len(db_query(artist=artist)) #we cant take the scrobble number from the charts because that includes all countas scrobbles
try: try:
c = [e for e in charts if e["artist"] == artist][0] c = [e for e in charts if e["artist"] == artist][0]
others = sovereign.getAllAssociated(artist) others = coa.getAllAssociated(artist)
return {"scrobbles":scrobbles,"position":charts.index(c) + 1,"associated":others} return {"scrobbles":scrobbles,"position":charts.index(c) + 1,"associated":others}
except: except:
# if the artist isnt in the charts, they are not being credited and we need to show information about the credited one # if the artist isnt in the charts, they are not being credited and we need to show information about the credited one
artist = sovereign.getCredited(artist) artist = coa.getCredited(artist)
c = [e for e in charts if e["artist"] == artist][0] c = [e for e in charts if e["artist"] == artist][0]
return {"replace":artist,"scrobbles":scrobbles,"position":charts.index(c) + 1} return {"replace":artist,"scrobbles":scrobbles,"position":charts.index(c) + 1}
@ -322,7 +324,7 @@ def isPast(date,limit):
return date[1] > limit[1] return date[1] > limit[1]
return (date[2] > limit[2]) return (date[2] > limit[2])
@get("/newscrobble") @dbserver.get("/newscrobble")
def pseudo_post_scrobble(): def pseudo_post_scrobble():
keys = FormsDict.decode(request.query) # The Dal★Shabet handler keys = FormsDict.decode(request.query) # The Dal★Shabet handler
artists = keys.get("artist") artists = keys.get("artist")
@ -331,7 +333,7 @@ def pseudo_post_scrobble():
time = int(keys.get("time")) time = int(keys.get("time"))
except: except:
time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp()) time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp())
(artists,title) = c.fullclean(artists,title) (artists,title) = cla.fullclean(artists,title)
## this is necessary for localhost testing ## this is necessary for localhost testing
response.set_header("Access-Control-Allow-Origin","*") response.set_header("Access-Control-Allow-Origin","*")
@ -343,7 +345,7 @@ def pseudo_post_scrobble():
return "" return ""
@post("/newscrobble") @dbserver.post("/newscrobble")
def post_scrobble(): def post_scrobble():
keys = FormsDict.decode(request.forms) # The Dal★Shabet handler keys = FormsDict.decode(request.forms) # The Dal★Shabet handler
artists = keys.get("artist") artists = keys.get("artist")
@ -357,7 +359,7 @@ def post_scrobble():
time = int(keys.get("time")) time = int(keys.get("time"))
except: except:
time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp()) time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp())
(artists,title) = c.fullclean(artists,title) (artists,title) = cla.fullclean(artists,title)
## this is necessary for localhost testing ## this is necessary for localhost testing
response.set_header("Access-Control-Allow-Origin","*") response.set_header("Access-Control-Allow-Origin","*")
@ -369,7 +371,7 @@ def post_scrobble():
return "" return ""
@route("/sync") @dbserver.route("/sync")
def abouttoshutdown(): def abouttoshutdown():
sync() sync()
#sys.exit() #sys.exit()
@ -382,17 +384,17 @@ def abouttoshutdown():
# Starts the server # Starts the server
def runserver(DATABASE_PORT): def runserver(PORT):
global lastsync global lastsync
lastsync = time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp()) lastsync = time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp())
#reload() #reload()
#buildh() #buildh()
build_db() build_db()
sovereign.updateIDs(ARTISTS) coa.updateIDs(ARTISTS)
loadAPIkeys() loadAPIkeys()
run(host='0.0.0.0', port=DATABASE_PORT, server='waitress') run(dbserver, host='0.0.0.0', port=PORT, server='waitress')
def build_db(): def build_db():
@ -496,7 +498,7 @@ def db_aggregate(by=None,since=None,to=None):
charts = {} charts = {}
for s in [scr for scr in SCROBBLES if since < scr[1] < to]: for s in [scr for scr in SCROBBLES if since < scr[1] < to]:
artists = TRACKS[s[0]][0] artists = TRACKS[s[0]][0]
for a in sovereign.getCreditedList(artists): for a in coa.getCreditedList(artists):
# this either creates the new entry or increments the existing one # this either creates the new entry or increments the existing one
charts[a] = charts.setdefault(a,0) + 1 charts[a] = charts.setdefault(a,0) + 1

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
from bottle import route, get, post, run, template, static_file, request, response, FormsDict from bottle import Bottle, route, get, post, error, run, template, static_file, request, response, FormsDict
from importlib.machinery import SourceFileLoader from importlib.machinery import SourceFileLoader
import _thread import _thread
import waitress import waitress
@ -15,18 +15,19 @@ import os
MAIN_PORT = 42010 MAIN_PORT = 42010
DATABASE_PORT = 42011 DATABASE_PORT = 42011
webserver = Bottle()
@route("")
@route("/") @webserver.route("")
@webserver.route("/")
def mainpage(): def mainpage():
return static_file("main.html",root="") return static_file("main.html",root="")
# this is the fallback option. If you run this service behind a reverse proxy, it is recommended to rewrite /db/ requests to the port of the db server # this is the fallback option. If you run this service behind a reverse proxy, it is recommended to rewrite /db/ requests to the port of the db server
# e.g. location /db { rewrite ^/db(.*)$ $1 break; proxy_pass http://yoururl:12349; } # e.g. location /db { rewrite ^/db(.*)$ $1 break; proxy_pass http://yoururl:12349; }
@get("/db/<pth:path>") @webserver.get("/db/<pth:path>")
def database_get(pth): def database_get(pth):
keys = FormsDict.decode(request.query) # The Dal★Shabet handler keys = FormsDict.decode(request.query) # The Dal★Shabet handler
keystring = "?" keystring = "?"
@ -43,7 +44,7 @@ def database_get(pth):
response.status = e.code response.status = e.code
return return
@post("/db/<pth:path>") @webserver.post("/db/<pth:path>")
def database_post(pth): def database_post(pth):
response.set_header("Access-Control-Allow-Origin","*") response.set_header("Access-Control-Allow-Origin","*")
try: try:
@ -60,7 +61,7 @@ def database_post(pth):
return return
@route("/exit") @webserver.route("/exit")
def shutdown(): def shutdown():
graceful_exit() graceful_exit()
@ -70,23 +71,23 @@ def graceful_exit(sig=None,frame=None):
sys.exit() sys.exit()
@route("/info/<pth:re:.*\\.jpeg>") @webserver.route("/info/<pth:re:.*\\.jpeg>")
@route("/info/<pth:re:.*\\.jpg>") @webserver.route("/info/<pth:re:.*\\.jpg>")
@route("/info/<pth:re:.*\\.png>") @webserver.route("/info/<pth:re:.*\\.png>")
def static_image(pth): def static_image(pth):
return static_file("info/" + pth,root="") return static_file("info/" + pth,root="")
@route("/<name:re:.*\\.html>") @webserver.route("/<name:re:.*\\.html>")
@route("/<name:re:.*\\.js>") @webserver.route("/<name:re:.*\\.js>")
@route("/<name:re:.*\\.css>") @webserver.route("/<name:re:.*\\.css>")
@route("/<name:re:.*\\.png>") @webserver.route("/<name:re:.*\\.png>")
@route("/<name:re:.*\\.jpeg>") @webserver.route("/<name:re:.*\\.jpeg>")
def static(name): def static(name):
return static_file("website/" + name,root="") return static_file("website/" + name,root="")
@route("/<name>") @webserver.route("/<name>")
def static_html(name): def static_html(name):
keys = FormsDict.decode(request.query) keys = FormsDict.decode(request.query)
@ -117,4 +118,4 @@ except:
## start database server ## start database server
_thread.start_new_thread(SourceFileLoader("database","database.py").load_module().runserver,(DATABASE_PORT,)) _thread.start_new_thread(SourceFileLoader("database","database.py").load_module().runserver,(DATABASE_PORT,))
run(host='0.0.0.0', port=MAIN_PORT, server='waitress') run(webserver, host='0.0.0.0', port=MAIN_PORT, server='waitress')

View File

@ -123,11 +123,14 @@ def getArtistInfo(artist):
imgurl imgurl
except NameError: except NameError:
imgurl = lastfm_data["artist"]["image"][2]["#text"] imgurl = lastfm_data["artist"]["image"][2]["#text"]
_thread.start_new_thread(cacheImage,(imgurl,"info/artists_cache",filename)) if imgurl == "":
imgurl = "/info/artists/default.jpg"
else:
_thread.start_new_thread(cacheImage,(imgurl,"info/artists_cache",filename))
try: try:
desc desc
except NameError: except NameError:
desc = lastfm_data["artist"]["bio"]["summary"] desc = lastfm_data["artist"]["bio"]["summary"].split("(1) ")[-1]
with open(filepath_cache + ".txt","w") as descfile: with open(filepath_cache + ".txt","w") as descfile:
descfile.write(desc) descfile.write(desc)
# this feels so dirty # this feels so dirty

View File

@ -18,7 +18,7 @@
<span>KEY_ASSOCIATED</span> <span>KEY_ASSOCIATED</span>
<p class="stats">KEY_SCROBBLES Scrobbles</p> <p class="stats">KEY_SCROBBLES Scrobbles</p>
KEY_DESCRIPTION <p>KEY_DESCRIPTION</p>
</td> </td>
</tr> </tr>
</table> </table>

View File

@ -16,6 +16,7 @@ a:hover {
text-decoration:underline; text-decoration:underline;
} }
table.top_info td.image { table.top_info td.image {
padding:20px; padding:20px;
padding-left:0px; padding-left:0px;

28
website/scrobbles.html Normal file
View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Maloja - Scrobbles</title>
<link rel="stylesheet" href="maloja.css" />
</head>
<body>
<table class="top_info">
<tr>
<td class="image">
<div style="background-image:url('KEY_IMAGEURL')"></div>
</td>
<td class="text">
<h1>Scrobbles</h1><br/>
<span>KEY_LIMITS</span>
<p class="stats">KEY_SCROBBLES Scrobbles</p>
</td>
</tr>
</table>
KEY_SCROBBLELIST
</body>
</html>