fix(linux): capture before cups-filters universal conversion
Some checks failed
Desktop Release / Bootstrap updater signing key (push) Has been cancelled
Desktop Release / Windows x64 NSIS (push) Has been cancelled
Desktop Release / Linux x64 DEB + AppImage (push) Has been cancelled
Desktop Release / Publish public desktop release (push) Has been cancelled

This commit is contained in:
Admin 2026-09-24 08:41:42 +00:00
parent f69bd7612b
commit 47db9ac867
5 changed files with 45 additions and 59 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@fieldlens/print", "name": "@fieldlens/print",
"version": "0.1.12", "version": "0.1.13",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "fieldlens-print" name = "fieldlens-print"
version = "0.1.12" version = "0.1.13"
description = "FieldLens print-stream barcode capture companion" description = "FieldLens print-stream barcode capture companion"
authors = ["Arrowstack"] authors = ["Arrowstack"]
edition = "2021" edition = "2021"

View File

@ -25,10 +25,7 @@ const FIELDLENS_CUPS_SPOOL_DIR: &str = "/var/cache/cups/fieldlens-print";
const FIELDLENS_CUPS_FILTER: &str = r#"#!/usr/bin/python3 const FIELDLENS_CUPS_FILTER: &str = r#"#!/usr/bin/python3
import os import os
import re import re
import shutil
import subprocess
import sys import sys
import tempfile
CACHE = os.path.join(os.environ.get("CUPS_CACHEDIR", "/var/cache/cups"), "fieldlens-print") CACHE = os.path.join(os.environ.get("CUPS_CACHEDIR", "/var/cache/cups"), "fieldlens-print")
@ -36,15 +33,6 @@ def safe(value):
value = re.sub(r"[^A-Za-z0-9._-]+", "-", value or "job").strip("-") value = re.sub(r"[^A-Za-z0-9._-]+", "-", value or "job").strip("-")
return value[:80] or "job" return value[:80] or "job"
def find_pdftoraster():
for path in (
"/usr/lib/cups/filter/pdftoraster",
"/usr/libexec/cups/filter/pdftoraster",
):
if os.path.isfile(path) and os.access(path, os.X_OK):
return path
return None
job_id = safe(sys.argv[1] if len(sys.argv) > 1 else "job") job_id = safe(sys.argv[1] if len(sys.argv) > 1 else "job")
title = safe(sys.argv[3] if len(sys.argv) > 3 else "print") title = safe(sys.argv[3] if len(sys.argv) > 3 else "print")
printer = safe(os.environ.get("PRINTER", "printer")) printer = safe(os.environ.get("PRINTER", "printer"))
@ -53,63 +41,62 @@ name = f"{prefix}{printer}-{job_id}-{title}.pdf"
final_path = os.path.join(CACHE, name) final_path = os.path.join(CACHE, name)
part_path = final_path + ".part" part_path = final_path + ".part"
input_path = None source = None
temporary_input = None capture = None
captured_ok = False
try: try:
if len(sys.argv) > 6 and sys.argv[6]: if len(sys.argv) > 6 and sys.argv[6]:
input_path = sys.argv[6] source = open(sys.argv[6], "rb")
else: else:
fd, temporary_input = tempfile.mkstemp(prefix="fieldlens-cups-", suffix=".pdf") source = sys.stdin.buffer
with os.fdopen(fd, "wb") as target:
shutil.copyfileobj(sys.stdin.buffer, target)
input_path = temporary_input
try: try:
os.makedirs(CACHE, exist_ok=True) os.makedirs(CACHE, exist_ok=True)
if not os.path.exists(final_path): if not os.path.exists(final_path):
shutil.copyfile(input_path, part_path) capture = open(part_path, "wb")
os.chmod(part_path, 0o644)
os.replace(part_path, final_path)
print(f"INFO: FieldLens captured {name}", file=sys.stderr)
except OSError as error: except OSError as error:
print(f"WARNING: FieldLens capture cache failed: {error}", file=sys.stderr) print(f"WARNING: FieldLens capture cache unavailable: {error}", file=sys.stderr)
capture = None
pdftoraster = find_pdftoraster() while True:
if pdftoraster is None: chunk = source.read(65536)
print("ERROR: FieldLens could not find the standard CUPS pdftoraster filter", file=sys.stderr) if not chunk:
sys.exit(1) break
env = os.environ.copy() if capture is not None:
env["FINAL_CONTENT_TYPE"] = "image/pwg-raster" try:
capture.write(chunk)
except OSError as error:
print(f"WARNING: FieldLens capture write failed: {error}", file=sys.stderr)
try:
capture.close()
except OSError:
pass
capture = None
args = [ sys.stdout.buffer.write(chunk)
pdftoraster,
sys.argv[1] if len(sys.argv) > 1 else "0",
sys.argv[2] if len(sys.argv) > 2 else "unknown",
sys.argv[3] if len(sys.argv) > 3 else "FieldLens Print",
sys.argv[4] if len(sys.argv) > 4 else "1",
sys.argv[5] if len(sys.argv) > 5 else "",
input_path,
]
result = subprocess.run( sys.stdout.buffer.flush()
args,
stdout=sys.stdout.buffer, if capture is not None:
stderr=sys.stderr.buffer, capture.flush()
env=env, capture.close()
) capture = None
sys.exit(result.returncode) os.chmod(part_path, 0o644)
os.replace(part_path, final_path)
captured_ok = True
print(f"INFO: FieldLens captured {name}", file=sys.stderr)
finally: finally:
if temporary_input is not None: if source is not None and source is not sys.stdin.buffer:
source.close()
if capture is not None:
capture.close()
if not captured_ok:
try: try:
os.unlink(temporary_input) os.unlink(part_path)
except OSError: except OSError:
pass pass
try:
os.unlink(part_path)
except OSError:
pass
"#; "#;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -589,9 +576,8 @@ fn build_fieldlens_ppd(target_printer: &str) -> Result<PathBuf> {
cleaned.push('\n'); cleaned.push('\n');
let prefilter = concat!( let prefilter = concat!(
"*% FieldLens original-document capture and PDF-to-PWG conversion\n", "*% FieldLens original-document capture before cups-filters universal conversion\n",
"*cupsFilter2: \"application/pdf image/pwg-raster 10 fieldlens-capture\"\n", "*cupsPreFilter: \"application/vnd.universal-input 0 fieldlens-capture\"\n"
"*cupsFilter2: \"application/vnd.cups-pdf image/pwg-raster 10 fieldlens-capture\"\n"
); );
if let Some(index) = cleaned.rfind("*% End") { if let Some(index) = cleaned.rfind("*% End") {
cleaned.insert_str(index, prefilter); cleaned.insert_str(index, prefilter);

View File

@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "FieldLens Print", "productName": "FieldLens Print",
"version": "0.1.12", "version": "0.1.13",
"identifier": "dev.arrowstack.fieldlens.print", "identifier": "dev.arrowstack.fieldlens.print",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",

View File

@ -85,7 +85,7 @@ let config: AppConfig
let jobs: Job[] = [] let jobs: Job[] = []
let status: Status let status: Status
let loginTimer: number | undefined let loginTimer: number | undefined
let currentVersion = '0.1.12' let currentVersion = '0.1.13'
let bundleType: BundleType | null = null let bundleType: BundleType | null = null
let availableUpdate: Update | null = null let availableUpdate: Update | null = null
let availableManualUpdate: ManualUpdate | null = null let availableManualUpdate: ManualUpdate | null = null