This commit is contained in:
team3
2026-10-07 15:41:41 +02:00
parent b65f4d75f4
commit 2f771a9c30
10 changed files with 527 additions and 37 deletions

View File

@@ -21,6 +21,7 @@ from . import (
features,
ki,
search,
spenden,
streamproxy,
suggestions,
sync,
@@ -98,6 +99,7 @@ async def startup():
clips.init()
wishlist.init()
features.init()
spenden.init()
# Erst die Sicherung, dann der Sync — so liegt vor jedem Katalog-Update
# ein sauberer Stand
if not HOST_SCHLUESSEL:
@@ -714,6 +716,60 @@ def info_setzen(
return {"text": db.get_meta("info_text")}
# ── Spendenbaum ─────────────────────────────────────────────────────────
@app.get("/api/spenden")
def spenden_liste():
return spenden.alle()
@app.post("/api/spenden")
def spende_eintragen(
response: Response,
user_id: int = Body(..., embed=True),
filmabend_sid: str | None = Cookie(None),
):
sid = sitzung(response, filmabend_sid)
if not users.ist_host(sid):
raise HTTPException(status_code=403, detail="Nur für den Host")
spenden.eintragen(user_id)
events.senden("spenden")
return spenden.alle()
@app.get("/api/kontostand")
def kontostand():
"""Was auf dem Filmabend-Konto liegt — der Host trägt die Zahl ein."""
wert = db.get_meta("kontostand")
return {"betrag": float(wert) if wert else None}
@app.put("/api/kontostand")
def kontostand_setzen(
response: Response,
betrag: float | None = Body(None, embed=True),
filmabend_sid: str | None = Cookie(None),
):
sid = sitzung(response, filmabend_sid)
if not users.ist_host(sid):
raise HTTPException(status_code=403, detail="Nur für den Host")
with db.connect() as conn:
db.set_meta(conn, "kontostand", "" if betrag is None else round(betrag, 2))
events.senden("spenden")
return kontostand()
@app.delete("/api/spenden/{user_id}")
def spende_entfernen(
user_id: int, response: Response, filmabend_sid: str | None = Cookie(None)
):
sid = sitzung(response, filmabend_sid)
if not users.ist_host(sid):
raise HTTPException(status_code=403, detail="Nur für den Host")
if spenden.entfernen(user_id):
events.senden("spenden")
return spenden.alle()
@app.get("/api/features")
def wuensche(response: Response, filmabend_sid: str | None = Cookie(None)):
sid = sitzung(response, filmabend_sid)
@@ -915,7 +971,9 @@ def schutz_setzen(
@app.get("/api/host")
def host_stand(response: Response, filmabend_sid: str | None = Cookie(None)):
sid = sitzung(response, filmabend_sid)
return {"host": users.ist_host(sid)}
# Ob es einen Host-Film gibt, darf jeder wissen — nur nicht welchen.
# Ohne Film hat die Tastenkombination nichts zu fragen.
return {"host": users.ist_host(sid), "film": users.host_film() is not None}
@app.post("/api/host")
@@ -930,7 +988,8 @@ def host_modus(
Freischalten geht mit dem Schlüssel aus der .env, einmal über
/?host=<schlüssel>, oder mit dem Host-Film: die Tastenkombination
fragt danach, wie beim Anmeldefilm eines Namens.
fragt danach, wie beim Anmeldefilm eines Namens. Ist kein Host-Film
gesetzt, reicht die Tastenkombination allein.
Die Freischaltung bleibt, bis jemand sie abgibt. Ob die Hostknöpfe
gerade sichtbar sind, entscheidet der Browser für sich — dafür ist
@@ -944,7 +1003,8 @@ def host_modus(
darf = (
users.ist_host(sid)
or (bool(HOST_SCHLUESSEL) and secrets.compare_digest(schluessel or "", HOST_SCHLUESSEL))
or (film is not None and movie_id == film)
or film is None
or movie_id == film
)
if not darf:
raise HTTPException(status_code=403, detail="Kein Hostschlüssel")