feat: Willkommensseite auf mehreren Screens anzeigen

Die Willkommensseite ging bisher fest in die Lobby-Playlist. Welche
Screens Begruessungsschirme sind, ist aber eine Eigenschaft der
Installation und nicht des einzelnen Kundenbesuchs - deshalb ein Flag
pro Screen statt einer Auswahl bei jedem Vorgang.

- Neue Screen-Einstellung "welcome_enabled" (Checkbox im Tab
  Einstellungen). Die generierte welcome.html wird in jeden markierten
  Screen des Standorts geschrieben und dort an Position 0 gesetzt.
- welcome_target_screens() faellt nur auf "lobby" zurueck, wenn kein
  Screen des Standorts den Schluessel besitzt. Bestehende Standorte
  verhalten sich damit ohne Konfigurationsaufwand unveraendert.
- add_customer_to_playlists() (frueher add_customer_to_lobby_playlist)
  raeumt welcome.html aus allen Screens des Standorts und fuegt sie nur
  in den Zielscreens wieder ein. Ein abgewaehlter Screen bleibt so nicht
  mit einer alten Begruessung stehen.
- Eingefuegt wird ein Dict statt eines Strings, damit der Eintrag
  enabled und schedule tragen kann.
- Optionales "Anzeigen bis" im Formular: setzt eine Zeitsteuerung, die
  Seite verschwindet danach auf allen Screens von selbst.
- Das Formular zeigt die aktuellen Zielscreens an und meldet
  verstaendlich, wenn keiner markiert ist.
- screens.setdefault("lobby", {}) entfernt - das legte an Standorten
  ohne Lobby stillschweigend einen Screen an. Es werden nur noch
  vorhandene Screens bespielt.

Die Seite referenziert alle Bilder absolut (/static/..., /media/...),
ist also ortsunabhaengig; je Screen liegt eine identische Kopie.

README, AGENTS.md und die Hilfeseite nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-09-02 12:26:22 +02:00
parent 3761497421
commit 848bcf93ab
7 changed files with 177 additions and 49 deletions

45
app.py
View File

@@ -892,13 +892,15 @@ def add_customer():
Formular für die Willkommensseite:
- Bis zu 3 Kundennamen eingeben
- Logos per OpenAI → Brandfetch suchen
- welcome.html wird generiert und in der Lobby-Playlist vorne platziert
- welcome.html wird generiert und in den Playlists aller Zielscreens
vorne platziert (Screens mit "welcome_enabled")
"""
error = None
success = None
logo_urls = [None, None, None]
customer_names = ["", "", ""]
contacts = ["", "", ""]
valid_until = (request.form.get("valid_until") or "").strip()
site = request.args.get("site") or request.form.get("site") or ""
# Fallback auf ersten für den User zugänglichen Standort
@@ -959,20 +961,34 @@ def add_customer():
break
bg_url = get_background_url(site)
html_filename = generate_welcome_page.save_welcome_page(valid_names, valid_urls, contacts=valid_contacts, site=site, background_url=bg_url)
targets = generate_welcome_page.welcome_target_screens(load_config(), site)
if not targets:
error = ("Kein Screen für die Willkommensseite ausgewählt – "
"im Tab 'Einstellungen' eines Screens aktivieren")
html_filename = None
else:
html_filename = generate_welcome_page.save_welcome_page(
valid_names, valid_urls, contacts=valid_contacts,
site=site, background_url=bg_url, screens=targets)
if html_filename:
if generate_welcome_page.add_customer_to_lobby_playlist(html_filename, site=site):
if generate_welcome_page.add_customer_to_playlists(
html_filename, site=site, screens=targets, valid_until=valid_until):
# Letzte Kundendaten für Background-Update speichern
config = load_config()
site_cfg = config.setdefault("sites", {}).setdefault(site, {})
site_cfg["welcome_data"] = {"names": valid_names, "logo_urls": valid_urls, "contacts": valid_contacts}
save_config(config)
add_history_entry("customer_added", f"Kunden ({', '.join(valid_names)}) zur Willkommensseite an Standort '{site}' hinzugefügt", current_user.email)
success = f"✅ Willkommensseite mit {len(valid_names)} Kunden erstellt!"
add_history_entry("customer_added", f"Kunden ({', '.join(valid_names)}) zur Willkommensseite an Standort '{site}' hinzugefügt (Screens: {', '.join(targets)})", current_user.email)
success = (f"✅ Willkommensseite mit {len(valid_names)} Kunden erstellt "
f"– angezeigt auf: {', '.join(targets)}")
if valid_until:
success += f" (bis einschliesslich {valid_until})"
else:
error = "Fehler beim Hinzufügen zur Playliste"
else:
elif targets:
# Ohne Zielscreens steht die Meldung dazu bereits in error
error = "Fehler beim Speichern der Willkommensseite"
except ValueError as e:
error = f"Konfigurationsfehler: {str(e)}"
@@ -1002,6 +1018,7 @@ def add_customer():
logo_urls=logo_urls,
customer_names=customer_names,
contacts=contacts,
welcome_screens=generate_welcome_page.welcome_target_screens(config, site) if site else [],
site=site,
site_list=site_list,
current_site=site,
@@ -1047,18 +1064,27 @@ def api_add_customer():
contact = data.get("contact", "").strip()
html_filename = generate_welcome_page.save_welcome_page([customer_name], [logo_url], contacts=[contact], site=site)
valid_until = (data.get("valid_until") or "").strip()
targets = generate_welcome_page.welcome_target_screens(load_config(), site)
if not targets:
return jsonify({"error": "No welcome screen configured for this site"}), 400
html_filename = generate_welcome_page.save_welcome_page(
[customer_name], [logo_url], contacts=[contact], site=site, screens=targets)
if not html_filename:
return jsonify({"error": "Failed to create welcome page"}), 500
if generate_welcome_page.add_customer_to_lobby_playlist(html_filename, site=site):
if generate_welcome_page.add_customer_to_playlists(
html_filename, site=site, screens=targets, valid_until=valid_until):
return jsonify({
"success": True,
"message": f"Customer '{customer_name}' added successfully",
"welcome_page": html_filename,
"logo_url": logo_url,
"site": site
"site": site,
"screens": targets
}), 201
else:
return jsonify({"error": "Failed to add to playlist"}), 500
@@ -1527,6 +1553,7 @@ def update_screen(site, screen):
cfg["newsticker_text"] = request.form.get("newsticker_text", "")
cfg["newsticker_enabled"] = "newsticker_enabled" in request.form
cfg["stay_on_first"] = "stay_on_first" in request.form
cfg["welcome_enabled"] = "welcome_enabled" in request.form
save_config(config)
return redirect(f"/admin/{site}")