update
This commit is contained in:
128
backend/app/suggestions.py
Normal file
128
backend/app/suggestions.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""Filmvorschläge fürs Rad.
|
||||
|
||||
Jede Sitzung darf einen Film vorschlagen. Die Sitzung erkennt ein Cookie —
|
||||
ohne Anmeldung geht es nicht genauer, und für einen Filmabend im Freundeskreis
|
||||
reicht es.
|
||||
|
||||
Titel, Jahr und Poster werden mitgespeichert. So bleibt ein Vorschlag
|
||||
lesbar, auch wenn der Film nie im Katalog war oder Netflix ihn abgibt.
|
||||
"""
|
||||
|
||||
import json
|
||||
import random
|
||||
import sqlite3
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from .db import connect
|
||||
|
||||
SCHEMA = """
|
||||
CREATE TABLE IF NOT EXISTS suggestions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL UNIQUE,
|
||||
movie_id INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
year INTEGER,
|
||||
poster_path TEXT,
|
||||
name TEXT,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
"""
|
||||
|
||||
COOKIE = "filmabend_sid"
|
||||
|
||||
# So lange läuft die Animation im Browser. Der Server merkt sich das
|
||||
# Ergebnis mit, damit eine Seite, die mitten im Dreh geladen wird, es
|
||||
# trotzdem bekommt.
|
||||
DREH_DAUER = 4.2
|
||||
|
||||
|
||||
def init():
|
||||
with connect() as conn:
|
||||
conn.executescript(SCHEMA)
|
||||
|
||||
|
||||
def neue_session():
|
||||
return uuid.uuid4().hex
|
||||
|
||||
|
||||
def alle():
|
||||
with connect() as conn:
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM suggestions ORDER BY created_at ASC"
|
||||
).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def von_session(session_id):
|
||||
with connect() as conn:
|
||||
row = conn.execute(
|
||||
"SELECT * FROM suggestions WHERE session_id = ?", (session_id,)
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def anlegen(session_id, movie, name=None):
|
||||
"""Gibt den Vorschlag zurück, oder None wenn die Sitzung schon einen hat."""
|
||||
eintrag = {
|
||||
"session_id": session_id,
|
||||
"movie_id": movie["id"],
|
||||
"title": movie["title"],
|
||||
"year": movie.get("year"),
|
||||
"poster_path": movie.get("poster_path"),
|
||||
"name": (name or "").strip()[:40] or None,
|
||||
"created_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
||||
}
|
||||
try:
|
||||
with connect() as conn:
|
||||
conn.execute(
|
||||
"INSERT INTO suggestions "
|
||||
"(session_id, movie_id, title, year, poster_path, name, created_at) "
|
||||
"VALUES (:session_id, :movie_id, :title, :year, :poster_path, "
|
||||
":name, :created_at)",
|
||||
eintrag,
|
||||
)
|
||||
except sqlite3.IntegrityError:
|
||||
return None
|
||||
return von_session(session_id)
|
||||
|
||||
|
||||
def ersetzen(session_id, movie, name=None):
|
||||
"""Wer schon vorgeschlagen hat, darf seinen Vorschlag ändern."""
|
||||
with connect() as conn:
|
||||
conn.execute("DELETE FROM suggestions WHERE session_id = ?", (session_id,))
|
||||
return anlegen(session_id, movie, name)
|
||||
|
||||
|
||||
def ziehen():
|
||||
"""Server lost aus, damit alle Seiten dasselbe Ergebnis sehen.
|
||||
|
||||
Der Zielwinkel gehört dazu: sonst dreht jede Seite woanders hin und
|
||||
der Zeiger stünde am Ende auf einem anderen Segment.
|
||||
"""
|
||||
eintraege = alle()
|
||||
if not eintraege:
|
||||
return None
|
||||
|
||||
treffer = random.randrange(len(eintraege))
|
||||
schritt = 360 / len(eintraege)
|
||||
runden = 5 + random.randrange(3)
|
||||
# Der Zeiger steht oben, also muss die Mitte des Zielsegments dorthin
|
||||
winkel = runden * 360 + (360 - (treffer * schritt + schritt / 2))
|
||||
|
||||
return {
|
||||
"index": treffer,
|
||||
"winkel": winkel,
|
||||
"dauer": DREH_DAUER,
|
||||
"gewinner": {
|
||||
k: v for k, v in eintraege[treffer].items() if k != "session_id"
|
||||
},
|
||||
"anzahl": len(eintraege),
|
||||
}
|
||||
|
||||
|
||||
def loeschen(session_id):
|
||||
with connect() as conn:
|
||||
return conn.execute(
|
||||
"DELETE FROM suggestions WHERE session_id = ?", (session_id,)
|
||||
).rowcount
|
||||
Reference in New Issue
Block a user