# PDF OCR Hotfolder Verwandelt eingehende gescannte PDFs automatisch in **durchsuchbare PDFs** (PDF/A optional) per OCR. Hauptanwendung: Kunden-Scanner schiebt PDF in einen Ordner — Sekunden später liegt die OCR-Version im Ausgang oder wird in Nextcloud / per SFTP weitergeleitet. ## Dokumentation | Dokument | Inhalt | |----------|--------| | **[docs/INSTALLATION.md](docs/INSTALLATION.md)** | Erstinstallation, Instanzen anlegen, LXC, Ghostscript, **Konfigurationsreferenz**, Troubleshooting | | **[docs/UPDATE.md](docs/UPDATE.md)** | Update mit `update.sh`: Ablauf, Backup, Rollback, `--check-config`, Config-Drift | | **[docs/OS-UPGRADE.md](docs/OS-UPGRADE.md)** | Debian-Major-Upgrade (12 → 13): venv neu bauen, Pins anheben | Weiter: [CHANGELOG.md](CHANGELOG.md) · [AI_AGENT_BRIEFING.md](AI_AGENT_BRIEFING.md) · [config.example.toml](config.example.toml) ## Features - 🔍 **OCR via ocrmypdf + Tesseract** (Library-Call, kein Subprozess-Overhead) - 📂 **Hotfolder via watchdog** — reagiert auf `created`, `moved`, `closed` Events - 🧠 **Stabilitäts-Erkennung**: wartet bis Scanner fertig geschrieben hat - 🔁 **Parallelverarbeitung** mehrerer PDFs (ThreadPool, konfigurierbar) - ♻️ **Wiederaufnahme aus `working/`** nach einem harten Stopp — keine Datei bleibt liegen - ✅ **PDF/A-Output** (1, 2 oder 3) optional - 🛡️ **veraPDF-Validierung** optional - ☁️ **Upload-Ziele**: lokaler Ordner, Nextcloud (WebDAV via Python), SFTP - 📧 **E-Mail-Notify** (immer / nur Fehler / nie) - 🔐 **Service-User-Support** für lokale **und AD-User mit lokaler UID** (SSSD/Winbind) - ⚙️ Saubere systemd-Integration mit auto-Restart, **Multi-Instanz** über eine Template-Unit - 🩺 **`--check-config`** prüft eine Instanz-Config ohne etwas zu verarbeiten ## Schnellstart **Voraussetzungen:** Debian 12 oder 13, Python 3.11+, root — und **mindestens 2 GB RAM** (512 MB reichen für 300-dpi-Scans nachweislich nicht, siehe [Systemanforderungen](docs/INSTALLATION.md#systemanforderungen)). ```bash git clone gitea@gitea.sonith.de:sonith_ug/pdf-ocr-hotfolder.git cd pdf-ocr-hotfolder sudo ./install.sh ``` Der Installer legt einmalig Code, venv und die systemd-Template-Unit an und fragt danach **pro Instanz** Name, Basis-Pfad, Service-User, OCR-Sprachen und die Original-Behandlung ab. Bei jedem erneuten Aufruf erkennt er bestehende Instanzen und fragt nur nach neuen. Test: ```bash cp irgendein-scan.pdf /var/lib/pdf-ocr-hotfolder//incoming/ journalctl -u pdf-ocr-hotfolder@ -f ``` Nach wenigen Sekunden liegt das OCR-PDF im `outgoing/`-Ordner der Instanz. Alle Details zu den Abfragen, zum Multi-Instanz-Betrieb und zu den Fallstricken (LXC, Ghostscript): **[docs/INSTALLATION.md](docs/INSTALLATION.md)**. Update: `git pull && sudo ./update.sh` — siehe **[docs/UPDATE.md](docs/UPDATE.md)**. Nach einem Debian-Major-Upgrade: **[docs/OS-UPGRADE.md](docs/OS-UPGRADE.md)**. ## Verzeichnisse | Pfad | Zweck | |------|-------| | `/opt/pdf-ocr-hotfolder/` | Code + venv (für alle Instanzen gemeinsam) | | `/etc/pdf-ocr-hotfolder/.toml` | Config pro Instanz (640, root:\) | | `/etc/systemd/system/pdf-ocr-hotfolder@.service` | systemd Template-Unit | | `/var/lib/pdf-ocr-hotfolder//incoming` | Eingang (Scanner schreibt hier rein) | | `/var/lib/pdf-ocr-hotfolder//working` | Arbeitsverzeichnis während OCR | | `/var/lib/pdf-ocr-hotfolder//outgoing` | Ausgang (fertige PDFs) | | `/var/lib/pdf-ocr-hotfolder//error` | Fehlgeschlagene PDFs | | `/var/backups/pdf-ocr-hotfolder/` | Update-Backups (0600, letzte 5) | Ein eigenes Logverzeichnis gibt es nicht — der Dienst loggt nach stdout und damit ins journal. ## Konfiguration im Überblick Jede Instanz hat ihre eigene TOML unter `/etc/pdf-ocr-hotfolder/.toml`. Vollständiges, kommentiertes Beispiel: [`config.example.toml`](config.example.toml). Key-für-Key-Referenz: [docs/INSTALLATION.md](docs/INSTALLATION.md#konfigurationsreferenz). | Sektion | Zweck | |---------|-------| | `[paths]` | `incoming`, `outgoing`, `working`, `error` — **Pflicht** | | `[ocr]` | Sprachen, `jobs`, `skip_text`, `pdfa_level`, `deskew`, `max_workers`, `timeout` (Sekunden **pro Seite**) | | `[output]` | Dateibenennung (`name_mode`/`name_tag`) und Original-Behandlung (`delete`/`archive`) | | `[verapdf]` | optionale PDF/A-Validierung per CLI | | `[upload.folder]` / `[upload.nextcloud]` / `[upload.sftp]` | Upload-Ziele, beliebig viele gleichzeitig | | `[notify.email]` | SMTP-Benachrichtigung: `always` \| `errors` \| `never` | | `[logging]` | `level` = DEBUG/INFO/WARNING/ERROR | Die Instanz-Configs enthalten **Klartext-Passwörter** (SMTP, Nextcloud, SFTP) — deshalb `640 root:` und beim Debuggen nicht in Tickets kopieren. Config prüfen, ohne etwas zu verarbeiten: ```bash cd /opt/pdf-ocr-hotfolder && sudo ./venv/bin/python -m pdf_ocr_hotfolder \ --check-config --config /etc/pdf-ocr-hotfolder/.toml ``` Exit 0 = sauber, 1 = Warnungen, 2 = Fehler. Details: [docs/UPDATE.md](docs/UPDATE.md#config-prüfung-per---check-config). ## Service-Verwaltung ```bash # Eine bestimmte Instanz sudo systemctl status pdf-ocr-hotfolder@kunde-a sudo systemctl restart pdf-ocr-hotfolder@kunde-a journalctl -u pdf-ocr-hotfolder@kunde-a -f # Alle Instanzen sudo systemctl status 'pdf-ocr-hotfolder@*' sudo systemctl restart 'pdf-ocr-hotfolder@*' journalctl -u 'pdf-ocr-hotfolder@*' --since today ``` Ein laufendes OCR darf beim Stoppen zu Ende laufen (`TimeoutStopSec=300`) — ein `stop` kann deshalb pro Instanz bis zu 5 Minuten dauern. ## Architektur ``` ┌──────────┐ watchdog ┌──────────────┐ ocrmypdf ┌──────────┐ │ Scanner │ ──────────────▶ │ incoming/ │ ─────────────▶ │ working/ │ └──────────┘ PDF-Datei └──────────────┘ (Library) └────┬─────┘ │ optional veraPDF │ ▼ ┌──────────────┐ │ outgoing/ │ └──────┬───────┘ │ ┌──────────────────────┼──────────────────────┐ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ Nextcloud │ │ SFTP │ │ E-Mail │ │ (WebDAV) │ │ (paramiko) │ │ Notify │ └────────────┘ └────────────┘ └────────────┘ ``` Beim Start wird `working/` zuerst durchsucht: was ein harter Stopp dort liegen ließ, wird wiederaufgenommen; unvollständige OCR-Fragmente (`__ocr_*`) werden gelöscht. ## Tests ```bash pytest # 152 Tests ``` `ocrmypdf` muss dafür nicht installiert sein — der Import ist lazy und wird in den Tests gemockt. ## Lizenz MIT — © Sonith UG --- **Version:** 0.6.3 **Repo:** https://gitea.sonith.de/sonith_ug/pdf-ocr-hotfolder