1 Commits

Author SHA1 Message Date
techadmin 2062476252 feat: Installer fragt OCR-Sprachen und Archiv pro Instanz ab (v0.5.0)
- Sprach-Abfrage pro Instanz (Default-Vorschlag deu+eng), bewusst
  instanz-lokal: ein Hotfolder kann mit "deu" laufen, ein anderer mit
  "deu+eng+fra". Hinweis im Prompt, dass jede zusaetzliche Sprache
  Laufzeit und Erkennungsqualitaet kostet.
- Jeder Sprachcode wird gegen "tesseract --list-langs" geprueft, fehlende
  Pakete (tesseract-ocr-<code>) werden zur Installation angeboten; lehnt
  der User ab oder scheitert apt, wird gewarnt und erneut gefragt.
- Abfrage "Original archivieren?" mit $BASE/archive als Default; Archiv
  ausserhalb von $BASE wird eigens angelegt und gechownt. Ein Pfad auf
  incoming/outgoing/working/error wird abgewiesen.
- sed-Kette der Config-Erzeugung jetzt verankert (^key =) und escaped,
  setzt zusaetzlich languages, original_on_success und archive_dir;
  die erzeugte Config wird gegen die Eingabe nachgeprueft.
- README und Briefing um "Sprachen pro Instanz" ergaenzt

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 21:24:56 +02:00
6 changed files with 277 additions and 12 deletions
+35 -3
View File
@@ -1,7 +1,7 @@
# AI Agent Briefing — PDF OCR Hotfolder # AI Agent Briefing — PDF OCR Hotfolder
**Zuletzt aktualisiert:** 2026-09-22 **Zuletzt aktualisiert:** 2026-09-22
**Version:** 0.4.1 **Version:** 0.5.0
**Status:** Multi-Instanz-Betrieb, Preflight-Checks und Fehlerzählung vorhanden, Test-Suite grün (95 pytest-Tests). Ein Produktiv-Einsatz ist im Repo (README/CHANGELOG) nicht dokumentiert — die bisherigen Fixes stammen aus Issues #1–#6, nicht aus einem belegten Dauerbetrieb. **Status:** Multi-Instanz-Betrieb, Preflight-Checks und Fehlerzählung vorhanden, Test-Suite grün (95 pytest-Tests). Ein Produktiv-Einsatz ist im Repo (README/CHANGELOG) nicht dokumentiert — die bisherigen Fixes stammen aus Issues #1–#6, nicht aus einem belegten Dauerbetrieb.
## 🎯 Projektziel ## 🎯 Projektziel
@@ -92,9 +92,41 @@ journalctl -u 'pdf-ocr-hotfolder@*' --since today # alle Instanzen, heute
- Erster Lauf: Basis-Install + erste Instanz anlegen (Pflicht) - Erster Lauf: Basis-Install + erste Instanz anlegen (Pflicht)
- Folgender Lauf: Basis-Install wird übersprungen (erkannt an `venv` + Template-Unit), bestehende Instanzen werden gelistet, weitere Instanzen können ergänzt werden - Folgender Lauf: Basis-Install wird übersprungen (erkannt an `venv` + Template-Unit), bestehende Instanzen werden gelistet, weitere Instanzen können ergänzt werden
- Eingaben pro Instanz: Name (`[a-z0-9][a-z0-9-]*`), Basis-Pfad (default `/var/lib/pdf-ocr-hotfolder/<name>`), Service-User - Eingaben pro Instanz (seit 0.5.0 fünf statt drei):
1. Name (`[a-z0-9][a-z0-9-]*`)
2. Basis-Pfad (default `/var/lib/pdf-ocr-hotfolder/<name>`)
3. Service-User (default `pdfocr`)
4. **OCR-Sprachen** (default `deu+eng`) — Format `^[a-z]{3}(_[A-Za-z]+)?(\+…)*$`,
bei Unsinn wird erneut gefragt. Jeder Code wird gegen `tesseract --list-langs`
geprüft; fehlt einer, bietet der Installer `tesseract-ocr-<code>` an
(Unterstrich → Bindestrich, `chi_sim` → `tesseract-ocr-chi-sim`). Ablehnung
oder fehlgeschlagene Installation → Warnung, dass OCR mit dieser Sprache
**pro Datei** scheitert, und die Sprach-Abfrage beginnt von vorn (kein
harter Abbruch). Ist `tesseract` nicht aufrufbar, wird die Prüfung
übersprungen und die Eingabe unverändert übernommen.
5. **Original nach erfolgreichem OCR archivieren?** (default **nein** →
`original_on_success = "delete"`). Bei ja wird der Archiv-Pfad abgefragt
(Vorschlag `$BASE/archive`, absoluter Pfad Pflicht), angelegt und auf
`$SVC_USER:$SVC_GROUP` gechownt — innerhalb von `$BASE` erledigt das
bestehende `chown -R` das schon, nur ein Archiv **außerhalb** bekommt ein
eigenes `chown -R`.
- **Sprachen sind bewusst instanz-lokal**, nicht global: ein Hotfolder
`buchhaltung` läuft mit `deu`, ein Hotfolder `export` mit `deu+eng+fra`.
`LANGS`/`ORIG_MODE`/`ARCHIVE_DIR` sind `local` in `create_instance()` — jeder
Durchlauf fragt neu, `deu+eng` ist nur der vorgeschlagene Default. Die Liste
gehört eng gehalten: jede zusätzliche Sprache kostet Laufzeit **und**
Erkennungsqualität.
- Basis-Install prüft zusätzlich die Ghostscript-Version und bietet auf Debian 12 bookworm-backports an; erkennt Container (`systemd-detect-virt --container`) und bietet das LXC-Drop-in an - Basis-Install prüft zusätzlich die Ghostscript-Version und bietet auf Debian 12 bookworm-backports an; erkennt Container (`systemd-detect-virt --container`) und bietet das LXC-Drop-in an
- `<instanz>.toml` wird aus `config.example.toml` mit sed-substituierten Pfaden generiert - `<instanz>.toml` wird aus `config.example.toml` per `sed` generiert. Substituiert
werden die vier `[paths]`-Zeilen **sowie** (seit 0.5.0) `[ocr].languages`,
`[output].original_on_success` und `[output].archive_dir`. Die Ausdrücke sind
am Zeilenanfang verankert (`^key[[:space:]]*=`), damit die deutschen
Kommentarzeilen über den Keys nicht getroffen werden (im Beispiel steht z.B.
`"archive" : Original wird in archive_dir verschoben` als Kommentar);
Pfad-Variablen laufen vorher durch `sed_escape_repl()` (maskiert `\`, `&`, `|`).
Nach dem sed-Lauf liest `config_value()` die drei Keys zurück und vergleicht
sie mit der Eingabe; erst wenn das passt, nennt die Zusammenfassung Sprachen
und Archiv-Verzeichnis.
- Instanz wird sofort `enable --now` gestartet - Instanz wird sofort `enable --now` gestartet
Manuelles Löschen einer Instanz: Manuelles Löschen einer Instanz:
+43
View File
@@ -1,5 +1,48 @@
# Changelog # Changelog
## [0.5.0] - 2026-09-22
### Added
- Der Installer weist einen Archiv-Pfad ab, der auf `incoming/`, `outgoing/`,
`working/` oder `error/` der Instanz zeigt — im Eingang wuerde das Original
sonst endlos neu aufgegriffen.
- **`install.sh` fragt beim Anlegen einer Instanz die OCR-Sprachen ab**
(`Tesseract-Sprachen [deu+eng]:`). Die Wahl gilt bewusst **pro Instanz** —
ein Hotfolder `buchhaltung` kann mit `deu` laufen, ein Hotfolder `export` mit
`deu+eng+fra`. Der Installer weist vorher darauf hin, dass jede zusaetzliche
Sprache Laufzeit **und** Erkennungsqualitaet kostet, die Liste also eng
gehalten werden sollte. Das Eingabeformat wird geprueft (Sprachcodes mit `+`
verbunden, `chi_sim` & Co. erlaubt); bei Unsinn wird erneut gefragt statt
abzubrechen.
- **Sprachpakete werden nachinstalliert.** Jeder eingegebene Code wird gegen
`tesseract --list-langs` geprueft. Fehlt eine Sprachdatei, bietet der
Installer das passende apt-Paket an (`tesseract-ocr-<code>`, Unterstrich wird
zum Bindestrich: `chi_sim` → `tesseract-ocr-chi-sim`). Lehnt der User ab oder
laesst sich das Paket nicht installieren, warnt der Installer, dass OCR mit
dieser Sprache **bei jeder Datei** scheitern wuerde, und fragt die Sprachen
erneut ab — so kann die Sprache einfach wieder rausgeworfen werden. Ist
`tesseract` nicht aufrufbar, wird die Pruefung uebersprungen und die Eingabe
unveraendert uebernommen.
- **Abfrage `Original nach erfolgreichem OCR archivieren? [j/N]:`** — Default
nein, also weiterhin `original_on_success = "delete"`. Bei ja wird der
Archiv-Pfad abgefragt (Vorschlag `<basis>/archive`), angelegt und auf den
Service-User gechownt; ein Archiv ausserhalb des Instanz-Basis-Pfads bekommt
ein eigenes `chown -R`.
### Changed
- Die Instanz-Config wird weiterhin per `sed` aus `config.example.toml`
erzeugt, substituiert jetzt aber zusaetzlich `[ocr].languages`,
`[output].original_on_success` und `[output].archive_dir` — bisher waren das
die Beispiel-Defaults, `archive_dir` musste von Hand nachgetragen werden.
Die Ausdruecke sind am Zeilenanfang verankert (`^key[[:space:]]*=`), damit die
deutschen Kommentarzeilen ueber den Keys unangetastet bleiben, und
Pfad-Variablen laufen durch `sed_escape_repl()` (maskiert `\`, `&`, `|`) —
Pfade mit Sonderzeichen landen damit korrekt in der Config.
- Nach dem sed-Lauf liest der Installer die drei Keys aus der erzeugten Config
zurueck und vergleicht sie mit der Eingabe. Erst wenn das passt, nennt die
Abschluss-Zusammenfassung zusaetzlich die gewaehlten **Sprachen** und (bei
Archivierung) das **Archiv-Verzeichnis**; sonst gibt es eine Warnung.
## [0.4.1] - 2026-09-22 ## [0.4.1] - 2026-09-22
### Fixed ### Fixed
+36 -3
View File
@@ -25,7 +25,14 @@ sudo ./install.sh
Der Installer: Der Installer:
1. Installiert einmalig Code + venv + systemd-Template-Unit 1. Installiert einmalig Code + venv + systemd-Template-Unit
2. Fragt nach Instanz-Name, Basis-Pfad, Service-User 2. Fragt **pro Instanz** ab:
- Instanz-Name
- Basis-Pfad für die Daten
- Service-User
- **OCR-Sprachen** (Tesseract, Default `deu+eng`) — fehlende Sprachpakete
(`tesseract-ocr-<code>`) werden erkannt und auf Wunsch nachinstalliert
- **Original nach erfolgreichem OCR archivieren?** (Default nein = löschen;
bei ja zusätzlich der Archiv-Pfad, vorgeschlagen `<basis>/archive`)
3. Legt so viele Hotfolder-Instanzen an, wie du willst (`Weitere Instanz anlegen? [j/N]`) 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. Bei jedem erneuten Aufruf erkennt der Installer bestehende Instanzen und fragt nur nach neuen.
@@ -47,6 +54,27 @@ Das Tool arbeitet komplett **instanzbasiert** über eine systemd Template-Unit `
- eigene Datenverzeichnisse: `/var/lib/pdf-ocr-hotfolder/<name>/{incoming,working,outgoing,error}/` - eigene Datenverzeichnisse: `/var/lib/pdf-ocr-hotfolder/<name>/{incoming,working,outgoing,error}/`
- eigene systemd-Unit: `pdf-ocr-hotfolder@<name>.service` - 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`) - optional eigenen Service-User (via Drop-in `/etc/systemd/system/pdf-ocr-hotfolder@<name>.service.d/user.conf`)
- **eigene OCR-Sprachen und eigene Original-Behandlung** (löschen oder archivieren)
### Sprachen pro Instanz
Die Tesseract-Sprachen werden bewusst **je Instanz** abgefragt, nicht global:
Hotfolder haben unterschiedliche Post. Ein Buchhaltungs-Hotfolder sieht nur
deutsche Belege, ein Export-Hotfolder internationale Korrespondenz:
```toml
# /etc/pdf-ocr-hotfolder/buchhaltung.toml
languages = "deu"
# /etc/pdf-ocr-hotfolder/export.toml
languages = "deu+eng+fra"
```
**Die Liste so eng wie möglich halten.** Jede zusätzliche Sprache kostet
Laufzeit *und* Erkennungsqualität: Tesseract muss mehr Modelle gegeneinander
abwägen und verwechselt dabei Wörter, die in der einen Sprache eindeutig wären.
`deu+eng+fra` auf reinen Deutsch-Scans ist also kein Sicherheitsnetz, sondern
ein Rückschritt.
Beispiel für 3 Hotfolder: Beispiel für 3 Hotfolder:
@@ -77,9 +105,13 @@ Manuell eine weitere Instanz anlegen geht auch — einfach `install.sh` erneut s
Vollständiges Beispiel: [`config.example.toml`](config.example.toml). Wichtigste Sektionen: Vollständiges Beispiel: [`config.example.toml`](config.example.toml). Wichtigste Sektionen:
Der Installer fragt `[ocr].languages`, `[output].original_on_success` und
`[output].archive_dir` pro Instanz ab und schreibt sie direkt in die
Instanz-Config — die Werte unten sind nur die Beispiel-Defaults.
### `[ocr]` ### `[ocr]`
```toml ```toml
languages = "deu+eng" # Tesseract-Sprachen languages = "deu+eng" # Tesseract-Sprachen (Installer fragt pro Instanz)
jobs = 4 # Threads pro PDF jobs = 4 # Threads pro PDF
skip_text = true # bereits OCR-haltige Seiten überspringen skip_text = true # bereits OCR-haltige Seiten überspringen
pdfa_level = "" # "1", "2", "3" oder "" für reines PDF (Default "" wegen Ghostscript-Bug, s.u.) pdfa_level = "" # "1", "2", "3" oder "" für reines PDF (Default "" wegen Ghostscript-Bug, s.u.)
@@ -100,6 +132,7 @@ name_tag = "OCR_"
# Nach erfolgreichem OCR mit dem Original: # Nach erfolgreichem OCR mit dem Original:
# "delete" → löschen # "delete" → löschen
# "archive" → in archive_dir verschieben # "archive" → in archive_dir verschieben
# Beides fragt der Installer beim Anlegen der Instanz ab:
original_on_success = "delete" original_on_success = "delete"
archive_dir = "" # absoluter Pfad, Pflicht bei "archive" archive_dir = "" # absoluter Pfad, Pflicht bei "archive"
``` ```
@@ -248,5 +281,5 @@ MIT — © Sonith UG
--- ---
**Version:** 0.4.1 **Version:** 0.5.0
**Repo:** https://gitea.sonith.de/sonith_ug/pdf-ocr-hotfolder **Repo:** https://gitea.sonith.de/sonith_ug/pdf-ocr-hotfolder
+1 -1
View File
@@ -1 +1 @@
0.4.1 0.5.0
+161 -4
View File
@@ -169,6 +169,66 @@ show_existing_instances() {
echo echo
} }
# Liest den Wert eines Keys (erste Zuweisung am Zeilenanfang) aus einer Config
config_value() {
local file="$1" key="$2"
sed -n "s|^${key}[[:space:]]*=[[:space:]]*\"\(.*\)\"[[:space:]]*$|\1|p" "$file" | head -n1
}
# Maskiert Sonderzeichen, damit ein Pfad gefahrlos in eine sed-Ersetzung darf
# (Trennzeichen '|', Rueckverweis '&', Backslash).
sed_escape_repl() {
printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'
}
# Prueft jeden Tesseract-Sprachcode gegen die installierten Sprachdateien und
# bietet fehlende Pakete zur Installation an.
# Rueckgabe: 0 = alle Sprachen verfuegbar (oder Pruefung nicht moeglich),
# 1 = mindestens eine Sprache fehlt weiterhin.
ensure_tesseract_langs() {
local langs="$1"
local raw installed code pkg answer rc=0
local -a codes
if ! command -v tesseract >/dev/null 2>&1; then
log_warn "tesseract ist nicht aufrufbar — Sprachpruefung wird uebersprungen."
log_warn "Eingabe '$langs' wird unveraendert uebernommen."
return 0
fi
if ! raw="$(tesseract --list-langs 2>/dev/null)"; then
log_warn "'tesseract --list-langs' schlug fehl — Sprachpruefung wird uebersprungen."
log_warn "Eingabe '$langs' wird unveraendert uebernommen."
return 0
fi
installed="$(printf '%s\n' "$raw" | grep -vi '^List of available' || true)"
IFS='+' read -r -a codes <<< "$langs"
for code in "${codes[@]}"; do
[ -n "$code" ] || continue
if printf '%s\n' "$installed" | grep -qxF "$code"; then
log_info "Sprache '$code' ist installiert ✓"
continue
fi
pkg="tesseract-ocr-${code//_/-}"
log_warn "Sprache '$code' ist nicht installiert (Paket: $pkg)."
read -r -p "Paket '$pkg' jetzt installieren? [J/n]: " answer
answer="${answer:-J}"
if [[ "$answer" =~ ^[JjYy]$ ]]; then
if ! apt-get install -y --no-install-recommends "$pkg"; then
log_error "Paket '$pkg' liess sich nicht installieren."
elif tesseract --list-langs 2>/dev/null | grep -qxF "$code"; then
log_info "Paket '$pkg' installiert ✓"
continue
else
log_error "Paket '$pkg' ist da, aber tesseract kennt '$code' weiterhin nicht."
fi
fi
log_warn "Ohne die Sprachdatei '$code' scheitert das OCR bei JEDER Datei."
rc=1
done
return $rc
}
create_instance() { create_instance() {
echo echo
read -r -p "Instanz-Name (nur a-z, 0-9, -): " INST read -r -p "Instanz-Name (nur a-z, 0-9, -): " INST
@@ -206,20 +266,111 @@ create_instance() {
fi fi
fi fi
# --- OCR-Sprachen ---
echo
log_info "Tesseract-Sprachen — gelten NUR fuer diese Instanz '$INST'."
log_info "Jede zusaetzliche Sprache kostet Laufzeit und verschlechtert zugleich"
log_info "die Erkennung — also so eng wie moeglich waehlen (z.B. nur 'deu')."
local LANGS
while true; do
read -r -p "Tesseract-Sprachen [deu+eng]: " LANGS
LANGS="${LANGS:-deu+eng}"
if [[ ! "$LANGS" =~ ^[a-z]{3}(_[A-Za-z]+)?(\+[a-z]{3}(_[A-Za-z]+)?)*$ ]]; then
log_error "Ungueltiges Format. Erwartet: Sprachcodes mit '+' verbunden,"
log_error "z.B. 'deu', 'deu+eng' oder 'chi_sim+eng'."
continue
fi
if ensure_tesseract_langs "$LANGS"; then
break
fi
log_warn "Bitte Sprachen erneut angeben (fehlende Sprache einfach weglassen)."
echo
done
# --- Original archivieren? ---
echo
local ORIG_MODE="delete"
local ARCHIVE_DIR=""
local ARCHIVE_ANS
read -r -p "Original nach erfolgreichem OCR archivieren? [j/N]: " ARCHIVE_ANS
ARCHIVE_ANS="${ARCHIVE_ANS:-N}"
if [[ "$ARCHIVE_ANS" =~ ^[JjYy]$ ]]; then
ORIG_MODE="archive"
local default_archive="$BASE/archive"
while true; do
read -r -p "Archiv-Verzeichnis [$default_archive]: " ARCHIVE_DIR
ARCHIVE_DIR="${ARCHIVE_DIR:-$default_archive}"
if [[ "$ARCHIVE_DIR" != /* ]]; then
log_error "Bitte einen absoluten Pfad angeben (beginnt mit '/')."
continue
fi
# Das Archiv darf keines der Arbeitsverzeichnisse sein: im Eingang
# wuerde das Original endlos neu aufgegriffen, in den uebrigen
# kollidiert es mit der Verarbeitung.
case "${ARCHIVE_DIR%/}" in
"$BASE/incoming"|"$BASE/outgoing"|"$BASE/working"|"$BASE/error")
log_error "Das Archiv darf nicht incoming/outgoing/working/error sein."
continue
;;
esac
break
done
else
log_info "Original wird nach erfolgreichem OCR geloescht (original_on_success = \"delete\")."
fi
log_info "Lege Datenverzeichnisse unter $BASE an..." log_info "Lege Datenverzeichnisse unter $BASE an..."
mkdir -p "$BASE"/{incoming,outgoing,working,error} mkdir -p "$BASE"/{incoming,outgoing,working,error}
if [ -n "$ARCHIVE_DIR" ]; then
mkdir -p "$ARCHIVE_DIR"
fi
chown -R "$SVC_USER":"$SVC_GROUP" "$BASE" chown -R "$SVC_USER":"$SVC_GROUP" "$BASE"
# Innerhalb von $BASE erledigt das chown -R oben schon alles; nur ein Archiv
# ausserhalb braucht eigenes mkdir/chown.
if [ -n "$ARCHIVE_DIR" ] && [[ "$ARCHIVE_DIR" != "$BASE"/* ]] && [ "$ARCHIVE_DIR" != "$BASE" ]; then
chown -R "$SVC_USER":"$SVC_GROUP" "$ARCHIVE_DIR"
log_info "Archiv-Verzeichnis $ARCHIVE_DIR angelegt (liegt ausserhalb von $BASE)"
fi
log_info "Erstelle Config $CONFIG_DIR/$INST.toml..." log_info "Erstelle Config $CONFIG_DIR/$INST.toml..."
# Verankerte Ausdruecke (Zeilenanfang + Key + '='), damit die deutschen
# Kommentarzeilen ueber den Keys unangetastet bleiben.
local ESC_BASE ESC_ARCHIVE ESC_LANGS
ESC_BASE="$(sed_escape_repl "$BASE")"
ESC_ARCHIVE="$(sed_escape_repl "$ARCHIVE_DIR")"
ESC_LANGS="$(sed_escape_repl "$LANGS")"
sed \ sed \
-e "s|/var/lib/pdf-ocr-hotfolder/incoming|$BASE/incoming|" \ -e "s|^incoming[[:space:]]*=.*|incoming = \"$ESC_BASE/incoming\"|" \
-e "s|/var/lib/pdf-ocr-hotfolder/outgoing|$BASE/outgoing|" \ -e "s|^outgoing[[:space:]]*=.*|outgoing = \"$ESC_BASE/outgoing\"|" \
-e "s|/var/lib/pdf-ocr-hotfolder/working|$BASE/working|" \ -e "s|^working[[:space:]]*=.*|working = \"$ESC_BASE/working\"|" \
-e "s|/var/lib/pdf-ocr-hotfolder/error|$BASE/error|" \ -e "s|^error[[:space:]]*=.*|error = \"$ESC_BASE/error\"|" \
-e "s|^languages[[:space:]]*=.*|languages = \"$ESC_LANGS\"|" \
-e "s|^original_on_success[[:space:]]*=.*|original_on_success = \"$ORIG_MODE\"|" \
-e "s|^archive_dir[[:space:]]*=.*|archive_dir = \"$ESC_ARCHIVE\"|" \
"$INSTALL_DIR/config.example.toml" > "$CONFIG_DIR/$INST.toml" "$INSTALL_DIR/config.example.toml" > "$CONFIG_DIR/$INST.toml"
chown root:"$SVC_GROUP" "$CONFIG_DIR/$INST.toml" chown root:"$SVC_GROUP" "$CONFIG_DIR/$INST.toml"
chmod 640 "$CONFIG_DIR/$INST.toml" chmod 640 "$CONFIG_DIR/$INST.toml"
# Erzeugte Config gegenpruefen: tragen die drei Keys wirklich die Auswahl?
local CFG_OK=1 got key want
for key in languages original_on_success archive_dir; do
case "$key" in
languages) want="$LANGS" ;;
original_on_success) want="$ORIG_MODE" ;;
archive_dir) want="$ARCHIVE_DIR" ;;
esac
got="$(config_value "$CONFIG_DIR/$INST.toml" "$key")"
if [ "$got" != "$want" ]; then
log_error "Config-Pruefung: $key ist \"$got\", erwartet \"$want\""
CFG_OK=0
fi
done
if [ "$CFG_OK" -eq 1 ]; then
log_info "Config-Pruefung ok ✓ (languages / original_on_success / archive_dir)"
else
log_warn "Bitte $CONFIG_DIR/$INST.toml von Hand nachziehen."
fi
# Drop-in für abweichenden Service-User # Drop-in für abweichenden Service-User
if [ "$SVC_USER" != "$DEFAULT_USER" ]; then if [ "$SVC_USER" != "$DEFAULT_USER" ]; then
local DROPIN_DIR="/etc/systemd/system/pdf-ocr-hotfolder@${INST}.service.d" local DROPIN_DIR="/etc/systemd/system/pdf-ocr-hotfolder@${INST}.service.d"
@@ -246,6 +397,12 @@ EOF
echo " Eingang: $BASE/incoming" echo " Eingang: $BASE/incoming"
echo " Ausgang: $BASE/outgoing" echo " Ausgang: $BASE/outgoing"
echo " User: $SVC_USER ($SVC_GROUP)" echo " User: $SVC_USER ($SVC_GROUP)"
if [ "$CFG_OK" -eq 1 ]; then
echo " Sprachen: $LANGS"
if [ "$ORIG_MODE" = "archive" ]; then
echo " Archiv: $ARCHIVE_DIR"
fi
fi
echo echo
} }
+1 -1
View File
@@ -1,3 +1,3 @@
"""PDF OCR Hotfolder — Scanner-PDFs automatisch durchsuchbar machen.""" """PDF OCR Hotfolder — Scanner-PDFs automatisch durchsuchbar machen."""
__version__ = "0.4.1" __version__ = "0.5.0"