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

Modularized Javascript

This commit is contained in:
Krateng 2019-03-24 16:04:44 +01:00
parent 3f22d6bc75
commit 011b6f6d91
7 changed files with 203 additions and 167 deletions

View File

@ -670,17 +670,20 @@ def issues():
@dbserver.post("/importrules")
def import_rulemodule():
keys = FormsDict.decode(request.forms)
filename = keys.get("filename")
remove = keys.get("remove") is not None
validchars = "'-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
filename = "".join(c for c in filename if c in validchars)
apikey = keys.pop("key",None)
if remove:
log("Deactivating predefined rulefile " + filename)
os.remove("rules/" + filename + ".tsv")
else:
log("Importing predefined rulefile " + filename)
os.symlink("predefined/" + filename + ".tsv","rules/" + filename + ".tsv")
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("rules/" + filename + ".tsv")
else:
log("Importing predefined rulefile " + filename)
os.symlink("predefined/" + filename + ".tsv","rules/" + filename + ".tsv")

View File

@ -1,86 +1,3 @@
<meta name="description" content='Maloja is a self-hosted music scrobble server.' />
<link rel="stylesheet" href="maloja.css" />
<script>
function search(searchfield) {
txt = searchfield.value;
if (txt == "") {
reallyclear()
}
else {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = searchresult
xhttp.open("GET","/db/search?max=5&query=" + encodeURIComponent(txt), true);
xhttp.send();
}
}
function searchresult() {
if (this.readyState == 4 && this.status == 200 && document.getElementById("searchinput").value != "") {
// checking if field is empty in case we get an old result coming in that would overwrite our cleared result window
result = JSON.parse(this.responseText);
artists = result["artists"].slice(0,5)
tracks = result["tracks"].slice(0,5)
html = `<div class="searchresults">
<span>Artists</span>
<table class="searchresults_artists">`
for (var i=0;i<artists.length;i++) {
name = artists[i];
uristr = "artist=" + encodeURIComponent(name);
uristr = uristr.replace("'","\\'");
image = "/image?" + uristr;
link = "/artist?" + uristr;
html += `<tr onclick="goto('` + link + `')">
<td class="image" style="background-image:url('` + image + `');"></td>
<td>
<span>` + name + `</span><br/>
</td>
</tr>`
}
html += `</table>
<br/><br/>
<span>Tracks</span>
<table class="searchresults_tracks">`
for (var i=0;i<tracks.length;i++) {
artists = tracks[i]["artists"].join(", ");
title = tracks[i]["title"];
uristr = "title=" + encodeURIComponent(title) + "&" + tracks[i]["artists"].map(x => "artist=" + encodeURIComponent(x)).join("&");
uristr = uristr.replace("'","\\'");
image = "/image?" + uristr;
link = "/track?" + uristr;
html += `<tr onclick="goto('` + link + `')">
<td class="image" style="background-image:url('` + image + `');"></td>
<td>
<span>` + artists + `</span><br/>
<span>` + title + `</span>
</td>
</tr>`
}
html += `</table>
</div>`
document.getElementById("resultwrap").innerHTML = html;
}
}
function clearresults() {
window.setTimeout(reallyclear,500)
}
function reallyclear() {
document.getElementById("resultwrap").innerHTML = "";
}
function goto(link) {
window.location = link
}
</script>
<script src="javascript/search.js"></script>

View File

