From fbcd1f22d63f6bac83fc3a87481e76808552972d Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 17 Jul 2021 03:10:28 +0200 Subject: Implement basic upload and listing --- backend/config.py | 4 +++ backend/main.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 81 insertions(+), 15 deletions(-) (limited to 'backend') diff --git a/backend/config.py b/backend/config.py index 6cfab69..3f70c39 100644 --- a/backend/config.py +++ b/backend/config.py @@ -1 +1,5 @@ homepage = "https://stumpf.es/" +fileroot = "/media/disk1/files.stumpf.es/" +global_limit = 0 +user_subdirs = True +database = "cargohold.db3" diff --git a/backend/main.py b/backend/main.py index ff703be..716ca13 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,33 +1,95 @@ -import HTTP import json import config +import cgi +import os +import sqlite3 +import mimetypes -def playout(filename): - return ["", [('Content-Type','text/html'), ("X-Accel-Redirect", filename)], None] +def playout(filename, content = "text/html"): + return ["", [('Content-Type', content if content else "application/binary"), ("X-Accel-Redirect", filename)], None] def home(): return ["", [('Content-Type','text/html'), ("Location", config.homepage)], "302 Home"] +def target_filename_internal(session, file): + target = "" + if not file: + file = "" + if config.user_subdirs: + target = session["user"] + "/" + return target + session["path"] + "/" + file + + +def target_filename(session, file): + return config.fileroot + target_filename_internal(session, file) + +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}) + data = cursor.fetchone() + if data: + session = {"user": data[0], "path": data[1], "access": data[2], "limit": data[3]} + else: + print("Unknown alias " + alias) + db.close() + return session + +def listing(session): + target = target_filename(session, None) + files = os.listdir(target) + return [json.dumps(files), [('Content-Type','application/json')], "200 OK"] + +def upload(session, post): + if post["file"].filename: + target = target_filename(session, os.path.basename(post["file"].filename)) + try: + open(target, 'wb').write(post["file"].file.read()) + print("Uploaded " + target) + return ["", [('Content-Type','text/html')], "200 OK"] + except PermissionError as e: + print("Failed to store " + target + ": " + e.msg) + return ["", [('Content-Type','text/html')], "500 Error"] + else: + print("Upload failed") + return ["", [('Content-Type','text/html')], "500 Error"] + def route(path, env, session, post): - if path[0] == "8cabc1fce52bcb565ae203267ce7e73f69a9272e": - return playout("interface/listing.htm") - if path[0] == "test": - return playout("interface/listing.htm") + # Get mapped user/path/limits + session = resolve_alias(path[0]) + + if not session: + return home() + + print(json.dumps(session)) + + if len(path) > 1 and path[1] == "upload": + return upload(session, post) + + if len(path) > 1 and path[1] == "listing": + return listing(session) + + if len(path) > 1 and path[1] == "file": + print("/data/" + target_filename_internal(session, path[2])) + return playout("/data/" + target_filename_internal(session, path[2]), mimetypes.guess_type(path[2])[0]) - # Default path - return home() + return playout("/interface/listing.htm") def handle_request(env, response): path = env.get('PATH_INFO', '').lstrip('/').split('/') - post = {} + post = None headers = [] + session = None # 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) + if env.get('CONTENT_TYPE', '').startswith("multipart/form-data"): + post = cgi.FieldStorage(environ=env, fp=env['wsgi.input'], keep_blank_values=True) + else: + content_length = int(env.get('CONTENT_LENGTH', '0')) + post_raw = env["wsgi.input"].read(content_length).decode('utf-8') + post = post_raw except ValueError as e: post = None @@ -35,4 +97,4 @@ def handle_request(env, response): data, addtl_headers, code = route(path, env, session, post) headers.extend(addtl_headers) response(code if code else "200 OK", headers) - return [bytes(data)] + return [bytes(data, "utf-8")] -- cgit v1.2.3