diff --git a/config/default.json b/config/default.json new file mode 100644 index 00000000..3c4dfb50 --- /dev/null +++ b/config/default.json @@ -0,0 +1,4 @@ +{ + "ip": "192.168.1.53", + "debug": false +} \ No newline at end of file diff --git a/package.json b/package.json index e6ed310e..4199ffa7 100644 --- a/package.json +++ b/package.json @@ -46,13 +46,15 @@ }, "license": "MIT", "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", "@types/bonjour": "^3.5.10", "@types/chai": "^4.3.1", + "@types/chai-string": "^1.4.2", + "@types/config": "^0.0.41", "@types/dateformat": "^5.0.0", "@types/mocha": "^9.1.1", "@types/node": "^18.0.0", "@types/xml2js": "^0.4.11", - "@types/chai-string": "^1.4.2", "chai": "^4.3.6", "chai-string": "^1.5.0", "codecov": "^3.8.3", @@ -64,13 +66,13 @@ "ts-mockito": "^2.6.1", "ts-node": "^10.8.2", "typescript": "^4.7.4", - "yarn": "^1.22.19", - "@istanbuljs/nyc-config-typescript": "^1.0.2" + "yarn": "^1.22.19" }, "dependencies": { "axios": "^0.27.2", "bonjour": "^3.5.0", "commander": "^9.3.0", + "config": "^3.3.7", "dateformat": "^4.6.3", "jspdf": "^2.5.1", "xml2js": "^0.4.23" diff --git a/src/index.ts b/src/index.ts index e4d4010c..12dc60c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import os from "os"; import fs from "fs/promises"; import { Command } from "commander"; import Bonjour from "bonjour"; +import config from "config"; import Destination from "./Destination"; import ScanJobSettings from "./ScanJobSettings"; @@ -21,8 +22,6 @@ import { createPdfFrom, ScanContent, ScanPage } from "./ScanContent"; import WalkupScanToCompCaps from "./WalkupScanToCompCaps"; import { DeviceCapabilities } from "./DeviceCapabilities"; -const program = new Command(); - function delay(t: number): Promise { return new Promise(function (resolve) { setTimeout(resolve, t); @@ -201,7 +200,8 @@ async function handleProcessingState( inputSource: "Adf" | "Platen", folder: string, scanCount: number, - currentPageNumber: number + currentPageNumber: number, + filePattern: string | undefined ): Promise { if ( job.pageState == "ReadyToUpload" && @@ -217,7 +217,7 @@ async function handleProcessingState( folder, scanCount, currentPageNumber, - program.opts().pattern, + filePattern, "jpg" ); const filePath = await HPApi.downloadPage( @@ -275,7 +275,8 @@ async function executeScanJob( inputSource: "Adf" | "Platen", folder: string, scanCount: number, - scanJobContent: ScanContent + scanJobContent: ScanContent, + filePattern: string | undefined ): Promise<"Completed" | "Canceled"> { const jobUrl = await HPApi.postJob(scanJobSettings); @@ -295,7 +296,8 @@ async function executeScanJob( inputSource, folder, scanCount, - scanJobContent.elements.length + 1 + scanJobContent.elements.length + 1, + filePattern ); job = await HPApi.getJob(jobUrl); if (page != null && job.jobState != "Canceled") { @@ -348,14 +350,16 @@ async function executeScanJobs( scanCount: number, scanJobContent: ScanContent, firstEvent: Event, - deviceCapabilities: DeviceCapabilities + deviceCapabilities: DeviceCapabilities, + filePattern: string | undefined ) { let jobState = await executeScanJob( scanJobSettings, inputSource, folder, scanCount, - scanJobContent + scanJobContent, + filePattern ); let lastEvent = firstEvent; if ( @@ -379,7 +383,8 @@ async function executeScanJobs( inputSource, folder, scanCount, - scanJobContent + scanJobContent, + filePattern ); if (jobState !== "Completed") { return; @@ -402,13 +407,14 @@ async function executeScanJobs( async function mergeToPdf( folder: string, scanCount: number, - scanJobContent: ScanContent + scanJobContent: ScanContent, + filePattern: string | undefined ): Promise { if (scanJobContent.elements.length > 0) { const pdfFilePath = PathHelper.getFileForScan( folder, scanCount, - program.opts().pattern, + filePattern, "pdf" ); await createPdfFrom(scanJobContent, pdfFilePath); @@ -454,7 +460,8 @@ async function saveScan( folder: string, tempFolder: string, scanCount: number, - deviceCapabilities: DeviceCapabilities + deviceCapabilities: DeviceCapabilities, + filePattern: string | undefined ): Promise { if (event.compEventURI) { const proceedToScan = await waitScanRequest(event.compEventURI); @@ -511,7 +518,8 @@ async function saveScan( scanCount, scanJobContent, event, - deviceCapabilities + deviceCapabilities, + filePattern ); console.log( @@ -519,7 +527,12 @@ async function saveScan( ); if (toPdf) { - const pdfFilePath = await mergeToPdf(folder, scanCount, scanJobContent); + const pdfFilePath = await mergeToPdf( + folder, + scanCount, + scanJobContent, + filePattern + ); displayPdfScan(pdfFilePath, scanJobContent); } else { displayJpegScan(scanJobContent); @@ -569,13 +582,19 @@ async function readDeviceCapabilities(): Promise { }; } +type DirectoryConfig = { + directory: string | undefined; + tempDirectory: string | undefined; + filePattern: string | undefined; +}; + let iteration = 0; -async function init() { - const folder = await PathHelper.getOutputFolder(program.opts().directory); +async function init(directoryConfig: DirectoryConfig) { + const folder = await PathHelper.getOutputFolder(directoryConfig.directory); console.log(`Target folder: ${folder}`); const tempFolder = await PathHelper.getOutputFolder( - program.opts().tempDirectory + directoryConfig.tempDirectory ); console.log(`Temp folder: ${tempFolder}`); @@ -599,7 +618,14 @@ async function init() { scanCount++; console.log(`Scan event captured, saving scan #${scanCount}`); - await saveScan(event, folder, tempFolder, scanCount, deviceCapabilities); + await saveScan( + event, + folder, + tempFolder, + scanCount, + deviceCapabilities, + directoryConfig.filePattern + ); } catch (e) { errorCount++; console.error(e); @@ -614,7 +640,7 @@ async function init() { } } -function findOfficejetIp(): Promise { +function findOfficejetIp(deviceNamePrefix: string): Promise { return new Promise((resolve) => { const bonjour = Bonjour(); console.log("Searching printer..."); @@ -625,7 +651,7 @@ function findOfficejetIp(): Promise { (service) => { console.log("."); if ( - service.name.startsWith(program.opts().name) && + service.name.startsWith(deviceNamePrefix) && service.port === 80 && service.type === "http" && service.addresses != null @@ -641,7 +667,12 @@ function findOfficejetIp(): Promise { }); } +function getConfig(name: string): T | undefined { + return config.has(name) ? config.get(name) : undefined; +} + async function main() { + const program = new Command(); program.option( "-ip, --address ", "IP address of the printer (this overrides -p)" @@ -649,8 +680,7 @@ async function main() { program.option( "-n, --name ", "Name of the printer for service discovery", - "HP Smart Tank Plus 570 series" - ); //or i.e. 'Deskjet 3520 series' + ); // i.e. 'Deskjet 3520 series' program.option( "-d, --directory ", "Directory where scans are saved (defaults to /tmp/scan-to-pc)" @@ -666,17 +696,23 @@ async function main() { program.option("-D, --debug", "Enable debug"); program.parse(process.argv); - let ip = program.opts().address || "192.168.1.53"; + let ip = program.opts().address || getConfig("ip"); if (!ip) { - ip = await findOfficejetIp(); + const name = program.opts().name || getConfig("name"); + ip = await findOfficejetIp(name || "HP Smart Tank Plus 570 series"); } console.log(`Using device ip: ${ip}`); - const debug = program.opts().debug != null; + const debug = program.opts().debug != null ? true : getConfig("debug") || false; HPApi.setDebug(debug); HPApi.setPrinterIP(ip); - await init(); + const directoryConfig = { + directory: program.opts().directory || getConfig("directory"), + tempDirectory: program.opts().tempDirectory || getConfig("tempDirectory"), + filePattern: program.opts().pattern || getConfig("pattern"), + } + await init(directoryConfig); } main(); diff --git a/yarn.lock b/yarn.lock index 6b1b6951..2e56c971 100644 --- a/yarn.lock +++ b/yarn.lock @@ -323,6 +323,11 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07" integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g== +"@types/config@^0.0.41": + version "0.0.41" + resolved "https://registry.yarnpkg.com/@types/config/-/config-0.0.41.tgz#c8237ab09730380801f3643beaefa077ca5f3c28" + integrity sha512-HjXUmIld0gwvyG8MU/17QtLzOyuMX4jbGuijmS9sWsob5xxgZ/hY9cbRCaHIHqTQ3HMLhwS3F8uXq3Bt9zgzHA== + "@types/dateformat@^5.0.0": version "5.0.0" resolved "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz" @@ -708,6 +713,13 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" +config@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.7.tgz#4310410dc2bf4e0effdca21a12a4035860a24ee4" + integrity sha512-mX/n7GKDYZMqvvkY6e6oBY49W8wxdmQt+ho/5lhwFDXqQW9gI+Ahp8EKp8VAbISPnmf2+Bv5uZK7lKXZ6pf1aA== + dependencies: + json5 "^2.1.1" + convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" @@ -1441,7 +1453,7 @@ json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" -json5@^2.2.1: +json5@^2.1.1, json5@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"