aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2021-07-17 03:10:28 +0200
committercbdev <cb@cbcdn.com>2021-07-17 03:10:28 +0200
commitfbcd1f22d63f6bac83fc3a87481e76808552972d (patch)
tree85d7895f9246eba1a473667e573bf55379e461b9 /backend
parent2fcb061a09cb237354ca6a5b7a0309745d3e4caf (diff)
downloadcargohold-fbcd1f22d63f6bac83fc3a87481e76808552972d.tar.gz
cargohold-fbcd1f22d63f6bac83fc3a87481e76808552972d.tar.bz2
cargohold-fbcd1f22d63f6bac83fc3a87481e76808552972d.zip
Implement basic upload and listing
Diffstat (limited to 'backend')
-rw-r--r--backend/config.py4
-rw-r--r--backend/main.py92
2 files changed, 81 insertions, 15 deletions
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")]