update
This commit is contained in:
@@ -6,6 +6,7 @@ Jeder darf aufschreiben, was er sich wünscht. Alle sehen alle Wünsche,
|
|||||||
|
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from . import users
|
||||||
from .db import connect
|
from .db import connect
|
||||||
from .users import besitzer, gehoert_mir
|
from .users import besitzer, gehoert_mir
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ SCHEMA = """
|
|||||||
CREATE TABLE IF NOT EXISTS features (
|
CREATE TABLE IF NOT EXISTS features (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
session_id TEXT NOT NULL,
|
session_id TEXT NOT NULL,
|
||||||
|
user_id INTEGER,
|
||||||
text TEXT NOT NULL,
|
text TEXT NOT NULL,
|
||||||
created_at TEXT NOT NULL
|
created_at TEXT NOT NULL
|
||||||
);
|
);
|
||||||
@@ -21,23 +23,10 @@ CREATE TABLE IF NOT EXISTS features (
|
|||||||
MAX_LAENGE = 500
|
MAX_LAENGE = 500
|
||||||
|
|
||||||
|
|
||||||
def _spalte_user_id(conn, tabelle):
|
|
||||||
"""Nachrüsten und aus der Sitzung füllen — einmalig je Datenbank."""
|
|
||||||
spalten = {r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")}
|
|
||||||
if "user_id" in spalten:
|
|
||||||
return
|
|
||||||
conn.execute(f"ALTER TABLE {tabelle} ADD COLUMN user_id INTEGER")
|
|
||||||
conn.execute(
|
|
||||||
f"UPDATE {tabelle} SET user_id = ("
|
|
||||||
" SELECT user_id FROM user_sessions s WHERE s.session_id = "
|
|
||||||
f" {tabelle}.session_id)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
conn.executescript(SCHEMA)
|
conn.executescript(SCHEMA)
|
||||||
_spalte_user_id(conn, "features")
|
users.user_id_nachruesten(conn, "features")
|
||||||
|
|
||||||
|
|
||||||
def alle(session_id):
|
def alle(session_id):
|
||||||
@@ -45,8 +34,7 @@ def alle(session_id):
|
|||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
rows = conn.execute(
|
rows = conn.execute(
|
||||||
"SELECT f.*, u.name FROM features f "
|
"SELECT f.*, u.name FROM features f "
|
||||||
"LEFT JOIN user_sessions s ON s.session_id = f.session_id "
|
"LEFT JOIN users u ON u.id = f.user_id "
|
||||||
"LEFT JOIN users u ON u.id = s.user_id "
|
|
||||||
"ORDER BY f.created_at DESC"
|
"ORDER BY f.created_at DESC"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
ich = besitzer(session_id)
|
ich = besitzer(session_id)
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ async def guarded_sync():
|
|||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
async def startup():
|
async def startup():
|
||||||
db.init()
|
db.init()
|
||||||
|
users.init()
|
||||||
suggestions.init()
|
suggestions.init()
|
||||||
watched.init()
|
watched.init()
|
||||||
users.init()
|
|
||||||
wishlist.init()
|
wishlist.init()
|
||||||
features.init()
|
features.init()
|
||||||
scheduler.add_job(guarded_sync, "cron", hour=4, minute=30, id="daily-sync")
|
scheduler.add_job(guarded_sync, "cron", hour=4, minute=30, id="daily-sync")
|
||||||
@@ -294,13 +294,15 @@ def letzter():
|
|||||||
def liste_vorschlaege(response: Response, filmabend_sid: str | None = Cookie(None)):
|
def liste_vorschlaege(response: Response, filmabend_sid: str | None = Cookie(None)):
|
||||||
sid = sitzung(response, filmabend_sid)
|
sid = sitzung(response, filmabend_sid)
|
||||||
eintraege = suggestions.alle()
|
eintraege = suggestions.alle()
|
||||||
|
ich = users.besitzer(sid)
|
||||||
return {
|
return {
|
||||||
"items": [
|
"items": [
|
||||||
{k: v for k, v in e.items() if k != "session_id"} for e in eintraege
|
{k: v for k, v in e.items() if k not in ("session_id", "user_id")}
|
||||||
|
for e in eintraege
|
||||||
],
|
],
|
||||||
# Damit die Oberfläche den eigenen Vorschlag hervorheben kann
|
# Damit die Oberfläche den eigenen Vorschlag hervorheben kann
|
||||||
"mine": next(
|
"mine": next(
|
||||||
(e["id"] for e in eintraege if e["session_id"] == sid),
|
(e["id"] for e in eintraege if users.gehoert_mir(e, sid, ich)),
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@@ -317,7 +319,9 @@ async def vorschlagen(
|
|||||||
# Ein zweiter Vorschlag ersetzt den ersten, statt abgelehnt zu werden
|
# Ein zweiter Vorschlag ersetzt den ersten, statt abgelehnt zu werden
|
||||||
eintrag = suggestions.ersetzen(sid, movie, users.name_von(sid))
|
eintrag = suggestions.ersetzen(sid, movie, users.name_von(sid))
|
||||||
events.senden("suggestions")
|
events.senden("suggestions")
|
||||||
return {k: v for k, v in eintrag.items() if k != "session_id"}
|
return {
|
||||||
|
k: v for k, v in eintrag.items() if k not in ("session_id", "user_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/api/suggestions")
|
@app.delete("/api/suggestions")
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ import sqlite3
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from . import users
|
||||||
from .db import connect
|
from .db import connect
|
||||||
from .users import besitzer
|
from .users import WEM, besitzer
|
||||||
|
|
||||||
SCHEMA = """
|
SCHEMA = """
|
||||||
CREATE TABLE IF NOT EXISTS suggestions (
|
CREATE TABLE IF NOT EXISTS suggestions (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
session_id TEXT NOT NULL,
|
session_id TEXT NOT NULL,
|
||||||
|
user_id INTEGER,
|
||||||
movie_id INTEGER NOT NULL,
|
movie_id INTEGER NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
year INTEGER,
|
year INTEGER,
|
||||||
@@ -38,67 +40,11 @@ COOKIE = "filmabend_sid"
|
|||||||
DREH_DAUER = 4.2
|
DREH_DAUER = 4.2
|
||||||
|
|
||||||
|
|
||||||
# Ein Vorschlag je Person. Früher stand das UNIQUE auf der Sitzung — dann
|
|
||||||
# blockierte der Vorschlag des einen Namens den des nächsten, sobald beide
|
|
||||||
# denselben Browser benutzten.
|
|
||||||
INDIZES = """
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS suggestions_je_benutzer
|
|
||||||
ON suggestions (user_id) WHERE user_id IS NOT NULL;
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS suggestions_je_sitzung
|
|
||||||
ON suggestions (session_id) WHERE user_id IS NULL;
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def _unique_loesen(conn):
|
|
||||||
"""Das alte UNIQUE steckt in der Spaltendefinition — Tabelle neu bauen."""
|
|
||||||
sql = conn.execute(
|
|
||||||
"SELECT sql FROM sqlite_master WHERE type='table' AND name='suggestions'"
|
|
||||||
).fetchone()
|
|
||||||
if not sql or "UNIQUE" not in sql["sql"]:
|
|
||||||
return
|
|
||||||
conn.executescript(
|
|
||||||
"""
|
|
||||||
ALTER TABLE suggestions RENAME TO suggestions_alt;
|
|
||||||
CREATE TABLE suggestions (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
session_id TEXT NOT NULL,
|
|
||||||
user_id INTEGER,
|
|
||||||
movie_id INTEGER NOT NULL,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
year INTEGER,
|
|
||||||
poster_path TEXT,
|
|
||||||
name TEXT,
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
INSERT INTO suggestions
|
|
||||||
(id, session_id, user_id, movie_id, title, year, poster_path,
|
|
||||||
name, created_at)
|
|
||||||
SELECT id, session_id, user_id, movie_id, title, year, poster_path,
|
|
||||||
name, created_at FROM suggestions_alt;
|
|
||||||
DROP TABLE suggestions_alt;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _spalte_user_id(conn, tabelle):
|
|
||||||
"""Nachrüsten und aus der Sitzung füllen — einmalig je Datenbank."""
|
|
||||||
spalten = {r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")}
|
|
||||||
if "user_id" in spalten:
|
|
||||||
return
|
|
||||||
conn.execute(f"ALTER TABLE {tabelle} ADD COLUMN user_id INTEGER")
|
|
||||||
conn.execute(
|
|
||||||
f"UPDATE {tabelle} SET user_id = ("
|
|
||||||
" SELECT user_id FROM user_sessions s WHERE s.session_id = "
|
|
||||||
f" {tabelle}.session_id)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
conn.executescript(SCHEMA)
|
conn.executescript(SCHEMA)
|
||||||
_spalte_user_id(conn, "suggestions")
|
# Ein Vorschlag je Person
|
||||||
_unique_loesen(conn)
|
users.je_person(conn, "suggestions", SCHEMA)
|
||||||
conn.executescript(INDIZES)
|
|
||||||
|
|
||||||
|
|
||||||
def neue_session():
|
def neue_session():
|
||||||
@@ -123,10 +69,6 @@ def alle():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Mit Namen zählt der Name, ohne Namen die Sitzung
|
|
||||||
WEM = "(user_id = ? OR (? IS NULL AND user_id IS NULL AND session_id = ?))"
|
|
||||||
|
|
||||||
|
|
||||||
def von_session(session_id):
|
def von_session(session_id):
|
||||||
"""Der eigene Vorschlag — auch aus einem anderen Browser."""
|
"""Der eigene Vorschlag — auch aus einem anderen Browser."""
|
||||||
ich = besitzer(session_id)
|
ich = besitzer(session_id)
|
||||||
@@ -191,7 +133,9 @@ def ziehen():
|
|||||||
"winkel": winkel,
|
"winkel": winkel,
|
||||||
"dauer": DREH_DAUER,
|
"dauer": DREH_DAUER,
|
||||||
"gewinner": {
|
"gewinner": {
|
||||||
k: v for k, v in eintraege[treffer].items() if k != "session_id"
|
k: v
|
||||||
|
for k, v in eintraege[treffer].items()
|
||||||
|
if k not in ("session_id", "user_id")
|
||||||
},
|
},
|
||||||
"anzahl": len(eintraege),
|
"anzahl": len(eintraege),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,63 @@ def gehoert_mir(zeile, session_id, user_id):
|
|||||||
return zeile["session_id"] == session_id
|
return zeile["session_id"] == session_id
|
||||||
|
|
||||||
|
|
||||||
|
# Dasselbe als WHERE-Klausel. Parameter: (user_id, user_id, session_id)
|
||||||
|
WEM = "(user_id = ? OR (? IS NULL AND user_id IS NULL AND session_id = ?))"
|
||||||
|
|
||||||
|
|
||||||
|
def user_id_nachruesten(conn, tabelle):
|
||||||
|
"""Spalte ergänzen und aus der Sitzung füllen — einmalig je Datenbank."""
|
||||||
|
spalten = {r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")}
|
||||||
|
if "user_id" in spalten:
|
||||||
|
return
|
||||||
|
conn.execute(f"ALTER TABLE {tabelle} ADD COLUMN user_id INTEGER")
|
||||||
|
conn.execute(
|
||||||
|
f"UPDATE {tabelle} SET user_id = ("
|
||||||
|
" SELECT user_id FROM user_sessions s WHERE s.session_id = "
|
||||||
|
f" {tabelle}.session_id)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def je_person(conn, tabelle, schema, *schluessel):
|
||||||
|
"""Eindeutig je Person statt je Sitzung.
|
||||||
|
|
||||||
|
Früher stand das UNIQUE auf der Sitzung — dann blockierte der Eintrag
|
||||||
|
des einen Namens den des nächsten, sobald beide denselben Browser
|
||||||
|
benutzten. Mit Namen zählt jetzt der Name, ohne Namen die Sitzung.
|
||||||
|
|
||||||
|
Das alte UNIQUE steckt in der Spaltendefinition und lässt sich nicht
|
||||||
|
ändern — die Tabelle wird dafür nach `schema` neu gebaut. Hat ein Name
|
||||||
|
aus mehreren Browsern doppelt eingetragen, bleibt der jüngste Eintrag.
|
||||||
|
"""
|
||||||
|
user_id_nachruesten(conn, tabelle)
|
||||||
|
alt = conn.execute(
|
||||||
|
"SELECT sql FROM sqlite_master WHERE type='table' AND name=?", (tabelle,)
|
||||||
|
).fetchone()
|
||||||
|
if alt and "UNIQUE" in alt["sql"]:
|
||||||
|
spalten = ", ".join(
|
||||||
|
r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")
|
||||||
|
)
|
||||||
|
conn.executescript(
|
||||||
|
f"ALTER TABLE {tabelle} RENAME TO {tabelle}_alt;"
|
||||||
|
f"{schema}"
|
||||||
|
f"INSERT INTO {tabelle} ({spalten}) "
|
||||||
|
f"SELECT {spalten} FROM {tabelle}_alt;"
|
||||||
|
f"DROP TABLE {tabelle}_alt;"
|
||||||
|
)
|
||||||
|
mit_name = ", ".join((*schluessel, "user_id"))
|
||||||
|
ohne_name = ", ".join((*schluessel, "session_id"))
|
||||||
|
conn.execute(
|
||||||
|
f"DELETE FROM {tabelle} WHERE user_id IS NOT NULL AND id NOT IN "
|
||||||
|
f"(SELECT MAX(id) FROM {tabelle} GROUP BY {mit_name})"
|
||||||
|
)
|
||||||
|
conn.executescript(
|
||||||
|
f"CREATE UNIQUE INDEX IF NOT EXISTS {tabelle}_je_benutzer "
|
||||||
|
f"ON {tabelle} ({mit_name}) WHERE user_id IS NOT NULL;"
|
||||||
|
f"CREATE UNIQUE INDEX IF NOT EXISTS {tabelle}_je_sitzung "
|
||||||
|
f"ON {tabelle} ({ohne_name}) WHERE user_id IS NULL;"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def name_von(session_id):
|
def name_von(session_id):
|
||||||
"""Nur der Name, für Vorschläge und Wertungen."""
|
"""Nur der Name, für Vorschläge und Wertungen."""
|
||||||
benutzer = aktuell(session_id)
|
benutzer = aktuell(session_id)
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ auch wenn der Film später aus dem Katalog fällt.
|
|||||||
|
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from . import users
|
||||||
from .db import connect
|
from .db import connect
|
||||||
from .users import besitzer, gehoert_mir
|
from .users import WEM, besitzer, gehoert_mir
|
||||||
|
|
||||||
SCHEMA = """
|
SCHEMA = """
|
||||||
CREATE TABLE IF NOT EXISTS watched (
|
CREATE TABLE IF NOT EXISTS watched (
|
||||||
@@ -23,38 +24,28 @@ CREATE TABLE IF NOT EXISTS watched (
|
|||||||
watched_at TEXT NOT NULL,
|
watched_at TEXT NOT NULL,
|
||||||
hidden INTEGER NOT NULL DEFAULT 0
|
hidden INTEGER NOT NULL DEFAULT 0
|
||||||
);
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
RATINGS = """
|
||||||
CREATE TABLE IF NOT EXISTS ratings (
|
CREATE TABLE IF NOT EXISTS ratings (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
watched_id INTEGER NOT NULL,
|
watched_id INTEGER NOT NULL,
|
||||||
session_id TEXT NOT NULL,
|
session_id TEXT NOT NULL,
|
||||||
|
user_id INTEGER,
|
||||||
stars INTEGER NOT NULL,
|
stars INTEGER NOT NULL,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
created_at TEXT NOT NULL,
|
created_at TEXT NOT NULL
|
||||||
UNIQUE (watched_id, session_id)
|
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
MAX_STERNE = 5
|
MAX_STERNE = 5
|
||||||
|
|
||||||
|
|
||||||
def _spalte_user_id(conn, tabelle):
|
|
||||||
"""Nachrüsten und aus der Sitzung füllen — einmalig je Datenbank."""
|
|
||||||
spalten = {r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")}
|
|
||||||
if "user_id" in spalten:
|
|
||||||
return
|
|
||||||
conn.execute(f"ALTER TABLE {tabelle} ADD COLUMN user_id INTEGER")
|
|
||||||
conn.execute(
|
|
||||||
f"UPDATE {tabelle} SET user_id = ("
|
|
||||||
" SELECT user_id FROM user_sessions s WHERE s.session_id = "
|
|
||||||
f" {tabelle}.session_id)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
conn.executescript(SCHEMA)
|
conn.executescript(SCHEMA + RATINGS)
|
||||||
_spalte_user_id(conn, "ratings")
|
# Eine Stimme je Person und Film
|
||||||
|
users.je_person(conn, "ratings", RATINGS, "watched_id")
|
||||||
# Die Tabelle stand vor der Spalte schon in bestehenden Datenbanken
|
# Die Tabelle stand vor der Spalte schon in bestehenden Datenbanken
|
||||||
spalten = {r["name"] for r in conn.execute("PRAGMA table_info(watched)")}
|
spalten = {r["name"] for r in conn.execute("PRAGMA table_info(watched)")}
|
||||||
if "hidden" not in spalten:
|
if "hidden" not in spalten:
|
||||||
@@ -165,21 +156,16 @@ def bewerten(watched_id, session_id, stars, name=None):
|
|||||||
).fetchone()
|
).fetchone()
|
||||||
if not da:
|
if not da:
|
||||||
return None
|
return None
|
||||||
# Eine Stimme je Person — die eigene alte fliegt vorher raus.
|
# Eine Stimme je Person — die eigene alte fliegt vorher raus
|
||||||
# Mit Namen zählt der Name, ohne Namen die Sitzung.
|
|
||||||
ich = besitzer(session_id)
|
ich = besitzer(session_id)
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"DELETE FROM ratings WHERE watched_id = ? AND "
|
f"DELETE FROM ratings WHERE watched_id = ? AND {WEM}",
|
||||||
"(user_id = ? OR (? IS NULL AND user_id IS NULL AND session_id = ?))",
|
|
||||||
(watched_id, ich, ich, session_id),
|
(watched_id, ich, ich, session_id),
|
||||||
)
|
)
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"INSERT INTO ratings "
|
"INSERT INTO ratings "
|
||||||
"(watched_id, session_id, user_id, stars, name, created_at) "
|
"(watched_id, session_id, user_id, stars, name, created_at) "
|
||||||
"VALUES (?, ?, ?, ?, ?, ?) "
|
"VALUES (?, ?, ?, ?, ?, ?)",
|
||||||
"ON CONFLICT (watched_id, session_id) DO UPDATE SET "
|
|
||||||
"user_id = excluded.user_id, stars = excluded.stars, "
|
|
||||||
"name = excluded.name, created_at = excluded.created_at",
|
|
||||||
(
|
(
|
||||||
watched_id,
|
watched_id,
|
||||||
session_id,
|
session_id,
|
||||||
|
|||||||
@@ -12,40 +12,29 @@ import json
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from . import users
|
||||||
from .db import connect
|
from .db import connect
|
||||||
from .users import besitzer, gehoert_mir
|
from .users import WEM, besitzer, gehoert_mir
|
||||||
|
|
||||||
SCHEMA = """
|
SCHEMA = """
|
||||||
CREATE TABLE IF NOT EXISTS wishlist (
|
CREATE TABLE IF NOT EXISTS wishlist (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
session_id TEXT NOT NULL,
|
session_id TEXT NOT NULL,
|
||||||
|
user_id INTEGER,
|
||||||
movie_id INTEGER NOT NULL,
|
movie_id INTEGER NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
year INTEGER,
|
year INTEGER,
|
||||||
poster_path TEXT,
|
poster_path TEXT,
|
||||||
created_at TEXT NOT NULL,
|
created_at TEXT NOT NULL
|
||||||
UNIQUE (session_id, movie_id)
|
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _spalte_user_id(conn, tabelle):
|
|
||||||
"""Nachrüsten und aus der Sitzung füllen — einmalig je Datenbank."""
|
|
||||||
spalten = {r[1] for r in conn.execute(f"PRAGMA table_info({tabelle})")}
|
|
||||||
if "user_id" in spalten:
|
|
||||||
return
|
|
||||||
conn.execute(f"ALTER TABLE {tabelle} ADD COLUMN user_id INTEGER")
|
|
||||||
conn.execute(
|
|
||||||
f"UPDATE {tabelle} SET user_id = ("
|
|
||||||
" SELECT user_id FROM user_sessions s WHERE s.session_id = "
|
|
||||||
f" {tabelle}.session_id)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
conn.executescript(SCHEMA)
|
conn.executescript(SCHEMA)
|
||||||
_spalte_user_id(conn, "wishlist")
|
# Jeder Film einmal je Person
|
||||||
|
users.je_person(conn, "wishlist", SCHEMA, "movie_id")
|
||||||
|
|
||||||
|
|
||||||
def alle(session_id):
|
def alle(session_id):
|
||||||
@@ -55,8 +44,7 @@ def alle(session_id):
|
|||||||
# Genres kommen aus dem Katalog. Ein Film, der nie darin stand,
|
# Genres kommen aus dem Katalog. Ein Film, der nie darin stand,
|
||||||
# hat keine — das Rad behandelt ihn dann als "nicht Horror".
|
# hat keine — das Rad behandelt ihn dann als "nicht Horror".
|
||||||
"SELECT w.*, u.name, m.genres FROM wishlist w "
|
"SELECT w.*, u.name, m.genres FROM wishlist w "
|
||||||
"LEFT JOIN user_sessions s ON s.session_id = w.session_id "
|
"LEFT JOIN users u ON u.id = w.user_id "
|
||||||
"LEFT JOIN users u ON u.id = s.user_id "
|
|
||||||
"LEFT JOIN movies m ON m.id = w.movie_id "
|
"LEFT JOIN movies m ON m.id = w.movie_id "
|
||||||
"ORDER BY w.created_at DESC"
|
"ORDER BY w.created_at DESC"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
@@ -98,10 +86,6 @@ def merken(session_id, movie):
|
|||||||
return alle(session_id)
|
return alle(session_id)
|
||||||
|
|
||||||
|
|
||||||
# Mit Namen zählt der Name, ohne Namen die Sitzung
|
|
||||||
WEM = "(user_id = ? OR (? IS NULL AND user_id IS NULL AND session_id = ?))"
|
|
||||||
|
|
||||||
|
|
||||||
def vergessen(session_id, movie_id):
|
def vergessen(session_id, movie_id):
|
||||||
ich = besitzer(session_id)
|
ich = besitzer(session_id)
|
||||||
with connect() as conn:
|
with connect() as conn:
|
||||||
|
|||||||
@@ -694,7 +694,8 @@ onUnmounted(() => {
|
|||||||
v-else-if="activeTab === 'wheel'"
|
v-else-if="activeTab === 'wheel'"
|
||||||
ref="rad"
|
ref="rad"
|
||||||
:host="host"
|
:host="host"
|
||||||
:ich="ich"
|
:merkliste="merkliste"
|
||||||
|
:mine="meinVorschlag?.id ?? null"
|
||||||
@open="selected = $event"
|
@open="selected = $event"
|
||||||
@reset="meinVorschlag = null"
|
@reset="meinVorschlag = null"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { posterUrl } from '../images'
|
import { posterUrl } from '../images'
|
||||||
import { abonnieren } from '../live'
|
import { abonnieren } from '../live'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
host: Boolean,
|
host: Boolean,
|
||||||
// Wer gerade angemeldet ist. Beim Wechsel gehört eine andere Sammlung dazu.
|
// Beides hält die App schon aktuell — auch nach einem Namenswechsel
|
||||||
ich: { type: Object, default: null },
|
merkliste: { type: Array, default: () => [] },
|
||||||
|
mine: { type: Number, default: null },
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['open', 'reset'])
|
const emit = defineEmits(['open', 'reset'])
|
||||||
|
|
||||||
const items = ref([])
|
const items = ref([])
|
||||||
const mine = ref(null)
|
|
||||||
const laden = ref(true)
|
const laden = ref(true)
|
||||||
const fehler = ref('')
|
const fehler = ref('')
|
||||||
|
|
||||||
@@ -91,7 +91,6 @@ async function laden_() {
|
|||||||
if (!resp.ok) throw new Error('Vorschläge konnten nicht geladen werden')
|
if (!resp.ok) throw new Error('Vorschläge konnten nicht geladen werden')
|
||||||
const daten = await resp.json()
|
const daten = await resp.json()
|
||||||
items.value = daten.items
|
items.value = daten.items
|
||||||
mine.value = daten.mine
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
fehler.value = err.message
|
fehler.value = err.message
|
||||||
} finally {
|
} finally {
|
||||||
@@ -99,14 +98,8 @@ async function laden_() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.ich?.id, () => {
|
|
||||||
sammlungLaden()
|
|
||||||
laden_()
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await laden_()
|
await laden_()
|
||||||
await sammlungLaden()
|
|
||||||
await laufendenDrehHolen()
|
await laufendenDrehHolen()
|
||||||
verbinden()
|
verbinden()
|
||||||
})
|
})
|
||||||
@@ -197,18 +190,9 @@ async function zuruecksetzen() {
|
|||||||
// Aus der eigenen Sammlung würfeln. Der Schalter trennt Horror von allem
|
// Aus der eigenen Sammlung würfeln. Der Schalter trennt Horror von allem
|
||||||
// anderen — für Abende, an denen es keiner gruselig mag.
|
// anderen — für Abende, an denen es keiner gruselig mag.
|
||||||
const nurHorror = ref(true)
|
const nurHorror = ref(true)
|
||||||
const sammlung = ref([])
|
const sammlung = computed(() => props.merkliste.filter((e) => e.mine))
|
||||||
const wuerfelt = ref(false)
|
const wuerfelt = ref(false)
|
||||||
|
|
||||||
async function sammlungLaden() {
|
|
||||||
try {
|
|
||||||
const resp = await fetch('/api/wishlist')
|
|
||||||
if (resp.ok) sammlung.value = (await resp.json()).filter((e) => e.mine)
|
|
||||||
} catch {
|
|
||||||
sammlung.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function nachGenre(horror) {
|
function nachGenre(horror) {
|
||||||
return sammlung.value.filter(
|
return sammlung.value.filter(
|
||||||
(e) => (e.genres || []).includes('Horror') === horror
|
(e) => (e.genres || []).includes('Horror') === horror
|
||||||
|
|||||||
Reference in New Issue
Block a user