feat(scan): support iX1600 duplex scanning on Linux
This commit is contained in:
@@ -1,66 +1,45 @@
|
||||
import path from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { AgentConfig, ScanResult } from "../types.js"
|
||||
import { commandExists, runCommand } from "../commands.js"
|
||||
import { runCommand } from "../commands.js"
|
||||
|
||||
const currentFile = fileURLToPath(import.meta.url)
|
||||
const agentRoot = path.resolve(path.dirname(currentFile), "../..")
|
||||
const postprocessScript = path.join(agentRoot, "scripts/opencv_postprocess.py")
|
||||
const agentRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..")
|
||||
const documentScript = path.join(agentRoot, "scripts/scan_document.py")
|
||||
|
||||
const extensionMimeTypes: Record<string, string> = {
|
||||
".pdf": "application/pdf",
|
||||
".png": "image/png",
|
||||
".tif": "image/tiff",
|
||||
".tiff": "image/tiff",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
export const checkScanRuntime = async (config: AgentConfig, postprocess: boolean) => {
|
||||
const imports = postprocess && config.postprocessStrict ? "import PIL, cv2, numpy" : "import PIL"
|
||||
try {
|
||||
const result = await runCommand(config.postprocessPython, ["-c", imports], { timeoutMs: 10_000 })
|
||||
if (result.code === 0) return
|
||||
} catch {
|
||||
// Report missing runtimes before the scanner consumes any paper.
|
||||
}
|
||||
throw new Error("Python/Pillow (bei strikter Nachbearbeitung zusätzlich OpenCV) fehlt. Bitte npm run setup:opencv ausführen oder python3-pil installieren.")
|
||||
}
|
||||
|
||||
const ensureOutputExtension = (filename: string, format: AgentConfig["scanFormat"]) => {
|
||||
const ext = path.extname(filename)
|
||||
if (ext) return filename
|
||||
return `${filename}.${format}`
|
||||
}
|
||||
|
||||
export const hasOpenCvPostprocessRuntime = async (config: AgentConfig) => {
|
||||
if (!await commandExists(config.postprocessPython)) return false
|
||||
|
||||
const result = await runCommand(config.postprocessPython, [
|
||||
"-c",
|
||||
"import cv2, PIL, numpy",
|
||||
], { timeoutMs: 10_000 })
|
||||
|
||||
return result.code === 0
|
||||
}
|
||||
|
||||
export const postprocessScan = async (
|
||||
export const createScanDocument = async (
|
||||
config: AgentConfig,
|
||||
inputPath: string,
|
||||
outputFilename: string,
|
||||
outputFormat: AgentConfig["scanFormat"],
|
||||
pages: string[],
|
||||
outputPath: string,
|
||||
resolution: number,
|
||||
postprocess: boolean,
|
||||
profile: AgentConfig["postprocessProfile"]
|
||||
): Promise<ScanResult> => {
|
||||
const filename = ensureOutputExtension(outputFilename, outputFormat)
|
||||
const outputPath = path.join(config.workDir, filename)
|
||||
const args = [documentScript, "--output", outputPath, "--resolution", String(resolution), "--profile", profile]
|
||||
if (postprocess) args.push("--postprocess")
|
||||
if (config.postprocessStrict) args.push("--strict")
|
||||
args.push("--inputs", ...pages)
|
||||
|
||||
const result = await runCommand(config.postprocessPython, [
|
||||
postprocessScript,
|
||||
"--input",
|
||||
inputPath,
|
||||
"--output",
|
||||
outputPath,
|
||||
"--profile",
|
||||
profile,
|
||||
], { timeoutMs: 5 * 60 * 1000 })
|
||||
const result = await runCommand(config.postprocessPython, args, {
|
||||
timeoutMs: config.scanTimeoutSeconds * 1000,
|
||||
})
|
||||
if (result.code !== 0) throw new Error(result.stderr || "Scan-Datei konnte nicht erstellt werden")
|
||||
|
||||
if (result.code !== 0) {
|
||||
throw new Error(result.stderr || `OpenCV-Nachbearbeitung wurde mit Code ${result.code} beendet`)
|
||||
}
|
||||
|
||||
const extension = path.extname(outputPath).toLowerCase()
|
||||
const details = JSON.parse(result.stdout) as { pageCount: number; warnings: string[] }
|
||||
return {
|
||||
path: outputPath,
|
||||
filename,
|
||||
mimeType: extensionMimeTypes[extension] || "application/octet-stream",
|
||||
filename: path.basename(outputPath),
|
||||
mimeType: outputPath.endsWith(".pdf") ? "application/pdf" : outputPath.endsWith(".png") ? "image/png" : "image/tiff",
|
||||
...details,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user