wolkje-gedeelde-mappen/wolkje_files/app.py

94 lines
2.6 KiB
Python
Raw Normal View History

2023-05-02 17:38:05 +02:00
#!/usr/bin/env python3
# TODO maxlength on folder name
# TODO maxlength on file name
# TODO maxlength on file contents
import json
import falcon
from slugify import slugify
from wolkje_files import img_store
def get_slug(folder: dict):
if "name" in folder:
return slugify(folder["name"])
else:
return "untitled"
def ensure_slug(folder: dict, folder_slug_in_url: str):
expected_slug = get_slug(folder)
if folder_slug_in_url != expected_slug:
raise falcon.HTTPPermanentRedirect(f"/folder/{folder['folder_id']}/{expected_slug}")
def redirect_to_folder(folder: dict):
assert folder
raise falcon.HTTPFound(f"/folder/{folder['folder_id']}/{get_slug(folder)}")
class FolderIndex:
def on_post(self, req: falcon.Request, resp: falcon.Response):
try:
data = json.load(req.bounded_stream)
except Exception as exc:
raise falcon.HTTPBadRequest(description="Could not read body as JSON") from exc
if "folder_name" not in data:
raise falcon.HTTPBadRequest(description="folder_name not given in body")
folder = img_store.new_folder(data["folder_name"])
if not folder:
raise falcon.HTTPInternalServerError(description="Failed to create a new folder")
redirect_to_folder(folder)
class FolderResource:
def on_get(self, req: falcon.Request, resp: falcon.Response, folder_id: str, folder_slug=None):
folder = img_store.get_folder(folder_id)
if not folder:
raise falcon.HTTPNotFound()
ensure_slug(folder, folder_slug)
resp.media = {
"name": folder.get("name"),
"created": folder.get("created"),
"files": img_store.ls(folder_id),
}
def on_post(self, req: falcon.Request, resp: falcon.Response, folder_id: str, folder_slug: str):
# TODO check authorization
form = req.get_media()
for part in form:
if part.filename is None:
pass
try:
img_store.save_file(folder_id, part.filename, part.stream, part.content_type)
except img_store.NoSuchFolderError:
raise falcon.HTTPNotFound(description="Folder does not exist")
folder = img_store.get_folder(folder_id)
redirect_to_folder(folder)
class FileResource:
def on_get(
self,
req: falcon.Request, resp: falcon.Response,
folder_id: str, folder_slug: str, file_name: str
):
try:
resp.stream, resp.content_length, resp.content_type = img_store.open_file(folder_id, file_name)
except img_store.NoSuchFolderError:
raise falcon.HTTPNotFound(description="Folder does not exist")
except img_store.NoSuchFileError:
raise falcon.HTTPNotFound(description="File does not exist")
app = falcon.App()
app.add_route("/", FolderIndex())
app.add_route("/{folder_id}/{folder_slug}", FolderResource())
app.add_route("/{folder_id}/{folder_slug}/{file_name}", FileResource())