Untis-Vertretungsplan: WebServer/Anzeige
  • HTML 60.4%
  • Python 17.8%
  • JavaScript 17.8%
  • CSS 2.5%
  • Shell 0.8%
  • Other 0.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Pablo1732 4769a8d70d Version 0.4.0
- Uebersicht am Rand: Leiste links zeigt je Jahrgang/Stunde/Lehrkraft,
  ob der Abschnitt schon durchgelaufen ist, gerade sichtbar ist oder
  noch kommt. Wenige Gruppen als mitlaufende Kaestchen, viele (Lehrkraefte)
  als Register mit Balken. Pro Ansicht in den Einstellungen schaltbar.
- Lehrer-Kuerzel in der Verwaltung: Namen werden aus den Plaenen gesammelt,
  Kuerzel zuordnen, Lehrkraefte entfernen, Warnung bei doppelten Kuerzeln,
  ausblendbarer Hinweis bei neuen Lehrkraeften ohne Kuerzel, Import/Export.
  Ohne Kuerzel: Kurzform des Nachnamens ("Must", bei Gleichstand "MusA").
- Abstaende immer kompakt, Kopfabstand angeglichen.
- Verwaltung am Handy: 16-px-Eingaben (kein iOS-Zoom), groessere Knoepfe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 13:01:49 +01:00
design Version 0.4.0 2026-11-09 13:01:49 +01:00
scripts Version 0.3.5 2026-09-16 21:33:03 +02:00
vendor Version 0.1.0 2026-09-15 14:33:33 +02:00
.gitattributes Version 0.1.0 2026-09-15 14:33:33 +02:00
.gitignore Version 0.1.0 2026-09-15 14:33:33 +02:00
DESIGN.md Version 0.3.5 2026-09-16 21:33:03 +02:00
docker-compose.yml Version 0.4.0 2026-11-09 13:01:49 +01:00
Dockerfile Version 0.3.5 2026-09-16 21:33:03 +02:00
entrypoint.sh Version 0.3.5 2026-09-16 21:33:03 +02:00
generate_views.py Version 0.3.5 2026-09-16 21:33:03 +02:00
README.md Version 0.4.0 2026-11-09 13:01:49 +01:00
server.py Version 0.4.0 2026-11-09 13:01:49 +01:00
view.css Version 0.1.0 2026-09-15 14:33:33 +02:00
view.js Version 0.1.0 2026-09-15 14:33:33 +02:00

vplan-webserver

Zeigt den Vertretungsplan (aus vertretungen.json, geschrieben vom vplan-parser) als Webseite -- in drei Ansichten, jede unter einer eigenen Adresse:

  • …/schueler/ -- Schueleransicht (nach Klassen)
  • …/lehrer_sort_stunden/ -- Lehreransicht, nach Stunden
  • …/lehrer_sort_lehrkraft/ -- Lehreransicht, nach Lehrkraft (Vertretung steht bei alter und neuer Lehrkraft)

Optional: Uebersicht am Rand -- zeigt auf einen Blick, ob ein Jahrgang / eine Lehrkraft heute dabei ist und ob der Abschnitt schon durchgelaufen ist (siehe Admin-Panel).

Laedt die JSON alle paar Sekunden neu und wechselt flackerfrei auf den neuen Stand.

Zusaetzlich gibt es eine Aushang-Verwaltung unter …/admin/ (nur fuer die Schulleitung): Bilder/PDFs/Textmeldungen als Aushang schalten, Feueralarm und Amok/Lockdown ein-/ausschalten -- serverseitig, von jedem Geraet aus bedienbar.

Setup / Installation

1. Docker vorhanden?

docker version

2. Bei der Registry anmelden (einmalig)

docker login git.pablo1732.de

3. Wo liegt die vertretungen.json?

Der Webserver erzeugt sie nicht selbst -- sie kommt vom Parser-Container. In der docker-compose.yml ist ./data/json eingehaengt; ggf. den Pfad anpassen.

4. Starten

docker compose pull
docker compose up -d

Anzeige unter http://<server>:8080/ (lokal: localhost).

Kontrolle: docker compose logs -f (mit Strg+C wieder raus).

Auf den Aula-Displays z.B. im Kiosk-Modus:

chrome.exe --kiosk http://<server>:8080/schueler/

Bedienung / Anpassung

docker compose up -d      # startet im Hintergrund
docker compose logs -f    # Live-Logs ansehen
docker compose down       # stoppt und entfernt den Container
docker compose restart    # neu starten (z.B. nach Aenderung der Einstellungen)

Einstellungen

Einstellung Standard Bedeutung
POLL_SECONDS 20 Sekunden zwischen zwei Pruefungen auf eine neue vertretungen.json.
PORT 8080 Port im Container. Muss zum Wert unter ports: passen.
JSON_DIR /data/json Ordner im Container mit der Live-vertretungen.json.
STATE_DIR /data/userdata Ordner im Container fuer Aushang-Zustand + Uploads.
SCHULNAME Johannes-Gutenberg-Gymnasium Schulname in der Kopfzeile.
ADMIN_USER schulleitung Benutzername fuers Admin-Panel.
ADMIN_PASSWORD bitte-aendern Passwort fuers Admin-Panel. Leer = Login deaktiviert. bitte-aendern = Login gesperrt, bis ein eigenes gesetzt ist.
ADMIN_PASSWORD_HASH (leer) Alternative zu ADMIN_PASSWORD: PBKDF2-Hash statt Klartext.
SESSION_HOURS 8 Wie lange eine Anmeldung gueltig bleibt.
MAX_UPLOAD_MB 25 Maximale Groesse pro hochgeladener Datei.
LOGIN_MAX_FAILS 5 Fehlversuche pro IP bis zur (ansteigenden) Sperre.
LOG_LEVEL warning debug = jede Anfrage · info = + Logins/Aushaenge · warning = Alarme, Fehlversuche, Warnungen · error = nur Fehler.
DESIGN_DIR (eingebaut) Nur fuer ein eigenes Design ohne Neubau (siehe unten).

