76 lines
3.3 KiB
Python
76 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from docx_template import fill_template
|
|
from ollama_client import ContentMismatchError, OllamaError, transform
|
|
from pdf_text import PdfTextError, extract_text, run
|
|
from betteroffice_render import render
|
|
|
|
|
|
def _date_label(raw: str) -> str:
|
|
date = datetime.strptime(raw, "%Y-%m-%d")
|
|
months = ("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli",
|
|
"August", "September", "Oktober", "November", "Dezember")
|
|
return f"{date.day:02d}. {months[date.month - 1]} {date.year:04d}"
|
|
|
|
|
|
def _args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(description="PDF-Aushang in NAK-DOCX-Template überführen und rendern")
|
|
parser.add_argument("--mode", choices=("original", "template"), default="template")
|
|
parser.add_argument("--pdf", required=True, type=Path)
|
|
parser.add_argument("--template", required=True, type=Path)
|
|
parser.add_argument("--output-dir", required=True, type=Path)
|
|
parser.add_argument("--base-name", required=True)
|
|
parser.add_argument("--date", required=True)
|
|
return parser.parse_args()
|
|
|
|
|
|
def main() -> int:
|
|
args = _args()
|
|
if not args.pdf.is_file() or (args.mode == "template" and not args.template.is_file()):
|
|
raise RuntimeError("PDF oder DOCX-Vorlage fehlt.")
|
|
if not args.base_name or any(ch in args.base_name for ch in "/\\\0"):
|
|
raise RuntimeError("Ungültiger Ausgabename.")
|
|
|
|
args.output_dir.mkdir(parents=True, exist_ok=True)
|
|
with tempfile.TemporaryDirectory(prefix="contentpanel_") as temp:
|
|
render_dir = Path(temp) / "render"
|
|
render_dir.mkdir()
|
|
result = {"ok": True, "ocr_pages": []}
|
|
if args.mode == "original":
|
|
run(["gs", "-dSAFER", "-dBATCH", "-dNOPAUSE", "-sDEVICE=png16m", "-r300",
|
|
f"-sOutputFile={render_dir}/page-%d.png", str(args.pdf)], timeout=540)
|
|
count = len(list(render_dir.glob("page-*.png")))
|
|
if not count:
|
|
raise RuntimeError("Ghostscript hat keine Seiten erzeugt.")
|
|
else:
|
|
extraction = extract_text(args.pdf, max_pages=int(os.getenv("CONTENTPANEL_MAX_INPUT_PAGES", "10")))
|
|
content = transform(extraction.text)
|
|
document = Path(temp) / "aushang.docx"
|
|
fill_template(args.template, document, content.title, _date_label(args.date), content.paragraphs)
|
|
count = render(document, render_dir)
|
|
result.update(title=content.title, source_pages=extraction.page_count, ocr_pages=extraction.ocr_pages)
|
|
for number in range(1, count + 1):
|
|
shutil.copy2(render_dir / f"page-{number}.png", args.output_dir / f"{args.base_name}_page_{number}.png")
|
|
print(json.dumps({**result, "pages": count}, ensure_ascii=False))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
raise SystemExit(main())
|
|
except Exception as exc:
|
|
print(f"contentpanel-aushang: {exc}", file=sys.stderr)
|
|
# Stable exit codes expose safe, actionable messages through PHP.
|
|
raise SystemExit(2 if isinstance(exc, ContentMismatchError) else
|
|
3 if isinstance(exc, OllamaError) else 4 if isinstance(exc, PdfTextError) else 1)
|