578472872e
- [ocr].timeout wird als tesseract_timeout (pro Seite) an ocrmypdf durchgereicht; Default 1800 -> 300, 0 = ocrmypdf-Default - Exceptions nach dem OCR zaehlen als Fehler, Datei wird nach error/ gerettet - Fehlgeschlagene Uploads zaehlen als Fehler und loesen Fehler-Mail aus - name_mode wird im Preflight geprueft, nicht erst pro Datei - Fehlende [paths]-Sektion -> ConfigError mit klarer Meldung statt KeyError - Stabilitaets-Timeout zaehlt als Fehler (--once liefert Exit 1) - upload_folder nutzt shutil.copyfile statt read_bytes/write_bytes - OcrConfig.pdfa_level Default "2" -> "" (Ghostscript-Bug, Issue #3) - 35 neue Tests (92 gesamt), pytest.ini - AI_AGENT_BRIEFING.md auf Stand 0.4.0 gebracht Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Changelog
[0.4.0] - 2026-09-22
Added
[ocr].timeoutist jetzt wirksam: der Wert wird alstesseract_timeout(Sekunden pro Seite) an ocrmypdf durchgereicht. Bisher war der Key zwar dokumentiert, wurde aber nirgends gelesen.check_output_config()validiert zusätzlich[output].name_mode. Ein Tippfehler führt jetzt beim Start zum Abbruch mit Exit-Code 2, statt erst pro Datei zuzuschlagen — und zwar bisher nach dem Verschieben nachworking/, wo die Datei dann liegen blieb.- Neue Exception
ConfigErrorinpdf_ocr_hotfolder.config— fehlende[paths]-Sektion oder ein fehlender Pfad-Eintrag liefern eine deutsche Fehlermeldung mit Datei- und Key-Nennung statt eines nacktenKeyError-Tracebacks. Die CLI bricht damit sauber mit Exit-Code 2 ab. pytest.inimittestpaths = tests, damitpytestaus dem Repo-Root läuft.- 35 neue Tests: Fehlerzählung (Exception, Upload, Stabilitäts-Timeout),
Config-Fehlermeldungen,
tesseract_timeout-Durchreichung (ocrmypdf gemockt) undupload_folder().
Changed
[ocr].timeouthat eine neue Bedeutung — für bestehende Installationen relevant! Der Wert ist kein (nie implementiertes) Gesamt-Timeout pro PDF mehr, sondern das Limit pro Seite für Tesseract. Der Default sinkt entsprechend von1800auf300. Wer den alten Wert1800in seinerconfig.tomlstehen hat, gibt Tesseract damit 30 Minuten je Seite — bitte auf einen Seiten-Wert anpassen (Richtwert 300).0bedeutet "kein eigenes Limit": der Wert wird dann gar nicht erst durchgereicht, weil ocrmypdftesseract_timeout=0als "OCR komplett überspringen" interpretiert._dispatch_uploads()liefert jetzt die Namen der fehlgeschlagenen Upload-Ziele zurück; die doppelteenabled-Prüfung (Service + Uploader) ist entfallen — die Uploader prüfen das selbst.upload_folder()kopiert mitshutil.copyfile()stattread_bytes()/write_bytes()— große PDFs landen nicht mehr komplett im Speicher. Die Selbst-Ziel-Erkennung bleibt unverändert.
Fixed
OcrConfig.pdfa_levelhatte im Code noch den Default"2", obwohlconfig.example.tomlseit 0.2.2 bewusst""setzt (Ghostscript-Bug, Issue #3). Eine Config ohne[ocr]-Sektion bzw. ohne den Key lief damit ungewollt in PDF/A. Default im Code jetzt ebenfalls"".- Eine Exception nach dem OCR (z.B. ein fehlgeschlagener
shutil.move()nachoutgoing/) wurde nur im Worker-Callback geloggt.error_countblieb 0 und--oncelieferte trotz Fehlschlag Exit-Code 0. Jede Exception ausprocess_pdf()zählt jetzt als Fehler, wird geloggt, löst eine Fehler-Mail aus und die Datei wandert — soweit noch auffindbar (incoming/oderworking/) — nacherror/. - Fehlgeschlagene Uploads waren folgenlos: die Rückgabewerte der Uploader wurden
verworfen, es ging sogar eine Erfolgs-Mail raus. Jetzt zählt mindestens ein
fehlgeschlagenes Ziel als Fehler und die E-Mail geht als FEHLER raus, mit
Nennung der betroffenen Ziele. Das OCR-PDF bleibt bewusst in
outgoing/liegen (das OCR selbst war ja erfolgreich) — das steht so auch im Log. - Lief der Stabilitäts-Check einer Datei in den 60-Sekunden-Timeout, gab es nur
ein
log.warning;--oncemeldete Exit-Code 0. Jetztlog.error+error_count. Die Datei bleibt bewusst inincoming/liegen und wird beim nächsten Lauf erneut versucht. Eine zwischenzeitlich verschwundene Datei wird davon unterschieden und zählt weiterhin nicht als Fehler.
[0.3.1] - 2026-04-10
Fixed
- Issue #4: LXC/Container-Kompatibilität — systemd-Hardening (
PrivateTmp,ProtectSystem, etc.) verursacht Error 226/NAMESPACE in LXC-Containern. Installer erkennt Container-Umgebung automatisch und bietet ein Drop-in an. Zusätzlich liegtsystemd/lxc-compat.confals Vorlage im Repo. - Issue #5:
WorkingDirectory=/opt/pdf-ocr-hotfolderin der systemd Template-Unit ergänzt — ohne diesen Eintrag konnte das Python-Modul nicht gefunden werden. - Issue #6: Auf Debian 12 bietet der Installer bei betroffenen Ghostscript-Versionen (10.0.0–10.02.0) jetzt automatisch an, bookworm-backports zu aktivieren und GS zu upgraden (statt nur zu warnen).
[0.3.0] - 2026-04-09
Added
- Neue Config-Sektion
[output]mit:name_mode— Platzierung des Tags im Dateinamen:"prefix","suffix"(vor Extension),"none"name_tag— verbatim einzufügender String, z.B."OCR_"oder"_OCR"original_on_success—"delete"(alter Default) oder"archive"archive_dir— Zielverzeichnis für"archive", mit Kollisions-Schutz (Timestamp-Suffix)
- Runtime-Validierung der Output-Config in
check_output_config() - 20 neue Tests für
build_output_name(),check_output_config()undprocess_pdf()mit allen Kombinationen aus Modus + Original-Behandlung
Changed
process_pdf()nimmt jetztoutput_cfg: OutputConfigals Pflicht-Argument
[0.2.2] - 2026-04-09
Fixed
- Issue #3: Ghostscript 10.0.0–10.02.0 (Debian 12 default) zerschießen OCR mit PDF/A +
skip_text=true.config.example.toml:pdfa_level = ""als sicherer Default- Runtime-Preflight: Prüft
gs --versionwennpdfa_levelgesetzt ist, bricht mit klarer Fehlermeldung ab install.sh: warnt bei betroffenen GS-Versionen mit Upgrade-Hinweis auf bookworm-backports
Added
is_ghostscript_broken()/detect_ghostscript_version()inpdf_ocr_hotfolder.service- 19 weitere pytest-Tests für GS-Versions-Detection (parametrisiert) und Preflight-Kombinationen
[0.2.1] - 2026-04-09
Fixed
- Issue #1: Preflight-Check beim Start prüft jetzt
tesseractundgs(Ghostscript). Fehlt eine Abhängigkeit, beendet sich der Service sofort mit Exit-Code 2 und klarer Fehlermeldung statt erst bei der ersten Datei. - Issue #2:
--once-Modus liefert jetzt Exit-Code1, sobald mindestens ein PDF fehlgeschlagen ist. Exit-Code0nur bei vollständigem Erfolg (inkl. "keine Dateien vorhanden"). Exit-Code2bei Preflight-Fehler.
Added
- Public API:
HotfolderService.run_once(),.success_count,.error_count,.ensure_dirs() check_preflight()/PreflightErrorinpdf_ocr_hotfolder.service- pytest-Test-Suite (
tests/) mit 11 Tests — deckt alle Szenarien aus Issue #1 und #2 ab ocrmypdf-Import inprocessor.pyist jetzt lazy (Tests ohne ocrmypdf-Installation möglich)
[0.2.0] - 2026-04-08
Added
- Multi-Instanz-Support via systemd Template-Unit
pdf-ocr-hotfolder@<name>.service - Pro Instanz: eigene Config (
/etc/pdf-ocr-hotfolder/<name>.toml), eigene Datenverzeichnisse (/var/lib/pdf-ocr-hotfolder/<name>/…), optional eigener Service-User via Drop-in - Instanz-Manager in
install.sh: erkennt bestehende Instanzen bei Re-Run, fragt nach weiteren, listet Namen + Status update.shstoppt/startet automatisch alle laufenden Instanzen
Changed
- Single-Unit
pdf-ocr-hotfolder.servicedurch Template-Unitpdf-ocr-hotfolder@.serviceersetzt - Installer fragt nicht mehr einmalig nach Service-User, sondern pro Instanz
Removed
- Alte Single-Config unter
/etc/pdf-ocr-hotfolder/config.toml— wird nicht mehr erzeugt
[0.1.0] - 2026-04-08
Added
- Initiale Version (Komplettes Rewrite des alten Bash-Tools
pdf-tool) - Python-Implementation auf Basis von
ocrmypdf(Library, kein Subprozess) - Hotfolder-Watcher mit
watchdog(created/moved/closed Events) - File-Stability-Check (wartet bis Scanner fertig geschrieben hat)
- ThreadPool für parallele PDF-Verarbeitung (
max_workers) - Upload-Targets: lokaler Ordner, Nextcloud (WebDAV via
requests), SFTP (paramiko) - E-Mail-Notify (
smtplib, immer / nur Fehler / nie) - Optional veraPDF-Validierung
- TOML-Konfiguration (
tomllibaus stdlib, Python ≥3.11) - systemd-Unit mit Hardening-Optionen
install.shmit interaktivem Service-User-Prompt (lokal anlegen oder bestehenden lokalen/AD-User übernehmen)update.shmit Backup, Code-Sync und Service-Reload- README.md, AI_AGENT_BRIEFING.md