diff --git a/Dockerfile b/Dockerfile index 63b18e9..c446db3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,8 @@ FROM alpine:3.20 AS ptouch-build RUN apk add --no-cache build-base cmake gd-dev gettext-dev git libusb-dev pkgconf RUN git clone --depth 1 --branch farix-main https://github.com/farixembedded/ptouch-print.git /src/ptouch -COPY patches/ptouch-print-cut-options.patch /tmp/ptouch-print-cut-options.patch WORKDIR /src/ptouch -RUN patch -p1 < /tmp/ptouch-print-cut-options.patch \ - && cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \ +RUN cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \ && cmake --build build \ && install -m 0755 build/ptouch-print /usr/local/bin/ptouch-print diff --git a/README.md b/README.md index 3a0a913..3591192 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Die Weboberflaeche bildet die wichtigsten P-touch-Editor-Funktionen nach: - Layout speichern/laden im Browser - serverseitige Vorschau und Druck ueber `ptouch-print` - vereinfachte Mobile-Webansicht unter `/mobile` -- Schnittmodi: normal, Halbschnitt ein/aus, Kettendruck, Schnittmarke, Kettendruck mit Schnittmarke +- Schnittmodi: normal, Kettendruck/Streifen, Schnittmarke und Streifen mit Schnittmarke ## Wichtig fuer den PT-P700 @@ -104,9 +104,9 @@ Umgebungsvariablen: - `LABEL_DPI=180` passt zum PT-P700. - `LABEL_DIR=/data/labels` speichert erzeugte PNG-Dateien. -Wenn `ptouch-print` auf deinem Setup andere Optionen braucht, nur `PRINT_COMMAND` anpassen. Der Platzhalter `{image}` wird von der App ersetzt. Bei `Halbschnitt: Ein` nutzt die App fuer mehrere Kopien `ptouch-print --copies` und erzwingt automatisch Kettendruck, damit der Drucker Kopiengrenzen fuer Halbschnitte kennt und nicht nach jeder Kopie voll schneidet. Bei `Halbschnitt: Aus` oder wenn `--copies` nicht verfuegbar ist, werden Kopien als ein langes Druckbild gerendert. Fuer Schnittoptionen kannst du optional `{cut_args}` im Kommando platzieren; ohne Platzhalter haengt die App die Schnittargumente automatisch an. +Wenn `ptouch-print` auf deinem Setup andere Optionen braucht, nur `PRINT_COMMAND` anpassen. Der Platzhalter `{image}` wird von der App ersetzt. Fuer Schnittoptionen kannst du optional `{cut_args}` im Kommando platzieren; ohne Platzhalter haengt die App die Schnittargumente automatisch an. -Hinweis: Der PT-P700-Halbschnitt ist in upstream `ptouch-print` nicht als CLI-Option vorhanden. Dieses Projekt patcht `ptouch-print` beim Containerstart um `--halfcut` und `--no-halfcut`. +Hinweis: Der PT-P700 unterstuetzt laut Brother Auto Cut und Kettendruck, aber keinen Halbschnitt. Die Option `Kettendruck / Streifen` rendert mehrere Kopien als ein langes Druckbild, damit keine Vollschnitte zwischen den Labels entstehen. ## USB testen diff --git a/app/app.py b/app/app.py index 56b3d89..7868da3 100644 --- a/app/app.py +++ b/app/app.py @@ -36,7 +36,6 @@ DEFAULT_PRINT_COMMAND = "ptouch-print --image {image}" PRINT_COMMAND = os.environ.get("PRINT_COMMAND", DEFAULT_PRINT_COMMAND) PRINT_ENABLED = os.environ.get("PRINT_ENABLED", "1").lower() in {"1", "true", "yes", "on"} DPI = int(os.environ.get("LABEL_DPI", "180")) -PTOUCH_SUPPORTS_HALFCUT: bool | None = None PTOUCH_SUPPORTS_COPIES: bool | None = None TAPE_WIDTHS_MM = [3.5, 6, 9, 12, 18, 24] @@ -284,22 +283,6 @@ def render_design(design: dict[str, Any], copies: int = 1) -> Path: return output -def ptouch_supports_halfcut() -> bool: - global PTOUCH_SUPPORTS_HALFCUT - if PTOUCH_SUPPORTS_HALFCUT is not None: - return PTOUCH_SUPPORTS_HALFCUT - result = subprocess.run( - ["ptouch-print", "--help"], - capture_output=True, - check=False, - text=True, - timeout=10, - ) - help_text = f"{result.stdout}\n{result.stderr}" - PTOUCH_SUPPORTS_HALFCUT = "--no-halfcut" in help_text and "--halfcut" in help_text - return PTOUCH_SUPPORTS_HALFCUT - - def ptouch_supports_copies() -> bool: global PTOUCH_SUPPORTS_COPIES if PTOUCH_SUPPORTS_COPIES is not None: @@ -316,31 +299,11 @@ def ptouch_supports_copies() -> bool: return PTOUCH_SUPPORTS_COPIES -def effective_cut_mode(design: dict[str, Any], copies: int) -> str: - cut_mode = str(design.get("cutMode", "auto")) - if copies > 1 and design.get("halfcut", "on") == "on": - if cut_mode == "cutmark": - return "cutmark-chain" - if cut_mode == "auto": - return "chain" - return cut_mode - - def cut_args_for_design(design: dict[str, Any], copies: int) -> str: args = [] - if effective_cut_mode(design, copies) in {"chain", "cutmark-chain"}: + cut_mode = str(design.get("cutMode", "auto")) + if cut_mode in {"chain", "cutmark-chain"} and copies <= 1: args.append("--chain") - halfcut = design.get("halfcut", "on") - if halfcut == "off": - if not ptouch_supports_halfcut(): - raise RuntimeError( - "Halbschnitt Aus braucht die gepatchte ptouch-print-Version. " - "Bitte start.sh und patches/ptouch-print-cut-options.patch nach Unraid kopieren, " - "ptouch-print im Container entfernen oder Container neu erstellen und danach neu starten." - ) - args.append("--no-halfcut") - elif halfcut == "on" and ptouch_supports_halfcut(): - args.append("--halfcut") return " ".join(args) @@ -380,15 +343,7 @@ def print_label(image_path: Path, copies: int, design: dict[str, Any]) -> list[s def should_render_copies_as_strip(design: dict[str, Any], copies: int) -> bool: if copies <= 1: return False - if design.get("halfcut", "on") == "on": - if ptouch_supports_copies() or "{copies}" in PRINT_COMMAND: - return False - raise RuntimeError( - "Mehrere Kopien mit Halbschnitt brauchen einen echten Kopien-Druckjob. " - "Ein langes PNG kann keine Halbschnitte zwischen den Etiketten ausloesen. " - "Bitte eine ptouch-print-Version mit --copies verwenden." - ) - return True + return str(design.get("cutMode", "auto")) in {"chain", "cutmark-chain"} def detect_tape_width() -> tuple[float | None, str]: @@ -494,11 +449,15 @@ def api_print(): render_copies = copies if should_render_copies_as_strip(design, copies) else 1 print_copies = 1 if render_copies > 1 else copies image_path = render_design(design, render_copies) + print_design = design + if render_copies > 1 and str(design.get("cutMode", "auto")) in {"chain", "cutmark-chain"}: + print_design = dict(design) + print_design["cutMode"] = "cutmark" if design.get("cutMode") == "cutmark-chain" else "auto" if PRINT_ENABLED: if not PRINT_LOCK.acquire(blocking=False): raise RuntimeError("Es laeuft bereits ein Druckjob. Bitte warten oder haengenden ptouch-print-Prozess beenden.") try: - results = print_label(image_path, print_copies, design) + results = print_label(image_path, print_copies, print_design) failed = next((result for result in results if result.returncode != 0), None) if failed: raise RuntimeError(format_print_error(failed)) diff --git a/app/static/editor.js b/app/static/editor.js index d053cb1..e9f4f2e 100644 --- a/app/static/editor.js +++ b/app/static/editor.js @@ -19,7 +19,7 @@ const state = { marginMm: 2, orientation: "landscape", cutMode: "auto", - halfcut: "on", + halfcut: "off", objects: [], }, }; @@ -33,7 +33,6 @@ const controls = { lengthMm: document.getElementById("lengthMm"), marginMm: document.getElementById("marginMm"), cutMode: document.getElementById("cutMode"), - halfcut: document.getElementById("halfcut"), copies: document.getElementById("copies"), zoomLabel: document.getElementById("zoomLabel"), previewImage: document.getElementById("previewImage"), @@ -95,7 +94,7 @@ function syncDesignControls() { state.design.lengthMm = Number(controls.lengthMm.value); state.design.marginMm = Number(controls.marginMm.value); state.design.cutMode = controls.cutMode.value; - state.design.halfcut = controls.halfcut.value; + state.design.halfcut = "off"; state.design.orientation = document.querySelector("input[name='orientation']:checked").value; } @@ -104,7 +103,6 @@ function applyDesignControls() { controls.lengthMm.value = state.design.lengthMm; controls.marginMm.value = state.design.marginMm; controls.cutMode.value = state.design.cutMode || "auto"; - controls.halfcut.value = state.design.halfcut || "on"; document.querySelector(`input[name='orientation'][value='${state.design.orientation}']`).checked = true; } @@ -413,7 +411,7 @@ window.addEventListener("keydown", (event) => { } }); -["tapeWidth", "lengthMm", "marginMm", "cutMode", "halfcut"].forEach((id) => document.getElementById(id).addEventListener("input", draw)); +["tapeWidth", "lengthMm", "marginMm", "cutMode"].forEach((id) => document.getElementById(id).addEventListener("input", draw)); document.querySelectorAll("input[name='orientation']").forEach((input) => input.addEventListener("change", draw)); Object.values(controls).forEach((control) => { if (control && control.id && control.id.startsWith("prop")) control.addEventListener("input", applyProps); diff --git a/app/static/mobile.js b/app/static/mobile.js index 8ace9d5..4e3309e 100644 --- a/app/static/mobile.js +++ b/app/static/mobile.js @@ -7,7 +7,6 @@ const fields = { copies: document.getElementById("mobileCopies"), align: document.getElementById("mobileAlign"), cutMode: document.getElementById("mobileCutMode"), - halfcut: document.getElementById("mobileHalfcut"), bold: document.getElementById("mobileBold"), frame: document.getElementById("mobileFrame"), preview: document.getElementById("mobilePreview"), @@ -56,7 +55,7 @@ function mobileDesign() { marginMm: margin, orientation: "landscape", cutMode: fields.cutMode.value, - halfcut: fields.halfcut.value, + halfcut: "off", objects, }; } diff --git a/app/templates/index.html b/app/templates/index.html index 0f6245c..c9fabd0 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -71,20 +71,13 @@ - -
Bei mehreren Kopien mit Halbschnitt wird automatisch Kettendruck verwendet.
+PT-P700: Halbschnitt wird laut Brother nicht unterstuetzt. Fuer mehrere zusammenhaengende Labels Kettendruck / Streifen nutzen.
Bei mehreren Kopien mit Halbschnitt wird automatisch Kettendruck verwendet.
+PT-P700: kein Halbschnitt. Fuer zusammenhaengende Labels Kettendruck / Streifen nutzen.