mirror of
https://github.com/skoelle/calender_sync.git
synced 2026-09-17 18:20:24 +00:00
152 lines
5.9 KiB
Markdown
152 lines
5.9 KiB
Markdown
# AGENTS.md
|
|
|
|
Richtlinien für AI-Agenten die mit dem calender_sync Projekt arbeiten.
|
|
|
|
## Projektübersicht
|
|
|
|
Python-basierter Google Calendar → MariaDB Synchronizer. Läuft als Docker Container im Homelab und pollt periodisch einen ICS-Feed.
|
|
|
|
## Technologie-Stack
|
|
|
|
- **Sprache**: Python 3.12
|
|
- **Datenbank**: MariaDB (mysql-connector-python) oder SQLite (stdlib) via `DB_BACKEND` Env-Var
|
|
- **API**: FastAPI + Uvicorn + Jinja2
|
|
- **Docker**: Multi-Stage Build nicht verwendet, simples Slim-Image
|
|
- **Dependencies**: requests, icalendar, recurring-ical-events, mysql-connector-python, fastapi, uvicorn, jinja2
|
|
|
|
## Projektstruktur
|
|
|
|
```
|
|
.
|
|
├── sync.py # Hauptskript (alles in einer Datei)
|
|
├── api/
|
|
│ ├── main.py # FastAPI App (REST API + HTML UI)
|
|
│ ├── database.py # DB-Verbindung (MySQL + SQLite)
|
|
│ └── templates/
|
|
│ └── index.html # Jinja2 Template für Web-UI
|
|
├── demo/
|
|
│ └── seed.py # SQLite Demo-Datenbank erstellen
|
|
├── demo.sh # Lokaler Demo-Start (ohne Docker)
|
|
├── requirements.txt # Python Dependencies
|
|
├── Dockerfile # Docker Image Definition
|
|
├── docker-compose.yml # Docker Compose Konfiguration
|
|
├── mariadb-setup.sql # Manuelles DB-Setup Script
|
|
├── .env.example # Beispiel-Umgebungsvariablen
|
|
└── .github/workflows/ # CI/CD (Docker Build + Push)
|
|
```
|
|
|
|
## Wichtige Hinweise
|
|
|
|
### Kein Framework
|
|
Das Projekt verwendet kein Web-Framework für den Sync-Teil. `sync.py` ist ein eigenständiges Python-Skript mit einer Endlosschleife (`main()` → `time.sleep()`).
|
|
|
|
### FastAPI Applikation
|
|
Die API (`api/main.py`) ist eine separarte FastAPI-App die als eigenständiger Container läuft:
|
|
- **Web-UI**: `GET /` - Jinja2 Template mit anstehenden Termine und Suchfunktion
|
|
- **REST API**: `GET /api/events` - JSON-Liste zukünftiger Events
|
|
- **Einzeln-Event**: `GET /api/events/{id}` - Einzelnes Event als JSON
|
|
- **Health Check**: `GET /api/health` - Gibt `{"status": "ok"}` zurück
|
|
- Läuft über Uvicorn auf Port 8000
|
|
- Teilt sich die Datenbank mit `sync.py`, verwendet aber eigene DB-Verbindung (`api/database.py`)
|
|
|
|
### Datenbank-Schema
|
|
Schema wird in `ensure_schema()` per `CREATE TABLE IF NOT EXISTS` erstellt. Bei Schema-Änderungen:
|
|
- `ensure_schema()` in `sync.py:83` anpassen
|
|
- MariaDB-kompatibles SQL verwenden (kein PostgreSQL-Specific)
|
|
- Indexe für Performance bedenken
|
|
|
|
### Event-Expansion
|
|
Verwendet `recurring_ical_events` Bibliothek für RRULE/EXDATE/RECURRENCE-ID Expansion. Fenster wird über `WINDOW_PAST_DAYS`/`WINDOW_FUTURE_DAYS` gesteuert.
|
|
|
|
### UTC-Normalisierung
|
|
Alle Zeiten werden in naive UTC datetime konvertiert (`to_naive_utc()`). Bei Datumsänderungen sicherstellen, dass die Zeitzone korrekt verarbeitet wird.
|
|
|
|
### Soft-Delete
|
|
Events werden nicht gelöscht, sondern mit `deleted=1` markiert (`mark_missing_as_deleted()`).
|
|
|
|
### Tägliche E-Mail-Benachrichtigung
|
|
Sendet täglich um konfigurierte Uhrzeit eine HTML-Email mit anstehenden Terminen:
|
|
- Nur Termine mit Uhrzeit (`all_day=0`), keine Ganztagstermine
|
|
- Subject: Bei 1 Termin direkt "Kalender heute: HH:MM - Termin", bei mehreren "Kalender heute: X Termine"
|
|
- Tracking via `daily_notification_log` Tabelle (verhindert Doppelversand)
|
|
- Konfiguration über SMTP_* und NOTIFY_* Umgebungsvariablen
|
|
- Funktionen: `get_today_events()`, `should_notify()`, `send_notification()`, `log_notification()`
|
|
|
|
### Wöchentliche E-Mail-Benachrichtigung (Vorab-Info)
|
|
Sendet wöchentlich (standardmäßig Freitags) eine HTML-Email mit Terminen, die auf Suchbegriffe passen:
|
|
- Sucht nach Begriffen in summary, description und location
|
|
- Optionale Blacklist: Begriffe die ausgeschlossen werden (z.B. `WEEKLY_BLACKLISTWORDS=Ausgeschlossen1,Ausgeschlossen2`)
|
|
- Zeitraum: Samstag bis Freitag der nächsten Woche
|
|
- Subject: Bei 1 Termin "Vorab-Info: Termin am Mo, DD.MM.", bei mehreren "Vorab-Info: X Termine nächste Woche"
|
|
- Tracking via `weekly_notification_log` Tabelle (verhindert Doppelversand)
|
|
- Nur Termine mit Uhrzeit (`all_day=0`), keine Ganztagstermine
|
|
- Keine Email wenn keine Treffer
|
|
- Konfiguration über WEEKLY_* Umgebungsvariablen
|
|
- Funktionen: `parse_weekly_searchwords()`, `parse_weekly_blacklistwords()`, `get_weekly_events()`, `should_send_weekly()`, `send_weekly_notification()`, `log_weekly_notification()`, `check_and_send_weekly_notification()`
|
|
|
|
## Entwicklung
|
|
|
|
### Lokaler Test (Docker)
|
|
```bash
|
|
# Dependencies installieren
|
|
pip install -r requirements.txt
|
|
|
|
# .env anlegen (aus .env.example kopieren)
|
|
cp .env.example .env
|
|
|
|
# Direkt ausführen
|
|
python sync.py
|
|
```
|
|
|
|
### Lokaler Test (Demo, ohne MariaDB)
|
|
```bash
|
|
# Startet venv, erstellt SQLite Demo-DB mit 4 Events, startet API
|
|
./demo.sh
|
|
```
|
|
|
|
Oder manuell:
|
|
```bash
|
|
python3 -m venv .venv && source .venv/bin/activate
|
|
pip install -r requirements.txt
|
|
python demo/seed.py
|
|
DB_BACKEND=sqlite DB_PATH=demo/demo.db python -m uvicorn api.main:app --port 8000
|
|
```
|
|
|
|
### Linting & Type Checking
|
|
Keine Linting/Type-Checking Tools konfiguriert. Bei Bedarf hinzufügen:
|
|
- `ruff` für Linting
|
|
- `mypy` für Type Checking
|
|
|
|
### Tests
|
|
Keine Tests vorhanden. Bei Bedarf:
|
|
- `pytest` als Test-Framework verwenden
|
|
- Mock für `requests.get()` und `mysql.connector` erstellen
|
|
- Unit Tests für `to_naive_utc()`, `instance_key_for()`, `expand_events()`
|
|
|
|
## Code-Style
|
|
|
|
- Kein Docstring-Standard definiert
|
|
- Logging über `logging` Modul mit configurable Level
|
|
- Error Handling: Exceptions fangen, loggen, aber nicht verschlucken
|
|
- Keine externen Config-Libraries (nur `os.environ`)
|
|
|
|
## Docker
|
|
|
|
- Image basiert auf `python:3.12-slim`
|
|
- Kein Multi-Stage Build nötig (einfaches Projekt)
|
|
- `PYTHONUNBUFFERED=1` für Logging im Container
|
|
- Watchtower Label für Auto-Updates
|
|
|
|
## CI/CD
|
|
|
|
GitHub Actions Workflow:
|
|
- Baut Docker Image bei Push zu `main`
|
|
- Published nach `ghcr.io/skoelle/calender_sync:latest`
|
|
- Keine Tests im Workflow (derzeit)
|
|
|
|
## Lizenz
|
|
|
|
MIT License - Copyright (c) 2026 Stefan Koelle (https://stefankoelle.de)
|
|
- Vollständiger Text in `LICENSE`
|
|
- Lizenz-Header in allen Python-Dateien
|