@ -4,17 +4,18 @@
<head>
<meta charset="UTF-8" />
<title>Maloja - Issues</title>
<script src="javascript/cookies.js"></script>
</head>
<body>
<body onload="insertAPIKeyFromCookie()">
<table class="top_info">
<tr>
<td class="text">
<h1>Possible Issues</h1><br/>
<span>with your library</span>
<p class="stats">KEY_ISSUES Issues</p>
<p>Maloja can identify possible problems with consistency or redundancy in your library. After making any changes, you should <a class="textlink" onclick='fullrebuild()'>rebuild your library</a>.<br/>
Your API key is required to make any changes to the server: <input id='apikey' onchange='checkAPIkey()' style='width:300px;'/></p>
</td>
@ -22,21 +23,12 @@
</table>
KEY_ISSUESLIST
</body>
<script>
cookies = decodeURIComponent(document.cookie).split(';');
for(var i = 0; i <cookies.length; i++) {
if (cookies[i].startsWith("apikey=")) {
document.getElementById("apikey").value = cookies[i].replace("apikey=","")
checkAPIkey()
}
}
apikeycorrect = false;
function newrule() {
if (apikeycorrect) {
keys = ""
@ -46,8 +38,8 @@
apikey = document.getElementById("apikey").value
keys += "key=" + encodeURIComponent(apikey)
console.log(keys)
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/newrule?", true);
xhttp.send(keys);
@ -56,47 +48,19 @@
line.parentNode.removeChild(line)
}
}
function fullrebuild() {
if (apikeycorrect) {
apikey = document.getElementById("apikey").value
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/rebuild", true);
xhttp.send("key=" + encodeURIComponent(apikey))
window.location = "/wait";
window.location = "/wait";
}
}
function saveAPIkey() {
key = document.getElementById("apikey").value
document.cookie = "apikey=" + encodeURIComponent(key)
}
function checkAPIkey() {
saveAPIkey()
url = "/db/test?key=" + document.getElementById("apikey").value
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && (this.status == 204 || this.status == 205)) {
document.getElementById("apikey").style.backgroundColor = "lawngreen"
apikeycorrect = true
}
else {
document.getElementById("apikey").style.backgroundColor = "red"
apikeycorrect = false
}
};
try {
xhttp.open("GET",url,true);
xhttp.send();
}
catch (e) {
document.getElementById("apikey").style.backgroundColor = "red"
apikeycorrect = false
}
}
</script>
</html>

View File

@ -0,0 +1,44 @@
apikeycorrect = false;
function insertAPIKeyFromCookie() {
cookies = decodeURIComponent(document.cookie).split(';');
for(var i = 0; i <cookies.length; i++) {
cookies[i] = cookies[i].trim()
if (cookies[i].startsWith("apikey=")) {
document.getElementById("apikey").value = cookies[i].replace("apikey=","")
checkAPIkey()
}
}
}
function saveAPIkey() {
key = document.getElementById("apikey").value
document.cookie = "apikey=" + encodeURIComponent(key)
}
function checkAPIkey() {
saveAPIkey()
url = "/db/test?key=" + document.getElementById("apikey").value
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && (this.status == 204 || this.status == 205)) {
document.getElementById("apikey").style.backgroundColor = "lawngreen"
apikeycorrect = true
}
else {
document.getElementById("apikey").style.backgroundColor = "red"
apikeycorrect = false
}
};
try {
xhttp.open("GET",url,true);
xhttp.send();
}
catch (e) {
document.getElementById("apikey").style.backgroundColor = "red"
apikeycorrect = false
}
}

View File

@ -0,0 +1,79 @@
function search(searchfield) {
txt = searchfield.value;
if (txt == "") {
reallyclear()
}
else {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = searchresult
xhttp.open("GET","/db/search?max=5&query=" + encodeURIComponent(txt), true);
xhttp.send();
}
}
function searchresult() {
if (this.readyState == 4 && this.status == 200 && document.getElementById("searchinput").value != "") {
// checking if field is empty in case we get an old result coming in that would overwrite our cleared result window
result = JSON.parse(this.responseText);
artists = result["artists"].slice(0,5)
tracks = result["tracks"].slice(0,5)
html = `<div class="searchresults">
<span>Artists</span>
<table class="searchresults_artists">`
for (var i=0;i<artists.length;i++) {
name = artists[i];
uristr = "artist=" + encodeURIComponent(name);
uristr = uristr.replace("'","\\'");
image = "/image?" + uristr;
link = "/artist?" + uristr;
html += `<tr onclick="goto('` + link + `')">
<td class="image" style="background-image:url('` + image + `');"></td>
<td>
<span>` + name + `</span><br/>
</td>
</tr>`
}
html += `</table>
<br/><br/>
<span>Tracks</span>
<table class="searchresults_tracks">`
for (var i=0;i<tracks.length;i++) {
artists = tracks[i]["artists"].join(", ");
title = tracks[i]["title"];
uristr = "title=" + encodeURIComponent(title) + "&" + tracks[i]["artists"].map(x => "artist=" + encodeURIComponent(x)).join("&");
uristr = uristr.replace("'","\\'");
image = "/image?" + uristr;
link = "/track?" + uristr;
html += `<tr onclick="goto('` + link + `')">
<td class="image" style="background-image:url('` + image + `');"></td>
<td>
<span>` + artists + `</span><br/>
<span>` + title + `</span>
</td>
</tr>`
}
html += `</table>
</div>`
document.getElementById("resultwrap").innerHTML = html;
}
}
function clearresults() {
window.setTimeout(reallyclear,500)
}
function reallyclear() {
document.getElementById("resultwrap").innerHTML = "";
}
function goto(link) {
window.location = link
}

