chore: remove non-docker artifacts and docs

This commit is contained in:
2026-03-03 08:47:19 +00:00
parent e888772488
commit 394a5fc234
28 changed files with 68 additions and 3136 deletions

View File

@@ -1,152 +0,0 @@
# Standalone Builds (Linux, macOS, Windows)
Diese Anleitung erstellt eigenständige Anwendungen mit **PyInstaller** auf dem jeweiligen Zielbetriebssystem.
## Wichtig
- Builds müssen **nativ pro OS** erstellt werden (kein Cross-Compile mit diesen Skripten).
- Verwenden Sie eine aktive und funktionierende `.venv` im Projektordner.
- Die GUI wird aus `gui_wxpython.py` gebaut.
---
## Release auf einen Blick
### Linux
```bash
./build/build_linux.sh
./build/package_linux.sh
```
### macOS
```bash
./build/build_macos.sh
./build/package_macos.sh
```
### Windows
```cmd
build\build_windows.cmd
build\package_windows.cmd
```
---
## Empfohlene Release-Reihenfolge
1. Version erhöhen (z. B. `version.txt` und Changelog)
2. Pro Zielplattform Build + Packaging ausführen
3. Artefakte im `release/`-Ordner prüfen
4. Git-Commit erstellen und Tag setzen (z. B. `v1.2.0`)
5. Tag und Branch pushen
6. Release-Artefakte auf der Release-Seite hochladen
Beispiel Git-Workflow:
```bash
git add -A
git commit -m "Release x.y.z"
git tag -a vx.y.z -m "vx.y.z"
git push origin main
git push origin vx.y.z
```
Optional per CI:
- Workflow: `.gitea/workflows/build-standalone-release.yml`
- Trigger: Tag-Push `v*`
- Ergebnis: Plattform-Artefakte als CI-Artefakte
---
## Linux
```bash
chmod +x build/build_linux.sh
./build/build_linux.sh
```
Ergebnis:
- `dist/PDFtoICS/` (Ordner mit ausführbarer Datei)
Optional als Release-Archiv (`.tar.gz`) verpacken:
```bash
chmod +x build/package_linux.sh
./build/package_linux.sh
```
Ergebnis:
- `release/PDFtoICS-linux-v<VERSION>.tar.gz`
---
## macOS
```bash
chmod +x build/build_macos.sh
./build/build_macos.sh
```
Ergebnis:
- `dist/PDFtoICS.app`
Hinweis:
- Für öffentliche Verteilung ist Code-Signing/Notarisierung empfohlen.
Optional als Release-Archiv (`.zip`) verpacken:
```bash
chmod +x build/package_macos.sh
./build/package_macos.sh
```
Ergebnis:
- `release/PDFtoICS-macos-v<VERSION>.zip`
---
## Windows
Starten Sie unter Windows:
```cmd
build\build_windows.cmd
```
Ergebnis:
- `dist\PDFtoICS\PDFtoICS.exe`
Hinweis:
- Für weniger SmartScreen-Warnungen ist Signierung empfohlen.
Optional als Release-Archiv (`.zip`) verpacken:
```cmd
build\package_windows.cmd
```
Ergebnis:
- `release\PDFtoICS-windows-v<VERSION>.zip`
---
## Clean Build
PyInstaller erstellt `build/` und `dist/` sowie eine `.spec` Datei im Projektverzeichnis.
Optionales Aufräumen:
```bash
rm -rf build dist *.spec
```
Unter Windows:
```cmd
rmdir /s /q build
rmdir /s /q dist
del /q *.spec
```

View File

@@ -1,54 +0,0 @@
# 🎨 GUI Installation (wxPython)
Die grafische Benutzeroberfläche nutzt **wxPython** für ein natives Look & Feel auf Linux, macOS und Windows.
## GUI starten
**Linux/macOS:**
```bash
./start_gui.sh
```
**Windows:**
```
Doppelklick auf start_gui.cmd
```
Beim ersten Start werden `.venv`, Kern-Abhängigkeiten und `wxPython` automatisch installiert.
## GUI-Features
**Native Oberfläche:** Optisch passend zum Betriebssystem
📋 **Mehrere PDFs:** Wählen Sie mehrere Dateien gleichzeitig
📁 **Ausgabe-Verzeichnis:** Wählen Sie, wo die ICS-Dateien gespeichert werden
📊 **Echtzeit-Log:** Sehen Sie den Fortschritt live
🖱️ **Drag & Drop:** Direkt in die PDF-Liste ziehen
## Fehlerbehebung
### "No module named 'wx'"
`wxPython` konnte nicht installiert werden.
Unter Linux Mint/Ubuntu helfen häufig:
```bash
sudo apt-get update
sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev
rm -rf .venv
./start_gui.sh
```
### GUI startet nicht
```bash
rm -rf .venv
./start_gui.sh
```
### Fenster erscheint nicht
→ Stellen Sie sicher, dass eine grafische Sitzung aktiv ist (kein reines SSH ohne X11/Wayland-Forwarding).
## Alternative: CLI-Version
Falls keine GUI möglich ist:
```bash
./start.sh
```

View File

@@ -1,162 +0,0 @@
# 📦 Installation - PDF zu ICS Konverter
Eine einfache Installation für Linux-Systeme, die die Anwendung in Ihr Anwendungsmenü integriert.
## 🚀 Schnell-Installation
```bash
chmod +x install.sh
./install.sh
```
Das war's! Die Anwendung erscheint nun in Ihrem Anwendungsmenü unter "PDF zu ICS Konverter".
## 📋 Was macht das Installations-Script?
1.**Prüft Python-Installation** (Python 3.6+)
2.**Installiert wxPython** in der virtuellen Umgebung
3.**Erstellt Installationsverzeichnis** in `~/.local/share/pdf-to-ics`
4.**Kopiert alle Dateien** ins Installationsverzeichnis
5.**Erstellt Python Virtual Environment** mit allen Abhängigkeiten
6.**Erstellt Desktop-Verknüpfung** für das Anwendungsmenü
7.**Erstellt Launcher-Script** in `~/.local/bin/pdf-to-ics`
## 🎯 Nach der Installation
Die Anwendung starten Sie auf drei Arten:
### 1. Über das Anwendungsmenü (Empfohlen)
- Öffnen Sie Ihr Anwendungsmenü (z.B. GNOME Activities, KDE Application Launcher)
- Suchen Sie nach "PDF zu ICS"
- Klicken Sie auf das Icon
### 2. Über die Kommandozeile
```bash
pdf-to-ics
```
### 3. Über den vollständigen Pfad
```bash
~/.local/bin/pdf-to-ics
```
## 🔧 Systemanforderungen
### Unterstützte Distributionen:
- ✅ Ubuntu / Debian / Linux Mint
- ✅ Fedora / RHEL
- ✅ Arch Linux
- ✅ Andere Distributionen (ggf. zusätzliche Build-Abhängigkeiten nötig)
### Voraussetzungen:
- Python 3.6 oder höher
- Internetzugang für `pip install wxPython`
- Etwa 50 MB Festplattenspeicher
## 📁 Installations-Pfade
```
~/.local/share/pdf-to-ics/ # Hauptinstallation
~/.local/bin/pdf-to-ics # Launcher-Script
~/.local/share/applications/ # Desktop-Verknüpfung
~/.pdf_to_ics_config.json # Benutzer-Einstellungen
```
## 🗑️ Deinstallation
```bash
~/.local/share/pdf-to-ics/uninstall.sh
```
Das Deinstallations-Script entfernt:
- ✅ Installationsverzeichnis
- ✅ Desktop-Verknüpfung
- ✅ Launcher-Script
- ⚠️ Konfigurationsdatei (optional)
## ⚠️ Fehlerbehebung
### "wxPython konnte nicht installiert werden"
**Ubuntu/Debian/Linux Mint:**
```bash
sudo apt-get update
sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev
```
### "pdf-to-ics: Befehl nicht gefunden"
Ihr `~/.local/bin` ist nicht im PATH. Fügen Sie zu `~/.bashrc` hinzu:
```bash
export PATH="$HOME/.local/bin:$PATH"
```
Dann Terminal neu laden:
```bash
source ~/.bashrc
```
### Windows: "python" oder "python3" wurde nicht gefunden
1. Installieren Sie Python 3.10+ von python.org und aktivieren Sie beim Setup **"Add Python to PATH"**.
2. Öffnen Sie danach eine neue Eingabeaufforderung im Projektordner.
3. Führen Sie aus:
```bat
py -3 -m venv .venv --upgrade-deps
.\.venv\Scripts\python.exe -m pip install -q pdfplumber icalendar pypdf2 pytz packaging
.\.venv\Scripts\pythonw.exe gui_wxpython.py
```
### Anwendung erscheint nicht im Menü
Aktualisieren Sie die Desktop-Datenbank:
```bash
update-desktop-database ~/.local/share/applications
```
Oder melden Sie sich ab und wieder an.
## 🔄 Update
Um auf eine neue Version zu aktualisieren:
```bash
# 1. Deinstallieren
~/.local/share/pdf-to-ics/uninstall.sh
# 2. Neue Version herunterladen
cd /pfad/zur/neuen/version
# 3. Neu installieren
./install.sh
```
## 💡 Entwickler-Modus
Wenn Sie an der Anwendung entwickeln möchten, nutzen Sie stattdessen:
```bash
./start_gui.sh # Startet aus dem aktuellen Verzeichnis
```
Die Installation ist nur für End-Benutzer gedacht.
## 🐧 Andere Betriebssysteme
- **Windows:** Nutzen Sie `start_gui.cmd` (Python 3.10+ erforderlich, Einrichtung beim ersten Start erfolgt automatisch)
- **macOS:** Nutzen Sie `start_gui.sh` (keine Installation nötig)
## 📞 Support
Bei Problemen während der Installation:
1. Prüfen Sie die Systemanforderungen
2. Lesen Sie die Fehlermeldungen sorgfältig
3. Konsultieren Sie die README.md
4. Öffnen Sie ein Issue im Repository
---
**Installation erfolgreich?** Viel Spaß beim Konvertieren Ihrer Dienstpläne! 📅✨

View File

