diff options
-rw-r--r-- | assets/cargohold.css | 13 | ||||
-rw-r--r-- | assets/cargohold.js | 105 | ||||
-rw-r--r-- | backend/HTTP.py | 16 | ||||
-rw-r--r-- | backend/main.py | 34 | ||||
-rw-r--r-- | config/uwsgi.ini | 11 | ||||
-rw-r--r-- | interface/listing.htm (renamed from listing.htm) | 3 |
6 files changed, 182 insertions, 0 deletions
diff --git a/assets/cargohold.css b/assets/cargohold.css index 1e56769..f3db7e9 100644 --- a/assets/cargohold.css +++ b/assets/cargohold.css @@ -9,6 +9,19 @@ html { background-color: #425; } +.queue-entry.errored { + background-color: red; +} + +.queue-entry { + width: 100%; + padding: 0.2em; +} + +.queue-entry > .name { + margin-right: 2em; +} + #selector-label { background-color: #333; border-radius: 1em; diff --git a/assets/cargohold.js b/assets/cargohold.js new file mode 100644 index 0000000..e1278b7 --- /dev/null +++ b/assets/cargohold.js @@ -0,0 +1,105 @@ +/* + * TODO: + * check if files exist + * check file sizes + */ + +var running = false; +var queue = []; + + +function queue_work(){ + let i = 0; + for(; i < queue.length; i++){ + item = queue[i]; + if(!item.started){ + console.log(item); + console.log("Starting " + item.file.name); + item.started = true; + + let req = new XMLHttpRequest(); + let data = new FormData(); + data.append("file", item.file); + req.upload.addEventListener("progress", function(evt){ + if(evt.lengthComputable){ + console.log("Upload for " + item.file.name + " at " + evt.loaded / evt.total); + item.node.childNodes[1].value = evt.loaded; + } + }); + req.onloadstart = function(evt){ + console.log("Upload for " + item.file.name + " started"); + item.node.childNodes[1].max = item.file.size; + item.node.childNodes[1].value = 0; + }; + req.onloadend = function(evt){ + console.log("Upload for " + item.file.name + " ended"); + queue_work(); + }; + req.onerror = function(evt){ + console.log("Upload for " + item.file.name + " errored"); + item.node.className += " errored"; + }; + req.onabort = function(evt){ + console.log("Upload for " + item.file.name + " aborted"); + item.node.className += "errored"; + }; + req.onreadystatechange = function(evt){ + console.log("Upload for " + item.file.name + " state " + req.readyState); + }; + req.open("POST", 'upload'); + req.send(data); + return; + } + } + + console.log("Queue run done"); + running = false; +} + +function queue_run(){ + if(running || queue.length == 0){ + return; + } + + running = true; + + console.log("Starting queue run"); + queue_work(); +} + +function element(id){ + return document.getElementById(id); +} + +function node(tag, style, text){ + let new_node = document.createElement(tag); + new_node.className = style; + if(text){ + new_node.textContent = text; + } + return new_node; +} + +function upload_element(file){ + let new_node = node("div", "queue-entry"); + new_node.appendChild(node("span", "name", file.name)); + new_node.appendChild(node("progress", "progress")); + element("queue").appendChild(new_node); + return new_node; +} + +function upload_start(element){ + for(let i = 0; i < element.target.files.length; i++){ + console.log(element.target.files[i]); + queue.push({"file": element.target.files[i], "node": upload_element(element.target.files[i]), "progress": 0, "started": false}); + } + queue_run(); +} + +function init(){ + element("file-submit").style.display = "none"; + element("files").onchange = upload_start; + //setInterval(queue_run, 1000); +} + +window.onload = init; diff --git a/backend/HTTP.py b/backend/HTTP.py new file mode 100644 index 0000000..4ba3d90 --- /dev/null +++ b/backend/HTTP.py @@ -0,0 +1,16 @@ +def cookies(data): + cookies = {} + for cookie in data.split(';'): + data = cookie.strip().split('=', 1) + if(len(data) == 2): + cookies[data[0]] = data[1] + return cookies + +def formdata(data): + fields = {} + for field in data.split('&'): + data = field.strip().split('=', 1) + if len(data) == 2: + fields[data[0]] = data[1] + # FIXME URLdecode the entries + return fields diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000..1678f24 --- /dev/null +++ b/backend/main.py @@ -0,0 +1,34 @@ +import HTTP +import json + +def playout(filename): + return ["", [('Content-Type','text/html'), ('X-Accel-Redirect', filename)], None] + +def route(path, env, session, post): + if path[0] == "8cabc1fce52bcb565ae203267ce7e73f69a9272e": + return playout("interface/listing.htm") + if path[0] == "test": + return playout("interface/listing.htm") + + # Default path + return ["", [("Content-type", "text/html")], "404 None such"] + +def handle_request(env, response): + path = env.get('PATH_INFO', '').lstrip('/').split('/') + post = {} + headers = [] + + # Read POST data + try: + content_length = int(env.get('CONTENT_LENGTH', '0')) + post_raw = env["wsgi.input"].read(content_length).decode('utf-8') + if env.get('CONTENT_TYPE', '') == "multipart/form-data": + post = HTTP.formdata(post_raw) + except ValueError as e: + post = None + + # Route request + data, addtl_headers, code = route(path, env, session, post) + headers.extend(addtl_headers) + response(code if code else "200 OK", headers) + return [bytes(data)] diff --git a/config/uwsgi.ini b/config/uwsgi.ini new file mode 100644 index 0000000..6ea3e51 --- /dev/null +++ b/config/uwsgi.ini @@ -0,0 +1,11 @@ +[uwsgi] +processes = 4 +master = 1 +socket = /tmp/cargohold.sock +chdir = /var/www/cargohold/ +wsgi-file = main.py +callable = handle_request +uid = www-data +gid = www-data +plugin = python3 + diff --git a/listing.htm b/interface/listing.htm index 0421eec..27b622a 100644 --- a/listing.htm +++ b/interface/listing.htm @@ -6,6 +6,7 @@ <title>cargohold</title> <link rel="stylesheet" href="assets/cargohold.css" /> <link rel="icon" href="assets/cargohold.ico" /> + <script src="assets/cargohold.js"></script> </head> <body> <div id="header"> @@ -42,6 +43,8 @@ </form> </div> + <div id="queue"> + </div> <div id="storage"> Storage space left: 2GB / 2GB <br/> <progress value="70" max="100">70 %</progress> |