Kantine BHZ Kiel-Wik Speiseplan zu iCal

Liest die PDF-Speisepläne von kantine-bhz.de aus und erzeugt eine iCal-Datei (.ics) für den Import in Google Kalender. Jeder Termin enthält alle Tagesgerichte (I. bis V.) und ist auf 12:00 Uhr mittags gesetzt.

Voraussetzungen

  • Python 3.9+ (für zoneinfo)
  • Bestehendes venv unter .venv

Installation

  1. Virtuelle Umgebung aktivieren:

    Windows (PowerShell):

    .venv\Scripts\Activate.ps1
    

    Windows (CMD):

    .venv\Scripts\activate.bat
    
  2. Abhängigkeiten installieren:

    pip install -r requirements.txt
    

Nutzung

python kantine2ical.py

Erzeugt standardmäßig die Datei kantine_speiseplan.ics im aktuellen Verzeichnis.

Optionen:

  • -o DATEI / --output DATEI Ausgabedatei (Standard: kantine_speiseplan.ics)
  • --url URL Basis-URL der Kantine (Standard: http://kantine-bhz.de)

Beispiel:

python kantine2ical.py -o mein_speiseplan.ics

Google Kalender Import

  1. Google Kalender öffnen
  2. Neben „Meine Kalender“ auf das Drei-Punkte-Menü klicken → Import
  3. Die erzeugte .ics-Datei auswählen und dem gewünschten Kalender zuordnen

Die Termine erscheinen mit der Zeitzone Europe/Berlin um 12:00 Uhr mit allen fünf Tagesgerichten in der Beschreibung.


Server-Modus (abonnierbare URL)

Der Speiseplan kann als externer Kalender per URL angeboten werden. Ein Flask-Server liefert die iCal-Daten; Google Kalender und andere Clients können die URL direkt abonnieren. Im Hintergrund wird täglich nach neuen Speiseplan-PDFs gesucht und der Kalender aktualisiert.

Startseite: Unter der Stamm-URL (/) liefert der Server eine Startseite mit:

  • der Abo-URL zum Kopieren (inkl. „Kopieren“-Button),
  • einer Anleitung zur Einbettung in Google Kalender (Schritt für Schritt),
  • Kurzhinweisen für andere Kalender-Apps (Outlook, Apple Kalender, Thunderbird, Android/iOS),
  • der Angabe, wann die Speisepläne zuletzt aktualisiert wurden.

Die eigentliche iCal-Datei für Abos und direkten Download ist unter /calendar.ics erreichbar.

Voraussetzung: Für „Von URL hinzufügen“ in Google Kalender muss die Server-URL von außen erreichbar sein (öffentliche IP, Reverse-Proxy oder z. B. ngrok für Tests).

  1. Abhängigkeiten installieren (inkl. Flask): pip install -r requirements.txt
  2. Server starten:
    python app.py
    
    Oder mit Flask-CLI: flask --app app run --host 0.0.0.0 --port 5000
  3. Im Browser die Startseite aufrufen: http://<host>:5000/ dort die Abo-URL kopieren und die Anleitung nutzen.
  4. Direkte Abo-URL: http://<host>:5000/calendar.ics (bzw. Port durch Ihren Host ersetzen).
  5. In Google Kalender: „Andere Kalender hinzufügen“ → „Von URL“ → Abo-URL eintragen.

Konfiguration (optional, Umgebungsvariablen):

  • KANTINE_BASE_URL Basis-URL der Kantine (Standard: http://kantine-bhz.de)
  • REFRESH_INTERVAL_SECONDS Sekunden zwischen Aktualisierungen (Standard: 43200 = 12 h)
  • PUBLIC_URL Öffentliche Basis-URL (z. B. https://kantine.elpatron.me). Wenn gesetzt, wird diese URL für die Kalender-Abo-URL auf der Startseite verwendet. Empfohlen hinter HTTPS-Proxy, falls der Proxy keine X-Forwarded-Proto/X-Forwarded-Host-Header sendet sonst erscheint dort weiterhin http://.

Docker (Production)

Für den Betrieb als Container (z. B. auf einem Server):

Build und Run:

docker build -t kantine2ical .
docker run -p 8000:8000 -e PUBLIC_URL=https://kantine.elpatron.me kantine2ical

(Ersetzen Sie https://kantine.elpatron.me durch Ihre öffentliche HTTPS-URL. Dann zeigt die Startseite die Kalender-URL mit https://.)

  • Startseite (Anleitung + Abo-URL): http://<host>:8000/ bzw. Ihre HTTPS-URL
  • iCal-Abo: http://<host>:8000/calendar.ics bzw. https://<host>/calendar.ics
  • Manueller Refresh: GET /refresh (z. B. https://<host>/refresh) löst sofort einen Abruf der Speiseplan-PDFs aus. Nützlich, wenn auf kantine-bhz.de ein neuer Plan liegt und der 24h-Refresh noch nicht gelaufen ist. Nach dem Aufruf enthält der Kalender die aktuellen Daten.

Kalender wird nicht aktualisiert? Container-Logs prüfen (docker logs <container>): Dort erscheinen gefundene PDFs und Fehler beim Laden/Parsen. Bei fehlgeschlagenem PDF wird die URL und die Exception geloggt.

Mit Docker Compose:

docker compose up -d

Deploy-Ablauf (Update auf dem Server): Nach git pull und docker build muss der Container neu gestartet werden, damit das neue Image genutzt wird der laufende Container verwendet sonst weiter das alte Image.

git pull
docker compose build --no-cache    # oder: docker build -t kantine2ical . --no-cache
docker compose up -d --force-recreate

Ohne Compose (einzelner Container):

git pull
docker build -t kantine2ical . --no-cache
docker stop <container-name>      # laufenden Container stoppen
docker rm <container-name>        # optional
docker run -d -p 8000:8000 -e PUBLIC_URL=https://kantine.elpatron.me --name kantine2ical kantine2ical

Der Container läuft auf Port 8000 und startet bei Bedarf neu (restart: unless-stopped).

Hinweis: Für den Einsatz in Production wird ein Reverse-Proxy mit HTTPS (z. B. Traefik, Caddy oder nginx) vor dem Container empfohlen, damit Google die Kalender-URL zuverlässig abrufen kann.

Description
No description provided
Readme 4 MiB
Languages
Python 58.4%
HTML 40.5%
Dockerfile 1.1%