From 394a5fc234ce48298ed6d767597c9810acf65e90 Mon Sep 17 00:00:00 2001 From: webfarben Date: Tue, 3 Mar 2026 08:47:19 +0000 Subject: [PATCH] chore: remove non-docker artifacts and docs --- BUILD_STANDALONE.md | 152 ----------- GUI_README.md | 54 ---- INSTALL.md | 162 ------------ QUICKSTART.md | 102 -------- README.md | 178 ++----------- WEB_README.md | 352 ++++---------------------- WEITERGABE.md | 89 ------- WXPYTHON_README.md | 287 --------------------- ZUSAMMENFASSUNG.md | 212 ---------------- build/build_linux.sh | 27 -- build/build_macos.sh | 27 -- build/build_windows.cmd | 24 -- build/package_linux.sh | 24 -- build/package_macos.sh | 25 -- build/package_windows.cmd | 27 -- docker-compose.yml | 28 --- gui_wxpython.py | 516 -------------------------------------- install.sh | 199 --------------- menu.py | 201 --------------- start.cmd | 19 -- start.sh | 78 ------ start_gui.cmd | 49 ---- start_gui.sh | 81 ------ start_web.cmd | 22 -- start_web.sh | 31 --- uninstall.sh | 85 ------- update_checker.py | 152 ----------- version.txt | 1 - 28 files changed, 68 insertions(+), 3136 deletions(-) delete mode 100644 BUILD_STANDALONE.md delete mode 100644 GUI_README.md delete mode 100644 INSTALL.md delete mode 100644 QUICKSTART.md delete mode 100644 WEITERGABE.md delete mode 100644 WXPYTHON_README.md delete mode 100644 ZUSAMMENFASSUNG.md delete mode 100755 build/build_linux.sh delete mode 100644 build/build_macos.sh delete mode 100644 build/build_windows.cmd delete mode 100755 build/package_linux.sh delete mode 100644 build/package_macos.sh delete mode 100644 build/package_windows.cmd delete mode 100644 docker-compose.yml delete mode 100644 gui_wxpython.py delete mode 100755 install.sh delete mode 100644 menu.py delete mode 100644 start.cmd delete mode 100755 start.sh delete mode 100644 start_gui.cmd delete mode 100755 start_gui.sh delete mode 100644 start_web.cmd delete mode 100755 start_web.sh delete mode 100755 uninstall.sh delete mode 100644 update_checker.py delete mode 100644 version.txt diff --git a/BUILD_STANDALONE.md b/BUILD_STANDALONE.md deleted file mode 100644 index 1e35b91..0000000 --- a/BUILD_STANDALONE.md +++ /dev/null @@ -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.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.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.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 -``` diff --git a/GUI_README.md b/GUI_README.md deleted file mode 100644 index b68b364..0000000 --- a/GUI_README.md +++ /dev/null @@ -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 -``` diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index f9e6872..0000000 --- a/INSTALL.md +++ /dev/null @@ -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! 📅✨ diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index f7928df..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -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ß! 😊 diff --git a/README.md b/README.md index 476e4bf..c93bbc8 100644 --- a/README.md +++ b/README.md @@ -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 - -### 1) GUI (empfohlen) -Native Oberfläche mit wxPython: +## Schnellstart ```bash -./start_gui.sh +cp .env.example .env +./deploy.sh ``` -**Highlights:** -- Drag & Drop für PDFs -- Mehrere PDFs gleichzeitig -- Frei wählbares Ausgabe-Verzeichnis -- Live-Log mit Fortschritt -- Optionale Filter: - - Ruhetage ausschließen - - Urlaub (060/0060) ausschließen +Danach erreichbar unter: +- `http://:8000` +- `http://:8000/app` -### 2) CLI -Interaktives Textmenü: +## Update ```bash -./start.sh +./update.sh ``` -### 3) Web (MVP für Mobilgeräte) -Browser-Variante mit Upload + direktem ICS-Download: +Für ein neues Release zuerst den Tag in `.env` anpassen: -```bash -./start_web.sh +```dotenv +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 -docker compose up -d --build -``` +## Hinweis ---- - -## ⚡ 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. +GUI-/CLI-Varianten wurden bewusst entfernt, da der Betrieb ausschließlich im Docker-Container erfolgt. diff --git a/WEB_README.md b/WEB_README.md index 344decb..7d012a7 100644 --- a/WEB_README.md +++ b/WEB_README.md @@ -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 -```bash -./start_web.sh -``` +- Docker + Docker Compose +- Optional externes Netzwerk `proxy` (wenn Reverse Proxy genutzt wird) -### Windows -Doppelklick auf `start_web.cmd` - -Danach im Browser öffnen: -- Landingpage: `http://localhost:8000` -- Anwendung: `http://localhost:8000/app` -- Im Netzwerk (z. B. Smartphone): `http://: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: +## Erststart ```bash 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 ``` -4) 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: +## Update ```bash ./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. -Mit festem Tag bleiben Deployments reproduzierbar und Updates kontrolliert. +```dotenv +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 git clone --filter=blob:none --sparse 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: - -```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://:8000` -- Anwendung: `http://: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 +Hinweis: Ein bestehender Voll-Clone wird dadurch nicht automatisch kleiner. diff --git a/WEITERGABE.md b/WEITERGABE.md deleted file mode 100644 index e51c896..0000000 --- a/WEITERGABE.md +++ /dev/null @@ -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! 📅 diff --git a/WXPYTHON_README.md b/WXPYTHON_README.md deleted file mode 100644 index 910b044..0000000 --- a/WXPYTHON_README.md +++ /dev/null @@ -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! diff --git a/ZUSAMMENFASSUNG.md b/ZUSAMMENFASSUNG.md deleted file mode 100644 index ebfb54f..0000000 --- a/ZUSAMMENFASSUNG.md +++ /dev/null @@ -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 diff --git a/build/build_linux.sh b/build/build_linux.sh deleted file mode 100755 index 9d77091..0000000 --- a/build/build_linux.sh +++ /dev/null @@ -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" diff --git a/build/build_macos.sh b/build/build_macos.sh deleted file mode 100644 index 3871b05..0000000 --- a/build/build_macos.sh +++ /dev/null @@ -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" diff --git a/build/build_windows.cmd b/build/build_windows.cmd deleted file mode 100644 index e02d314..0000000 --- a/build/build_windows.cmd +++ /dev/null @@ -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 diff --git a/build/package_linux.sh b/build/package_linux.sh deleted file mode 100755 index 0c0b57a..0000000 --- a/build/package_linux.sh +++ /dev/null @@ -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" diff --git a/build/package_macos.sh b/build/package_macos.sh deleted file mode 100644 index c1b5628..0000000 --- a/build/package_macos.sh +++ /dev/null @@ -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" diff --git a/build/package_windows.cmd b/build/package_windows.cmd deleted file mode 100644 index 6fcf72d..0000000 --- a/build/package_windows.cmd +++ /dev/null @@ -1,27 +0,0 @@ -@echo off -setlocal - -cd /d "%~dp0\.." - -set /p VERSION= 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() diff --git a/install.sh b/install.sh deleted file mode 100755 index 96cca69..0000000 --- a/install.sh +++ /dev/null @@ -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 "" diff --git a/menu.py b/menu.py deleted file mode 100644 index f2e889c..0000000 --- a/menu.py +++ /dev/null @@ -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) diff --git a/start.cmd b/start.cmd deleted file mode 100644 index 2e5e572..0000000 --- a/start.cmd +++ /dev/null @@ -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 diff --git a/start.sh b/start.sh deleted file mode 100755 index d16e7dd..0000000 --- a/start.sh +++ /dev/null @@ -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 diff --git a/start_gui.cmd b/start_gui.cmd deleted file mode 100644 index 4526e95..0000000 --- a/start_gui.cmd +++ /dev/null @@ -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 -) diff --git a/start_gui.sh b/start_gui.sh deleted file mode 100755 index 143e6bc..0000000 --- a/start_gui.sh +++ /dev/null @@ -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 diff --git a/start_web.cmd b/start_web.cmd deleted file mode 100644 index 35907f5..0000000 --- a/start_web.cmd +++ /dev/null @@ -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 diff --git a/start_web.sh b/start_web.sh deleted file mode 100755 index bd45c59..0000000 --- a/start_web.sh +++ /dev/null @@ -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 diff --git a/uninstall.sh b/uninstall.sh deleted file mode 100755 index b3a0f2f..0000000 --- a/uninstall.sh +++ /dev/null @@ -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 "" diff --git a/update_checker.py b/update_checker.py deleted file mode 100644 index 6719cad..0000000 --- a/update_checker.py +++ /dev/null @@ -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})") diff --git a/version.txt b/version.txt deleted file mode 100644 index 23aa839..0000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -1.2.2