CI / test (push) Successful in 28s
Faseskift venter, til speakeren er færdig med den aktuelle skærm, og replikker til en skærm, der er væk, afspilles ikke. Ny kategori-intro med en lyd pr. kategori, musik pr. fase med bløde overgange og lydeffekter til alt, der flyver over skærmen. Efter afsløringen eksploderer løgne, ingen valgte, og pointene tæller op. Hjerter gives kun under afsløringen og ses live på storskærmen. Lyv for mig giver halve point. Narrede spilleres telefon kan blive drillet med et fjollet billede og et buh. Alle lyd- og billedfiler serveres med versionerede navne og caches af browseren. Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
25 lines
907 B
Python
25 lines
907 B
Python
"""Lyd- og billedfiler med versionerede URL'er, så browseren kan gemme dem for altid.
|
|
|
|
Templates indlejrer `asset_map()` som JSON (window.WPP_ASSETS), og JS slår op i den i stedet for at
|
|
bygge stier selv. I drift giver {% static %} hashede filnavne (immutable cache); i udvikling de rå navne.
|
|
"""
|
|
|
|
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
from django.templatetags.static import static
|
|
|
|
STATIC_DIR = Path(__file__).resolve().parent / "static" / "party"
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def asset_map() -> dict:
|
|
sfx = {p.stem: static(f"party/sfx/{p.name}") for p in sorted((STATIC_DIR / "sfx").glob("*.mp3"))}
|
|
tease = [static(f"party/tease/{p.name}") for p in sorted((STATIC_DIR / "tease").glob("*.*"))
|
|
if p.suffix.lower() in (".png", ".jpg", ".jpeg", ".webp", ".svg")]
|
|
return {"sfx": sfx, "tease": tease}
|
|
|
|
|
|
def tease_images() -> list[str]:
|
|
return asset_map()["tease"]
|