From 941c68bbf8a74972ebe9e2d9fdaeed0fce40b055 Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:56:27 +0200 Subject: [PATCH] Align cut options with PT-P700 capabilities --- Dockerfile | 4 +- README.md | 6 +-- app/app.py | 57 ++++---------------------- app/static/editor.js | 8 ++-- app/static/mobile.js | 3 +- app/templates/index.html | 13 ++---- app/templates/mobile.html | 13 ++---- patches/ptouch-print-cut-options.patch | 52 ----------------------- start.sh | 7 +--- 9 files changed, 24 insertions(+), 139 deletions(-) delete mode 100644 patches/ptouch-print-cut-options.patch 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.

diff --git a/app/templates/mobile.html b/app/templates/mobile.html index 58ea6b8..e37acf3 100644 --- a/app/templates/mobile.html +++ b/app/templates/mobile.html @@ -70,20 +70,13 @@ - -

Bei mehreren Kopien mit Halbschnitt wird automatisch Kettendruck verwendet.

+

PT-P700: kein Halbschnitt. Fuer zusammenhaengende Labels Kettendruck / Streifen nutzen.

diff --git a/patches/ptouch-print-cut-options.patch b/patches/ptouch-print-cut-options.patch deleted file mode 100644 index c16c077..0000000 --- a/patches/ptouch-print-cut-options.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/src/ptouch-print.c -+++ b/src/ptouch-print.c -@@ -58,6 +58,7 @@ - int fontsize = 0; - bool debug = false; - bool chain = false; -+int precut = 1; - int forced_tape_width = 0; - - /* -------------------------------------------------------------------- -@@ -123,8 +124,8 @@ - } - } - if ((ptdev->devinfo->flags & FLAG_HAS_PRECUT) == FLAG_HAS_PRECUT) { -- ptouch_send_precut_cmd(ptdev, 1); -- if (debug) { -+ if (precut) ptouch_send_precut_cmd(ptdev, 1); -+ if (debug && precut) { - printf(_("send precut command\n")); - } - } -@@ -439,6 +440,8 @@ - printf("\t--cutmark\t\tPrint a mark where the tape should be cut\n"); - printf("\t--pad \t\tAdd n pixels padding (blank tape)\n"); - printf("\t--chain\t\t\tSkip final feed of label and any automatic cut\n"); -+ printf("\t--halfcut\t\tEnable half cut / precut when supported\n"); -+ printf("\t--no-halfcut\t\tDisable half cut / precut when supported\n"); - printf("other commands:\n"); - printf("\t--version\t\tshow version info (required for bug report)\n"); - printf("\t--info\t\t\tshow info about detected tape\n"); -@@ -484,6 +487,10 @@ - continue; /* not done here */ - } else if (strcmp(&argv[i][1], "-chain") == 0) { - chain=true; -+ } else if (strcmp(&argv[i][1], "-halfcut") == 0) { -+ precut=1; -+ } else if (strcmp(&argv[i][1], "-no-halfcut") == 0) { -+ precut=0; - } else if (strcmp(&argv[i][1], "-debug") == 0) { - debug=true; - } else if (strcmp(&argv[i][1], "-info") == 0) { -@@ -634,6 +641,10 @@ - im = NULL; - } else if (strcmp(&argv[i][1], "-chain") == 0) { - chain = true; -+ } else if (strcmp(&argv[i][1], "-halfcut") == 0) { -+ precut = 1; -+ } else if (strcmp(&argv[i][1], "-no-halfcut") == 0) { -+ precut = 0; - } else if (strcmp(&argv[i][1], "-debug") == 0) { - debug = true; - } else if (strcmp(&argv[i][1], "-copies") == 0) { diff --git a/start.sh b/start.sh index 19a47e1..4c8d12c 100644 --- a/start.sh +++ b/start.sh @@ -23,7 +23,7 @@ import os command = os.environ.get("PRINT_COMMAND", "ptouch-print --image {image}") try: - command.format(image="/tmp/test.png", copies=1) + command.format(image="/tmp/test.png", copies=1, cut_args="") except Exception as exc: raise SystemExit(f"ERROR: invalid PRINT_COMMAND: {exc}") PY @@ -56,12 +56,9 @@ if ! python3 -c "import qrcode, barcode" >/dev/null 2>&1; then python3 -m pip install --root-user-action=ignore --no-cache-dir qrcode python-barcode fi -if ! command -v ptouch-print >/dev/null 2>&1 || ! ptouch-print --help 2>&1 | grep -q -- "--no-halfcut"; then +if ! command -v ptouch-print >/dev/null 2>&1; then rm -rf "$PTOUCH_SRC_DIR" git clone --depth 1 --branch farix-main https://github.com/farixembedded/ptouch-print.git "$PTOUCH_SRC_DIR" - if [ -f "$APP_DIR/patches/ptouch-print-cut-options.patch" ]; then - patch -d "$PTOUCH_SRC_DIR" -p1 < "$APP_DIR/patches/ptouch-print-cut-options.patch" - fi cmake -S "$PTOUCH_SRC_DIR" -B "$PTOUCH_SRC_DIR/build" -DCMAKE_BUILD_TYPE=Release cmake --build "$PTOUCH_SRC_DIR/build" install -m 0755 "$PTOUCH_SRC_DIR/build/ptouch-print" /usr/local/bin/ptouch-print