Die drei Ansichten

Immer dieselben Daten, nur anders sortiert. Jede Ansicht ist auf 1920x1080 ausgelegt und skaliert sich automatisch auf die Fenstergroesse.

Aushang-Verwaltung (Admin-Panel)

Unter http://<server>:8080/admin/ meldet sich die Schulleitung an und kann neben dem Plan einen Aushang einblenden oder einen Alarm schalten (Platzierung links/rechts/vollbild, dauerhaft oder im Intervall, Diashow). Zustand liegt auf dem Server -- Bedienung von jedem Geraet aus moeglich.

  • Einstellungen (Zahnrad): getrennt fuer Schueler- und Lehreransicht, mit "Standard"-Knopf:
    • Scrollgeschwindigkeit und Tabellenschrift (je 5 Stufen)
    • Uebersicht am Rand (an/aus, Standard aus): links neben dem Plan ein Eintrag je Jahrgang / Stunde / Lehrkraft. Dunkel = gerade zu sehen, grau = schon durchgelaufen, umrandet = kommt noch. Wenige Gruppen: Kaestchen laufen mit ihrer Ueberschrift mit. Viele (Lehrkraefte): alle Kuerzel als Liste, ein dunkler Balken markiert die sichtbaren.
  • Lehrer-Kuerzel (Einstellungen, unten): Untis liefert nur Namen (Muster_A), keine Kuerzel.
    • Lehrkraefte aus dem Plan kommen automatisch in die Liste; Kuerzel eintragen, speichern.
    • Warnung bei doppelten/ungueltigen Kuerzeln (max. 6 Zeichen, Buchstaben/Ziffern).
    • Hinweis im Panel bei Lehrkraeften ohne Kuerzel; "Ausblenden" bis eine neue dazukommt.
    • Import (CSV/Text): Kuerzel;Name je Zeile oder abwechselnd Kuerzel- und Namenszeile. Volle Namen ("Anna Muster") werden zugeordnet, bei gleichem Nachnamen per Vornamen. Wer noch nie im Plan war, wird vorgemerkt und automatisch zugeordnet, sobald er auftaucht.
    • Export: CSV (Excel-tauglich), vollstaendige Sicherung inkl. Vorgemerkter.
    • Ohne Kuerzel zeigt die Anzeige den gekuerzten Namen gross geschrieben (Erlm, bei Gleichstand mit Initiale HacR).
    • Gespeichert in STATE_DIR (state.json) -- Namen der Lehrkraefte, nicht ins Git.
  • Plan-Hinweise: Stoerungen/Warnungen zur vertretungen.json stehen oben im Panel, mit Details zur Fehlersuche, und im Log (Stoerung = FEHLER, sonst WARNUNG).

Hinweise auf der Anzeige

Hinweis Wann
Server nicht erreichbar – Anzeige evtl. veraltet > 1 min keine Server-Antwort (hat Vorrang, auch im Vollbild-Aushang; blinkt ab 15 min)
Störung: Plan konnte nicht gelesen werden vertretungen.json fehlt, ist kaputt oder der Parser meldet "fehlgeschlagen"
Plan möglicherweise unvollständig / Angaben teilweise unsicher Warnstufe des Parsers
Plan veraltet Datei enthaelt keinen Tag ab heute

Aushang-Bilder werden vorgeladen; faellt der Server aus, laeuft die Diashow weiter. Nicht ladbare Bilder zeigen "Aushang kann nicht geladen werden" statt einer weissen Flaeche.

Zugangsdaten kommen aus der docker-compose.yml (ADMIN_USER/ ADMIN_PASSWORD). Ohne gesetztes ADMIN_PASSWORD ist der Login deaktiviert -- also ein sicheres Passwort setzen.

Passwort nicht im Klartext? PBKDF2-Hash statt ADMIN_PASSWORD erzeugen:

docker run --rm --entrypoint python3 git.pablo1732.de/schule/vplan-webserver:latest /opt/vplan-web/server.py --hash 'MeinPasswort'

Ergebnis in ADMIN_PASSWORD_HASH eintragen, ADMIN_PASSWORD leer lassen.

⚠️ Kein HTTPS. Login und Sitzungs-Cookie reisen im LAN im Klartext -- nur im vertrauenswuerdigen Schul-LAN betreiben, sonst TLS-Reverse-Proxy davor.

Keine/veraltete Daten?

  • "Keine Plandaten geladen": Der Webserver findet keine vertretungen.json. Liegt sie im eingehaengten Ordner? Laeuft der Parser-Container?
  • "Plan veraltet": Die JSON enthaelt nur vergangene Tage -- normal, wenn gerade kein aktueller Plan vorliegt.

Eigenes Design ohne Neubau (optional)

  1. Designordner in der docker-compose.yml einhaengen:
    - ./mein_design:/design:ro
    
  2. Darueber unter environment: setzen: DESIGN_DIR: "/design".
  3. docker compose up -d -- kein Neubau noetig.

Wie ein Design aufgebaut sein muss und wie man eins fest einbaut: siehe DESIGN.md.

Image selbst bauen

IMAGE_TAG=0.4.0 sh scripts/build-images.sh

Baut Multi-Arch (amd64+arm64) und pusht nach git.pablo1732.de/schule/vplan-webserver. Voraussetzung: einmalig docker login git.pablo1732.de (Token-Scope "package: Lesen und Schreiben").