From 4cee66e814d1fbd043643599606070deb0427792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Luiz=20Bortot=20Monteiro=20do=20Ros=C3=A1rio?= <60971278+PedroBMR@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:57:43 -0300 Subject: [PATCH] Add printer host/port persistence for print jobs --- db/migrations.py | 4 +++ db/store.py | 12 ++++++- printing/__init__.py | 8 +++++ printing/queue.py | 2 ++ quick_print.py | 2 ++ tests/db/test_init_and_migrate.py | 2 ++ tests/test_db_store.py | 7 ++++ tests/test_printing_new.py | 60 +++++++++++++++++++++++++++++++ ui/__init__.py | 6 ++++ 9 files changed, 102 insertions(+), 1 deletion(-) diff --git a/db/migrations.py b/db/migrations.py index d2515ff..c7a0447 100644 --- a/db/migrations.py +++ b/db/migrations.py @@ -177,6 +177,8 @@ def table_columns(name: str) -> set[str]: printer_name TEXT, printer_backend TEXT, printer_transport TEXT, + printer_host TEXT, + printer_port INTEGER, media_settings TEXT, status TEXT NOT NULL DEFAULT 'pending', pending_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -194,6 +196,8 @@ def table_columns(name: str) -> set[str]: "printer_name", "printer_backend", "printer_transport", + "printer_host", + "printer_port", "media_settings", "pending_at", "running_at", diff --git a/db/store.py b/db/store.py index 8168cc1..6251ec9 100644 --- a/db/store.py +++ b/db/store.py @@ -850,6 +850,8 @@ def insert_print_job( printer_name: str | None = None, printer_backend: str | None = None, printer_transport: str | None = None, + printer_host: str | None = None, + printer_port: int | None = None, media_settings: Mapping[str, object] | None = None, db_path: str | Path | None = None, ) -> int: @@ -879,11 +881,13 @@ def insert_print_job( printer_name, printer_backend, printer_transport, + printer_host, + printer_port, media_settings, status, pending_at ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?) """, ( payload_hash, @@ -893,6 +897,8 @@ def insert_print_job( printer_name, printer_backend, printer_transport, + printer_host, + printer_port, media_blob, pending_at, ), @@ -1030,6 +1036,8 @@ def get_print_job( printer_name, printer_backend, printer_transport, + printer_host, + printer_port, media_settings, status, pending_at, @@ -1082,6 +1090,8 @@ def list_print_jobs( printer_name, printer_backend, printer_transport, + printer_host, + printer_port, media_settings, status, pending_at, diff --git a/printing/__init__.py b/printing/__init__.py index 9852142..c3894f9 100644 --- a/printing/__init__.py +++ b/printing/__init__.py @@ -1180,6 +1180,8 @@ def _record_and_send( printer_name: str | None, printer_backend: str | None, printer_transport: str | None, + printer_host: str | None = None, + printer_port: int | None = None, media_settings: Mapping[str, Any] | None, send_callable: Callable[[bytes], None], logger: logging.Logger | None, @@ -1198,6 +1200,10 @@ def _record_and_send( "printer_transport": printer_transport, "media_settings": media_settings, } + if printer_host: + params["printer_host"] = printer_host + if printer_port is not None: + params["printer_port"] = printer_port job_id, status = enqueue_job( template_name, payload, @@ -1411,6 +1417,8 @@ def send_commands( printer_name=self.config.printer_name, printer_backend=self.config.backend, printer_transport=self.config.transport, + printer_host=self.config.host, + printer_port=self.config.port if self.config.host else None, media_settings=media_settings, send_callable=self.transport.send, logger=self.logger, diff --git a/printing/queue.py b/printing/queue.py index 96eb011..ea65156 100644 --- a/printing/queue.py +++ b/printing/queue.py @@ -211,6 +211,8 @@ def enqueue_job( printer_name=printer.name, printer_backend=params.get("printer_backend", printer.backend), printer_transport=params.get("printer_transport", printer.transport), + printer_host=params.get("printer_host"), + printer_port=params.get("printer_port"), media_settings=params.get("media_settings"), ) diff --git a/quick_print.py b/quick_print.py index 61606f5..8c5c9ed 100644 --- a/quick_print.py +++ b/quick_print.py @@ -340,6 +340,8 @@ def _on_print(self) -> None: "printer_backend": backend_name, "printer_transport": "win32", "media_settings": media_settings, + "printer_host": None, + "printer_port": None, }, ) except Exception as exc: # pragma: no cover - defensive diff --git a/tests/db/test_init_and_migrate.py b/tests/db/test_init_and_migrate.py index a2a3693..c51ab65 100644 --- a/tests/db/test_init_and_migrate.py +++ b/tests/db/test_init_and_migrate.py @@ -88,6 +88,8 @@ "printer_name", "printer_backend", "printer_transport", + "printer_host", + "printer_port", "media_settings", "status", "pending_at", diff --git a/tests/test_db_store.py b/tests/test_db_store.py index c210b57..f9a7f08 100644 --- a/tests/test_db_store.py +++ b/tests/test_db_store.py @@ -649,6 +649,13 @@ def test_print_job_lifecycle(tmp_path): assert row["status"] == "pending" assert row["pending_at"] is not None assert row["running_at"] is None + host_row = conn.execute( + "SELECT printer_host, printer_port FROM print_jobs WHERE id = ?", + (job_id,), + ).fetchone() + assert host_row is not None + assert host_row["printer_host"] is None + assert host_row["printer_port"] is None assert store.update_print_job_status( job_id=job_id, status="running", db_path=db_path diff --git a/tests/test_printing_new.py b/tests/test_printing_new.py index 6902d30..3772668 100644 --- a/tests/test_printing_new.py +++ b/tests/test_printing_new.py @@ -461,3 +461,63 @@ def test_reprint_uses_saved_payload(): assert wait_for_all_jobs(2.0) assert reprint_stub.payloads == [original_payload] assert new_job_id != original_job_id + + +def test_tcp_job_replay_preserves_host_port(): + config = PrinterConfig(backend="tspl", transport="tcp", host="192.0.2.10", port=9200) + printer = Printer(config) + stub = StubTransport() + printer.transport = stub + + ok, status, job_id = printer.send_commands( + b"tcp-payload", + backend="tspl", + template_name="tcp-job", + template_backend="tspl", + ) + + assert ok and status is not None and status.get("status") == "pending" + assert job_id is not None + assert wait_for_all_jobs(2.0) + assert stub.payloads == [b"tcp-payload"] + + record = db_store.get_print_job(job_id=job_id) + assert record is not None + assert record.get("printer_host") == "192.0.2.10" + assert record.get("printer_port") == 9200 + + payload = db_store.get_job_payload(job_id=job_id) + assert payload == b"tcp-payload" + + reprint_config = PrinterConfig( + backend=str(record.get("printer_backend") or "tspl"), + transport=str(record.get("printer_transport") or "tcp"), + printer_name=str(record.get("printer_name") or "") or None, + ) + host_value = record.get("printer_host") + if host_value: + reprint_config.host = str(host_value) + port_value = record.get("printer_port") + if port_value is not None: + reprint_config.port = int(port_value) + + reprint_printer = Printer(reprint_config) + reprint_stub = StubTransport() + reprint_printer.transport = reprint_stub + + ok2, status2, replay_job_id = reprint_printer.send_commands( + payload, + backend=str(record.get("template_backend") or "tspl"), + template_name=str(record.get("template_name") or "") or None, + template_backend=str(record.get("template_backend") or "") or None, + ) + + assert ok2 and status2 is not None and status2.get("status") == "pending" + assert replay_job_id is not None + assert wait_for_all_jobs(2.0) + assert reprint_stub.payloads == [b"tcp-payload"] + + replay_record = db_store.get_print_job(job_id=replay_job_id) + assert replay_record is not None + assert replay_record.get("printer_host") == "192.0.2.10" + assert replay_record.get("printer_port") == 9200 diff --git a/ui/__init__.py b/ui/__init__.py index 9a6c424..d032a20 100644 --- a/ui/__init__.py +++ b/ui/__init__.py @@ -1346,6 +1346,9 @@ def _resend_job( "printer_transport": config.transport, "media_settings": media_settings, } + if config.host: + params["printer_host"] = config.host + params["printer_port"] = config.port template_name = str(record.get("template_name") or "") or None @@ -1813,6 +1816,9 @@ def _imprimir_etiqueta(self) -> None: "printer_transport": config.transport, "media_settings": media_settings, } + if config.host: + params["printer_host"] = config.host + params["printer_port"] = config.port try: job_id, status = enqueue_job(tpl, payload, target, copies=1, params=params)