From b87909c9dd7aabe7b8f8bd63138876dff5cd2200 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 29 Oct 2021 20:22:18 +0200 Subject: Implement gallery view, add noscript notice, implement rudimentary overwrite protection --- assets/502.html | 1 + assets/cargohold.css | 10 ++++++++++ assets/cargohold.js | 29 +++++++++++++++++++++++++++-- backend/HTTP.py | 16 ---------------- backend/main.py | 29 ++++++++++++++++++----------- interface/listing.htm | 14 ++++++++++++-- 6 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 assets/502.html delete mode 100644 backend/HTTP.py diff --git a/assets/502.html b/assets/502.html new file mode 100644 index 0000000..1bc0ca4 --- /dev/null +++ b/assets/502.html @@ -0,0 +1 @@ +FIXME: Do a proper error page diff --git a/assets/cargohold.css b/assets/cargohold.css index bec6b3a..747b916 100644 --- a/assets/cargohold.css +++ b/assets/cargohold.css @@ -9,6 +9,16 @@ html { background-color: #425; } +.listing-entry > img { + display: inline-block; + width: 100%; +} + +#noscript-warning { + padding: 1em; + font-size: 110%; +} + .listing-entry, .listing-entry:visited { display: block; text-decoration: none; diff --git a/assets/cargohold.js b/assets/cargohold.js index 2ba8cc0..18dbeae 100644 --- a/assets/cargohold.js +++ b/assets/cargohold.js @@ -45,6 +45,10 @@ function queue_work(){ }; req.onreadystatechange = function(evt){ console.log("Upload for " + item.file.name + " state " + req.readyState); + if(req.readyState === XMLHttpRequest.DONE && req.status != 200){ + console.log("Upload for " + item.file.name + " failed with " + req.status); + item.node.className += " errored"; + } }; req.open("POST", 'upload'); req.send(data); @@ -100,9 +104,28 @@ function listing_clear(){ element("dirlisting").innerHTML = ""; } -function listing_add(file){ +function interface_update(access){ + if(!access.includes("c")){ + element("tab-upload-label").style.display = "none"; + } + + if(!access.includes("r")){ + element("tab-view-label").style.display = "none"; + element("tab-upload").checked = "checked"; + } +} + +function listing_add(file, style = "default"){ let link = node("a", "listing-entry", file.name); link.href = "file/" + encodeURIComponent(file.name); + + if(style == "gallery"){ + let image = node("img", "preview"); + image.src = "preview/" + encodeURIComponent(file.name); + //link.insertBefore(image, link.firstChild); + link.appendChild(image); + } + element("dirlisting").appendChild(link); } @@ -111,8 +134,10 @@ function listing_update(){ let req = new XMLHttpRequest(); req.onload = function(evt){ let data = JSON.parse(req.response); + interface_update(data.access); + for(let i = 0; i < data.files.length; i++){ - listing_add(data.files[i]); + listing_add(data.files[i], data.display); } }; req.open("GET", "listing"); diff --git a/backend/HTTP.py b/backend/HTTP.py deleted file mode 100644 index 4ba3d90..0000000 --- a/backend/HTTP.py +++ /dev/null @@ -1,16 +0,0 @@ -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 index 592b7a3..bbb853d 100644 --- a/backend/main.py +++ b/backend/main.py @@ -26,27 +26,27 @@ def resolve_alias(alias): session = None db = sqlite3.connect(config.database, check_same_thread = False) cursor = db.cursor() - cursor.execute("SELECT user, real, access, storage FROM aliases WHERE alias=:alias", {"alias": alias}) + cursor.execute("SELECT user, real, access, storage, display FROM aliases WHERE alias=:alias", {"alias": alias}) data = cursor.fetchone() if data: - session = {"user": data[0], "path": data[1], "access": data[2], "limit": data[3]} + session = {"user": data[0], "path": data[1], "access": data[2], "limit": data[3], "display": data[4]} else: print("Unknown alias " + alias) db.close() return session def listing(session): - listing = {"total": 0, "files": []} - if 'r' not in session["access"]: - return ["", [('Content-Type','text/html')], "403 No"] + listing = {"total": 0, "files": [], "access": session["access"], "display": session["display"]} - directory = target_filename(session, None) - files = os.listdir(directory) + if 'r' in session["access"]: + directory = target_filename(session, None) + files = os.listdir(directory) - for filename in files: - size = os.path.getsize(directory + filename) - listing["files"].append({"name": filename, "size": size}) - listing["total"] += size + for filename in files: + if os.path.isfile(directory + filename): + size = os.path.getsize(directory + filename) + listing["files"].append({"name": filename, "size": size}) + listing["total"] += size return [json.dumps(listing), [('Content-Type','application/json')], "200 OK"] @@ -55,6 +55,10 @@ def upload(session, post): return ["", [('Content-Type','text/html')], "403 No"] if post["file"].filename: target = target_filename(session, os.path.basename(post["file"].filename)) + + while os.path.isfile(target): + target += "_dup" + try: open(target, 'wb').write(post["file"].file.read()) print("Uploaded " + target) @@ -85,6 +89,9 @@ def route(path, env, session, post): print("/data/" + target_filename_internal(session, path[2])) return playout("/data/" + target_filename_internal(session, path[2]), mimetypes.guess_type(path[2])[0]) + if len(path) > 1 and path[1] == "preview" and session["display"] == "gallery": + return playout("/data/" + target_filename_internal(session, "preview/" + path[2]), mimetypes.guess_type(path[2])[0]) + return playout("/interface/listing.htm") def handle_request(env, response): diff --git a/interface/listing.htm b/interface/listing.htm index 220df68..f2b1a14 100644 --- a/interface/listing.htm +++ b/interface/listing.htm @@ -15,12 +15,20 @@
- + - +
+
@@ -37,10 +45,12 @@
+
-- cgit v1.2.3