diff --git a/backend/app/main.py b/backend/app/main.py
index 2be1023..bfec216 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -541,12 +541,13 @@ def bewerten(
watched_id: int,
response: Response,
stars: int = Body(..., embed=True),
+ text: str | None = Body(None, embed=True),
filmabend_sid: str | None = Cookie(None),
):
sid = sitzung(response, filmabend_sid)
stars = max(1, min(watched.MAX_STERNE, stars))
# Der Name kommt aus der Runde, nicht aus der Anfrage
- eintrag = watched.bewerten(watched_id, sid, stars, users.name_von(sid))
+ eintrag = watched.bewerten(watched_id, sid, stars, users.name_von(sid), text)
if not eintrag:
raise HTTPException(status_code=404, detail="Film steht nicht in der Liste")
events.senden("watched")
diff --git a/backend/app/watched.py b/backend/app/watched.py
index 1c32319..d1c6ac1 100644
--- a/backend/app/watched.py
+++ b/backend/app/watched.py
@@ -34,11 +34,14 @@ CREATE TABLE IF NOT EXISTS ratings (
user_id INTEGER,
stars INTEGER NOT NULL,
name TEXT,
+ text TEXT,
created_at TEXT NOT NULL
);
"""
MAX_STERNE = 5
+# Manche schreiben eine ganze Rezension — rund 600 Wörter passen hinein
+MAX_TEXT = 4000
def init():
@@ -52,6 +55,10 @@ def init():
conn.execute(
"ALTER TABLE watched ADD COLUMN hidden INTEGER NOT NULL DEFAULT 0"
)
+ # Ein Satz zur Wertung kam später dazu
+ spalten = {r["name"] for r in conn.execute("PRAGMA table_info(ratings)")}
+ if "text" not in spalten:
+ conn.execute("ALTER TABLE ratings ADD COLUMN text TEXT")
def _jetzt():
@@ -65,8 +72,8 @@ def alle(session_id):
"SELECT * FROM watched ORDER BY watched_at DESC, id DESC"
).fetchall()
stimmen = conn.execute(
- "SELECT id, watched_id, session_id, user_id, stars, name FROM ratings "
- "ORDER BY created_at ASC"
+ "SELECT id, watched_id, session_id, user_id, stars, name, text "
+ "FROM ratings ORDER BY created_at ASC"
).fetchall()
ich = besitzer(session_id)
@@ -78,23 +85,24 @@ def alle(session_id):
for film in filme:
eigene = je_film.get(film["id"], [])
werte = [s["stars"] for s in eigene]
+ meine = next((s for s in eigene if gehoert_mir(s, session_id, ich)), None)
out.append(
{
**dict(film),
"ratings": [
- {"id": s["id"], "stars": s["stars"], "name": s["name"]}
+ {
+ "id": s["id"],
+ "stars": s["stars"],
+ "name": s["name"],
+ "text": s["text"],
+ "mine": gehoert_mir(s, session_id, ich),
+ }
for s in eigene
],
"average": round(sum(werte) / len(werte), 1) if werte else None,
"count": len(werte),
- "mine": next(
- (
- s["stars"]
- for s in eigene
- if gehoert_mir(s, session_id, ich)
- ),
- None,
- ),
+ "mine": meine["stars"] if meine else None,
+ "mine_text": meine["text"] if meine else None,
}
)
return out
@@ -148,34 +156,50 @@ def sichtbarkeit(watched_id, versteckt):
).rowcount
-def bewerten(watched_id, session_id, stars, name=None):
- """Gibt None zurück, wenn der Film gar nicht in der Liste steht."""
+def bewerten(watched_id, session_id, stars, name=None, text=None):
+ """Sterne und ein optionaler Satz dazu.
+
+ Kommt kein Text mit (None), bleibt der bisherige stehen — wer nur die
+ Sterne nachjustiert, verliert seinen Satz nicht. Ein leerer String
+ löscht ihn ausdrücklich.
+
+ Gibt None zurück, wenn der Film gar nicht in der Liste steht.
+ """
with connect() as conn:
da = conn.execute(
"SELECT 1 FROM watched WHERE id = ?", (watched_id,)
).fetchone()
if not da:
return None
- # Eine Stimme je Person — die eigene alte fliegt vorher raus
ich = besitzer(session_id)
+ if text is None:
+ alt = conn.execute(
+ f"SELECT text FROM ratings WHERE watched_id = ? AND {WEM}",
+ (watched_id, ich, ich, session_id),
+ ).fetchone()
+ text = alt["text"] if alt else None
+ else:
+ text = text.strip()[:MAX_TEXT] or None
+ # Eine Stimme je Person — die eigene alte fliegt vorher raus
conn.execute(
f"DELETE FROM ratings WHERE watched_id = ? AND {WEM}",
(watched_id, ich, ich, session_id),
)
conn.execute(
"INSERT INTO ratings "
- "(watched_id, session_id, user_id, stars, name, created_at) "
- "VALUES (?, ?, ?, ?, ?, ?)",
+ "(watched_id, session_id, user_id, stars, name, text, created_at) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)",
(
watched_id,
session_id,
ich,
stars,
(name or "").strip()[:40] or None,
+ text,
_jetzt(),
),
)
- return {"watched_id": watched_id, "stars": stars}
+ return {"watched_id": watched_id, "stars": stars, "text": text}
def stimme_loeschen(rating_id):
diff --git a/frontend/src/components/WatchedTab.vue b/frontend/src/components/WatchedTab.vue
index ea7f300..148063d 100644
--- a/frontend/src/components/WatchedTab.vue
+++ b/frontend/src/components/WatchedTab.vue
@@ -1,5 +1,5 @@
@@ -173,10 +246,35 @@ onUnmounted(() => abbestellen?.())
+
+
+