383 lines
19 KiB
HTML
Executable File
383 lines
19 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<link rel="icon"href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🖥️</text></svg>">
|
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
|
<meta content="utf-8" http-equiv="encoding" />
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
|
<meta http-equiv="Pragma" content="no-cache" />
|
|
<meta http-equiv="Expires" content="0" />
|
|
<link rel="stylesheet" href="server.css" />
|
|
<title>Compare</title>
|
|
<h1 id="title_h1" class="confply">Compare</h1>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="description_div" class="logbox"></div>
|
|
<div id="form_div" style='background-color: #fafafa; padding: 5px; width: 100%;'></div>
|
|
<div id="run_buttons" class="run_buttons_div"></div>
|
|
<div id="logs" class="logbox">waiting for logs...</div>
|
|
<span style="display: block; margin-top: 5px;" />
|
|
<details style="padding: 5px;" class="logbox">
|
|
<summary>debug</summary>
|
|
<div id="debug_div"></div>
|
|
</details>
|
|
<script>
|
|
// #todo: try to modularise parts of this
|
|
// #todo: httpget add failure handling
|
|
var currentrun = null;
|
|
var running_button = null;
|
|
var run_queue = [];
|
|
var debug_div = document.getElementById("debug_div");
|
|
var form_json = null;
|
|
var cmds_json = null;
|
|
var details_open = false;
|
|
function debug_log(message) {
|
|
if (debug_div !== null) {
|
|
debug_div.innerHTML += message + "<br>";
|
|
}
|
|
};
|
|
debug_log("debug information will be logged here.");
|
|
function httpGet(theUrl, callback) {
|
|
debug_log("GET " + theUrl);
|
|
var xmlHttp = new XMLHttpRequest();
|
|
xmlHttp.onreadystatechange = function () {
|
|
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
|
|
debug_log("GET " + theUrl + " response:");
|
|
try {
|
|
var holder = JSON.parse(xmlHttp.responseText);
|
|
var debug_str = "<details><summary>json</summary>" + JSON.stringify(holder, null, 2) + "</details>";
|
|
debug_log(debug_str);
|
|
}
|
|
catch (err) { debug_log("response not json parsable"); }
|
|
callback(xmlHttp.responseText);
|
|
}
|
|
}
|
|
xmlHttp.open("GET", theUrl, true); // true for asynchronous
|
|
xmlHttp.send(null);
|
|
};
|
|
function httpPost(theUrl, data, callback) {
|
|
debug_log("POST " + theUrl);
|
|
debug_log(data);
|
|
var xmlHttp = new XMLHttpRequest();
|
|
xmlHttp.onreadystatechange = function () {
|
|
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
|
|
debug_log("POST " + theUrl + " response:");
|
|
try {
|
|
var holder = JSON.parse(xmlHttp.responseText);
|
|
var debug_str = "<details><summary>json</summary>" + JSON.stringify(holder, null, 2) + "</details>";
|
|
debug_log(debug_str);
|
|
}
|
|
catch (err) { debug_log("response not json parsable"); }
|
|
callback(xmlHttp.responseText);
|
|
}
|
|
}
|
|
xmlHttp.open("POST", theUrl, true); // true for asynchronous
|
|
xmlHttp.send(data);
|
|
};
|
|
function get_arguments()
|
|
{
|
|
var arguments_form = document.getElementById("arguments_form");
|
|
var form_data = {};
|
|
// create json parsable dictionary from form
|
|
for (var form of [arguments_form]) {
|
|
var dict = {}
|
|
for (var [k, v] of new FormData(form)) {
|
|
v = v.replace(/[\u2018\u2019]/g, "'");
|
|
v = v.replace(/[\u201C\u201D]/g, '"');
|
|
v = v.replace(/[\u2013\u2014]/g, '-');
|
|
v = v.replace(/[\u2026]/g, '...');
|
|
if (k in dict) {
|
|
if (Array.isArray(dict[k])) { dict[k].push(v); }
|
|
else { dict[k] = [dict[k], v]; }
|
|
}
|
|
else {
|
|
try { dict[k] = JSON.parse(v); }
|
|
catch (err) { dict[k] = v; }
|
|
}
|
|
};
|
|
form_data = dict;
|
|
}
|
|
function sanatise_fields(form_dict, conf_dict) {
|
|
for (var [k, v] of Object.entries(conf_dict)) {
|
|
if (k.startsWith("__")) { continue; }
|
|
if (!(k in form_dict) || !form_dict[k]) {
|
|
if (typeof (v) === "boolean")
|
|
form_dict[k] = false;
|
|
else if (Array.isArray(v))
|
|
form_dict[k] = [];
|
|
else if (v.constructor == Object)
|
|
form_dict[k] = {};
|
|
}
|
|
else if (typeof (v) === "boolean" && form_dict[k] === "on") {
|
|
form_dict[k] = true;
|
|
}
|
|
}
|
|
};
|
|
sanatise_fields(form_data, form_json);
|
|
form_data = {
|
|
...form_json,
|
|
...form_data
|
|
};
|
|
return form_data;
|
|
}
|
|
function submit_form(url)
|
|
{
|
|
button_id = "";
|
|
prefix = "";
|
|
if (url.includes("run")) { button_id = "form_run_button"; prefix = "Run"; }
|
|
else if (url.includes("save")) { button_id = "form_save_button"; prefix = "Save"; }
|
|
else if (url.includes("remove")) { button_id = "form_remove_button"; prefix = "Remove"; }
|
|
if(running_button == null)
|
|
{
|
|
form_data = get_arguments();
|
|
var file_out = form_data["file_out"];
|
|
currentrun = prefix+" "+file_out+" - " + new Date().toLocaleString();
|
|
running_button = document.getElementById(button_id);
|
|
running_button.setAttribute("class", "run_button running");
|
|
sessionStorage.setItem("form_json", JSON.stringify(form_data));
|
|
httpPost(url, JSON.stringify(form_data),
|
|
function(response)
|
|
{
|
|
run_complete(response);
|
|
response = JSON.parse(response);
|
|
if("cmds" in response)
|
|
{
|
|
cmds_json = response["cmds"];
|
|
create_buttons(cmds_json);
|
|
}
|
|
});
|
|
}
|
|
else
|
|
{
|
|
var index = run_queue.indexOf(["arguement_form", url]);
|
|
var button = document.getElementById(button_id);
|
|
if (index >= 0)
|
|
{
|
|
run_queue.splice(index, 1);
|
|
button.setAttribute("class", "run_button");
|
|
}
|
|
else {
|
|
button.setAttribute("class", "run_button queued");
|
|
run_queue.push(["arguement_form", url]);
|
|
}
|
|
}
|
|
};
|
|
function run_cmd(cmd)
|
|
{
|
|
if (running_button === null) {
|
|
populate_form(cmds_json[cmd]);
|
|
if (!details_open)
|
|
{
|
|
running_button = document.getElementById(cmd + "_button");
|
|
running_button.setAttribute("class", "run_button running");
|
|
currentrun = "Run " + cmd + " - " + new Date().toLocaleString();
|
|
httpPost("api/run.cmd", JSON.stringify({ "cmd": cmd }), run_complete)
|
|
}
|
|
else
|
|
{
|
|
button = document.getElementById(cmd + "_button");
|
|
button.setAttribute("class", "run_button highlight");
|
|
setTimeout(function(){
|
|
button.setAttribute("class", "run_button");
|
|
}, 300);
|
|
}
|
|
}
|
|
else if (running_button.id !== (cmd + "_button")) {
|
|
var index = run_queue.indexOf(cmd);
|
|
var button = document.getElementById(cmd + "_button");
|
|
if (index >= 0) {
|
|
run_queue.splice(index, 1);
|
|
button.setAttribute("class", "run_button");
|
|
}
|
|
else {
|
|
button.setAttribute("class", "run_button queued");
|
|
run_queue.push(cmd);
|
|
}
|
|
}
|
|
};
|
|
function run_complete(response) {
|
|
response = JSON.parse(response);
|
|
if (response["ok"]) {
|
|
if ("status" in response) {
|
|
if (response["status"] === "success") {
|
|
running_button.setAttribute("class", "run_button success end_running");
|
|
currentrun += "<span class='success' style='padding: 0 5px 0 5px; color: white; float:right;'>success</span>"
|
|
}
|
|
else {
|
|
running_button.setAttribute("class", "run_button failure end_running");
|
|
currentrun += "<span class='failure' style='padding: 0 5px 0 5px; color: white; float:right;'>failure</span>"
|
|
}
|
|
}
|
|
else {
|
|
running_button.setAttribute("class", "run_button end_running");
|
|
}
|
|
|
|
running_button = null;
|
|
var logs = document.getElementById("logs");
|
|
if (logs.innerHTML == "waiting for logs...") {
|
|
logs.setAttribute("class", "");
|
|
logs.innerHTML = "";
|
|
}
|
|
|
|
var details = document.createElement("details");
|
|
details.innerHTML = "<summary>" + currentrun + "</summary>" + response["log"];
|
|
details.setAttribute("class", "logbox");
|
|
var br = document.createElement("span");
|
|
br.setAttribute("style", "display: block; margin-top: 5px;");
|
|
logs.prepend(br);
|
|
logs.prepend(details);
|
|
if (run_queue.length > 0) {
|
|
var run = run_queue.shift();
|
|
|
|
if (typeof(run) == "object")
|
|
{
|
|
if(run[0] === "arguement_form")
|
|
{
|
|
submit_form(run[1]);
|
|
}
|
|
}
|
|
else if (typeof(run) == "string")
|
|
{
|
|
run_cmd(run);
|
|
}
|
|
}
|
|
for (var link in response["links"])
|
|
{
|
|
window.open(response["links"][link]);
|
|
}
|
|
}
|
|
};
|
|
|
|
function create_buttons(cmds)
|
|
{
|
|
var run_buttons = document.getElementById("run_buttons");
|
|
run_buttons.innerHTML = "";
|
|
for (var key in cmds)
|
|
{
|
|
var button = document.createElement("button");
|
|
button.setAttribute("onclick", "run_cmd('" + key + "')");
|
|
button.setAttribute("class", "run_button");
|
|
button.setAttribute("id", key + "_button");
|
|
button.setAttribute("tabindex", "0");
|
|
button.innerHTML = key;
|
|
run_buttons.appendChild(button);
|
|
}
|
|
}
|
|
function populate_form(dict)
|
|
{
|
|
for (var [k, v] of Object.entries(dict)) {
|
|
if (k.startsWith("__")) { continue; }
|
|
var elem = document.getElementById("id_"+k);
|
|
if (elem == null) { continue; }
|
|
else if (v == null) { elem.value = null; }
|
|
else if (typeof (v) === 'boolean') {
|
|
if (v)
|
|
elem.value = true;
|
|
else
|
|
elem.value = false;
|
|
}
|
|
else if (v.constructor == Object || Array.isArray(v))
|
|
{
|
|
elem.value = JSON.stringify(v);
|
|
}
|
|
else {
|
|
if (v == "None") { v = ""; }
|
|
elem.value = v;
|
|
}
|
|
}
|
|
}
|
|
function create_form(in_json, name, form_div = "form_div")
|
|
{
|
|
function dict_to_form(dict, name) {
|
|
var lines = [];
|
|
lines.push("<details id='"+name+"_details' style='padding: 5px; background-color:#fafafa;'><summary>" + name + " form</summary>");
|
|
lines.push("<form id='" + name + "_form'>");
|
|
for (var [k, v] of Object.entries(dict)) {
|
|
if (k.startsWith("__")) { continue; }
|
|
lines.push("<label for='id_" + k + "'>" + k + ":</label>");
|
|
|
|
if (typeof (v) === 'boolean') {
|
|
lines.push("<div class='autocomplete'>");
|
|
if (v)
|
|
lines.push("<input type='checkbox' id='id_" + k + "' name='" + k + "' checked />");
|
|
else
|
|
lines.push("<input type='checkbox' id='id_" + k + "' name='" + k + "' />");
|
|
|
|
lines.push("</div>");
|
|
}
|
|
else if (v.constructor == Object || Array.isArray(v)) {
|
|
lines.push("<div class='autocomplete'>");
|
|
lines.push("<input type='text' id='id_" + k + "' name='" + k + "' value='" + JSON.stringify(v) + "' />");
|
|
lines.push("</div>")
|
|
}
|
|
else {
|
|
lines.push("<div class='autocomplete'>");
|
|
if (v == "None") { v = ""; }
|
|
lines.push("<input type='text' id='id_" + k + "' name='" + k + "' value='" + String(v) + "' />");
|
|
lines.push("</div>");
|
|
}
|
|
lines.push("<br>");
|
|
}
|
|
lines.push("</form>");
|
|
lines.push("</details>")
|
|
return lines.join("\n");
|
|
};
|
|
var form = document.getElementById(form_div);
|
|
form.innerHTML = dict_to_form(in_json, name);
|
|
function new_button(url, button_name) {
|
|
var derp = document.getElementById(name + "_form")
|
|
var button = document.createElement("button");
|
|
button.setAttribute("onclick", "submit_form('"+url+"')");
|
|
button.setAttribute("class", "run_button");
|
|
button.setAttribute("style", "width: 120px;");
|
|
button.setAttribute("id", "form_"+button_name+"_button");
|
|
button.setAttribute("tabindex", "0");
|
|
button.innerHTML = button_name;
|
|
derp.parentNode.appendChild(button);
|
|
}
|
|
new_button("api/run.cmdline", "run");
|
|
new_button("api/save.cmdline", "save");
|
|
new_button("api/remove.cmdline", "remove");
|
|
var details = document.getElementById(name + "_details")
|
|
details.addEventListener("toggle", function(event) { details_open = details.open; });
|
|
}
|
|
function populate_page()
|
|
{
|
|
httpGet("api/get.cmdline.info", function (response) {
|
|
response = JSON.parse(response);
|
|
if (response["ok"])
|
|
{
|
|
form_json = response["args"];
|
|
cmds_json = response["cmds"];
|
|
var old_form_json = sessionStorage.getItem("form_json");
|
|
if (old_form_json)
|
|
{
|
|
old_form_json = JSON.parse(old_form_json);
|
|
for (var [k, v] of Object.entries(old_form_json))
|
|
{
|
|
if (k in form_json)
|
|
{
|
|
form_json[k] = v;
|
|
}
|
|
}
|
|
}
|
|
var description_div = document.getElementById("description_div");
|
|
description_div.innerHTML = response["description"];
|
|
var title_div = document.getElementById("title_h1");
|
|
title_div.innerHTML = response["title"];
|
|
var description = response["description"];
|
|
create_form(form_json, "arguments");
|
|
create_buttons(cmds_json);
|
|
}
|
|
});
|
|
};
|
|
populate_page();
|
|
window.onbeforeunload = function ()
|
|
{
|
|
sessionStorage.setItem("form_json", JSON.stringify(get_arguments()));
|
|
};
|
|
</script>
|
|
<body>
|
|
|
|
</html> |