View File

@ -4,8 +4,11 @@
<head>
<meta charset="UTF-8" />
<title>Maloja - Setup</title>
<script src="javascript/cookies.js"></script>
<script>
function replaceurls() {
url = window.location.origin
s = document.getElementsByName("serverurl")
@ -20,26 +23,34 @@
}
function activateRuleModule(e,filename) {
keys = "filename=" + encodeURIComponent(filename)
if (apikeycorrect) {
keys = "filename=" + encodeURIComponent(filename)
apikey = document.getElementById("apikey").value
keys += "&key=" + encodeURIComponent(apikey)
console.log(keys)
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/importrules", true);
xhttp.send(keys);
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/importrules", true);
xhttp.send(keys);
e.innerHTML = e.innerHTML.replace("Add","Remove")
e.getAttributeNode("onclick").value = e.getAttribute("onclick").replace("activate","deactivate")
/* Nobody ever look at this code please */
e.innerHTML = e.innerHTML.replace("Add","Remove")
e.getAttributeNode("onclick").value = e.getAttribute("onclick").replace("activate","deactivate")
/* Nobody ever look at this code please */
}
}
function deactivateRuleModule(e,filename) {
keys = "remove&filename=" + encodeURIComponent(filename)
if (apikeycorrect) {
keys = "remove&filename=" + encodeURIComponent(filename)
apikey = document.getElementById("apikey").value
keys += "&key=" + encodeURIComponent(apikey)
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/importrules", true);
xhttp.send(keys);
var xhttp = new XMLHttpRequest();
xhttp.open("POST","/db/importrules", true);
xhttp.send(keys);
e.innerHTML = e.innerHTML.replace("Remove","Add")
e.getAttributeNode("onclick").value = e.getAttribute("onclick").replace("deactivate","activate")
e.innerHTML = e.innerHTML.replace("Remove","Add")
e.getAttributeNode("onclick").value = e.getAttribute("onclick").replace("deactivate","activate")
}
}
</script>
@ -53,7 +64,7 @@
</head>
<body onload="replace()">
<body onload="replace();insertAPIKeyFromCookie()">
<table class="top_info">
<tr>
<td class="image">
@ -99,7 +110,11 @@
After you've scrobbled for a bit, you might want to check the <a class="textlink" href="/issues">Issues page</a> 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.
<br/><br/>
You can also set up some predefined rulesets right away!
You can also set up some predefined rulesets right away! Enter your API key and click the buttons.
<br/>
API Key:
<input id='apikey' onchange='checkAPIkey()' style='width:300px;'/>
<br/><br/>
KEY_PREDEFINED_RULESETS
@ -117,4 +132,6 @@
Done! Visit <a class="textlink" href="/"><span name="serverurl">yourserver.tld</span></a> (or your public / proxy URL) to look at your overview page. Almost everything is clickable!
</body>
</html>

View File

@ -6,9 +6,21 @@ def instructions(keys):
html += "<tr><th></th><th>Module</th><th>Author</th><th>Description</th></tr>"
validchars = "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for f in os.listdir("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("rules/predefined/" + f) as tsvfile:
line1 = tsvfile.readline()
@ -16,21 +28,21 @@ def instructions(keys):
if "# NAME: " in line1:
name = line1.replace("# NAME: ","")
else: name = f
else: name = rawf.split("_")[1]
if "# DESC: " in line2:
desc = line2.replace("# DESC: ","")
else: desc = ""
author = f.split("_")[0]
author = rawf.split("_")[0]
except:
continue
html += "<tr>"
if os.path.exists("rules/" + f):
html += "<td class='interaction' onclick=deactivateRuleModule(this,'" + f.replace(".tsv","") + "')><a class='textlink'>Remove:</a></td>"
html += "<td class='interaction' onclick=deactivateRuleModule(this,'" + rawf + "')><a class='textlink'>Remove:</a></td>"
else:
html += "<td class='interaction' onclick=activateRuleModule(this,'" + f.replace(".tsv","") + "')><a class='textlink'>Add:</a></td>"
html += "<td class='interaction' onclick=activateRuleModule(this,'" + rawf + "')><a class='textlink'>Add:</a></td>"
html += "<td>" + name + "</td>"
html += "<td>" + author + "</td>"
html += "<td>" + desc + "</td>"