Die Runde ist jetzt benannt. Der Host pflegt die Namensliste im neuen Reiter "Verwaltung", alle anderen wählen sich oben rechts einen aus. Der Name landet serverseitig an Vorschlägen und Wertungen, statt aus einem Textfeld zu kommen, in das jeder schreiben konnte, was er wollte. Dazu zwei Sammelstellen, beide nach Person gruppiert und für alle sichtbar, aber nur selbst bearbeitbar: - "Sammlungen": Filme, die man sehen möchte. Getrennt vom Rad-Vorschlag, von dem es weiterhin einen je Person gibt. - "Wünsche": was der Seite noch fehlt. Der Host darf hier alle Einträge ändern und löschen. Die Filmliste hat jetzt zwei Ansichten. Kompakt ist die gewohnte Karte, Details stellt Cover, Text und vier Szenenbilder nebeneinander — eine Karte so breit wie vier kompakte oder die halbe Reihe, je nachdem was zuerst zutrifft. Reihen und Einzelfilme sind dabei exakt gleich hoch; die Blätterleiste liegt dafür über dem Cover statt darunter. Die Filmansicht nutzt die Breite: links Cover, Text und Knöpfe, rechts der Trailer, darunter die Bilder. Ein Klick zeigt ein Bild in voller Größe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013XVnRop5c3or3B8xE2hpgZ
92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
"""Was jeder für sich sehen möchte.
|
|
|
|
Alle sehen alle Sammlungen — man merkt so, worauf die anderen Lust haben.
|
|
Ändern darf jeder nur die eigene. Der Vorschlag fürs Rad ist eine andere
|
|
Sache: davon gibt es einen je Person, und er landet im Glücksrad.
|
|
|
|
Titel und Poster kommen mit in die Zeile. Ein gemerkter Film soll lesbar
|
|
bleiben, auch wenn er nie im Katalog stand oder Netflix ihn abgibt.
|
|
"""
|
|
|
|
import sqlite3
|
|
from datetime import datetime, timezone
|
|
|
|
from .db import connect
|
|
|
|
SCHEMA = """
|
|
CREATE TABLE IF NOT EXISTS wishlist (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
session_id TEXT NOT NULL,
|
|
movie_id INTEGER NOT NULL,
|
|
title TEXT NOT NULL,
|
|
year INTEGER,
|
|
poster_path TEXT,
|
|
created_at TEXT NOT NULL,
|
|
UNIQUE (session_id, movie_id)
|
|
);
|
|
"""
|
|
|
|
|
|
def init():
|
|
with connect() as conn:
|
|
conn.executescript(SCHEMA)
|
|
|
|
|
|
def alle(session_id):
|
|
"""Alle Sammlungen, jede mit dem Namen ihres Besitzers."""
|
|
with connect() as conn:
|
|
rows = conn.execute(
|
|
"SELECT w.*, u.name FROM wishlist w "
|
|
"LEFT JOIN user_sessions s ON s.session_id = w.session_id "
|
|
"LEFT JOIN users u ON u.id = s.user_id "
|
|
"ORDER BY w.created_at DESC"
|
|
).fetchall()
|
|
return [
|
|
{
|
|
**{k: v for k, v in dict(r).items() if k != "session_id"},
|
|
"mine": r["session_id"] == session_id,
|
|
}
|
|
for r in rows
|
|
]
|
|
|
|
|
|
def merken(session_id, movie):
|
|
"""Ein zweites Mal merken ändert nichts."""
|
|
try:
|
|
with connect() as conn:
|
|
conn.execute(
|
|
"INSERT INTO wishlist "
|
|
"(session_id, movie_id, title, year, poster_path, created_at) "
|
|
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
(
|
|
session_id,
|
|
movie["id"],
|
|
movie["title"],
|
|
movie.get("year"),
|
|
movie.get("poster_path"),
|
|
datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
),
|
|
)
|
|
except sqlite3.IntegrityError:
|
|
pass
|
|
return alle(session_id)
|
|
|
|
|
|
def vergessen(session_id, movie_id):
|
|
with connect() as conn:
|
|
return conn.execute(
|
|
"DELETE FROM wishlist WHERE session_id = ? AND movie_id = ?",
|
|
(session_id, movie_id),
|
|
).rowcount
|
|
|
|
|
|
def ids(session_id):
|
|
"""movie_ids der gemerkten Filme, für die Detailansicht."""
|
|
with connect() as conn:
|
|
return [
|
|
r["movie_id"]
|
|
for r in conn.execute(
|
|
"SELECT movie_id FROM wishlist WHERE session_id = ?", (session_id,)
|
|
)
|
|
]
|