diff --git a/.moonweb.yml b/.moonweb.yml new file mode 100644 index 0000000..7dcfd37 --- /dev/null +++ b/.moonweb.yml @@ -0,0 +1,6 @@ +title: "MVG Departures" +emoji: "πŸš‡" +category: code +subcategory: "Smart Home Apps" +status: active +stack: [Python, FastAPI, Uvicorn, Jinja2] diff --git a/README.md b/README.md index 48664f6..e1f4c92 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# mvg-departures +# πŸš‡ mvg-departures Kompakter Abfahrtsmonitor fuer MVG U-Bahn und S-Bahn (Muenchen), primaer fuer mobile Nutzung optimiert. -## Features - -- Konfigurierbare Stationsliste (`config.yaml`) mit Typ (UBAHN/SBAHN/TRAM/BUS) -- Ausschluss-Filter pro Station: nur unerwuenschte Zielrichtungen werden ausgeblendet, - neue/unbekannte Ziele werden automatisch weiter angezeigt -- Profile zur Gruppierung von Stationen (z.B. "Hinfahrt" und "RΓΌckfahrt") - - Klickbare Kacheln zum Profilwechsel (nur bei >1 Profil) - - URL-Param `?profile=` + Auto-Refresh -- Zwei Endpunkte: - - `/` β€” mobile-optimierte HTML-Ansicht mit Auto-Refresh (alle 60s per Meta-Refresh) - - `/api/departures` β€” JSON-Ausgabe derselben Daten -- Anzeige von Linie, Ziel, Abfahrtszeit, Verspaetung und Stoerungsmeldungen -- Visuelle Unterscheidung von U-Bahn (blau) und S-Bahn (gruen) per Icon - ![Screenshot der Webseite](docs/screenshot.png) -## Konfiguration +## ✨ Features + +- πŸ—ΊοΈ Konfigurierbare Stationsliste (`config.yaml`) mit Typ (UBAHN/SBAHN/TRAM/BUS) +- 🚫 Ausschluss-Filter pro Station: nur unerwuenschte Zielrichtungen werden ausgeblendet, + neue/unbekannte Ziele werden automatisch weiter angezeigt +- πŸ‘€ Profile zur Gruppierung von Stationen (z.B. "Hinfahrt" und "RΓΌckfahrt") + - πŸ–±οΈ Klickbare Kacheln zum Profilwechsel (nur bei >1 Profil) + - πŸ”— URL-Param `?profile=` + Auto-Refresh +- 🌐 Zwei Endpunkte: + - `/` β€” mobile-optimierte HTML-Ansicht mit Auto-Refresh (alle 60s per Meta-Refresh) + - `/api/departures` β€” JSON-Ausgabe derselben Daten +- πŸ“Š Anzeige von Linie, Ziel, Abfahrtszeit, Verspaetung und Stoerungsmeldungen +- 🎨 Visuelle Unterscheidung von U-Bahn (blau) und S-Bahn (gruen) per Icon + +## βš™οΈ Konfiguration Siehe `config.yaml`: @@ -51,21 +51,21 @@ profiles: NICHT in der Liste steht, wird angezeigt β€” so fallen Linienaenderungen/Umleitungen sofort auf, statt lautlos verschwunden zu sein. -## Lokal starten +## πŸƒ Lokal starten ```bash pip install -r requirements.txt uvicorn app.main:app --reload ``` -## Docker +## 🐳 Docker ```bash docker build -t mvg-departures . docker run -p 8000:8000 -e TZ=Europe/Berlin -v $(pwd)/config.yaml:/app/config.yaml mvg-departures ``` -## Deployment +## πŸš€ Deployment Siehe `docker-compose.yml` im Repo als Referenz. Beispiel (Owner anpassen): @@ -85,28 +85,28 @@ services: - "com.centurylinklabs.watchtower.enable=true" ``` -## CI/CD +## πŸ”„ CI/CD `.github/workflows/build.yml`: -- Baut bei jedem Push auf `main` das Docker-Image und pusht es nach +- πŸ—οΈ Baut bei jedem Push auf `main` das Docker-Image und pusht es nach `ghcr.io//:latest` sowie mit Short-SHA-Tag -- Anschliessender Cleanup-Job loescht alte Image-Versionen in der GHCR-Package-Registry +- 🧹 Anschliessender Cleanup-Job loescht alte Image-Versionen in der GHCR-Package-Registry und behaelt nur die letzten 4 Versionen (`min-versions-to-keep: 4`) -### Voraussetzung +### πŸ“‹ Voraussetzung Repo-Settings β†’ Actions β†’ General β†’ Workflow permissions auf "Read and write permissions" stellen, sonst schlaegt der Push nach GHCR fehl. -## mvg api +## πŸ“‘ mvg api https://www.mvg.de/api/bgw-pt/v3/locations?query=Josephsburg \ https://www.mvg.de/api/bgw-pt/v3/locations?query=Berg%20am \ https://www.mvg.de/api/bgw-pt/v3/departures?globalId=de:09162:1220&limit=10&transportTypes=UBAHN \ https://www.mvg.de/api/bgw-pt/v3/departures?globalId=de:09162:910&limit=10&transportTypes=SBAHN -## Endpunkte +## πŸ”Œ Endpunkte | Route | Beschreibung | |---|---| @@ -116,7 +116,7 @@ https://www.mvg.de/api/bgw-pt/v3/departures?globalId=de:09162:910&limit=10&trans | `/api/departures?profile=` | JSON-Liste fΓΌr ein bestimmtes Profil | | `/healthz` | Healthcheck fuer Docker/Watchtower | -## Projektstruktur +## πŸ“ Projektstruktur ``` mvg-departures/ @@ -139,28 +139,28 @@ mvg-departures/ └── build.yml # CI/CD: Docker-Build + GHCR-Push ``` -## Tech-Stack +## πŸ› οΈ Tech-Stack -- **Runtime**: Python 3.14 -- **Framework**: FastAPI + Uvicorn -- **Templating**: Jinja2 (server-seitig) -- **MVG-API**: `mvg` Python-Client (oeffentlich, kein Auth noetig) -- **Config**: YAML via `pyyaml` -- **Container**: Docker (python:3.14-slim) +- ⚑ **Runtime**: Python 3.14 +- πŸš€ **Framework**: FastAPI + Uvicorn +- 🎨 **Templating**: Jinja2 (server-seitig) +- πŸš‡ **MVG-API**: `mvg` Python-Client (oeffentlich, kein Auth noetig) +- βš™οΈ **Config**: YAML via `pyyaml` +- 🐳 **Container**: Docker (python:3.14-slim) -## Caching +## πŸ’Ύ Caching -- **Station-ID**: In-memory Dict, lifetime=Session (loest Station-Namen auf) -- **Abfahrten**: In-memory Dict, TTL=`cache_seconds` (Default: 20s) pro Station+Typ -- Keine Persistenz β†’ Neustart = Cache-Verlust +- πŸ†” **Station-ID**: In-memory Dict, lifetime=Session (loest Station-Namen auf) +- ⏱️ **Abfahrten**: In-memory Dict, TTL=`cache_seconds` (Default: 20s) pro Station+Typ +- πŸ”„ Keine Persistenz β†’ Neustart = Cache-Verlust -## Einschraenkungen +## ⚠️ Einschraenkungen -- Kein WebSocket/Live-Updates (nur periodischer Meta-Refresh) -- Keine Datenbank (nur In-Memory) -- Kein Test-Framework vorhanden -- Ein `config.yaml` pro Deployment (kein Multi-Tenancy) +- πŸ“‘ Kein WebSocket/Live-Updates (nur periodischer Meta-Refresh) +- πŸ’½ Keine Datenbank (nur In-Memory) +- πŸ§ͺ Kein Test-Framework vorhanden +- πŸ“„ Ein `config.yaml` pro Deployment (kein Multi-Tenancy) -## Lizenz +## πŸ“œ Lizenz MIT License - Copyright (c) 2026 Stefan Koelle (https://stefankoelle.de)