Formate zentral aus Directus + Kuvert-/Agent-/Login-Fixes
Formate zentralisiert (Phase 1)
- Neue Collection render_formats (Seitengröße, Ränder, Zeilenhöhe/-limit +
Plotter-Template) als einzige Quelle. Backend liest sie gecacht (Start +
stündlich, synchroner Zugriff → keine Latenz) mit eingebauten Defaults als
Fallback; manueller Trigger via POST /api/formats/refresh.
- Ermöglicht frei definierbare Formate ohne Codeänderung.
Kuvert-Templates
- Werte 1:1 aus dem alten Job-Manager übernommen (falsche/vertauschte Maße
korrigiert, per Upsert) und je Format die zweite Variante ergänzt
(individuelle Beschriftung). Druck-Popup schlägt bei freiem Text Variante 2 vor.
Produktions-Agent
- Datei-Endpunkt liefert {files} ohne data-Hülle → eigener get_raw statt des
data-auspackenden get; Dokumentauswahl positionsbasiert (robust gegen 0-/1-
basierte Dateinamen).
Bootstrap
- Ungültiger DIRECTUS_TOKEN wird erkannt und fällt auf ADMIN_EMAIL/PASSWORD
zurück, statt mit einem 401 abzubrechen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -46,10 +46,17 @@ class Directus:
|
||||
self.s.headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
def get(self, path, **params):
|
||||
"""Für /items/… – Directus verpackt die Nutzdaten in `data`."""
|
||||
r = self.s.get(self.base + path, params=params, timeout=30)
|
||||
r.raise_for_status()
|
||||
return r.json().get("data")
|
||||
|
||||
def get_raw(self, path, **params):
|
||||
"""Für Custom-Endpunkte (z. B. /skrift-orders/files) ohne `data`-Hülle."""
|
||||
r = self.s.get(self.base + path, params=params, timeout=30)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def patch(self, path, body):
|
||||
r = self.s.patch(self.base + path, json=body, timeout=30)
|
||||
r.raise_for_status()
|
||||
@@ -152,12 +159,6 @@ def parse_nummern(spec):
|
||||
return treffer or None
|
||||
|
||||
|
||||
def datei_nummer(name):
|
||||
"""Zahl aus einem Dateinamen ziehen (letter_003.svg → 3)."""
|
||||
ziffern = "".join(ch for ch in os.path.splitext(os.path.basename(name))[0] if ch.isdigit())
|
||||
return int(ziffern) if ziffern else None
|
||||
|
||||
|
||||
def main():
|
||||
cfg = lade_config()
|
||||
dx = Directus(cfg["directus_url"], cfg["directus_token"])
|
||||
@@ -248,15 +249,18 @@ def _druck(dx, plotter, job, KIND):
|
||||
try:
|
||||
if not order_nr:
|
||||
raise RuntimeError("Auftragsnummer fehlt am Job.")
|
||||
liste = dx.get(f"/skrift-orders/files/{order_nr}") or {}
|
||||
liste = dx.get_raw(f"/skrift-orders/files/{order_nr}") or {}
|
||||
gewuenscht = KIND.get(typ, "schriftstueck")
|
||||
passende = sorted(
|
||||
[f for f in (liste.get("files") or []) if f.get("kind") == gewuenscht],
|
||||
key=lambda f: f.get("name", ""),
|
||||
)
|
||||
# Nur bestimmte Briefnummern drucken, falls im Job angegeben.
|
||||
# Positionsbasiert (1 = erstes Dokument), NICHT über die Zahl im
|
||||
# Dateinamen: Alt-Aufträge sind 0-basiert (letter_000.svg), neue
|
||||
# 1-basiert (letter_001.svg). Die Position stimmt in beiden Fällen.
|
||||
if nummern is not None:
|
||||
passende = [f for f in passende if datei_nummer(f.get("name")) in nummern]
|
||||
passende = [f for i, f in enumerate(passende, start=1) if i in nummern]
|
||||
if not passende:
|
||||
raise RuntimeError(f"Keine Dateien vom Typ '{gewuenscht}' für {order_nr} gefunden.")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user