kronos/src/kronos-ui/main.py
2026-05-02 12:50:22 +02:00

74 lines
2.1 KiB
Python

from datetime import datetime
import json
import os
import shutil
from fastapi import FastAPI, File, UploadFile, Form
from fastapi.responses import HTMLResponse, Response
from fastapi.staticfiles import StaticFiles
import typst
from kronos.mobilizon import get_raw_events
app = FastAPI()
app.mount("/static", StaticFiles(directory="src/kronos-ui/static/"), name="static")
@app.get("/", response_class=HTMLResponse)
async def root():
with open("src/kronos-ui/static/index.html", "rb") as f:
index = f.read()
return index
@app.get("/calendar", responses={200: {"content": {"image/png": {}}}}, response_class=Response)
async def calendar():
get_raw_events()
png_bytes = typst.compile("src/typst/calendar.typ", format="png")
return Response(content=png_bytes, media_type="image/png")
@app.post("/event_card", responses={200: {"content": {"image/png": {}}}}, response_class=Response)
async def event_card( # noqa: PLR0913
title: str = Form(""),
description: str = Form(""),
begins=Form(...),
ends=Form(...),
speaker: str = Form(""),
picture: UploadFile = File(...),
):
pic_path = os.path.join("src", "typst", "assets", "tmp", f"{datetime.now()}.jpg")
fp = open(pic_path, "wb")
if picture and picture.size > 0:
shutil.copyfileobj(picture.file, fp)
else:
with open(os.path.join("src", "typst", "assets", "photo.jpg"), "rb") as placeholder:
shutil.copyfileobj(placeholder, fp)
# TODO: pack this in a method
events = [
{
"title": title,
"beginsOn": begins,
"endsOn": ends,
"description": description,
"physicalAddress": None,
"picture": os.path.relpath(pic_path, start="src/typst"),
"url": None,
"txt_description": description,
"txt_date": f"{begins.split('T')[0]} {begins.split('T')[1]}-{ends.split('T')[1]}",
# "txt_date": "2026-04-29 18:00-19:00",
"speaker": speaker,
}
]
sys_inputs = {"events": json.dumps(events)}
print(sys_inputs)
# FIXME: remove hardcoded paths
png_bytes = typst.compile("src/typst/event.typ", format="png", sys_inputs=sys_inputs)
fp.close()
return Response(content=png_bytes, media_type="image/png")