@@ -1,102 +0,0 @@
# 🚀 Quick Start Guide
## Schnellstart - 3 Schritte
### 1. Programm starten
**macOS/Linux:**
```bash
./start_gui.sh
```
**Windows:**
Doppelklick auf `start_gui.cmd` (empfohlen)
Beim ersten Start werden Python-Umgebung (`.venv`) und Abhängigkeiten automatisch eingerichtet.
Alternative (CLI): Doppelklick auf `start.cmd`
### 2. PDF-Dateien hinzufügen
Kopieren Sie Ihre Dienstplan-PDF-Dateien in dieses Verzeichnis:
```
/home/sebastian/Dokumente/ICS-Import/
```
## 3. Konvertieren und Importieren
In der GUI auf "ICS Datei erstellen" klicken. Die ICS-Dateien werden dann automatisch erstellt.
---
## 📅 In deinen Kalender importieren
### Google Kalender
1. Öffne [google.com/calendar](https://google.com/calendar)
2. Einstellungen → Kalender importieren
3. "Datei aussuchen" → `.ics` Datei auswählen
4. Importieren
### Outlook
1. Öffne Outlook
2. Datei → Öffnen und exportieren → Importieren
3. `.ics` Datei auswählen
4. In einen Kalender importieren
### Thunderbird/SeaMonkey
1. Kalender öffnen
2. Datei → Importieren
3. `.ics` Datei auswählen
### Apple Kalender (macOS/iOS)
1. Doppelklick auf die `.ics` Datei
2. Bestätigen Sie den Import
### Linux (KDE Kontact, etc.)
1. Öffnen Sie die Kalenderanwendung
2. Datei → Importieren
3. `.ics` Datei auswählen
---
## 💡 Tipps und Tricks
### Mehrere PDFs gleichzeitig
Das Programm verarbeitet automatisch alle `.pdf` Dateien im Verzeichnis. Kopieren Sie einfach mehrere PDFs hinein!
### Zeitzone anpassen
Falls Sie eine andere Zeitzone benötigen, bearbeiten Sie `pdf_to_ics.py`:
```python
tz = pytz.timezone('Europe/Berlin') # Ändern Sie diesen Wert
```
Verfügbare Zeitzonen: [Liste hier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
### Automatische Updates
Sobald Sie neue Dienstplan-PDFs hinzufügen und das Programm erneut ausführen, werden neue `.ics` Dateien erstellt.
---
## ❓ Häufige Probleme
### "Keine PDF-Dateien gefunden"
- Überprüfen Sie, dass die PDF-Dateien im gleichen Verzeichnis wie die Skripte sind
- Dateiname darf Leerzeichen enthalten
### "Keine Events gefunden"
- Die PDF muss das richtige Format haben (ein Dienstplan mit Tabelle)
- Kontrollieren Sie die PDF-Struktur
### Zeitangaben falsch
- Die Standard-Einstellung ist Zeitzone "Europe/Berlin"
- Falls Sie eine andere Zeitzone benötigen, siehe "Zeitzone anpassen" oben
---
## 📞 Weitere Hilfe
Siehe **README.md** für ausführliche Dokumentation.
---
Viel Spaß! 😊

178
README.md
View File

@@ -1,174 +1,38 @@
# PDF zu ICS Konverter - Dienstplan Importer # PDF zu ICS Docker/Web Only
Dieses Tool extrahiert Kalenderdaten aus Dienstplan-PDFs und konvertiert sie in das iCalendar-Format (ICS), das in gängigen Kalender-Apps importiert werden kann. Dieses Repository ist auf den Web-Betrieb im Docker-Container reduziert.
## 🎯 Varianten ## Schnellstart
### 1) GUI (empfohlen)
Native Oberfläche mit wxPython:
```bash ```bash
./start_gui.sh cp .env.example .env
./deploy.sh
``` ```
**Highlights:** Danach erreichbar unter:
- Drag & Drop für PDFs - `http://<SERVER-IP>:8000`
- Mehrere PDFs gleichzeitig - `http://<SERVER-IP>:8000/app`
- Frei wählbares Ausgabe-Verzeichnis
- Live-Log mit Fortschritt
- Optionale Filter:
- Ruhetage ausschließen
- Urlaub (060/0060) ausschließen
### 2) CLI ## Update
Interaktives Textmenü:
```bash ```bash
./start.sh ./update.sh
``` ```
### 3) Web (MVP für Mobilgeräte) Für ein neues Release zuerst den Tag in `.env` anpassen:
Browser-Variante mit Upload + direktem ICS-Download:
```bash ```dotenv
./start_web.sh PDF_TO_ICS_IMAGE=ghcr.io/webfarben/pdf_to_ics:v1.1.0
``` ```
Details siehe [WEB_README.md](WEB_README.md). ## Enthaltene Betriebsdateien
Docker-Variante (Server): - `docker-compose.deploy.yml` image-basiertes Deployment
- `.env.example` Konfigurationsvorlage
- `deploy.sh` Erststart
- `update.sh` Update-Workflow
- `WEB_README.md` ausführliche Web-/Server-Doku
```bash ## Hinweis
docker compose up -d --build
```
--- GUI-/CLI-Varianten wurden bewusst entfernt, da der Betrieb ausschließlich im Docker-Container erfolgt.
## ⚡ Schnellstart (60 Sekunden)
1. GUI starten (`./start_gui.sh` oder `start_gui.cmd` unter Windows)
2. PDF-Dateien hinzufügen
3. Optional Filter aktivieren
4. Auf **"ICS Datei erstellen"** klicken
---
## 🧩 Installation nach Betriebssystem
### Linux (Ubuntu/Debian/Mint)
```bash
./start_gui.sh
```
Beim ersten Start wird automatisch `.venv` erstellt und alles installiert.
Wenn `wxPython` nicht installiert werden kann, helfen häufig:
```bash
sudo apt-get update
sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev
```
Für systemweite Installation mit Menüeintrag siehe [INSTALL.md](INSTALL.md).
### macOS
```bash
./start_gui.sh
```
Beim ersten Start wird `.venv` erstellt und die Abhängigkeiten werden installiert.
### Windows
1. Python 3.10+ installieren (Option **Add Python to PATH** aktivieren)
2. `start_gui.cmd` per Doppelklick starten
Beim ersten Start wird `.venv` automatisch eingerichtet.
---
## 🧱 Standalone-Apps (ohne Python beim Endnutzer)
Für Build/Packaging auf Linux, macOS und Windows:
- [BUILD_STANDALONE.md](BUILD_STANDALONE.md)
Dort enthalten:
- Build-Skripte pro OS
- Packaging-Skripte für Release-Artefakte
- empfohlene Release-Reihenfolge
---
## 🖥️ CLI-Nutzung
### Beispiele
```bash
# Alle PDFs im aktuellen Verzeichnis konvertieren
python3 pdf_to_ics.py
# Input/Output-Verzeichnis setzen
python3 pdf_to_ics.py --input ./pdfs --output ./ics_dateien
# Ruhetage ausschließen
python3 pdf_to_ics.py --exclude-rest
# Urlaub (060/0060) ausschließen
python3 pdf_to_ics.py --exclude-vacation
# Einzelne PDF-Datei
python3 pdf_to_ics.py /pfad/zur/datei.pdf
```
### Optionen
| Option | Kurzform | Beschreibung |
|--------|----------|-------------|
| `--input DIR` | `-i` | Eingabe-Verzeichnis mit PDF-Dateien (Standard: aktuelles Verzeichnis) |
| `--output DIR` | `-o` | Ausgabe-Verzeichnis für ICS-Dateien (Standard: Eingabe-Verzeichnis) |
| `--exclude-rest` | `-e` | Ruhetage ausschließen (Ruhe, R56, R36, vRWF48, RWE, vR48) |
| `--exclude-vacation` | `-u` | Urlaub ausschließen (060, 0060) |
| `--verbose` | `-v` | Detaillierte Ausgabe |
| `--help` | `-h` | Hilfe anzeigen |
---
## 📅 ICS-Import
Die erzeugten `.ics`-Dateien lassen sich u. a. in folgende Kalender importieren:
- Outlook
- Google Kalender
- Apple Kalender
- Thunderbird
- LibreOffice
- Android-Kalender-Apps
---
## 🛠️ Fehlerbehebung
- **Keine Events gefunden:** PDF-Layout prüfen
- **GUI startet nicht:** `.venv` löschen und neu starten
```bash
rm -rf .venv
./start_gui.sh
```
- **Zeitzone ändern:** in `pdf_to_ics.py` den Wert `Europe/Berlin` anpassen
---
## 📚 Weitere Dokumentation
- [INSTALL.md](INSTALL.md) - Linux-Installation mit Menüeintrag
- [WXPYTHON_README.md](WXPYTHON_README.md) - wxPython-spezifische Hinweise
- [WEB_README.md](WEB_README.md) - Web-Version (Browser/Mobil)
- [BUILD_STANDALONE.md](BUILD_STANDALONE.md) - Standalone-Builds/Packaging
- [QUICKSTART.md](QUICKSTART.md) - Kurzanleitung Kalender-Import
- [ZUSAMMENFASSUNG.md](ZUSAMMENFASSUNG.md) - Projekt- und Changelog-Übersicht
## Lizenz
Dieses Tool ist zur privaten Verwendung gedacht.

View File

@@ -1,329 +1,71 @@
# 🌐 Web-Version (MVP) # 🌐 Web-Version (Docker-only)
Diese Variante stellt den PDF-zu-ICS-Konverter im Browser bereit, damit die Nutzung auch auf mobilen Geräten möglich ist. Diese Anwendung wird ausschließlich als Container betrieben.
## Starten ## Voraussetzungen
### Linux/macOS - Docker + Docker Compose
```bash - Optional externes Netzwerk `proxy` (wenn Reverse Proxy genutzt wird)
./start_web.sh
```
### Windows ## Erststart
Doppelklick auf `start_web.cmd`
Danach im Browser öffnen:
- Landingpage: `http://localhost:8000`
- Anwendung: `http://localhost:8000/app`
- Im Netzwerk (z. B. Smartphone): `http://<IP-des-Rechners>:8000/app`
## Docker (Server ohne VPN)
Diese Variante ist für deinen aktuellen Wunsch geeignet: öffentlich erreichbar ohne VPN.
### Docker-only Betrieb (empfohlen für Webserver)
Wenn auf dem Webserver **nur Docker laufen soll**, nutze die image-basierte Compose-Datei statt lokalem Build.
1) Vorlage übernehmen:
```bash ```bash
cp .env.example .env cp .env.example .env
```
2) Optional Werte in `.env` anpassen:
```dotenv
PDF_TO_ICS_IMAGE=ghcr.io/webfarben/pdf_to_ics:v1.0.0
WEB_AUTH_USER=
WEB_AUTH_PASSWORD=
```
3) Starten:
```bash
docker compose -f docker-compose.deploy.yml up -d
```
Kurzvariante für Erststart:
```bash
./deploy.sh ./deploy.sh
``` ```
4) Update: ## Update
```bash
git pull
# in .env auf neues Release setzen, z. B. v1.1.0
docker compose -f docker-compose.deploy.yml pull
docker compose -f docker-compose.deploy.yml up -d
```
Kurzvariante mit Helper-Skript:
```bash ```bash
./update.sh ./update.sh
``` ```
Hinweis: Für ein neues Release vorher den Tag in `.env` anpassen. Für ein neues Release den Tag in `.env` erhöhen, z. B.:
Damit entfallen lokale Python/venv-Abhängigkeiten auf dem Host vollständig. ```dotenv
Mit festem Tag bleiben Deployments reproduzierbar und Updates kontrolliert. PDF_TO_ICS_IMAGE=ghcr.io/webfarben/pdf_to_ics:v1.1.0
```
### Schlanker Checkout auf dem Server (Sparse) Danach `./update.sh` ausführen.
Für einen neuen Server-Checkout kannst du den Arbeitsbaum klein halten: ## Manuelle Kommandos (optional)
Starten:
```bash
docker compose -f docker-compose.deploy.yml up -d
```
Status/Logs:
```bash
docker compose -f docker-compose.deploy.yml ps
docker compose -f docker-compose.deploy.yml logs -f pdf-to-ics-web
```
Stoppen:
```bash
docker compose -f docker-compose.deploy.yml down
```
## Sicherheit
Optional App-Basic-Auth in `.env` setzen:
```dotenv
WEB_AUTH_USER=kalender
WEB_AUTH_PASSWORD=BitteSicheresPasswortSetzen
```
Für öffentliches Deployment zusätzlich Reverse Proxy + HTTPS verwenden.
## Schlanker Server-Checkout (Sparse)
```bash ```bash
git clone --filter=blob:none --sparse <REPO_URL> pdf_to_ics git clone --filter=blob:none --sparse <REPO_URL> pdf_to_ics
cd pdf_to_ics cd pdf_to_ics
git sparse-checkout set docker-compose.deploy.yml .env.example deploy.sh update.sh WEB_README.md git sparse-checkout set docker-compose.deploy.yml .env.example deploy.sh update.sh README.md WEB_README.md
``` ```
Optional zusätzlich aufnehmen: Hinweis: Ein bestehender Voll-Clone wird dadurch nicht automatisch kleiner.
```bash
git sparse-checkout add README.md
```
Hinweis: Ein bestehender Voll-Clone wird dadurch nicht automatisch klein; dafür einmal neu klonen.
### 1) Starten
```bash
docker compose up -d --build
```
Aufruf:
- Landingpage: `http://<SERVER-IP>:8000`
- Anwendung: `http://<SERVER-IP>:8000/app`
- Oder mit Domain über Reverse Proxy (empfohlen)
### 2) Status und Logs
```bash
docker compose ps
docker compose logs -f pdf-to-ics-web
```
### 3) Stoppen / Update
```bash
docker compose down
git pull
docker compose up -d --build
```
### 4) Optional: App-Login aktivieren
In `docker-compose.yml` die beiden Variablen aktivieren:
```yaml
environment:
- WEB_AUTH_USER=kalender
- WEB_AUTH_PASSWORD=BitteSicheresPasswortSetzen
```
Dann neu starten:
```bash
docker compose up -d --build
```
Hinweis: Ohne VPN ist mindestens HTTPS + Basic Auth empfohlen, wenn die App öffentlich im Internet hängt.
## Funktionen
- PDF-Datei hochladen
- Optional Ruhetage ausschließen
- Optional Urlaub ausschließen
- ICS-Datei direkt herunterladen
## Hinweise für mobile Nutzung
- Smartphone und Server müssen im gleichen Netzwerk sein (lokaler Betrieb)
- Bei Internet-Betrieb sollte HTTPS und ein Reverse Proxy (z. B. Nginx) genutzt werden
- Hochgeladene Dateien werden nur temporär verarbeitet
## Technischer Aufbau
- `web/app.py` FastAPI-Backend + Upload/Download-Endpunkte
- `web/templates/index.html` mobile Web-Oberfläche
- `web/requirements-web.txt` Web-spezifische Abhängigkeiten
## Produktion (Kurz)
Beispiel mit Uvicorn direkt:
```bash
.venv/bin/python -m uvicorn web.app:app --host 0.0.0.0 --port 8000
```
Optional mit App-Auth (zusätzliche Schutzschicht):
```bash
WEB_AUTH_USER=kalender WEB_AUTH_PASSWORD='StarkesPasswort' \
.venv/bin/python -m uvicorn web.app:app --host 0.0.0.0 --port 8000
```
Empfohlen für Internet-Betrieb:
- Uvicorn hinter Nginx
- HTTPS aktivieren
- Upload-Größenlimit setzen
- Zugriff absichern (z. B. Basic Auth oder Login)
## App-Auth (optional, zusätzlich zu Nginx)
Wenn `WEB_AUTH_USER` und `WEB_AUTH_PASSWORD` gesetzt sind, schützt die App alle Endpunkte per HTTP Basic Auth.
Linux/macOS Beispiel:
```bash
export WEB_AUTH_USER=kalender
export WEB_AUTH_PASSWORD='StarkesPasswort'
./start_web.sh
```
Windows (PowerShell) Beispiel:
```powershell
$env:WEB_AUTH_USER='kalender'
$env:WEB_AUTH_PASSWORD='StarkesPasswort'
./start_web.cmd
```
Hinweis: Für öffentlich erreichbare Server weiterhin Nginx + HTTPS verwenden.
## Öffentliches Deployment (HTTPS)
Beispiel für Ubuntu-Server mit Domain `ics.example.de`.
### 1) App als Service starten
`/etc/systemd/system/pdf-to-ics-web.service`
```ini
[Unit]
Description=PDF to ICS Web
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/pdf_to_ics
ExecStart=/opt/pdf_to_ics/.venv/bin/python -m uvicorn web.app:app --host 127.0.0.1 --port 8000
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
```
Aktivieren:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now pdf-to-ics-web
sudo systemctl status pdf-to-ics-web
```
### 2) Nginx als Reverse Proxy
`/etc/nginx/sites-available/pdf-to-ics`
```nginx
server {
listen 80;
server_name ics.example.de;
client_max_body_size 10M;
auth_basic "Geschuetzter Bereich";
auth_basic_user_file /etc/nginx/.htpasswd-pdf-to-ics;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Aktivieren:
```bash
sudo ln -s /etc/nginx/sites-available/pdf-to-ics /etc/nginx/sites-enabled/pdf-to-ics
sudo nginx -t
sudo systemctl reload nginx
```
### 2b) Basic Auth einrichten (empfohlen)
```bash
sudo apt-get update
sudo apt-get install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd-pdf-to-ics kalender
sudo nginx -t
sudo systemctl reload nginx
```
Weitere Nutzer hinzufügen (ohne `-c`):
```bash
sudo htpasswd /etc/nginx/.htpasswd-pdf-to-ics weiterer_user
```
Schnelltest:
```bash
curl -I https://ics.example.de
```
Erwartung: zuerst `401 Unauthorized`, mit Login im Browser dann Zugriff.
### 2c) IP-Whitelist (optional, zusätzlich)
Wenn nur bestimmte Netze zugreifen sollen, kann Nginx den Zugriff auf IP-Bereiche begrenzen.
Beispiel (lokales Netz + einzelne feste IP):
```nginx
location / {
allow 192.168.178.0/24;
allow 203.0.113.10;
deny all;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
```
Danach prüfen und neu laden:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
Kombiniert mit Basic Auth ist das eine robuste Mindestabsicherung.
### 3) HTTPS mit Let's Encrypt
```bash
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d ics.example.de
```
Test der Erneuerung:
```bash
sudo certbot renew --dry-run
```
### 4) Mindest-Sicherheit
- Zugriffe absichern (mindestens Basic Auth)
- Optional zusätzlich per IP-Whitelist einschränken
- Upload-Limit klein halten (`client_max_body_size`)
- Server und Pakete regelmäßig aktualisieren

View File

@@ -1,89 +0,0 @@
# 📦 PDF zu ICS Konverter - Weitergabe-Paket
Dieses Paket enthält alles, was Sie brauchen, um Dienstplan-PDFs in Kalender-Dateien (ICS) zu konvertieren.
## ⚡ Schnellstart für Nicht-Technische Nutzer
### 1. Installation
1. Öffnen Sie diesen Ordner im Dateimanager
2. Rechtsklick auf `install.sh`
3. Wählen Sie "Als Programm ausführen" oder "Mit Terminal öffnen"
4. Folgen Sie den Anweisungen auf dem Bildschirm
**Alternativ:** Öffnen Sie ein Terminal in diesem Ordner und führen Sie aus:
```bash
./install.sh
```
### 2. Anwendung starten
Nach der Installation finden Sie "PDF zu ICS Konverter" in Ihrem Anwendungsmenü:
- **GNOME:** Drücken Sie die Super-Taste, tippen Sie "PDF"
- **KDE:** Klicken Sie auf das Anwendungsmenü, suchen Sie "PDF zu ICS"
- **XFCE/Andere:** Im Anwendungsmenü unter "Büro" oder "Dienstprogramme"
### 3. PDFs konvertieren
1. Klicken Sie auf " PDF hinzufügen" oder ziehen Sie PDF-Dateien in die Liste
2. Wählen Sie optional ein Ausgabe-Verzeichnis
3. Klicken Sie auf "📄 ICS Datei erstellen"
4. Fertig! Importieren Sie die ICS-Dateien in Ihren Kalender
## 📋 Was wird installiert?
- Die Anwendung wird in Ihrem Home-Verzeichnis installiert (keine Systemänderungen)
- Ein Eintrag im Anwendungsmenü wird erstellt
- Alle benötigten Python-Bibliotheken werden automatisch heruntergeladen
## 🗑️ Deinstallation
Falls Sie die Anwendung wieder entfernen möchten:
1. Öffnen Sie ein Terminal
2. Führen Sie aus:
```bash
~/.local/share/pdf-to-ics/uninstall.sh
```
## 💡 Für technisch versierte Nutzer
Siehe [INSTALL.md](INSTALL.md) für detaillierte Informations- und [README.md](README.md) für die vollständige Dokumentation.
## ⚙️ Systemvoraussetzungen
- Linux (Ubuntu, Fedora, Debian, Arch, etc.)
- Python 3.6 oder neuer (meist vorinstalliert)
- Etwa 50 MB freier Speicherplatz
- Internetzugang für die Installation
## ❓ Probleme?
### Die Installation schlägt fehl
Öffnen Sie ein Terminal und führen Sie aus:
```bash
python3 --version
```
Falls "Befehl nicht gefunden" erscheint, installieren Sie Python:
```bash
sudo apt install python3 python3-pip python3-venv
```
### Die Anwendung startet nicht
Prüfen Sie, ob wxPython-Build-Abhängigkeiten installiert sind:
```bash
sudo apt-get update
sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev
```
## 📞 Weitere Hilfe
Lesen Sie die vollständige Dokumentation in [README.md](README.md) oder [INSTALL.md](INSTALL.md).
---
Viel Erfolg beim Konvertieren Ihrer Dienstpläne! 📅

View File

@@ -1,287 +0,0 @@
# wxPython GUI - PDF zu ICS Konverter
Native GUI-Lösung mit **wxPython** - funktioniert zuverlässig auf macOS 13.6, Windows und Linux.
## ✅ Warum wxPython?
Nach den Problemen mit BeeWare/Toga (macOS 13.7+ erforderlich) ist wxPython die perfekte Lösung:
| Feature | BeeWare/Toga | **wxPython** |
|---------|--------------|--------------|
| Native auf macOS | ✅ (nur 13.7+) | ✅ **Alle Versionen** |
| Native auf Windows | ✅ | ✅ |
| Native auf Linux | ✅ | ✅ |
| Stabilität | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Look & Feel | Modern | **Perfekt nativ** |
| macOS 13.6 Support | ❌ | ✅ |
| Installation | Kompliziert | Einfach |
---
## 🚀 Installation
```bash
cd /Users/sebastian/PDFTOICS/pdf_to_ics
python3 -m pip install wxPython
```
**Dependencies werden automatisch installiert:**
- wxPython 4.2+
- numpy (für wxPython)
- Alle anderen sind bereits vorhanden (pdfplumber, icalendar, etc.)
---
## 🎯 Starten
```bash
cd /Users/sebastian/PDFTOICS/pdf_to_ics
python3 gui_wxpython.py
```
Die App startet sofort mit **nativen macOS-Widgets**! 🎉
---
## 📊 Features
### ✅ Vollständig implementiert:
1. **PDF-Verwaltung**
- Mehrfach-Auswahl über nativen macOS File Dialog
- Drag & Drop (automatisch durch wxPython)
- PDFs entfernen/löschen
2. **Ausgabeverzeichnis**
- Nativer Directory Picker
- Merkt letztes Verzeichnis
3. **Exportoptionen**
- Checkbox für "Ruhetage ausschließen"
- Checkbox für "Urlaub ausschließen (060, 0060)"
- Speichert Einstellung persistent
4. **Konvertierung**
- Threading (blockiert UI nicht)
- Progress-Logging in Echtzeit
- Erfolgs-Dialog nach Abschluss
5. **Menüleiste**
- "Hilfe" → Android-Export-Anleitung
- "Über dieses Programm"
- Beenden (Cmd+Q)
6. **Update-Checker**
- Automatische Update-Prüfung beim Start
- Dialog wenn neues Update verfügbar
7. **Konfiguration**
- Speichert automatisch Einstellungen
- `~/.pdf_to_ics_config.json`
---
## 🎨 Look & Feel
### macOS 13.6
```
┌─────────────────────────────────────┐
│ Datei Bearbeiten Hilfe │ ← Native macOS Menu Bar
├─────────────────────────────────────┤
│ 📅 PDF zu ICS Konverter │ ← Dunkler Header
├─────────────────────────────────────┤
│ PDF-Dateien: │
│ ┌─────────────────────────────────┐ │
│ │ ☑ dienstplan_januar.pdf │ │ ← Native ListBox
│ │ ☑ dienstplan_februar.pdf │ │
│ └─────────────────────────────────┘ │
│ [ Hinzufügen] [ Entfernen] [...] │ ← Native Buttons
├─────────────────────────────────────┤
│ Ausgabe-Verzeichnis: │
│ [/Users/sebastian/Documents ] 📁 │ ← Native TextCtrl
├─────────────────────────────────────┤
│ ☐ Ruhetage ausschließen │ ← Native CheckBox
│ ☐ Urlaub ausschließen (060) │ ← Native CheckBox
├─────────────────────────────────────┤
│ Status: │
│ ┌─────────────────────────────────┐ │
│ │ [10:30:15] ✓ 2 PDFs hinzugefügt│ │ ← Log Output
│ │ [10:30:20] 🔄 Starte... │ │
│ └─────────────────────────────────┘ │
│ │
│ [📄 ICS Datei erstellen] │ ← Grüner Button
└─────────────────────────────────────┘
```
**Sieht exakt wie eine native macOS-App aus!** 🎨
---
## 🔧 wxPython APIs im Überblick
### 1. Event Handling
```python
btn = wx.Button(panel, label="Klick")
btn.Bind(wx.EVT_BUTTON, self.on_click)
```
### 2. Layout
```python
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(widget, 1, wx.EXPAND)
panel.SetSizer(sizer)
```
### 3. Threading + UI
```python
wx.CallAfter(self.log_text.AppendText, "Message\n")
```
### 4. Dialog
```python
with wx.FileDialog(...) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return
paths = dialog.GetPaths()
```
---
## 💡 Vorteile von wxPython
### ✅ Native Widgets
- Nutzt echte **Cocoa** auf macOS
- Nutzt echte **Win32** auf Windows
- Nutzt **GTK** auf Linux
### ✅ Drag & Drop
Funktioniert automatisch! Keine extra Implementierung nötig:
```python
# Drag PDF-Dateien direkt auf die Listbox
self.pdf_listbox = wx.ListBox(panel, style=wx.LB_EXTENDED)
# wxPython handled DnD automatisch!
```
### ✅ Bessere Performance
- Schnelle native Darstellung
- Native Controls = weniger CPU
### ✅ Moderne Features
- Transparenz
- Native Notifications
- Statusbar
- Toolbar
- Split Windows
### ✅ Dark Mode Support
Automatisch! wxPython folgt dem System-Theme.
---
## 🧪 Testing Checklist
Jetzt testen:
```bash
cd /Users/sebastian/PDFTOICS/pdf_to_ics
python3 gui_wxpython.py
```
**Checklist:**
- [ ] App startet ohne Fehler
- [ ] Fenster sieht nativ aus (perfektes macOS Look & Feel)
- [ ] "PDF hinzufügen" öffnet nativen macOS Dialog
- [ ] Mehrere PDFs können ausgewählt werden
- [ ] PDFs erscheinen in der Liste
- [ ] "Entfernen" funktioniert
- [ ] "Alle entfernen" funktioniert
- [ ] "Durchsuchen" für Ausgabe-Verzeichnis funktioniert
- [ ] Checkbox "Ruhetage" funktioniert
- [ ] Checkbox "Urlaub ausschließen (060)" funktioniert
- [ ] "ICS Datei erstellen" startet Konvertierung
- [ ] Log zeigt Status in Echtzeit
- [ ] Nach Konvertierung: Erfolgs-Dialog
- [ ] Menü "Hilfe" → "Android-Anleitung" funktioniert
- [ ] Menü "Über" zeigt About-Dialog
- [ ] Einstellungen werden gespeichert (nach Neustart testen)
---
## 📈 Migration auf wxPython
### Was blieb gleich:
- Threading-Logik
- PDF-Parsing mit pdfplumber
- ICS-Erstellung mit icalendar
- Config-Speicherung (JSON)
### Was wurde verbessert:
- ✅ Nativer Look & Feel (statt blechig)
- ✅ Bessere Farben / Styling
- ✅ Automatisches Drag & Drop
- ✅ Native Menüleiste (statt Popup)
- ✅ Native Dialoge (About, File, Directory)
- ✅ Thread-sicheres UI-Update mit `wx.CallAfter`
### Status
- ✅ GUI-Start erfolgt über `start_gui.sh` / `start_gui.cmd`
- ✅ GUI-Einstiegspunkt ist `gui_wxpython.py`
---
## 🚀 Nächste Schritte (optional)
### 1. Packaging mit PyInstaller
```bash
pip install pyinstaller
pyinstaller --onefile --windowed gui_wxpython.py
```
→ Erstellt `.app` Bundle für macOS!
### 2. Weitere Features
- Icon hinzufügen
- Statusbar mit Progress
- Toolbar mit Icons
- Preferences-Dialog
- Drag & Drop direkt auf Window
---
## 🆚 Plattformstatus
| Kriterium | wxPython |
|-----------|----------|
| **Look auf macOS** | ✅ **Perfekt nativ** |
| **Menüleiste** | ✅ **Native MenuBar** |
| **File Dialoge** | ✅ **Perfekt nativ** |
| **Thread-Safety** | ✅ **wx.CallAfter** |
| **Installation** | ⚠️ Pip install |
| **Bundle-Größe** | ⚠️ Größer (~20MB) |
| **macOS 13.6 Support** | ✅ **Ja!** |
| **Dark Mode** | ✅ **Automatisch** |
---
## 📚 Ressourcen
- [wxPython Dokumentation](https://docs.wxpython.org/)
- [wxPython Phoenix Docs](https://wxpython.org/Phoenix/docs/html/index.html)
- [Widget Gallery](https://docs.wxpython.org/gallery.html)
- [Tutorial](https://wxpython.org/pages/overview/)
---
## ✅ Fazit
**wxPython ist die perfekte Lösung für Ihr Projekt:**
1. ✅ Funktioniert auf macOS 13.6 (im Gegensatz zu Toga)
2. ✅ Perfekter nativer Look & Feel
3. ✅ Keine Versionskonflikte
4. ✅ Stabil und production-ready
5. ✅ Einheitlicher GUI-Stack mit wxPython
6. ✅ Alle Features vollständig implementiert
**Status:** 🎉 **PRODUCTION READY!**
Viel Erfolg mit der nativen GUI!

View File

@@ -1,212 +0,0 @@
# 📋 Projekt-Zusammenfassung
## ✅ Projekt abgeschlossen!
Ihr PDF zu ICS Konverter für Dienstpläne ist vollständig eingerichtet und einsatzbereit.
---
## 📁 Projektstruktur
```
ICS-Import/
├── 📄 README.md ← ausführliche Dokumentation
├── 📄 QUICKSTART.md ← schnelle Anleitung
├── 📄 ZUSAMMENFASSUNG.md ← dieses Dokument
├── 🐍 pdf_to_ics.py ← Kern-Konvertierungsskript
├── 🎨 menu.py ← interaktives Benutzermenü
├── 🚀 start.sh ← Startskript (macOS/Linux)
├── 🚀 start.cmd ← Startskript (Windows)
├── 📦 .venv/ ← Python-Umgebung (automatisch)
└── 📝 PDF-Dateien & ICS-Dateien ← ihre Daten
├── 2026-02-23 DB Köhler00100718_März2026.pdf
└── 2026-02-23 DB Köhler00100718_März2026.ics ✓
```
---
## 🎯 Was wurde erstellt
### 1. **PDF-Parser** (`pdf_to_ics.py`)
- Extrahiert Dienstplan-Informationen aus PDFs
- Erkennt Zeitangaben und Schichtdaten
- Erstellt valide iCalendar-Dateien
- Unterstützt mehrere PDF-Dateien
### 2. **Benutzermenü** (`menu.py`)
- Interaktive Oberfläche
- PDF-Verzeichnis durchsuchen
- Mehrere PDFs konvertieren
- Fehlerbehandlung
### 3. **Startskripte**
- Linux/macOS: `start.sh`
- Windows: `start.cmd`
- Automatische Umgebungseinrichtung
### 4. **Dokumentation**
- README.md - ausführliche Anleitung
- QUICKSTART.md - schnelle Einstieg
- Diese Zusammenfassung
---
## 🎛️ Verwendung
### Von der Kommandozeile:
```bash
cd /home/sebastian/Dokumente/ICS-Import
python3 pdf_to_ics.py # Alle PDFs konvertieren
python3 menu.py # Interaktives Menü
./start.sh # Schnellstart (Linux/macOS)
```
### Von Windows:
```
Doppelklick auf start.cmd
```
---
## 📅 Funktionen der erstellten ICS-Dateien
**Vollständige Ereignisinformationen:**
- Titel: Name - Dienstart
- Beschreibung: Dienstart & Betriebshof
- Datum und Uhrzeit
- Zeitzone: Europe/Berlin
**Intelligente Zeitverarbeitung:**
- Nachtschichten (über Mitternacht)
- Ganztagesveranstaltungen
- Automatische Zeitzone-Anpassung
**Kalender-kompatibel mit:**
- Google Kalender ✓
- Outlook ✓
- Apple Kalender ✓
- Thunderbird ✓
- LibreOffice ✓
- Linux Kalender-Apps ✓
---
## 🔧 Technische Details
- **Sprache:** Python 3.6+
- **Abhängigkeiten:** pdfplumber, icalendar, pytz, pypdf2, packaging
- **Format:** iCalendar 2.0 (RFC 5545)
- **Umgebung:** Python virtual environment (.venv)
### Installierte Pakete:
```
pdfplumber==0.10.0+ - PDF-Datenextraktion
icalendar==5.0.0+ - ICS-Datei-Erstellung
pytz - Zeitzonenverwaltung
pypdf2 - PDF-Parsing
packaging - Versionsvergleich
```
---
## 💡 Nächste Schritte
### 1. **Ihre erste Konvertierung:**
```bash
cd /home/sebastian/Dokumente/ICS-Import
./start.sh
```
Wählen Sie Option "1. PDF(s) konvertieren"
### 2. **ICS in Kalender importieren:**
- Siehe README.md für Anleitung pro Kalender-App
- Oder siehe QUICKSTART.md für schnelle Übersicht
### 3. **Weitere PDFs hinzufügen:**
- Kopieren Sie PDF-Dateien in das Verzeichnis
- Das Programm verarbeitet sie automatisch
---
## 🐛 Fehlerbehebung
| Problem | Lösung |
|---------|--------|
| "Keine PDF gefunden" | PDFs müssen im Projektverzeichnis sein |
| "Keine Events" | PDF muss das richtige Tabellenformat haben |
| "Zeitzone falsch" | Bearbeiten Sie `pdf_to_ics.py` Zeile mit `pytz.timezone()` |
| Import-Fehler in Kalender | Stelle sicher, dass die `.ics` Datei nicht beschädigt ist |
---
## 📊 Beispiel-Output
```
Verarbeite: 2026-02-23 DB Köhler00100718_März2026.pdf
Name: Sebastian Köhler
Personalnummer: 00100718
Betriebshof: NSCH3
Anzahl der Events: 31
✓ ICS-Datei erstellt: 2026-02-23 DB Köhler00100718_März2026.ics
```
Jedes Event in der ICS-Datei:
- **Datum:** Automatisch aus PDF extrahiert
- **Zeit:** z.B. 04:51-15:46 Uhr
- **Titel:** z.B. "Sebastian Köhler - 36234"
- **Beschreibung:** Dienstart & Betriebshof
---
## 📝 Changelog (März 2026)
### v1.2.2
- README grundlegend strukturiert und bereinigt
- Installationshinweise nach Betriebssystem ergänzt (Linux, macOS, Windows)
- Standalone-Hinweise im README klar hervorgehoben
- Schnellstart und Troubleshooting kompakter und ohne Redundanzen
### v1.2.1
- Standalone-Build-Workflow mit PyInstaller ergänzt (`build/build_*.{sh,cmd}`)
- Packaging-Skripte für Release-Artefakte ergänzt:
- Linux: `.tar.gz`
- macOS: `.zip`
- Windows: `.zip`
- Neue Build-Dokumentation `BUILD_STANDALONE.md`
- `.gitignore` um Build-Artefakte erweitert (`dist/`, `release/`, `*.spec`, `build/PDFtoICS/`)
### v1.2.0
- GUI-Technik vollständig auf **wxPython** umgestellt
- Standard-Startpfade auf `gui_wxpython.py` angepasst (`start_gui.sh`, `start_gui.cmd`, `install.sh`)
- Linux-Hinweise für wxPython-Build-Abhängigkeiten ergänzt
- Alte Tkinter-GUI-Datei `gui.py` entfernt
- Neue Exportoption ergänzt: **Urlaub ausschließen (060/0060)**
- GUI: zusätzliche Checkbox
- CLI: `--exclude-vacation` / `-u`
- Core-Logik: Urlaubseinträge werden optional nicht in ICS exportiert
- Dokumentation konsolidiert und auf wxPython-only aktualisiert
---
## 📞 Support
Für detaillierte Informationen:
- **README.md** - Ausführliche Dokumentation
- **QUICKSTART.md** - Schnelle Anleitung zum Import
- **Python-Code** - Gut kommentiert und erweiterbar
---
## 🎉 Fertig!
Ihr System ist bereit. Viel Erfolg mit der Dienstplan-Verwaltung! 📅✨
**Letzte Änderung:** 2. März 2026
**Status:** ✅ Einsatzbereit

View File

@@ -1,27 +0,0 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
PYTHON_BIN="${PYTHON_BIN:-.venv/bin/python}"
if [ ! -x "$PYTHON_BIN" ]; then
echo "❌ Python nicht gefunden: $PYTHON_BIN"
echo "💡 Erwartet wird eine Virtual Environment unter .venv"
exit 1
fi
echo "🐧 Erstelle Linux-Standalone mit PyInstaller..."
"$PYTHON_BIN" -m pip install --upgrade pip pyinstaller
"$PYTHON_BIN" -m PyInstaller \
--noconfirm \
--clean \
--name "PDFtoICS" \
--windowed \
--add-data "version.txt:." \
gui_wxpython.py
echo "✅ Fertig: dist/PDFtoICS"

View File

@@ -1,27 +0,0 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
PYTHON_BIN="${PYTHON_BIN:-.venv/bin/python}"
if [ ! -x "$PYTHON_BIN" ]; then
echo "❌ Python nicht gefunden: $PYTHON_BIN"
echo "💡 Erwartet wird eine Virtual Environment unter .venv"
exit 1
fi
echo "🍎 Erstelle macOS-Standalone mit PyInstaller..."
"$PYTHON_BIN" -m pip install --upgrade pip pyinstaller
"$PYTHON_BIN" -m PyInstaller \
--noconfirm \
--clean \
--name "PDFtoICS" \
--windowed \
--add-data "version.txt:." \
gui_wxpython.py
echo "✅ Fertig: dist/PDFtoICS.app"

View File

@@ -1,24 +0,0 @@
@echo off
setlocal
cd /d "%~dp0\.."
set "PYTHON_BIN=.venv\Scripts\python.exe"
if not exist "%PYTHON_BIN%" (
echo ❌ Python nicht gefunden: %PYTHON_BIN%
echo 💡 Erwartet wird eine Virtual Environment unter .venv
exit /b 1
)
echo 🪟 Erstelle Windows-Standalone mit PyInstaller...
"%PYTHON_BIN%" -m pip install --upgrade pip pyinstaller
"%PYTHON_BIN%" -m PyInstaller ^
--noconfirm ^
--clean ^
--name "PDFtoICS" ^
--windowed ^
--add-data "version.txt;." ^
gui_wxpython.py
echo ✅ Fertig: dist\PDFtoICS\PDFtoICS.exe

View File

@@ -1,24 +0,0 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
APP_DIR="dist/PDFtoICS"
VERSION="$(tr -d '[:space:]' < version.txt)"
OUT_DIR="release"
ARCHIVE_NAME="PDFtoICS-linux-v${VERSION}.tar.gz"
if [ ! -d "$APP_DIR" ]; then
echo "❌ Build-Ordner nicht gefunden: $APP_DIR"
echo "💡 Bitte zuerst ausführen: ./build/build_linux.sh"
exit 1
fi
mkdir -p "$OUT_DIR"
echo "📦 Erstelle Archiv: $OUT_DIR/$ARCHIVE_NAME"
tar -czf "$OUT_DIR/$ARCHIVE_NAME" -C dist PDFtoICS
echo "✅ Fertig: $OUT_DIR/$ARCHIVE_NAME"

View File

@@ -1,25 +0,0 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
APP_BUNDLE="dist/PDFtoICS.app"
VERSION="$(tr -d '[:space:]' < version.txt)"
OUT_DIR="release"
ARCHIVE_NAME="PDFtoICS-macos-v${VERSION}.zip"
if [ ! -d "$APP_BUNDLE" ]; then
echo "❌ App-Bundle nicht gefunden: $APP_BUNDLE"
echo "💡 Bitte zuerst ausführen: ./build/build_macos.sh"
exit 1
fi
mkdir -p "$OUT_DIR"
echo "📦 Erstelle Archiv: $OUT_DIR/$ARCHIVE_NAME"
rm -f "$OUT_DIR/$ARCHIVE_NAME"
(cd dist && zip -r "../$OUT_DIR/$ARCHIVE_NAME" "PDFtoICS.app" >/dev/null)
echo "✅ Fertig: $OUT_DIR/$ARCHIVE_NAME"

View File

@@ -1,27 +0,0 @@
@echo off
setlocal
cd /d "%~dp0\.."
set /p VERSION=<version.txt
set "VERSION=%VERSION: =%"
if not exist "dist\PDFtoICS\PDFtoICS.exe" (
echo ❌ Build-Ausgabe nicht gefunden: dist\PDFtoICS\PDFtoICS.exe
echo 💡 Bitte zuerst ausfuehren: build\build_windows.cmd
exit /b 1
)
if not exist "release" mkdir release
set "ARCHIVE=release\PDFtoICS-windows-v%VERSION%.zip"
if exist "%ARCHIVE%" del /q "%ARCHIVE%"
echo 📦 Erstelle Archiv: %ARCHIVE%
powershell -NoProfile -Command "Compress-Archive -Path 'dist\PDFtoICS\*' -DestinationPath '%ARCHIVE%'"
if errorlevel 1 (
echo ❌ Konnte Archiv nicht erstellen
exit /b 1
)
echo ✅ Fertig: %ARCHIVE%

View File

@@ -1,28 +0,0 @@
networks:
internal:
external: false
proxy:
name: proxy
external: true
services:
pdf-to-ics-web:
build: .
container_name: pdf-to-ics-web
restart: unless-stopped
ports:
- "8000:8000"
networks:
- internal
- proxy
environment:
- TZ=Europe/Berlin
# Optional aktivieren für App-Login:
- WEB_AUTH_USER=dbregio
- WEB_AUTH_PASSWORD=dbregio
healthcheck:
test: ["CMD", "python3", "-c", "import http.client,sys;c=http.client.HTTPConnection('127.0.0.1',8000,timeout=5);c.request('GET','/');r=c.getresponse();sys.exit(0 if r.status in (200,401) else 1)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s

View File

@@ -1,516 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GUI für PDF zu ICS Konverter mit wxPython
Native Benutzeroberfläche für macOS, Windows, Linux
"""
import wx
import wx.adv
from pathlib import Path
import threading
import json
import webbrowser
from datetime import datetime
from pdf_to_ics import extract_dienstplan_data, create_ics_from_dienstplan
from update_checker import check_for_updates, get_current_version
# Konfigurationsdatei
CONFIG_FILE = Path.home() / '.pdf_to_ics_config.json'
class FileDropTarget(wx.FileDropTarget):
"""Custom FileDropTarget für Drag & Drop von PDF-Dateien"""
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
"""Handle für Drag & Drop Events"""
pdf_count = 0
for filepath in filenames:
# Nur PDF-Dateien akzeptieren
if filepath.lower().endswith('.pdf'):
if filepath not in self.window.pdf_files:
self.window.pdf_files.append(filepath)
self.window.pdf_listbox.Append(Path(filepath).name)
pdf_count += 1
# Merke Verzeichnis
self.window.last_pdf_dir = str(Path(filepath).parent)
if pdf_count > 0:
self.window.log(f"{pdf_count} PDF-Datei(en) per Drag & Drop hinzugefügt")
elif filenames:
self.window.log("⚠ Nur PDF-Dateien können hinzugefügt werden")
return True
class PDFtoICSFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='PDF zu ICS Konverter - Dienstplan Importer', size=(800, 700))
# Lade gespeicherte Einstellungen
self.config = self.load_config()
# Variablen
self.pdf_files = []
# Nutze letztes Ausgabeverzeichnis oder Standard
default_dir = self.config.get('last_output_dir', None)
if not default_dir or not Path(default_dir).exists():
default_dir = Path.cwd()
if str(default_dir).split('/')[-1].startswith('.'):
default_dir = Path.home()
self.output_dir = str(default_dir)
# Letztes PDF-Verzeichnis merken
self.last_pdf_dir = self.config.get('last_pdf_dir', str(Path.home()))
# Erstelle UI
self.create_widgets()
# Erstelle Menüleiste
self.create_menu()
# Center window
self.Centre()
# Update-Prüfung im Hintergrund starten
update_thread = threading.Thread(target=self.check_for_updates_background, daemon=True)
update_thread.start()
# Handle window close
self.Bind(wx.EVT_CLOSE, self.on_closing)
def load_config(self):
"""Lade gespeicherte Konfiguration"""
try:
if CONFIG_FILE.exists():
with open(CONFIG_FILE, 'r') as f:
return json.load(f)
except Exception as e:
print(f"Warnung: Konfiguration konnte nicht geladen werden: {e}")
return {}
def save_config(self):
"""Speichere Konfiguration"""
try:
config = {
'last_output_dir': self.output_dir,
'last_pdf_dir': self.last_pdf_dir,
'exclude_rest': self.exclude_rest_checkbox.GetValue(),
'exclude_vacation': self.exclude_vacation_checkbox.GetValue()
}
with open(CONFIG_FILE, 'w') as f:
json.dump(config, f, indent=2)
except Exception as e:
print(f"Warnung: Konfiguration konnte nicht gespeichert werden: {e}")
def create_menu(self):
"""Erstelle die Menüleiste"""
menubar = wx.MenuBar()
# Hilfe-Menü
help_menu = wx.Menu()
android_item = help_menu.Append(wx.ID_ANY, 'PDF-Export auf Android (iPD)\tCtrl+H')
help_menu.AppendSeparator()
about_item = help_menu.Append(wx.ID_ABOUT, 'Über dieses Programm\tCtrl+I')
help_menu.AppendSeparator()
quit_item = help_menu.Append(wx.ID_EXIT, 'Beenden\tCtrl+Q')
menubar.Append(help_menu, '&Hilfe')
self.SetMenuBar(menubar)
# Bind events
self.Bind(wx.EVT_MENU, self.show_android_export_guide, android_item)
self.Bind(wx.EVT_MENU, self.show_about_dialog, about_item)
self.Bind(wx.EVT_MENU, self.on_closing, quit_item)
def create_widgets(self):
"""Erstelle die UI-Komponenten"""
panel = wx.Panel(self)
main_sizer = wx.BoxSizer(wx.VERTICAL)
# ========== HEADER ==========
header_panel = wx.Panel(panel)
header_panel.SetBackgroundColour('#2c3e50')
header_sizer = wx.BoxSizer(wx.VERTICAL)
title_label = wx.StaticText(header_panel, label='PDF zu ICS Konverter')
title_font = wx.Font(20, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
title_label.SetFont(title_font)
title_label.SetForegroundColour(wx.WHITE)
header_sizer.Add(title_label, 0, wx.ALL | wx.ALIGN_CENTER, 20)
header_panel.SetSizer(header_sizer)
main_sizer.Add(header_panel, 0, wx.EXPAND)
# ========== CONTENT AREA ==========
content_sizer = wx.BoxSizer(wx.VERTICAL)
# PDF-Dateien Bereich
pdf_label = wx.StaticText(panel, label='PDF-Dateien:')
pdf_font = wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
pdf_label.SetFont(pdf_font)
content_sizer.Add(pdf_label, 0, wx.ALL, 10)
# ListBox für PDFs
self.pdf_listbox = wx.ListBox(panel, style=wx.LB_EXTENDED)
# Richte Drag & Drop ein
self.pdf_listbox.SetDropTarget(FileDropTarget(self))
content_sizer.Add(self.pdf_listbox, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
# Buttons für PDF-Verwaltung
button_sizer = wx.BoxSizer(wx.HORIZONTAL)
add_btn = wx.Button(panel, label='PDF hinzufügen')
add_btn.Bind(wx.EVT_BUTTON, self.add_pdf_files)
button_sizer.Add(add_btn, 1, wx.ALL, 5)
remove_btn = wx.Button(panel, label='Entfernen')
remove_btn.Bind(wx.EVT_BUTTON, self.remove_selected_pdfs)
button_sizer.Add(remove_btn, 1, wx.ALL, 5)
clear_btn = wx.Button(panel, label='Alle entfernen')
clear_btn.Bind(wx.EVT_BUTTON, self.clear_all_pdfs)
button_sizer.Add(clear_btn, 1, wx.ALL, 5)
content_sizer.Add(button_sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
# Ausgabe-Verzeichnis
output_label = wx.StaticText(panel, label='Ausgabe-Verzeichnis:')
content_sizer.Add(output_label, 0, wx.ALL, 10)
output_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.output_text = wx.TextCtrl(panel, value=self.output_dir, style=wx.TE_READONLY)
output_sizer.Add(self.output_text, 1, wx.ALIGN_CENTER_VERTICAL, 5)
browse_btn = wx.Button(panel, label='Durchsuchen')
browse_btn.Bind(wx.EVT_BUTTON, self.browse_output_dir)
output_sizer.Add(browse_btn, 0, wx.LEFT, 5)
content_sizer.Add(output_sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
# Exportoptionen
self.exclude_rest_checkbox = wx.CheckBox(
panel,
label='🧘 Ruhetage ausschließen (Ruhe, R56, R36, vRWF48, RWE, vR48)'
)
self.exclude_rest_checkbox.SetValue(self.config.get('exclude_rest', False))
content_sizer.Add(self.exclude_rest_checkbox, 0, wx.ALL, 10)
self.exclude_vacation_checkbox = wx.CheckBox(
panel,
label='🏖️ Urlaub ausschließen (060, 0060)'
)
self.exclude_vacation_checkbox.SetValue(self.config.get('exclude_vacation', False))
content_sizer.Add(self.exclude_vacation_checkbox, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
# Log-Bereich
log_label = wx.StaticText(panel, label='Status:')
log_label.SetFont(pdf_font)
content_sizer.Add(log_label, 0, wx.ALL, 10)
self.log_text = wx.TextCtrl(
panel,
style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_WORDWRAP
)
self.log_text.SetBackgroundColour('#f8f9fa')
content_sizer.Add(self.log_text, 2, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
# Konvertieren Button
self.convert_btn = wx.Button(panel, label='ICS Datei erstellen')
self.convert_btn.Bind(wx.EVT_BUTTON, self.convert_pdfs)
content_sizer.Add(self.convert_btn, 0, wx.EXPAND | wx.ALL, 10)
main_sizer.Add(content_sizer, 1, wx.EXPAND)
panel.SetSizer(main_sizer)
# Initial log message
self.log("Bereit. Fügen Sie PDF-Dateien hinzu um zu starten.")
self.log("✓ Native wxPython GUI - perfekte Integration auf macOS, Windows & Linux!")
def log(self, message):
"""Füge eine Nachricht zum Log hinzu"""
timestamp = datetime.now().strftime("%H:%M:%S")
wx.CallAfter(self._append_log, f"[{timestamp}] {message}\n")
def _append_log(self, message):
"""Thread-sichere Log-Ausgabe"""
self.log_text.AppendText(message)
def add_pdf_files(self, event=None):
"""Öffne Datei-Dialog zum Hinzufügen von PDFs"""
with wx.FileDialog(
self,
"PDF-Dateien auswählen",
defaultDir=self.last_pdf_dir,
wildcard="PDF Dateien (*.pdf)|*.pdf|Alle Dateien (*.*)|*.*",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return
paths = fileDialog.GetPaths()
for path in paths:
if path not in self.pdf_files:
self.pdf_files.append(path)
self.pdf_listbox.Append(Path(path).name)
if paths:
# Merke Verzeichnis der ersten ausgewählten Datei
self.last_pdf_dir = str(Path(paths[0]).parent)
self.log(f"{len(paths)} PDF-Datei(en) hinzugefügt")
def remove_selected_pdfs(self, event=None):
"""Entferne ausgewählte PDFs aus der Liste"""
selections = self.pdf_listbox.GetSelections()
if not selections:
return
# Rückwärts durchlaufen, um Indexprobleme zu vermeiden
for index in reversed(selections):
self.pdf_listbox.Delete(index)
del self.pdf_files[index]
self.log(f"{len(selections)} PDF-Datei(en) entfernt")
def clear_all_pdfs(self, event=None):
"""Entferne alle PDFs aus der Liste"""
count = len(self.pdf_files)
self.pdf_listbox.Clear()
self.pdf_files.clear()
if count > 0:
self.log(f"✓ Alle {count} PDF-Datei(en) entfernt")
def browse_output_dir(self, event=None):
"""Öffne Dialog zur Auswahl des Ausgabe-Verzeichnisses"""
with wx.DirDialog(
self,
"Ausgabe-Verzeichnis auswählen",
defaultPath=self.output_dir,
style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST
) as dirDialog:
if dirDialog.ShowModal() == wx.ID_CANCEL:
return
self.output_dir = dirDialog.GetPath()
self.output_text.SetValue(self.output_dir)
self.save_config()
self.log(f"✓ Ausgabe-Verzeichnis: {self.output_dir}")
def convert_pdfs(self, event=None):
"""Konvertiere alle PDFs zu ICS"""
if not self.pdf_files:
wx.MessageBox(
'Bitte fügen Sie mindestens eine PDF-Datei hinzu.',
'Keine PDFs',
wx.OK | wx.ICON_WARNING
)
return
# Starte Konvertierung in separatem Thread
thread = threading.Thread(target=self._convert_worker, daemon=True)
thread.start()
def _convert_worker(self):
"""Worker-Thread für Konvertierung"""
# Deaktiviere Button
wx.CallAfter(self.convert_btn.Enable, False)
output_dir = Path(self.output_dir)
success_count = 0
self.log("\n" + "="*50)
self.log("🔄 Starte Konvertierung...")
self.log("="*50)
for i, pdf_path in enumerate(self.pdf_files, 1):
try:
self.log(f"\n[{i}/{len(self.pdf_files)}] Verarbeite: {Path(pdf_path).name}")
# Extrahiere Daten
dienstplan = extract_dienstplan_data(pdf_path)
# Zeige Informationen
self.log(f" ├─ Name: {dienstplan['vorname']} {dienstplan['name']}")
self.log(f" ├─ Personalnummer: {dienstplan['personalnummer']}")
self.log(f" ├─ Betriebshof: {dienstplan['betriebshof']}")
self.log(f" └─ Events gefunden: {len(dienstplan['events'])}")
if not dienstplan['events']:
self.log(" ⚠️ Warnung: Keine Events gefunden!")
continue
# Erstelle ICS-Datei
ics_filename = Path(pdf_path).stem + '.ics'
ics_path = output_dir / ics_filename
create_ics_from_dienstplan(
dienstplan,
str(ics_path),
exclude_rest=self.exclude_rest_checkbox.GetValue(),
exclude_vacation=self.exclude_vacation_checkbox.GetValue()
)
self.log(f" ✓ ICS erstellt: {ics_filename}")
success_count += 1
except Exception as e:
self.log(f" ✗ Fehler: {str(e)}")
# Zusammenfassung
self.log("\n" + "="*50)
self.log(f"✅ Fertig! {success_count}/{len(self.pdf_files)} ICS-Dateien erstellt")
self.log("="*50 + "\n")
# Speichere Config
self.save_config()
# Reaktiviere Button
wx.CallAfter(self.convert_btn.Enable, True)
# Erfolgsmeldung
if success_count > 0:
wx.CallAfter(
wx.MessageBox,
f"Es wurden {success_count} ICS-Datei(en) erfolgreich erstellt!\n\n"
f"Speicherort: {output_dir}",
"Konvertierung abgeschlossen",
wx.OK | wx.ICON_INFORMATION
)
def show_android_export_guide(self, event=None):
"""Zeige Anleitung für PDF-Export aus Android App (iPD)"""
guide_window = wx.Dialog(self, title="PDF-Export auf Android (iPD)", size=(600, 600))
panel = wx.Panel(guide_window)
sizer = wx.BoxSizer(wx.VERTICAL)
# Header
header = wx.StaticText(panel, label="PDF-Export aus iPD")
header_font = wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
header.SetFont(header_font)
sizer.Add(header, 0, wx.ALL | wx.ALIGN_CENTER, 15)
# Anleitung-Text
guide_text = wx.TextCtrl(
panel,
value="""1. Öffne die iPD App auf deinem Android-Gerät
2. Öffne einen Dienstplan
3. Wähle den gewünschten Monat aus
4. Tippe auf das PDF-Symbol
(rechts oben, links neben dem 3-Punkte-Menü)
5. Tippe auf "Datei herunterladen"
(rechts oben, neben Drucker-Button)
6. Wähle "Im Arbeitsprofil speichern"
7. Sende die PDF-Datei als E-Mail-Anhang
an deine private E-Mailadresse
8. Transferiere die PDF-Datei auf deinen Computer
9. Öffne diese Anwendung und füge die PDF ein
10. Klicke "ICS Datei erstellen"
11. Importiere die ICS-Datei in deinen Kalender
✓ Fertig!""",
style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_WORDWRAP
)
guide_text.SetBackgroundColour('#f8f9fa')
sizer.Add(guide_text, 1, wx.EXPAND | wx.ALL, 10)
# Buttons
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
online_btn = wx.Button(panel, label='Detaillierte Anleitung online')
online_btn.Bind(wx.EVT_BUTTON, lambda e: webbrowser.open("https://git.file-archive.de/webfarben/pdf_to_ics"))
btn_sizer.Add(online_btn, 0, wx.ALL, 5)
close_btn = wx.Button(panel, wx.ID_CLOSE, 'Schließen')
close_btn.Bind(wx.EVT_BUTTON, lambda e: guide_window.Close())
btn_sizer.Add(close_btn, 0, wx.ALL, 5)
sizer.Add(btn_sizer, 0, wx.ALIGN_CENTER | wx.ALL, 10)
panel.SetSizer(sizer)
guide_window.ShowModal()
guide_window.Destroy()
def show_about_dialog(self, event=None):
"""Zeige About-Dialog mit Programminformationen"""
version = get_current_version()
info = wx.adv.AboutDialogInfo()
info.SetName("PDF zu ICS Konverter")
info.SetVersion(f"Version {version}")
info.SetDescription(
"Ein Programm zur Konvertierung von Dienstplan-PDFs "
"zu ICS-Kalenderdateien für einfaches Importieren "
"in Kalenderprogramme."
)
info.SetWebSite("https://git.file-archive.de/webfarben/pdf_to_ics")
info.AddDeveloper("Sebastian Köhler - Webfarben")
info.SetLicence("Proprietär")
wx.adv.AboutBox(info)
def check_for_updates_background(self):
"""Prüfe auf Updates im Hintergrund"""
try:
update_available, new_version, download_url = check_for_updates()
if update_available:
wx.CallAfter(self.show_update_dialog, new_version, download_url)
except Exception:
pass
def show_update_dialog(self, new_version, download_url):
"""Zeige Update-Dialog"""
current_version = get_current_version()
result = wx.MessageBox(
f"Eine neue Version ist verfügbar!\n\n"
f"Aktuelle Version: v{current_version}\n"
f"Neue Version: v{new_version}\n\n"
f"Möchten Sie die neue Version herunterladen?",
"Update verfügbar",
wx.YES_NO | wx.ICON_INFORMATION
)
if result == wx.YES:
webbrowser.open(download_url)
def on_closing(self, event=None):
"""Handle für Fenster schließen"""
self.save_config()
self.Destroy()
def main():
"""Hauptfunktion"""
app = wx.App()
frame = PDFtoICSFrame()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -1,199 +0,0 @@
#!/bin/bash
###############################################################################
# PDF zu ICS Konverter - Installations-Script für Linux
# Installiert die Anwendung systemweit mit Desktop-Integration
###############################################################################
set -e # Beende bei Fehlern
# Farben für bessere Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Installation-Pfade
INSTALL_DIR="$HOME/.local/share/pdf-to-ics"
DESKTOP_FILE="$HOME/.local/share/applications/pdf-to-ics.desktop"
BIN_DIR="$HOME/.local/bin"
LAUNCHER="$BIN_DIR/pdf-to-ics"
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ PDF zu ICS Konverter - Installations-Assistent ║${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
# Funktion für Fortschrittsanzeige
print_step() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
print_success() {
echo -e "${GREEN}${NC} $1"
}
# Prüfe Python-Installation
print_step "Prüfe Python-Installation..."
if ! command -v python3 &> /dev/null; then
print_error "Python 3 ist nicht installiert!"
echo "Bitte installieren Sie Python 3:"
echo " sudo apt install python3 python3-pip python3-venv"
exit 1
fi
PYTHON_VERSION=$(python3 --version)
print_success "Python gefunden: $PYTHON_VERSION"
# Prüfe und installiere python3-venv wenn nötig
print_step "Prüfe venv-Installation..."
# Prüfe ob ensurepip verfügbar ist (wird für venv benötigt)
if ! python3 -c "import ensurepip" 2>/dev/null; then
print_warning "ensurepip ist nicht verfügbar. Installation von python3-venv erforderlich..."
# Erkenne Distribution
if [ -f /etc/debian_version ]; then
echo "Debian/Ubuntu erkannt. Installiere python3-venv..."
# Ermittle Python-Version für das richtige Paket
PYTHON_VERSION_NUM=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
VENV_PACKAGE="python${PYTHON_VERSION_NUM}-venv"
if command -v sudo &> /dev/null; then
sudo apt-get update && sudo apt-get install -y "$VENV_PACKAGE"
else
print_error "sudo nicht verfügbar. Bitte installieren Sie $VENV_PACKAGE manuell:"
echo " apt install $VENV_PACKAGE"
exit 1
fi
elif [ -f /etc/fedora-release ]; then
echo "Fedora erkannt. Python venv sollte bereits enthalten sein..."
print_error "Falls venv fehlt, installieren Sie bitte python3-devel"
exit 1
elif [ -f /etc/arch-release ]; then
echo "Arch Linux erkannt. Python venv sollte bereits enthalten sein..."
print_error "Falls venv fehlt, installieren Sie bitte python erneut"
exit 1
else
print_error "Distribution nicht erkannt. Bitte installieren Sie python3-venv manuell."
exit 1
fi
# Verifiziere Installation
if ! python3 -c "import ensurepip" 2>/dev/null; then
print_error "Installation von $VENV_PACKAGE fehlgeschlagen!"
exit 1
fi
print_success "venv installiert"
else
print_success "venv ist bereits installiert"
fi
# Erstelle Installationsverzeichnis
print_step "Erstelle Installationsverzeichnis..."
mkdir -p "$INSTALL_DIR"
mkdir -p "$BIN_DIR"
mkdir -p "$(dirname "$DESKTOP_FILE")"
# Kopiere Dateien
print_step "Kopiere Anwendungsdateien..."
cp -r *.py *.md *.sh *.cmd version.txt .gitignore "$INSTALL_DIR/" 2>/dev/null || true
print_success "Dateien kopiert nach $INSTALL_DIR"
# Erstelle Python Virtual Environment
print_step "Erstelle Python-Umgebung..."
cd "$INSTALL_DIR"
python3 -m venv .venv --upgrade-deps
print_success "Virtual Environment erstellt"
# Installiere Python-Abhängigkeiten
print_step "Installiere Python-Abhängigkeiten..."
.venv/bin/pip install -q --upgrade pip
.venv/bin/pip install -q pdfplumber icalendar pypdf2 pytz packaging
print_step "Installiere wxPython..."
if .venv/bin/pip install wxPython; then
print_success "wxPython installiert"
else
print_error "wxPython konnte nicht installiert werden."
print_warning "Auf Linux fehlen ggf. Build-Abhängigkeiten. Unter Debian/Ubuntu/Mint oft hilfreich:"
echo " sudo apt-get update"
echo " sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev"
echo "Danach die Installation erneut starten: ./install.sh"
exit 1
fi
print_success "Abhängigkeiten installiert"
# Erstelle Launcher-Script
print_step "Erstelle Launcher-Script..."
cat > "$LAUNCHER" << 'EOF'
#!/bin/bash
# PDF zu ICS Konverter Launcher
INSTALL_DIR="$HOME/.local/share/pdf-to-ics"
cd "$INSTALL_DIR"
exec .venv/bin/python gui_wxpython.py
EOF
chmod +x "$LAUNCHER"
print_success "Launcher erstellt: $LAUNCHER"
# Erstelle Desktop-Verknüpfung
print_step "Erstelle Desktop-Verknüpfung..."
cat > "$DESKTOP_FILE" << EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=PDF zu ICS Konverter
Comment=Konvertiere Dienstplan-PDFs zu iCalendar-Dateien
Exec=$LAUNCHER
Icon=calendar
Terminal=false
Categories=Office;Utility;
Keywords=PDF;ICS;Kalender;Dienstplan;
StartupNotify=true
EOF
chmod +x "$DESKTOP_FILE"
print_success "Desktop-Verknüpfung erstellt"
# Desktop-Datenbank aktualisieren
if command -v update-desktop-database &> /dev/null; then
update-desktop-database "$HOME/.local/share/applications" 2>/dev/null || true
fi
# Prüfe ob ~/.local/bin im PATH ist
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
print_warning "~/.local/bin ist nicht im PATH!"
echo "Fügen Sie folgende Zeile zu ~/.bashrc oder ~/.zshrc hinzu:"
echo ""
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
echo ""
fi
# Abschluss
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Installation erfolgreich abgeschlossen! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
print_success "Die Anwendung wurde installiert!"
echo ""
echo "Sie können die Anwendung nun starten:"
echo ""
echo -e " 1. ${BLUE}Über das Anwendungsmenü${NC} (suchen Sie nach 'PDF zu ICS')"
echo -e " 2. ${BLUE}Über die Kommandozeile:${NC} pdf-to-ics"
echo ""
echo "Installation Details:"
echo " • Installationsverzeichnis: $INSTALL_DIR"
echo " • Launcher: $LAUNCHER"
echo " • Desktop-Verknüpfung: $DESKTOP_FILE"
echo ""
echo "Zum Deinstallieren führen Sie aus:"
echo " bash $INSTALL_DIR/uninstall.sh"
echo ""

201
menu.py
View File

@@ -1,201 +0,0 @@
#!/usr/bin/env python3
"""
Interaktives Menü für PDF zu ICS Konvertierung
Benutzerfreundliche Oberfläche zum Verarbeiten von Dienstplan-PDFs
"""
import os
import sys
from pathlib import Path
from pdf_to_ics import extract_dienstplan_data, create_ics_from_dienstplan
def print_header():
"""Zeige Programm-Header"""
print("\n" + "="*60)
print("PDF zu ICS Konverter - Dienstplan Importer".center(60))
print("="*60 + "\n")
def print_menu():
"""Zeige Hauptmenü"""
print("\nHauptmenü:")
print("1. PDF(s) konvertieren")
print("2. Verzeichnis durchsuchen")
print("3. Über dieses Programm")
print("4. Beenden")
print("-" * 40)
def list_pdf_files():
"""Liste alle PDF-Dateien im aktuellen Verzeichnis"""
pdf_files = list(Path('.').glob('*.pdf'))
return pdf_files
def convert_pdf(pdf_path):
"""Konvertiere eine einzelne PDF-Datei"""
try:
print(f"\n▶ Verarbeite: {pdf_path}")
# Extrahiere Daten
dienstplan = extract_dienstplan_data(str(pdf_path))
# Zeige Informationen
print(f" Name: {dienstplan['vorname']} {dienstplan['name']}")
print(f" Personalnummer: {dienstplan['personalnummer']}")
print(f" Betriebshof: {dienstplan['betriebshof']}")
print(f" Zeitraum: {dienstplan['monat_start']}")
print(f" Sollarbeitszeit: {dienstplan['sollarbeitszeit']}")
print(f" Events gefunden: {len(dienstplan['events'])}")
if not dienstplan['events']:
print(" ⚠ Warnung: Keine Events gefunden!")
return False
# Erstelle ICS-Datei
ics_path = pdf_path.with_suffix('.ics')
create_ics_from_dienstplan(dienstplan, str(ics_path))
print(f" ✓ ICS-Datei erstellt: {ics_path}")
print(f" ✓ Erfolg!\n")
return True
except Exception as e:
print(f" ✗ Fehler: {e}\n")
return False
def convert_multiple_pdfs():
"""Konvertiere mehrere PDF-Dateien"""
pdf_files = list_pdf_files()
if not pdf_files:
print("\n⚠ Keine PDF-Dateien im aktuellen Verzeichnis gefunden!")
return
print(f"\n{len(pdf_files)} PDF-Datei(en) gefunden:\n")
for i, pdf in enumerate(pdf_files, 1):
print(f"{i}. {pdf}")
print("\n" + "-" * 40)
success_count = 0
for pdf in pdf_files:
if convert_pdf(pdf):
success_count += 1
print(f"\n{'='*40}")
print(f"Zusammenfassung: {success_count}/{len(pdf_files)} ICS-Dateien erstellt")
print(f"{'='*40}\n")
def find_and_show_pdfs():
"""Durchsuche Verzeichnis und zeige PDFs"""
current_dir = Path('.')
print("\n📁 PDF-Dateien in diesem Verzeichnis:")
print("-" * 40)
pdf_files = list(current_dir.glob('*.pdf'))
if not pdf_files:
print("Keine PDF-Dateien gefunden.")
return
for i, pdf in enumerate(pdf_files, 1):
size = pdf.stat().st_size
size_mb = size / (1024 * 1024)
# Versuche Größe lesbar zu machen
if size_mb > 1:
size_str = f"{size_mb:.2f} MB"
else:
size_kb = size / 1024
size_str = f"{size_kb:.2f} KB"
print(f"{i}. {pdf.name:50} {size_str:>10}")
print("-" * 40)
print(f"\nGesamt: {len(pdf_files)} PDF-Datei(en)\n")
def show_about():
"""Zeige Informationen über das Programm"""
print("""
╔═══════════════════════════════════════════════════════════╗
║ PDF zu ICS Konverter - Dienstplan Importer ║
║ Version 1.0 ║
╚═══════════════════════════════════════════════════════════╝
BESCHREIBUNG:
Dieses Programm extrahiert Kalenderdaten aus Dienstplan-
PDFs und konvertiert sie in das iCalendar-Format (ICS).
FEATURES:
✓ Automatische Extraktion von Schichtdaten
✓ Erkennung von Zeitangaben und Nachtschichten
✓ Standard-konforme ICS-Datei-Erstellung
✓ Unterstützung für mehrere PDFs
VERWENDETE LIBRARIES:
• pdfplumber - PDF-Verarbeitung
• icalendar - ICS-Datei-Erstellung
• pytz - Zeitzonenverwaltung
IMPORT IN KALENDER:
Die erstellten ICS-Dateien können in folgende
Anwendungen importiert werden:
✓ Outlook
✓ Google Kalender
✓ Apple Kalender (macOS/iOS)
✓ Thunderbird
✓ LibreOffice Kalender
✓ und viele andere...
FÜR MEHR INFORMATIONEN:
Siehe README.md für ausführliche Dokumentation
""")
def main():
"""Hauptprogramm"""
print_header()
while True:
print_menu()
choice = input("Wählen Sie eine Option (1-4): ").strip()
if choice == '1':
convert_multiple_pdfs()
input("Drücken Sie Enter zum Fortfahren...")
elif choice == '2':
find_and_show_pdfs()
input("Drücken Sie Enter zum Fortfahren...")
elif choice == '3':
show_about()
input("Drücken Sie Enter zum Fortfahren...")
elif choice == '4':
print("\nAuf Wiedersehen! 👋\n")
sys.exit(0)
else:
print("\n✗ Ungültige Auswahl. Bitte versuchen Sie es erneut.")
os.system('clear' if os.name == 'posix' else 'cls')
print_header()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print("\n\n✗ Programm von Benutzer unterbrochen.\n")
sys.exit(1)

View File

@@ -1,19 +0,0 @@
@echo off
REM PDF zu ICS Konverter - Windows Startskript
setlocal enabledelayedexpansion
REM Wechsel ins Skriptverzeichnis
cd /d "%~dp0"
REM Überprüfe, ob venv existiert
if not exist ".venv" (
echo Python-Umgebung wird eingerichtet...
python3 -m venv .venv
call .venv\Scripts\pip.exe install -q pdfplumber icalendar pypdf2 pytz packaging
)
REM Starte das Menü
call .venv\Scripts\python.exe menu.py
pause

View File

@@ -1,78 +0,0 @@
#!/bin/bash
# PDF zu ICS Konverter - Startskript
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
# Finde Python-Executable
PYTHON_CMD=""
if command -v python3 &> /dev/null; then
PYTHON_CMD="python3"
elif command -v python &> /dev/null; then
PYTHON_CMD="python"
else
echo "❌ Fehler: Python nicht gefunden!"
echo "Bitte installieren Sie Python 3.6 oder höher."
exit 1
fi
echo "🐍 Nutze: $PYTHON_CMD"
# Erstelle venv wenn nicht vorhanden
if [ ! -d ".venv" ]; then
echo "📦 Python-Umgebung wird eingerichtet..."
$PYTHON_CMD -m venv .venv --upgrade-deps || {
echo "❌ venv konnte nicht erstellt werden"
exit 1
}
fi
# Nutze Python aus venv
PYTHON_VENV=".venv/bin/python"
# Überprüfe, ob Abhängigkeiten installiert sind
if ! $PYTHON_VENV -c "import pdfplumber" 2>/dev/null; then
echo "📚 Installiere Abhängigkeiten..."
# Nutze python -m pip statt pip direkt
if $PYTHON_VENV -m pip install -q pdfplumber icalendar pypdf2 pytz packaging 2>/dev/null; then
echo "✓ Abhängigkeiten installiert"
else
echo "❌ Installation fehlgeschlagen"
echo "🔧 Versuche venv neu aufzubauen..."
rm -rf .venv
$PYTHON_CMD -m venv .venv --upgrade-deps || {
echo "❌ venv konnte nicht neu erstellt werden"
exit 1
}
$PYTHON_VENV -m pip install -q pdfplumber icalendar pypdf2 pytz packaging || {
echo "❌ Abhängigkeiten konnten nicht installiert werden"
exit 1
}
echo "✓ venv neu erstellt"
fi
fi
# Starte das Skript
if [ -f "$PYTHON_VENV" ]; then
# Versuche zuerst das interaktive Menü, falls TTY verfügbar
if [ -t 0 ]; then
$PYTHON_VENV menu.py
else
# Sonst starte die direkte Konvertierung
echo ""
echo "🔄 Konvertiere PDF-Dateien..."
echo "-----------------------------------"
$PYTHON_VENV pdf_to_ics.py
echo "-----------------------------------"
echo ""
echo "✅ Fertig!"
fi
else
echo "❌ Fehler: Python-Umgebung ist beschädigt"
echo "📁 Bitte löschen Sie das .venv Verzeichnis und versuchen Sie erneut:"
echo " rm -rf .venv"
echo " ./start.sh"
exit 1
fi

View File

@@ -1,49 +0,0 @@
@echo off
REM PDF zu ICS Konverter - GUI Startskript (Windows)
setlocal enabledelayedexpansion
REM Wechsel ins Skriptverzeichnis
cd /d "%~dp0"
REM Überprüfe, ob venv existiert
if not exist ".venv" (
echo 📦 Python-Umgebung wird eingerichtet...
python3 -m venv .venv --upgrade-deps
if errorlevel 1 (
python -m venv .venv --upgrade-deps
)
)
REM Überprüfe, ob Abhängigkeiten installiert sind
.venv\Scripts\python.exe -c "import pdfplumber" 2>nul
if errorlevel 1 (
echo 📚 Installiere Abhängigkeiten...
call .venv\Scripts\python.exe -m pip install -q pdfplumber icalendar pypdf2 pytz packaging
echo ✓ Abhängigkeiten installiert
)
REM Überprüfe, ob wxPython installiert ist
.venv\Scripts\python.exe -c "import wx" 2>nul
if errorlevel 1 (
echo 📚 Installiere wxPython...
call .venv\Scripts\python.exe -m pip install -q wxPython
if errorlevel 1 (
echo.
echo ❌ wxPython konnte nicht installiert werden.
echo Bitte installieren Sie Visual C++ Build Tools und versuchen Sie es erneut.
pause
exit /b 1
)
echo ✓ wxPython installiert
)
REM Starte die GUI
echo 🎨 Starte GUI...
call .venv\Scripts\pythonw.exe gui_wxpython.py
if errorlevel 1 (
echo.
echo ❌ Fehler beim Starten der GUI
pause
)

View File

@@ -1,81 +0,0 @@
#!/bin/bash
# PDF zu ICS Konverter - GUI Startskript
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
# Finde Python-Executable
PYTHON_CMD=""
if command -v python3 &> /dev/null; then
PYTHON_CMD="python3"
elif command -v python &> /dev/null; then
PYTHON_CMD="python"
else
echo "❌ Fehler: Python nicht gefunden!"
echo "Bitte installieren Sie Python 3.6 oder höher."
exit 1
fi
echo "🐍 Nutze: $PYTHON_CMD"
# Erstelle venv wenn nicht vorhanden
if [ ! -d ".venv" ]; then
echo "📦 Python-Umgebung wird eingerichtet..."
$PYTHON_CMD -m venv .venv --upgrade-deps || {
echo "❌ venv konnte nicht erstellt werden"
exit 1
}
fi
# Nutze Python aus venv
PYTHON_VENV=".venv/bin/python"
# Überprüfe, ob Kern-Abhängigkeiten installiert sind
if ! $PYTHON_VENV -c "import pdfplumber, icalendar, pypdf2, pytz, packaging" 2>/dev/null; then
echo "📚 Installiere Abhängigkeiten..."
if $PYTHON_VENV -m pip install -q pdfplumber icalendar pypdf2 pytz packaging 2>/dev/null; then
echo "✓ Abhängigkeiten installiert"
else
echo "❌ Installation fehlgeschlagen"
echo "🔧 Versuche venv neu aufzubauen..."
rm -rf .venv
$PYTHON_CMD -m venv .venv --upgrade-deps || {
echo "❌ venv konnte nicht neu erstellt werden"
exit 1
}
$PYTHON_VENV -m pip install -q pdfplumber icalendar pypdf2 pytz packaging || {
echo "❌ Abhängigkeiten konnten nicht installiert werden"
exit 1
}
echo "✓ venv neu erstellt"
fi
fi
# Überprüfe, ob wxPython installiert ist
if ! $PYTHON_VENV -c "import wx" 2>/dev/null; then
echo "📚 Installiere wxPython..."
if $PYTHON_VENV -m pip install wxPython; then
echo "✓ wxPython installiert"
else
echo "❌ wxPython konnte nicht installiert werden"
echo "💡 Auf Linux fehlen ggf. Build-Abhängigkeiten. Unter Debian/Ubuntu/Mint oft hilfreich:"
echo " sudo apt-get update"
echo " sudo apt-get install -y build-essential python3-dev libgtk-3-dev libglib2.0-dev libjpeg-dev libtiff-dev libpng-dev"
echo " rm -rf .venv && ./start_gui.sh"
exit 1
fi
fi
# Starte die GUI
echo "🎨 Starte GUI..."
if [ -f "$PYTHON_VENV" ]; then
$PYTHON_VENV gui_wxpython.py
else
echo "❌ Fehler: Python-Umgebung ist beschädigt"
echo "📁 Bitte löschen Sie das .venv Verzeichnis und versuchen Sie erneut:"
echo " rm -rf .venv"
echo " ./start_gui.sh"
exit 1
fi

View File

@@ -1,22 +0,0 @@
@echo off
REM PDF zu ICS Web-MVP starten (Windows)
setlocal enabledelayedexpansion
cd /d "%~dp0"
if not exist ".venv" (
echo 📦 Python-Umgebung wird eingerichtet...
py -3 -m venv .venv --upgrade-deps
if errorlevel 1 (
python -m venv .venv --upgrade-deps
)
)
.venv\Scripts\python.exe -c "import fastapi" 2>nul
if errorlevel 1 (
echo 📚 Installiere Web-Abhängigkeiten...
call .venv\Scripts\python.exe -m pip install -q -r web\requirements-web.txt
)
echo 🌐 Starte Web-App auf http://0.0.0.0:8000
call .venv\Scripts\python.exe -m uvicorn web.app:app --host 0.0.0.0 --port 8000

View File

@@ -1,31 +0,0 @@
#!/bin/bash
# PDF zu ICS Web-MVP starten (Linux/macOS)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
PYTHON_CMD=""
if command -v python3 &> /dev/null; then
PYTHON_CMD="python3"
elif command -v python &> /dev/null; then
PYTHON_CMD="python"
else
echo "❌ Fehler: Python nicht gefunden!"
exit 1
fi
if [ ! -d ".venv" ]; then
echo "📦 Python-Umgebung wird eingerichtet..."
$PYTHON_CMD -m venv .venv --upgrade-deps || exit 1
fi
PYTHON_VENV=".venv/bin/python"
if ! $PYTHON_VENV -c "import fastapi" 2>/dev/null; then
echo "📚 Installiere Web-Abhängigkeiten..."
$PYTHON_VENV -m pip install -q -r web/requirements-web.txt || exit 1
fi
echo "🌐 Starte Web-App auf http://0.0.0.0:8000"
exec $PYTHON_VENV -m uvicorn web.app:app --host 0.0.0.0 --port 8000

View File

@@ -1,85 +0,0 @@
#!/bin/bash
###############################################################################
# PDF zu ICS Konverter - Deinstallations-Script
###############################################################################
set -e
# Farben
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
INSTALL_DIR="$HOME/.local/share/pdf-to-ics"
DESKTOP_FILE="$HOME/.local/share/applications/pdf-to-ics.desktop"
LAUNCHER="$HOME/.local/bin/pdf-to-ics"
CONFIG_FILE="$HOME/.pdf_to_ics_config.json"
echo -e "${YELLOW}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${YELLOW}║ PDF zu ICS Konverter - Deinstallations-Assistent ║${NC}"
echo -e "${YELLOW}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Folgende Dateien und Verzeichnisse werden entfernt:"
echo "$INSTALL_DIR"
echo "$DESKTOP_FILE"
echo "$LAUNCHER"
echo ""
echo "Konfigurationsdatei behalten? (sie enthält Ihre letzten Verzeichnisse)"
echo "$CONFIG_FILE"
echo ""
echo -e "${RED}Möchten Sie fortfahren? (y/n)${NC}"
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Deinstallation abgebrochen."
exit 0
fi
# Lösche Dateien
echo ""
echo "Entferne Installationsdateien..."
if [ -d "$INSTALL_DIR" ]; then
rm -rf "$INSTALL_DIR"
echo -e "${GREEN}${NC} Installationsverzeichnis entfernt"
fi
if [ -f "$DESKTOP_FILE" ]; then
rm -f "$DESKTOP_FILE"
echo -e "${GREEN}${NC} Desktop-Verknüpfung entfernt"
fi
if [ -f "$LAUNCHER" ]; then
rm -f "$LAUNCHER"
echo -e "${GREEN}${NC} Launcher entfernt"
fi
# Konfigurationsdatei nur entfernen wenn explizit gewünscht
if [ -f "$CONFIG_FILE" ]; then
echo ""
echo -e "Konfigurationsdatei $CONFIG_FILE gefunden."
echo -e "${YELLOW}Auch entfernen? (y/n)${NC}"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
rm -f "$CONFIG_FILE"
echo -e "${GREEN}${NC} Konfigurationsdatei entfernt"
else
echo -e "${GREEN}${NC} Konfigurationsdatei behalten"
fi
fi
# Desktop-Datenbank aktualisieren
if command -v update-desktop-database &> /dev/null; then
update-desktop-database "$HOME/.local/share/applications" 2>/dev/null || true
fi
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Deinstillation erfolgreich abgeschlossen! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "PDF zu ICS Konverter wurde von Ihrem System entfernt."
echo ""

View File

@@ -1,152 +0,0 @@
#!/usr/bin/env python3
"""
Update-Checker für PDF zu ICS Konverter
Prüft auf Updates über Gitea API
"""
import urllib.request
import json
from pathlib import Path
try:
from packaging import version as pkg_version
except Exception: # pragma: no cover - packaging may be missing in user envs
pkg_version = None
# Gitea-Konfiguration
GITEA_URL = "https://git.file-archive.de"
REPO_OWNER = "webfarben"
REPO_NAME = "pdf_to_ics"
def get_current_version():
"""Lese aktuelle lokal gespeicherte Version"""
try:
version_file = Path(__file__).parent / 'version.txt'
if version_file.exists():
with open(version_file, 'r') as f:
return f.read().strip()
except Exception as e:
print(f"Warnung: Version konnte nicht gelesen werden: {e}")
return "0.0.0"
def get_latest_version():
"""
Prüfe Latest Release auf Gitea
Returns:
Tupel (version_string, download_url) oder (None, None) bei Fehler
"""
try:
# Gitea API Endpoint für neueste Release
url = f"{GITEA_URL}/api/v1/repos/{REPO_OWNER}/{REPO_NAME}/releases/latest"
with urllib.request.urlopen(url, timeout=5) as response:
data = json.loads(response.read().decode())
# Extrahiere Version aus Tag (z.B. "v1.0.0" -> "1.0.0")
tag = data.get('tag_name', '').lstrip('v')
if not tag:
return None, None
# HTML-URL für Download (Download-Seite auf Gitea)
download_url = f"{GITEA_URL}/{REPO_OWNER}/{REPO_NAME}/releases/tag/{data.get('tag_name', '')}"
return tag, download_url
except urllib.error.URLError as e:
print(f"Warnung: Konnte Gitea nicht erreichen ({GITEA_URL}): {e}")
return None, None
except json.JSONDecodeError:
print("Warnung: Gitea Response konnte nicht geparst werden")
return None, None
except Exception as e:
print(f"Warnung: Update-Check fehlgeschlagen: {e}")
return None, None
def check_for_updates():
"""
Prüfe ob ein Update verfügbar ist
Returns:
Tupel (update_available, new_version, download_url)
- update_available: Bool
- new_version: Version String oder None
- download_url: URL zur Download-Seite oder None
"""
current = get_current_version()
latest, url = get_latest_version()
if latest is None:
# Bei Fehler kein Update-Dialog
return False, None, None
try:
# Vergleiche Versionen
if pkg_version is not None:
if pkg_version.parse(latest) > pkg_version.parse(current):
return True, latest, url
else:
if _simple_version_compare(latest, current) > 0:
return True, latest, url
except Exception as e:
print(f"Warnung: Versionenvergleich fehlgeschlagen: {e}")
return False, None, None
def _simple_version_compare(left, right):
"""
Fallback-Versionsvergleich ohne externe Abhaengigkeiten.
Gibt 1 zurueck wenn left > right, -1 wenn left < right, sonst 0.
"""
def to_parts(value):
parts = []
for item in value.replace("v", "").split("."):
try:
parts.append(int(item))
except ValueError:
parts.append(item)
return parts
left_parts = to_parts(left)
right_parts = to_parts(right)
max_len = max(len(left_parts), len(right_parts))
for i in range(max_len):
l_val = left_parts[i] if i < len(left_parts) else 0
r_val = right_parts[i] if i < len(right_parts) else 0
if l_val == r_val:
continue
try:
return 1 if l_val > r_val else -1
except TypeError:
l_str = str(l_val)
r_str = str(r_val)
if l_str == r_str:
continue
return 1 if l_str > r_str else -1
return 0
if __name__ == "__main__":
# Test
current = get_current_version()
print(f"Aktuelle Version: {current}")
print(f"Gitea-Server: {GITEA_URL}/{REPO_OWNER}/{REPO_NAME}\n")
latest, url = get_latest_version()
if latest:
print(f"Neueste Version auf Gitea: {latest}")
print(f"Download-URL: {url}")
update_available, new_version, download_url = check_for_updates()
if update_available:
print(f"✓ Update verfügbar: v{new_version}")
else:
print("✓ Sie verwenden bereits die neueste Version")
else:
print(f"⚠ Konnte Gitea nicht erreichen ({GITEA_URL})")

View File

@@ -1 +0,0 @@
1.2.2