74 lines
2.1 KiB
Python
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")
|