feat: Schalter platziert die Willkommensseite sofort

Die Willkommensseite ist je Standort identisch. Bisher musste man nach
dem Einschalten des Schalters "Willkommensseite hier anzeigen" erneut
generieren, damit sie auf dem Screen ankam - ein Handgriff ohne anderes
Ergebnis, und ohne Rueckmeldung, dass er noetig ist.

- sync_welcome_for_screen() kopiert beim Einschalten eine vorhandene
  welcome.html in den Screen und setzt sie vorne in die Playlist; beim
  Ausschalten werden Eintrag und Datei entfernt. Aufgerufen aus
  update_screen(), nur wenn sich der Schalter wirklich aendert.
- save_welcome_page() legt zusaetzlich eine Standort-Kopie unter
  media/<site>/welcome.html an, die nie geloescht wird. Ohne sie waere
  nach dem Abschalten aller Screens keine Quelle mehr vorhanden und der
  Schalter wuerde wieder stillschweigend nichts tun.

Nebenbei behoben: beim Generieren wurde welcome.html aus abgewaehlten
Screens nur aus der Playlist entfernt, die Datei blieb liegen. Bei
leerer Playlist spielt player() noch nicht verzeichnete Dateien aus dem
Ordner ab - die Begruessung waere dort also weiter zu sehen gewesen.

README, AGENTS.md und Hilfeseite nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-09-02 14:54:44 +02:00
parent 048f2499d8
commit 9dae841461
5 changed files with 110 additions and 3 deletions

View File

@@ -499,6 +499,12 @@ def save_welcome_page(customer_names, logo_urls, contacts=None, site="stuttgart"
html_content = generate_welcome_html(customer_names, logo_urls, contacts=contacts,
site=site, background_url=background_url)
# Standort-Kopie zuerst - sie ueberlebt das Abschalten aller Screens
master = _welcome_master_path(site)
os.makedirs(os.path.dirname(master), exist_ok=True)
with open(master, "w", encoding="utf-8") as f:
f.write(html_content)
for screen in screens:
welcome_dir = os.path.join(MEDIA_DIR, site, screen)
os.makedirs(welcome_dir, exist_ok=True)
@@ -530,6 +536,87 @@ def _strip_welcome(playlist, filename):
]
def _welcome_path(site, screen):
return os.path.join(MEDIA_DIR, site, screen, WELCOME_FILENAME)
def _welcome_master_path(site):
"""Standort-Kopie der Willkommensseite. Sie liegt neben den Screen-Ordnern,
wird beim Generieren mitgeschrieben und nie geloescht - damit der Schalter
eines Screens die Seite auch dann noch platzieren kann, wenn sie zuvor
auf allen Screens abgeschaltet war."""
return os.path.join(MEDIA_DIR, site, WELCOME_FILENAME)
def find_welcome_source(site, config):
"""Sucht eine vorhandene welcome.html für einen Standort.
Die Seite ist je Standort identisch, jede Kopie taugt als Quelle.
Gibt den Pfad zurück oder None, wenn noch nie eine erzeugt wurde."""
master = _welcome_master_path(site)
if os.path.exists(master):
return master
screens = config.get("sites", {}).get(site, {}).get("screens", {})
for screen in sorted(screens):
pfad = _welcome_path(site, screen)
if os.path.exists(pfad):
return pfad
return None
def _remove_welcome_file(site, screen):
"""Löscht die welcome.html eines Screens, falls vorhanden."""
pfad = _welcome_path(site, screen)
if os.path.exists(pfad):
try:
os.remove(pfad)
except OSError as e:
print(f"⚠️ Generate - welcome.html in {site}/{screen} nicht löschbar: {e}")
def sync_welcome_for_screen(config, site, screen, enabled):
"""Bringt einen einzelnen Screen mit dem Schalter "Willkommensseite hier
anzeigen" in Einklang - ohne dass neu generiert werden muss.
enabled=True : vorhandene welcome.html hineinkopieren und vorne einfügen
enabled=False: Eintrag entfernen und die Kopie löschen
Verändert nur das übergebene config-Dict; das Speichern übernimmt der
Aufrufer. Gibt True zurück, wenn sich an der Playlist etwas geändert hat."""
screen_cfg = config.get("sites", {}).get(site, {}).get("screens", {}).get(screen)
if screen_cfg is None:
return False
playlist = screen_cfg.setdefault("playlist", [])
vorher = list(playlist)
if not enabled:
_strip_welcome(playlist, WELCOME_FILENAME)
_remove_welcome_file(site, screen)
return playlist != vorher
quelle = find_welcome_source(site, config)
if not quelle:
# Noch keine Willkommensseite erzeugt - dann gibt es nichts zu platzieren.
return False
ziel = _welcome_path(site, screen)
if os.path.abspath(quelle) != os.path.abspath(ziel):
try:
os.makedirs(os.path.dirname(ziel), exist_ok=True)
with open(quelle, "rb") as q, open(ziel, "wb") as z:
z.write(q.read())
except OSError as e:
print(f"❌ Generate - welcome.html nach {site}/{screen} nicht kopierbar: {e}")
return False
# Vorhandenen Eintrag entfernen und vorne neu einfügen
_strip_welcome(playlist, WELCOME_FILENAME)
playlist.insert(0, {"name": WELCOME_FILENAME, "enabled": True})
print(f"✅ Generate - Willkommensseite in {site}/{screen} platziert")
return True
def add_customer_to_playlists(html_filename, site="stuttgart", screens=None, valid_until=None):
"""Setzt die Willkommensseite an Position 0 der Playlist jedes Zielscreens.
@@ -570,6 +657,11 @@ def add_customer_to_playlists(html_filename, site="stuttgart", screens=None, val
_strip_welcome(playlist, html_filename)
if name in targets:
playlist.insert(0, dict(entry))
else:
# Auch die Datei entfernen - sonst bliebe auf einem abgewaehlten
# Screen eine verwaiste Kopie liegen, die bei leerer Playlist
# sogar noch abgespielt wuerde.
_remove_welcome_file(site, name)
save_config(config)