diff --git a/server.py b/server.py index 9b59a76..5fe527e 100644 --- a/server.py +++ b/server.py @@ -1,6 +1,11 @@ from typing import Optional from fastapi import FastAPI, Request, HTTPException, Response -from fastapi.responses import RedirectResponse, HTMLResponse, FileResponse, PlainTextResponse +from fastapi.responses import ( + RedirectResponse, + HTMLResponse, + FileResponse, + PlainTextResponse, +) from fastapi.middleware.cors import CORSMiddleware import logging import time @@ -46,11 +51,11 @@ DATABASE_FILE = args.database_file_path sqlite_helpers.maybe_create_table(DATABASE_FILE) qr_code_cache = QRCode( - base_url=args.qr_code_base_url, - qr_cache_path=args.qr_code_cache_path, - max_size=args.qr_code_cache_size, - cache_state_file=args.qr_code_cache_state_file, - qr_image_path=args.qr_code_center_image_path, + base_url=args.qr_code_base_url, + qr_cache_path=args.qr_code_cache_path, + max_size=args.qr_code_cache_size, + cache_state_file=args.qr_code_cache_state_file, + qr_image_path=args.qr_code_center_image_path, ) @@ -166,12 +171,15 @@ async def delete_url(alias: str): else: raise HTTPException(status_code=HttpResponse.NOT_FOUND.code) + @app.post("/paste/create") async def create_paste(request: Request): api_key = request.headers.get("x-api-key") if CLEEZY_PASTE_API_KEY is None: - logging.warning("CLEEZY_PASTE_API_KEY isn't set, skipping api key check for /paste/create") + logging.warning( + "CLEEZY_PASTE_API_KEY isn't set, skipping api key check for /paste/create" + ) elif api_key != CLEEZY_PASTE_API_KEY: raise HTTPException(status_code=401, detail=f"Invalid API Key '{api_key}'") @@ -180,32 +188,30 @@ async def create_paste(request: Request): except Exception: logging.exception("/paste/create couldnt parse json") raise HTTPException( - status_code=HttpResponse.BAD_REQUEST.code, - detail="Invalid JSON payload" + status_code=HttpResponse.BAD_REQUEST.code, detail="Invalid JSON payload" ) text_bytes = payload.get("text", "").encode("utf-8") if len(text_bytes) > MAX_PASTE_SIZE_BYTES: raise HTTPException( status_code=HttpResponse.REQUEST_TOO_LARGE, - detail="Paste content exceeds the maximum allowed size of 10MB." + detail="Paste content exceeds the maximum allowed size of 10MB.", ) - paste_id = generate_alias(len(payload.get('text'))) + paste_id = generate_alias(len(payload.get("text"))) - success = sqlite_helpers.insert_paste(DATABASE_FILE, paste_id, payload.get('title', 'Untitled Paste')) + success = sqlite_helpers.insert_paste( + DATABASE_FILE, paste_id, payload.get("title", "Untitled Paste") + ) if not success: raise HTTPException( status_code=HttpResponse.INTERNAL_SERVER_ERROR, - detail="Failed to save paste metadata." + detail="Failed to save paste metadata.", ) paste_path = PASTES_DIR / str(paste_id) paste_path.write_bytes(text_bytes) - return { - "id": paste_id, - "size_bytes": len(text_bytes) - } + return {"id": paste_id, "size_bytes": len(text_bytes)} @app.get("/paste/{paste_id}") @@ -216,7 +222,7 @@ async def view_paste(paste_id: str): paste_title = sqlite_helpers.get_paste(DATABASE_FILE, paste_id) return HTMLResponse( - f""" + f"""
{paste_path.read_text(encoding="utf-8")}
-""")
+"""
+ )
+
-@app.get("/qr/{alias}")
+@app.get("/qr/{alias}")
async def qr(alias: str):
logging.debug(f"/qr code generation called with alias: {alias}")
with MetricsHandler.query_time.labels("qr").time():
maybe_image_data = qr_code_cache.find(alias)
if maybe_image_data is not None:
return FileResponse(
- maybe_image_data,
- media_type='image/jpeg',
+ maybe_image_data,
+ media_type="image/jpeg",
)
-
+
url_output = sqlite_helpers.get_url(DATABASE_FILE, alias)
if url_output is None:
raise HTTPException(status_code=HttpResponse.NOT_FOUND.code)
image_data = qr_code_cache.add(alias)
return FileResponse(
image_data,
- media_type='image/jpeg',
+ media_type="image/jpeg",
)
+
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
if exc.status_code not in http_code_to_enum:
@@ -259,8 +268,7 @@ async def http_exception_handler(request, exc):
original_url = request.headers.get("x-original-url", request.url)
base_url = request.headers.get("x-base-url", request.base_url)
content = content.format(
- requested_url=str(original_url),
- base_url=str(base_url)
+ requested_url=str(original_url), base_url=str(base_url)
)
if status_code_enum == HttpResponse.REQUEST_TOO_LARGE:
request_size = "Unknown"
@@ -274,9 +282,7 @@ async def http_exception_handler(request, exc):
request_size=request_size,
max_size=MAX_PASTE_SIZE_BYTES,
)
- return HTMLResponse(
- content=content, status_code=status_code_enum.code
- )
+ return HTMLResponse(content=content, status_code=status_code_enum.code)
@app.get("/metrics")
@@ -286,14 +292,16 @@ def get_metrics():
content=prometheus_client.generate_latest(),
)
+
# write qr-codes to json file on shutdown if cache state file arg is specified
@app.on_event("shutdown")
def signal_handler():
if args.qr_code_cache_state_file is None:
return qr_code_cache.clear()
-
+
qr_code_cache.write_cache_state()
+
logging.Formatter.converter = time.gmtime
logging.basicConfig(