Maloja can identify possible problems with consistency or redundancy in your library. After making any changes, you should rebuild your library.
+
+
+
+
+
+
+{% if issuedata.inconsistent %}
+
+
The current database wasn't built with all current rules in effect. Any problem below might be a false alarm and fixing it could create redundant rules.
+
Rebuild the database
+
+{% endif %}
+
+{% for issue in issuedata.duplicates %}
+
+
{{ htmlgenerators.artistLink(issue[0]) }} is a possible duplicate of {{ htmlgenerators.artistLink(issue[1]) }}
+
{{ issue[1] }} is correct
+
{{ issue[0] }} is correct
+
+{% endfor %}
+
+{% for issue in issuedata.combined %}
+
+
{{ artistLink(issue[0]) }} sounds like the combination of {{ len(issue[1]) }} artists:
+ {{ issue[1]|join(", ") }}
+
+
Fix it
+
+{% endfor %}
+
+{% for issue in issuedata.newartists %}
+
+
Is '{{ issue[0] }}' in '{{ htmlgenerators.artistLink(issue[1]) }}' an artist?
+
Yes
+
+{% endfor %}
+
+
+
+{% endblock %}
diff --git a/maloja/web/pyhp/admin.pyhp b/maloja/web/pyhp/admin.pyhp
index 61ff121..8b00718 100644
--- a/maloja/web/pyhp/admin.pyhp
+++ b/maloja/web/pyhp/admin.pyhp
@@ -53,22 +53,6 @@
window.location.reload(true);
}
- function buttonlock() {
- button = document.getElementById("adminmodebutton")
- if (apikeycorrect) {
- button.classList.remove("locked");
- if (button.innerHTML == "Activate") { button.onclick = activate; }
- else { button.onclick = deactivate; }
- // ugh
- }
- else {
- button.classList.add("locked");
- button.onclick = null;
- }
- }
-
- window.addEventListener("load",function(){checkAPIkey(buttonlock)});
- // we do this twice, but this one ensures that the button is correctly locked / unlocked after the api key has been checked
@@ -83,9 +67,7 @@
-
Admin Panel
-
- API Key:
+
Admin Panel
@@ -101,8 +83,8 @@
Admin Mode
Admin Mode allows you to manually scrobble from various places on the web interface instead of just the dedicated page.
Maloja can identify possible problems with consistency or redundancy in your library. After making any changes, you should rebuild your library.
- Your API key is required to make any changes to the server:
The current database wasn't built with all current rules in effect. Any problem below might be a false alarm and fixing it could create redundant rules.
"
- html += """
Rebuild the database
"""
- html += "
"
- i += 1
- for d in db_data["duplicates"]:
- html += "
"
- html += "
'" + artistLink(d[0]) + "'"
- html += " is a possible duplicate of "
- html += "'" + artistLink(d[1]) + "'
"
- html += """
""" + d[1] + """ is correct
"""
- html += """
""" + d[0] + """ is correct
"""
- html += "
"
- i += 1
- for c in db_data["combined"]:
- html += "
"
- html += "
'" + artistLink(c[0]) + "' sounds like the combination of " + str(len(c[1])) + " artists: "
- for a in c[1]:
- html += "'" + artistLink(a) + "' "
- html += "
"
- html += """
Fix it
"""
- html += "
"
- i += 1
- for n in db_data["newartists"]:
- html += "
"
- html += "
Is '" + n[0] + "' in '" + artistLink(n[1]) + "' an artist?
-
-
-
-
-
-
-
-
-
From 0ddb5a4dd9f970c3520053efc2ad961357b2f281 Mon Sep 17 00:00:00 2001
From: Krateng
Date: Wed, 29 Jul 2020 17:49:55 +0200
Subject: [PATCH 04/14] Updated server setup page
---
maloja/database.py | 47 ++++++++++++
maloja/web/jinja/setup.jinja | 140 +++++++++++++++++++++++++++++++++++
maloja/web/setup.html | 133 ---------------------------------
maloja/web/setup.py | 57 --------------
4 files changed, 187 insertions(+), 190 deletions(-)
create mode 100644 maloja/web/jinja/setup.jinja
delete mode 100644 maloja/web/setup.html
delete mode 100644 maloja/web/setup.py
diff --git a/maloja/database.py b/maloja/database.py
index 608da89..c3dec71 100644
--- a/maloja/database.py
+++ b/maloja/database.py
@@ -829,6 +829,53 @@ def issues():
return {"duplicates":duplicates,"combined":combined,"newartists":newartists,"inconsistent":inconsistent}
+def get_predefined_rulesets():
+ validchars = "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+
+ rulesets = []
+
+ for f in os.listdir(datadir("rules/predefined")):
+ if f.endswith(".tsv"):
+
+ rawf = f.replace(".tsv","")
+ valid = True
+ for char in rawf:
+ if char not in validchars:
+ valid = False
+ break # don't even show up invalid filenames
+
+ if not valid: continue
+ if not "_" in rawf: continue
+
+ try:
+ with open(datadir("rules/predefined",f)) as tsvfile:
+ line1 = tsvfile.readline()
+ line2 = tsvfile.readline()
+
+ if "# NAME: " in line1:
+ name = line1.replace("# NAME: ","")
+ else: name = rawf.split("_")[1]
+ if "# DESC: " in line2:
+ desc = line2.replace("# DESC: ","")
+ else: desc = ""
+
+ author = rawf.split("_")[0]
+ except:
+ continue
+
+ ruleset = {"file":rawf}
+ rulesets.append(ruleset)
+ if os.path.exists(datadir("rules",f)):
+ ruleset["active"] = True
+ else:
+ ruleset["active"] = False
+
+ ruleset["name"] = name
+ ruleset["author"] = author
+ ruleset["desc"] = desc
+
+ return rulesets
+
@dbserver.post("importrules")
def import_rulemodule(**keys):
apikey = keys.pop("key",None)
diff --git a/maloja/web/jinja/setup.jinja b/maloja/web/jinja/setup.jinja
new file mode 100644
index 0000000..5fd88fe
--- /dev/null
+++ b/maloja/web/jinja/setup.jinja
@@ -0,0 +1,140 @@
+{% extends "base.jinja" %}
+{% block title %}Maloja - Setup{% endblock %}
+
+{% block scripts %}
+
+
+
+{% endblock %}
+
+{% set rulesets = dbp.get_predefined_rulesets() %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
Maloja
+
+
Welcome to your own Maloja server!
+
+
+
+
+
Start Scrobbling
+
+ If you use Vivaldi, Brave, Iridium or any other Chromium-based browser and listen to music on Plex or YouTube Music, download the extension and simply enter the server URL as well as your API key in the relevant fields. They will turn green if the server is accessible.
+
+ You can also use any standard-compliant scrobbler. For GNUFM (audioscrobbler) scrobblers, enter yourserver.tld/api/s/audioscrobbler as your Gnukebox server and your API key as the password. For Listenbrainz scrobblers, use yourserver.tld/api/s/listenbrainz as the API URL and your API key as token.
+
+ If you use another browser or another music player, you could try to code your own extension. The API is super simple! Just send a POST HTTP request to
+
+ yourserver.tld/api/newscrobble
+
+ (make sure to use the public URL) with the key-value-pairs
+
+
+
+
artist
Artist String
+
title
Title String
+
key
API Key
+
seconds
Duration of Scrobble - optional and currently not used
+
+ Switching from Last.fm? Download all your data and run the command maloja import (the file you just downloaded).
+
+
+
Set up some rules
+
+ After you've scrobbled for a bit, you might want to check the Issues page to see if you need to set up some rules. You can also manually add rules in your server's "rules" directory - just add your own .tsv file and read the instructions on how to declare a rule.
+
+
+ You can also set up some predefined rulesets right away! Enter your API key and click the buttons.
+
+
+
+
+ Donations are never required, but always appreciated. If you really like Maloja, you can fund my next Buttergipfel via
+ PayPal, Bitcoin or Flattr.
+
+
+
+
View your stats
+
+ Done! Visit yourserver.tld (or your public / proxy URL) to look at your overview page. Almost everything is clickable!
+
+{% endblock %}
diff --git a/maloja/web/setup.html b/maloja/web/setup.html
deleted file mode 100644
index fed262d..0000000
--- a/maloja/web/setup.html
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
- Maloja - Setup
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Maloja
-
-
Welcome to your own Maloja server!
-
-
-
-
-
Start Scrobbling
-
- If you use Vivaldi, Brave, Iridium or any other Chromium-based browser and listen to music on Plex or YouTube Music, download the extension and simply enter the server URL as well as your API key in the relevant fields. They will turn green if the server is accessible.
-
- You can also use any standard-compliant scrobbler. For GNUFM (audioscrobbler) scrobblers, enter yourserver.tld/api/s/audioscrobbler as your Gnukebox server and your API key as the password. For Listenbrainz scrobblers, use yourserver.tld/api/s/listenbrainz as the API URL and your API key as token.
-
- If you use another browser or another music player, you could try to code your own extension. The API is super simple! Just send a POST HTTP request to
-
- yourserver.tld/api/newscrobble
-
- (make sure to use the public URL) with the key-value-pairs
-
-
-
-
artist
Artist String
-
title
Title String
-
key
API Key
-
seconds
Duration of Scrobble - optional and currently not used
-
- Switching from Last.fm? Download all your data and run the command maloja import (the file you just downloaded).
-
-
-
Set up some rules
-
- After you've scrobbled for a bit, you might want to check the Issues page to see if you need to set up some rules. You can also manually add rules in your server's "rules" directory - just add your own .tsv file and read the instructions on how to declare a rule.
-
-
- You can also set up some predefined rulesets right away! Enter your API key and click the buttons.
-
- API Key:
-
-
-
- KEY_PREDEFINED_RULESETS
-
-
-
-
Say thanks
-
- Coding open source projects is fun, but not really monetizable. If you like Maloja, I would appreciate a small donation via
- PayPal, Bitcoin or Flattr.
-
-
-
-
View your stats
-
- Done! Visit yourserver.tld (or your public / proxy URL) to look at your overview page. Almost everything is clickable!
-
-
-
-
-
diff --git a/maloja/web/setup.py b/maloja/web/setup.py
deleted file mode 100644
index 596a3c1..0000000
--- a/maloja/web/setup.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import os
-from ..globalconf import datadir
-
-def instructions(keys):
-
- html = "
"
-
- html += "
Module
Author
Description
"
-
-
- validchars = "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- for f in os.listdir(datadir("rules/predefined")):
- if f.endswith(".tsv"):
-
- rawf = f.replace(".tsv","")
- valid = True
- for char in rawf:
- if char not in validchars:
- valid = False
- break # don't even show up invalid filenames
-
- if not valid: continue
- if not "_" in rawf: continue
-
- try:
- with open(datadir("rules/predefined",f)) as tsvfile:
- line1 = tsvfile.readline()
- line2 = tsvfile.readline()
-
- if "# NAME: " in line1:
- name = line1.replace("# NAME: ","")
- else: name = rawf.split("_")[1]
- if "# DESC: " in line2:
- desc = line2.replace("# DESC: ","")
- else: desc = ""
-
- author = rawf.split("_")[0]
- except:
- continue
-
- html += "
"
-
- if os.path.exists(datadir("rules",f)):
- html += "
"
-
-
- pushresources = []
- replace = {"KEY_PREDEFINED_RULESETS":html}
- return (replace,pushresources)
From b5b09c405232dc20d1777cbe2deb0afba3dcd668 Mon Sep 17 00:00:00 2001
From: Krateng
Date: Wed, 29 Jul 2020 20:11:51 +0200
Subject: [PATCH 05/14] Updated some methods to new authentication method
---
maloja/database.py | 105 +++++++++++++++++++---------------
maloja/static/js/upload.js | 4 +-
maloja/web/jinja/artist.jinja | 2 +-
maloja/web/jinja/setup.jinja | 2 +-
maloja/web/jinja/track.jinja | 2 +-
5 files changed, 63 insertions(+), 52 deletions(-)
diff --git a/maloja/database.py b/maloja/database.py
index c3dec71..e1e90d2 100644
--- a/maloja/database.py
+++ b/maloja/database.py
@@ -18,6 +18,7 @@ from doreah.logging import log
from doreah import tsv
from doreah import settings
from doreah.caching import Cache, DeepCache
+from doreah.auth import authenticated_api, authenticated_api_with_alternate
try:
from doreah.persistence import DiskDict
except: pass
@@ -240,6 +241,23 @@ def normalize_name(name):
########
########
+# skip regular authentication if api key is present in request
+# an api key now ONLY permits scrobbling tracks, no other admin tasks
+def api_key_correct(request):
+ args = request.query
+ print(dict(args))
+ if "key" in args:
+ apikey = args["key"]
+ print(args)
+ del args["key"]
+ print(args)
+ elif "apikey" in args:
+ apikey = args["apikey"]
+ del args["apikey"]
+ else: return False
+
+ return checkAPIkey(apikey)
+
dbserver = API(delay=True,path="api")
@@ -669,23 +687,19 @@ def trackInfo(track):
@dbserver.get("newscrobble")
@dbserver.post("newscrobble")
+@authenticated_api_with_alternate(api_key_correct)
def post_scrobble(artist:Multi,**keys):
artists = "/".join(artist)
title = keys.get("title")
album = keys.get("album")
duration = keys.get("seconds")
- apikey = keys.get("key")
- client = checkAPIkey(apikey)
- if client == False: # empty string allowed!
- response.status = 403
- return ""
try:
time = int(keys.get("time"))
except:
time = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp())
- log("Incoming scrobble (native API): Client " + client + ", ARTISTS: " + str(artists) + ", TRACK: " + title,module="debug")
+ log("Incoming scrobble (native API): ARTISTS: " + str(artists) + ", TRACK: " + title,module="debug")
(artists,title) = cla.fullclean(artists,title)
## this is necessary for localhost testing
@@ -719,18 +733,18 @@ def sapi(path:Multi,**keys):
@dbserver.get("sync")
+@authenticated_api
def abouttoshutdown():
sync()
#sys.exit()
@dbserver.post("newrule")
+@authenticated_api
def newrule(**keys):
- apikey = keys.pop("key",None)
- if (checkAPIkey(apikey)):
- tsv.add_entry(datadir("rules/webmade.tsv"),[k for k in keys])
- #addEntry("rules/webmade.tsv",[k for k in keys])
- global db_rulestate
- db_rulestate = False
+ tsv.add_entry(datadir("rules/webmade.tsv"),[k for k in keys])
+ #addEntry("rules/webmade.tsv",[k for k in keys])
+ global db_rulestate
+ db_rulestate = False
@dbserver.get("issues")
@@ -877,39 +891,36 @@ def get_predefined_rulesets():
return rulesets
@dbserver.post("importrules")
+@authenticated_api
def import_rulemodule(**keys):
- apikey = keys.pop("key",None)
+ filename = keys.get("filename")
+ remove = keys.get("remove") is not None
+ validchars = "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ filename = "".join(c for c in filename if c in validchars)
- if (checkAPIkey(apikey)):
- filename = keys.get("filename")
- remove = keys.get("remove") is not None
- validchars = "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- filename = "".join(c for c in filename if c in validchars)
-
- if remove:
- log("Deactivating predefined rulefile " + filename)
- os.remove(datadir("rules/" + filename + ".tsv"))
- else:
- log("Importing predefined rulefile " + filename)
- os.symlink(datadir("rules/predefined/" + filename + ".tsv"),datadir("rules/" + filename + ".tsv"))
+ if remove:
+ log("Deactivating predefined rulefile " + filename)
+ os.remove(datadir("rules/" + filename + ".tsv"))
+ else:
+ log("Importing predefined rulefile " + filename)
+ os.symlink(datadir("rules/predefined/" + filename + ".tsv"),datadir("rules/" + filename + ".tsv"))
@dbserver.post("rebuild")
+@authenticated_api
def rebuild(**keys):
- apikey = keys.pop("key",None)
- if (checkAPIkey(apikey)):
- log("Database rebuild initiated!")
- global db_rulestate
- db_rulestate = False
- sync()
- from .proccontrol.tasks.fixexisting import fix
- fix()
- global cla, coa
- cla = CleanerAgent()
- coa = CollectorAgent()
- build_db()
- invalidate_caches()
+ log("Database rebuild initiated!")
+ global db_rulestate
+ db_rulestate = False
+ sync()
+ from .proccontrol.tasks.fixexisting import fix
+ fix()
+ global cla, coa
+ cla = CleanerAgent()
+ coa = CollectorAgent()
+ build_db()
+ invalidate_caches()
@@ -950,15 +961,15 @@ def search(**keys):
@dbserver.post("addpicture")
-def add_picture(b64,key,artist:Multi=[],title=None):
- if (checkAPIkey(key)):
- keys = FormsDict()
- for a in artist:
- keys.append("artist",a)
- if title is not None: keys.append("title",title)
- k_filter, _, _, _ = uri_to_internal(keys)
- if "track" in k_filter: k_filter = k_filter["track"]
- utilities.set_image(b64,**k_filter)
+@authenticated_api
+def add_picture(b64,artist:Multi=[],title=None):
+ keys = FormsDict()
+ for a in artist:
+ keys.append("artist",a)
+ if title is not None: keys.append("title",title)
+ k_filter, _, _, _ = uri_to_internal(keys)
+ if "track" in k_filter: k_filter = k_filter["track"]
+ utilities.set_image(b64,**k_filter)
####
## Server operation
diff --git a/maloja/static/js/upload.js b/maloja/static/js/upload.js
index 103ea12..797543a 100644
--- a/maloja/static/js/upload.js
+++ b/maloja/static/js/upload.js
@@ -1,3 +1,3 @@
-function upload(encodedentity,apikey,b64) {
- neo.xhttprequest("/api/addpicture?key=" + apikey + "&" + encodedentity,{"b64":b64},"POST")
+function upload(encodedentity,b64) {
+ neo.xhttprequest("/api/addpicture?" + encodedentity,{"b64":b64},"POST")
}
diff --git a/maloja/web/jinja/artist.jinja b/maloja/web/jinja/artist.jinja
index acc6cad..99b030a 100644
--- a/maloja/web/jinja/artist.jinja
+++ b/maloja/web/jinja/artist.jinja
@@ -36,7 +36,7 @@
{% if adminmode %}
{% else %}
diff --git a/maloja/web/jinja/setup.jinja b/maloja/web/jinja/setup.jinja
index 5fd88fe..0b93561 100644
--- a/maloja/web/jinja/setup.jinja
+++ b/maloja/web/jinja/setup.jinja
@@ -99,7 +99,7 @@
After you've scrobbled for a bit, you might want to check the Issues page to see if you need to set up some rules. You can also manually add rules in your server's "rules" directory - just add your own .tsv file and read the instructions on how to declare a rule.
- You can also set up some predefined rulesets right away! Enter your API key and click the buttons.
+ You can also set up some predefined rulesets right away!
-
-
-{% endblock %}
From a88afe40ec5068b849141dee274543aed049a0bc Mon Sep 17 00:00:00 2001
From: Krateng
Date: Sun, 16 Aug 2020 20:08:17 +0200
Subject: [PATCH 09/14] Added ability to quickly prefill manual scrobble form
with last scrobble
---
maloja/proccontrol/control.py | 2 +-
maloja/static/js/manualscrobble.js | 66 ++++++++++++++++++++---------
maloja/web/jinja/admin_manual.jinja | 1 +
3 files changed, 48 insertions(+), 21 deletions(-)
diff --git a/maloja/proccontrol/control.py b/maloja/proccontrol/control.py
index d0cf53e..12c4342 100644
--- a/maloja/proccontrol/control.py
+++ b/maloja/proccontrol/control.py
@@ -43,7 +43,7 @@ def start():
print("Visit your server address (Port " + str(port) + ") to see your web interface. Visit /setup to get started.")
print("If you're installing this on your local machine, these links should get you there:")
print("\t" + col["blue"]("http://localhost:" + str(port)))
- print("\t" + col["blue"]("http://localhost:" + str(port) + "/setup"))
+ print("\t" + col["blue"]("http://localhost:" + str(port) + "/admin_setup"))
return True
except:
print("Error while starting Maloja.")
diff --git a/maloja/static/js/manualscrobble.js b/maloja/static/js/manualscrobble.js
index 8b24c30..03ce272 100644
--- a/maloja/static/js/manualscrobble.js
+++ b/maloja/static/js/manualscrobble.js
@@ -1,30 +1,47 @@
+var lastArtists = []
+var lastTrack = ""
+
+
+function addArtist(artist) {
+ var newartistfield = document.getElementById("artists");
+ var artistelement = document.createElement("span");
+ artistelement.innerHTML = artist;
+ artistelement.style = "padding:5px;";
+ document.getElementById("artists_td").insertBefore(artistelement,newartistfield);
+ newartistfield.placeholder = "Backspace to remove last"
+}
+
function keyDetect(event) {
- if (event.key === "Enter" || event.key === "Tab") { addArtist() }
+ if (event.key === "Enter" || event.key === "Tab") { addEnteredArtist() }
if (event.key === "Backspace" && document.getElementById("artists").value == "") { removeArtist() }
}
-function addArtist() {
- element = document.getElementById("artists");
- newartist = element.value.trim();
- element.value = "";
+function addEnteredArtist() {
+ var newartistfield = document.getElementById("artists");
+ var newartist = newartistfield.value.trim();
+ newartistfield.value = "";
if (newartist != "") {
- artist = document.createElement("span");
- artist.innerHTML = newartist;
- artist.style = "padding:5px;";
- document.getElementById("artists_td").insertBefore(artist,element);
-
- element.placeholder = "Backspace to remove last"
+ addArtist(newartist);
}
}
function removeArtist() {
- artists = document.getElementById("artists_td").getElementsByTagName("span")
- lastartist = artists[artists.length-1]
+ var artists = document.getElementById("artists_td").getElementsByTagName("span")
+ var lastartist = artists[artists.length-1]
document.getElementById("artists_td").removeChild(lastartist);
if (artists.length < 1) {
document.getElementById("artists").placeholder = "Separate with Enter"
}
}
+function clear() {
+ document.getElementById("title").value = "";
+ document.getElementById("artists").value = "";
+ var artists = document.getElementById("artists_td").getElementsByTagName("span")
+ while (artists.length > 0) {
+ removeArtist();
+ }
+}
+
function scrobbleIfEnter(event) {
if (event.key === "Enter") {
@@ -33,19 +50,22 @@ function scrobbleIfEnter(event) {
}
function scrobbleNew() {
- artistnodes = document.getElementById("artists_td").getElementsByTagName("span");
- artists = [];
+ var artistnodes = document.getElementById("artists_td").getElementsByTagName("span");
+ var artists = [];
for (let node of artistnodes) {
artists.push(node.innerHTML);
}
- title = document.getElementById("title").value;
+ var title = document.getElementById("title").value;
scrobble(artists,title);
}
function scrobble(artists,title) {
+ lastArtists = artists;
+ lastTrack = title;
- artist = artists.join(";");
+
+ var artist = artists.join(";");
if (title != "" && artists.length > 0) {
xhttp = new XMLHttpRequest();
@@ -57,8 +77,7 @@ function scrobble(artists,title) {
document.getElementById("title").value = "";
document.getElementById("artists").value = "";
- parent = document.getElementById("artists_td");
- artists = document.getElementById("artists_td").getElementsByTagName("span")
+ var artists = document.getElementById("artists_td").getElementsByTagName("span");
while (artists.length > 0) {
removeArtist();
}
@@ -76,6 +95,13 @@ function scrobbledone() {
}
+function repeatLast() {
+ clear();
+ for (let artist of lastArtists) {
+ addArtist(artist);
+ }
+ document.getElementById("title").value = lastTrack;
+}
@@ -84,7 +110,7 @@ function scrobbledone() {
///
function search_manualscrobbling(searchfield) {
- txt = searchfield.value;
+ var txt = searchfield.value;
if (txt == "") {
}
diff --git a/maloja/web/jinja/admin_manual.jinja b/maloja/web/jinja/admin_manual.jinja
index 6c9a6f5..5f55c60 100644
--- a/maloja/web/jinja/admin_manual.jinja
+++ b/maloja/web/jinja/admin_manual.jinja
@@ -31,6 +31,7 @@
Scrobble!
+ Last Manual Scrobble
From 9a1bc8be03489d5f7e1042998979b473b271bb7a Mon Sep 17 00:00:00 2001
From: Krateng
Date: Mon, 17 Aug 2020 17:14:38 +0200
Subject: [PATCH 10/14] Fixed error page
---
maloja/server.py | 83 +++++++++++++++--------------
maloja/web/jinja/error.jinja | 18 +++++++
maloja/web/pyhp/errors/generic.pyhp | 28 ----------
3 files changed, 60 insertions(+), 69 deletions(-)
create mode 100644 maloja/web/jinja/error.jinja
delete mode 100644 maloja/web/pyhp/errors/generic.pyhp
diff --git a/maloja/server.py b/maloja/server.py
index e00ab47..d8707a8 100755
--- a/maloja/server.py
+++ b/maloja/server.py
@@ -4,7 +4,7 @@ from .globalconf import datadir, DATA_DIR
# server stuff
-from bottle import Bottle, route, get, post, error, run, template, static_file, request, response, FormsDict, redirect, template, HTTPResponse, BaseRequest
+from bottle import Bottle, route, get, post, error, run, template, static_file, request, response, FormsDict, redirect, template, HTTPResponse, BaseRequest, abort
import waitress
# templating
from jinja2 import Environment, PackageLoader, select_autoescape
@@ -94,10 +94,9 @@ def mainpage():
def customerror(error):
code = int(str(error).split(",")[0][1:])
- if os.path.exists(pthjoin(WEBFOLDER,"errors",str(code) + ".pyhp")):
- return pyhpfile(pthjoin(WEBFOLDER,"errors",str(code) + ".pyhp"),{"errorcode":code})
- else:
- return pyhpfile(pthjoin(WEBFOLDER,"errors","generic.pyhp"),{"errorcode":code})
+ template = jinjaenv.get_template('error.jinja')
+ res = template.render(errorcode=code)
+ return res
@@ -222,7 +221,7 @@ jinjaenv = Environment(
jinjaenv.globals.update(JINJA_CONTEXT)
-@webserver.route("/")
+@webserver.route("/")
@auth.authenticated
def static_html_private(name):
return static_html(name)
@@ -291,48 +290,50 @@ def static_html(name):
# if not, use the old way
else:
+ try:
+ with open(pthjoin(WEBFOLDER,name + ".html")) as htmlfile:
+ html = htmlfile.read()
- with open(pthjoin(WEBFOLDER,name + ".html")) as htmlfile:
- html = htmlfile.read()
-
- # apply global substitutions
- with open(pthjoin(WEBFOLDER,"common/footer.html")) as footerfile:
- footerhtml = footerfile.read()
- with open(pthjoin(WEBFOLDER,"common/header.html")) as headerfile:
- headerhtml = headerfile.read()
- html = html.replace("
-
-
-
-
-
-
-
Error
-
-
-
That did not work. Don't ask me why.
-
-
-
-
-
-
",footerhtml + "").replace("",headerhtml + "")
+ # apply global substitutions
+ with open(pthjoin(WEBFOLDER,"common/footer.html")) as footerfile:
+ footerhtml = footerfile.read()
+ with open(pthjoin(WEBFOLDER,"common/header.html")) as headerfile:
+ headerhtml = headerfile.read()
+ html = html.replace("",footerhtml + "").replace("",headerhtml + "")
- # If a python file exists, it provides the replacement dict for the html file
- if os.path.exists(pthjoin(WEBFOLDER,name + ".py")):
- #txt_keys = SourceFileLoader(name,"web/" + name + ".py").load_module().replacedict(keys,DATABASE_PORT)
- try:
- module = importlib.import_module(".web." + name,package="maloja")
- txt_keys,resources = module.instructions(keys)
- except Exception as e:
- log("Error in website generation: " + str(sys.exc_info()),module="error")
- raise
+ # If a python file exists, it provides the replacement dict for the html file
+ if os.path.exists(pthjoin(WEBFOLDER,name + ".py")):
+ #txt_keys = SourceFileLoader(name,"web/" + name + ".py").load_module().replacedict(keys,DATABASE_PORT)
+ try:
+ module = importlib.import_module(".web." + name,package="maloja")
+ txt_keys,resources = module.instructions(keys)
+ except Exception as e:
+ log("Error in website generation: " + str(sys.exc_info()),module="error")
+ raise
- # add headers for server push
- for resource in resources:
- if all(ord(c) < 128 for c in resource["file"]):
- # we can only put ascii stuff in the http header
- linkheaders.append("<" + resource["file"] + ">; rel=preload; as=" + resource["type"])
+ # add headers for server push
+ for resource in resources:
+ if all(ord(c) < 128 for c in resource["file"]):
+ # we can only put ascii stuff in the http header
+ linkheaders.append("<" + resource["file"] + ">; rel=preload; as=" + resource["type"])
- # apply key substitutions
- for k in txt_keys:
- if isinstance(txt_keys[k],list):
- # if list, we replace each occurence with the next item
- for element in txt_keys[k]:
- html = html.replace(k,element,1)
- else:
- html = html.replace(k,txt_keys[k])
+ # apply key substitutions
+ for k in txt_keys:
+ if isinstance(txt_keys[k],list):
+ # if list, we replace each occurence with the next item
+ for element in txt_keys[k]:
+ html = html.replace(k,element,1)
+ else:
+ html = html.replace(k,txt_keys[k])
- response.set_header("Link",",".join(linkheaders))
- log("Generated page {name} in {time:.5f}s (Python+HTML)".format(name=name,time=clock.stop()),module="debug")
- return html
- #return static_file("web/" + name + ".html",root="")
+ response.set_header("Link",",".join(linkheaders))
+ log("Generated page {name} in {time:.5f}s (Python+HTML)".format(name=name,time=clock.stop()),module="debug")
+ return html
+
+ except:
+ abort(404, "Page does not exist")
# Shortlinks
diff --git a/maloja/web/jinja/error.jinja b/maloja/web/jinja/error.jinja
new file mode 100644
index 0000000..5ce08a2
--- /dev/null
+++ b/maloja/web/jinja/error.jinja
@@ -0,0 +1,18 @@
+{% extends "admin.jinja" %}
+
+{% block content %}
+