Files
pdf-ocr-hotfolder/README.md
T
techadmin 985a33d3f9 feat: Multi-Instanz-Support via systemd Template-Unit (v0.2.0)
- pdf-ocr-hotfolder@<name>.service mit Config pro Instanz
- install.sh als Instanz-Manager: erkennt bestehende, fragt nach weiteren
- Optional eigener Service-User pro Instanz (systemd drop-in)
- update.sh stoppt/startet alle aktiven Instanzen automatisch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 14:31:58 +02:00

210 lines
7.9 KiB
Markdown

# 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.
## 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)
-**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
## Schnellstart
```bash
git clone https://gitea.sonith.de/sonith_ug/pdf-ocr-hotfolder.git
cd pdf-ocr-hotfolder
sudo ./install.sh
```
Der Installer:
1. Installiert einmalig Code + venv + systemd-Template-Unit
2. Fragt nach Instanz-Name, Basis-Pfad, Service-User
3. Legt so viele Hotfolder-Instanzen an, wie du willst (`Weitere Instanz anlegen? [j/N]`)
Bei jedem erneuten Aufruf erkennt der Installer bestehende Instanzen und fragt nur nach neuen.
Test:
```bash
cp irgendein-scan.pdf /var/lib/pdf-ocr-hotfolder/<instanz>/incoming/
journalctl -u pdf-ocr-hotfolder@<instanz> -f
```
Nach wenigen Sekunden liegt das OCR-PDF im `outgoing/`-Ordner der Instanz.
## Multi-Instanz-Betrieb
Das Tool arbeitet komplett **instanzbasiert** über eine systemd Template-Unit `pdf-ocr-hotfolder@<name>.service`. Jede Instanz hat:
- eigene Config-Datei: `/etc/pdf-ocr-hotfolder/<name>.toml`
- eigene Datenverzeichnisse: `/var/lib/pdf-ocr-hotfolder/<name>/{incoming,working,outgoing,error}/`
- eigene systemd-Unit: `pdf-ocr-hotfolder@<name>.service`
- optional eigenen Service-User (via Drop-in `/etc/systemd/system/pdf-ocr-hotfolder@<name>.service.d/user.conf`)
Beispiel für 3 Hotfolder:
```bash
sudo ./install.sh
# → legt z.B. kunde-a, kunde-b, buchhaltung an
systemctl status 'pdf-ocr-hotfolder@*'
journalctl -u pdf-ocr-hotfolder@kunde-a -f
```
Manuell eine weitere Instanz anlegen geht auch — einfach `install.sh` erneut starten, er fragt wieder nach.
## Verzeichnisse
| Pfad | Zweck |
|------|-------|
| `/opt/pdf-ocr-hotfolder/` | Code + venv (für alle Instanzen gemeinsam) |
| `/etc/pdf-ocr-hotfolder/<instanz>.toml` | Config pro Instanz |
| `/etc/systemd/system/pdf-ocr-hotfolder@.service` | systemd Template-Unit |
| `/var/lib/pdf-ocr-hotfolder/<instanz>/incoming` | Eingang (Scanner schreibt hier rein) |
| `/var/lib/pdf-ocr-hotfolder/<instanz>/working` | Arbeitsverzeichnis während OCR |
| `/var/lib/pdf-ocr-hotfolder/<instanz>/outgoing` | Ausgang (fertige PDFs) |
| `/var/lib/pdf-ocr-hotfolder/<instanz>/error` | Fehlgeschlagene PDFs |
| `/var/log/pdf-ocr-hotfolder/` | Logs (zusätzlich zu journald) |
| `/var/backups/pdf-ocr-hotfolder/` | Update-Backups |
## Konfiguration
Vollständiges Beispiel: [`config.example.toml`](config.example.toml). Wichtigste Sektionen:
### `[ocr]`
```toml
languages = "deu+eng" # Tesseract-Sprachen
jobs = 4 # Threads pro PDF
skip_text = true # bereits OCR-haltige Seiten überspringen
pdfa_level = "2" # "1", "2", "3" oder "" für reines PDF
deskew = true
max_workers = 2 # parallele PDFs
timeout = 1800
```
### `[upload.nextcloud]`
```toml
enabled = true
url = "https://cloud.example.com"
username = "scanuser"
password = "app-password"
remote_path = "Scans/Inbox"
```
### `[upload.sftp]`
```toml
enabled = true
host = "sftp.example.com"
username = "scanuser"
key_file = "/etc/pdf-ocr-hotfolder/sftp_key"
remote_path = "/uploads"
```
### `[notify.email]`
```toml
enabled = true
smtp_host = "smtp.example.com"
smtp_port = 587
smtp_user = "alerts@example.com"
smtp_password = "secret"
from_addr = "PDF OCR <alerts@example.com>"
to_addrs = ["admin@example.com"]
on = "errors" # always | errors | never
```
## 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@*'
```
## Update
```bash
cd /pfad/zum/repo
git pull
sudo ./update.sh
```
`update.sh`:
1. Stoppt alle laufenden Instanzen
2. Sichert den alten Code nach `/var/backups/pdf-ocr-hotfolder/`
3. Aktualisiert Code + venv + systemd-Template-Unit in `/opt/pdf-ocr-hotfolder/`
4. Startet alle zuvor laufenden Instanzen neu
Config-Dateien unter `/etc/pdf-ocr-hotfolder/` werden **nie** überschrieben.
Das Repo muss bestehen bleiben — `update.sh` kopiert daraus.
## Manueller Lauf (One-Shot)
Bestehende PDFs einer Instanz einmalig verarbeiten und beenden:
```bash
sudo -u pdfocr /opt/pdf-ocr-hotfolder/venv/bin/python -m pdf_ocr_hotfolder \
--config /etc/pdf-ocr-hotfolder/kunde-a.toml --once
```
## Troubleshooting
### Tesseract findet die Sprache nicht
```bash
sudo apt install tesseract-ocr-deu tesseract-ocr-eng
```
### "PriorOcrFoundError"
ocrmypdf erkennt bereits vorhandenen OCR-Text. `skip_text = true` in der Config setzen.
### Berechtigungsprobleme bei AD-User
Service-User braucht **rw** auf alle vier Verzeichnisse unter `/var/lib/pdf-ocr-hotfolder/`. Bei AD-User mit lokaler UID:
```bash
sudo chown -R DOMAIN\\scanuser:DOMAIN\\scangroup /var/lib/pdf-ocr-hotfolder
```
### veraPDF-Validierung schlägt immer fehl
veraPDF binary prüfen (`[verapdf].binary`). Wenn nicht zwingend gebraucht: `enabled = false`.
## Architektur
```
┌──────────┐ watchdog ┌──────────────┐ ocrmypdf ┌──────────┐
│ Scanner │ ──────────────▶ │ incoming/ │ ─────────────▶ │ working/ │
└──────────┘ PDF-Datei └──────────────┘ (Library) └────┬─────┘
optional veraPDF
┌──────────────┐
│ outgoing/ │
└──────┬───────┘
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Nextcloud │ │ SFTP │ │ E-Mail │
│ (WebDAV) │ │ (paramiko) │ │ Notify │
└────────────┘ └────────────┘ └────────────┘
```
## Lizenz
MIT — © Sonith UG
---
**Version:** 0.2.0
**Repo:** https://gitea.sonith.de/sonith_ug/pdf-ocr-hotfolder