node-hp-scan-to 1.1.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -6
- package/dist/Destination.js +10 -9
- package/dist/Destination.js.map +1 -1
- package/dist/Event.d.ts +10 -6
- package/dist/Event.js +18 -2
- package/dist/Event.js.map +1 -1
- package/dist/HPApi.d.ts +13 -4
- package/dist/HPApi.js +198 -61
- package/dist/HPApi.js.map +1 -1
- package/dist/Job.d.ts +13 -1
- package/dist/Job.js +32 -0
- package/dist/Job.js.map +1 -1
- package/dist/JpegUtil.d.ts +26 -0
- package/dist/JpegUtil.js +238 -0
- package/dist/JpegUtil.js.map +1 -0
- package/dist/PathHelper.d.ts +5 -0
- package/dist/PathHelper.js +79 -0
- package/dist/PathHelper.js.map +1 -0
- package/dist/ScanContent.d.ts +12 -0
- package/dist/ScanContent.js +82 -0
- package/dist/ScanContent.js.map +1 -0
- package/dist/ScanStatus.d.ts +1 -1
- package/dist/ScanStatus.js.map +1 -1
- package/dist/WalkupScanToCompDestinations.js +3 -3
- package/dist/WalkupScanToCompDestinations.js.map +1 -1
- package/dist/WalkupScanToCompEvent.d.ts +10 -0
- package/dist/WalkupScanToCompEvent.js +17 -0
- package/dist/WalkupScanToCompEvent.js.map +1 -0
- package/dist/index.js +406 -102
- package/dist/index.js.map +1 -1
- package/package.json +26 -13
- package/src/Destination.ts +8 -7
- package/src/Event.ts +21 -7
- package/src/HPApi.ts +117 -43
- package/src/Job.ts +39 -1
- package/src/JpegUtil.ts +319 -0
- package/src/PathHelper.ts +44 -0
- package/src/ScanContent.ts +34 -0
- package/src/ScanStatus.ts +1 -1
- package/src/WalkupScanToCompDestinations.ts +4 -5
- package/src/WalkupScanToCompEvent.ts +18 -0
- package/src/index.ts +390 -76
package/src/index.ts
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// noinspection XmlDeprecatedElement,HtmlDeprecatedTag
|
|
3
|
+
|
|
2
4
|
"use strict";
|
|
3
5
|
|
|
4
6
|
import os from "os";
|
|
5
|
-
import fs from "fs";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
import Bonjour, { Service } from "bonjour";
|
|
7
|
+
import fs from "fs/promises";
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
import Bonjour from "bonjour";
|
|
10
10
|
|
|
11
11
|
import Destination from "./Destination";
|
|
12
12
|
import ScanJobSettings from "./ScanJobSettings";
|
|
13
13
|
import Event from "./Event";
|
|
14
14
|
import HPApi from "./HPApi";
|
|
15
15
|
import Job from "./Job";
|
|
16
|
+
import WalkupScanDestination from "./WalkupScanDestination";
|
|
17
|
+
import WalkupScanToCompDestination from "./WalkupScanToCompDestination";
|
|
18
|
+
import JpegUtil from "./JpegUtil";
|
|
19
|
+
import PathHelper from "./PathHelper";
|
|
20
|
+
import { createPdfFrom, ScanContent, ScanPage } from "./ScanContent";
|
|
21
|
+
|
|
22
|
+
const program = new Command();
|
|
16
23
|
|
|
17
24
|
function delay(t: number): Promise<void> {
|
|
18
25
|
return new Promise(function (resolve) {
|
|
@@ -20,10 +27,13 @@ function delay(t: number): Promise<void> {
|
|
|
20
27
|
});
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
async function waitForScanEvent(
|
|
30
|
+
async function waitForScanEvent(
|
|
31
|
+
resourceURI: string,
|
|
32
|
+
afterEtag: string | null = null
|
|
33
|
+
): Promise<Event> {
|
|
24
34
|
console.log("Start listening for new ScanEvent");
|
|
25
35
|
|
|
26
|
-
let eventTable = await HPApi.getEvents();
|
|
36
|
+
let eventTable = await HPApi.getEvents(afterEtag ?? "");
|
|
27
37
|
let acceptedScanEvent = null;
|
|
28
38
|
let currentEtag = eventTable.etag;
|
|
29
39
|
while (acceptedScanEvent == null) {
|
|
@@ -31,7 +41,10 @@ async function waitForScanEvent(resourceURI: string): Promise<Event> {
|
|
|
31
41
|
currentEtag = eventTable.etag;
|
|
32
42
|
|
|
33
43
|
acceptedScanEvent = eventTable.eventTable.events.find(
|
|
34
|
-
(ev) =>
|
|
44
|
+
(ev) =>
|
|
45
|
+
ev.isScanEvent &&
|
|
46
|
+
ev.destinationURI &&
|
|
47
|
+
ev.destinationURI.indexOf(resourceURI) >= 0
|
|
35
48
|
);
|
|
36
49
|
}
|
|
37
50
|
return acceptedScanEvent;
|
|
@@ -44,9 +57,19 @@ async function waitPrinterUntilItIsReadyToUploadOrCompleted(
|
|
|
44
57
|
let isReadyToUpload = false;
|
|
45
58
|
do {
|
|
46
59
|
job = await HPApi.getJob(jobUrl);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
if (job.jobState === "Canceled") {
|
|
61
|
+
return job;
|
|
62
|
+
} else if (
|
|
63
|
+
job.pageState === "ReadyToUpload" ||
|
|
64
|
+
job.jobState === "Completed"
|
|
65
|
+
) {
|
|
66
|
+
isReadyToUpload = true;
|
|
67
|
+
} else if (job.jobState == "Processing") {
|
|
68
|
+
isReadyToUpload = false;
|
|
69
|
+
} else {
|
|
70
|
+
console.log(`Unknown jobState: ${job.jobState}`);
|
|
71
|
+
}
|
|
72
|
+
await delay(300);
|
|
50
73
|
} while (!isReadyToUpload);
|
|
51
74
|
return job;
|
|
52
75
|
}
|
|
@@ -57,7 +80,8 @@ async function register(): Promise<string> {
|
|
|
57
80
|
const toComp = await HPApi.getWalkupScanToCompCaps();
|
|
58
81
|
|
|
59
82
|
if (toComp) {
|
|
60
|
-
const walkupScanDestinations =
|
|
83
|
+
const walkupScanDestinations =
|
|
84
|
+
await HPApi.getWalkupScanToCompDestinations();
|
|
61
85
|
const destinations = walkupScanDestinations.destinations;
|
|
62
86
|
|
|
63
87
|
console.log(
|
|
@@ -94,40 +118,144 @@ async function register(): Promise<string> {
|
|
|
94
118
|
return resourceURI;
|
|
95
119
|
}
|
|
96
120
|
|
|
97
|
-
async function
|
|
98
|
-
folder: string,
|
|
99
|
-
currentPageNumber: string
|
|
100
|
-
): Promise<string> {
|
|
101
|
-
return path.join(folder, `scanPage${currentPageNumber}.jpg`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function saveScan(event: Event): Promise<void> {
|
|
105
|
-
let shortcut = "";
|
|
106
|
-
let contentType = "";
|
|
121
|
+
async function TryGetDestination(event: Event) {
|
|
107
122
|
//this code can in some cases be executed before the user actually chooses between Document or Photo
|
|
108
123
|
//so lets fetch the contentType (Document or Photo) until we get a value
|
|
109
|
-
let
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
let destination: WalkupScanDestination | WalkupScanToCompDestination | null =
|
|
125
|
+
null;
|
|
126
|
+
|
|
127
|
+
for (let i = 0; i < 20; i++) {
|
|
128
|
+
const destinationURI = event.destinationURI;
|
|
129
|
+
if (destinationURI) {
|
|
130
|
+
destination = await HPApi.getDestination(destinationURI);
|
|
131
|
+
|
|
132
|
+
const shortcut = destination.shortcut;
|
|
133
|
+
if (shortcut !== "") {
|
|
134
|
+
return destination;
|
|
135
|
+
}
|
|
116
136
|
} else {
|
|
117
|
-
|
|
118
|
-
i += 1;
|
|
119
|
-
if (i > 20) {
|
|
120
|
-
return;
|
|
121
|
-
} //prevent endless loop
|
|
137
|
+
console.log(`No destination URI found`);
|
|
122
138
|
}
|
|
139
|
+
|
|
140
|
+
console.log(`No shortcut yet available, attempt: ${i + 1}/20`);
|
|
141
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); //wait 1s
|
|
123
142
|
}
|
|
124
143
|
|
|
125
|
-
|
|
126
|
-
console.log(
|
|
144
|
+
console.log("Failing to detect destination shortcut");
|
|
145
|
+
console.log(JSON.stringify(destination));
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
127
148
|
|
|
128
|
-
|
|
149
|
+
async function fixJpegSize(filePath: string): Promise<number | null> {
|
|
150
|
+
const buffer: Buffer = await fs.readFile(filePath);
|
|
129
151
|
|
|
130
|
-
let
|
|
152
|
+
let height = JpegUtil.fixSizeWithDNL(buffer);
|
|
153
|
+
if (height != null) {
|
|
154
|
+
// rewrite the fixed file
|
|
155
|
+
await fs.writeFile(filePath, buffer);
|
|
156
|
+
return height;
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function createScanPage(
|
|
162
|
+
job: Job,
|
|
163
|
+
currentPageNumber: number,
|
|
164
|
+
filePath: string,
|
|
165
|
+
sizeFixed: number | null
|
|
166
|
+
): ScanPage {
|
|
167
|
+
let height = sizeFixed ?? job.imageHeight;
|
|
168
|
+
return {
|
|
169
|
+
path: filePath,
|
|
170
|
+
pageNumber: currentPageNumber,
|
|
171
|
+
width: job.imageWidth,
|
|
172
|
+
height,
|
|
173
|
+
xResolution: job.xResolution,
|
|
174
|
+
yResolution: job.yResolution,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function handleProcessingState(
|
|
179
|
+
job: Job,
|
|
180
|
+
inputSource: "Adf" | "Platen",
|
|
181
|
+
folder: string,
|
|
182
|
+
scanCount: number,
|
|
183
|
+
currentPageNumber: number
|
|
184
|
+
): Promise<ScanPage | null> {
|
|
185
|
+
if (
|
|
186
|
+
job.pageState == "ReadyToUpload" &&
|
|
187
|
+
job.binaryURL != null &&
|
|
188
|
+
job.currentPageNumber != null
|
|
189
|
+
) {
|
|
190
|
+
console.log(
|
|
191
|
+
`Ready to download page job page ${job.currentPageNumber} at:`,
|
|
192
|
+
job.binaryURL
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const destinationFilePath = PathHelper.getFileForPage(
|
|
196
|
+
folder,
|
|
197
|
+
scanCount,
|
|
198
|
+
currentPageNumber,
|
|
199
|
+
program.opts().pattern,
|
|
200
|
+
"jpg"
|
|
201
|
+
);
|
|
202
|
+
const filePath = await HPApi.downloadPage(
|
|
203
|
+
job.binaryURL,
|
|
204
|
+
destinationFilePath
|
|
205
|
+
);
|
|
206
|
+
console.log("Page downloaded to:", filePath);
|
|
207
|
+
|
|
208
|
+
let sizeFixed: null | number = null;
|
|
209
|
+
if (inputSource == "Adf") {
|
|
210
|
+
sizeFixed = await fixJpegSize(filePath);
|
|
211
|
+
if (sizeFixed == null) {
|
|
212
|
+
console.log(
|
|
213
|
+
`File size has not been fixed, DNF may not have been found and approximate height is: ${job.imageHeight}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return createScanPage(job, currentPageNumber, filePath, sizeFixed);
|
|
218
|
+
} else {
|
|
219
|
+
console.log(`Unknown pageState: ${job.pageState}`);
|
|
220
|
+
await delay(200);
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function waitScanRequest(compEventURI: string): Promise<boolean> {
|
|
226
|
+
const waitMax = 50;
|
|
227
|
+
for (let i = 0; i < waitMax; i++) {
|
|
228
|
+
let walkupScanToCompEvent = await HPApi.getWalkupScanToCompEvent(
|
|
229
|
+
compEventURI
|
|
230
|
+
);
|
|
231
|
+
let message = walkupScanToCompEvent.eventType;
|
|
232
|
+
if (message === "HostSelected") {
|
|
233
|
+
// this ok to wait
|
|
234
|
+
} else if (message === "ScanRequested") {
|
|
235
|
+
break;
|
|
236
|
+
} else if (message === "ScanNewPageRequested") {
|
|
237
|
+
break;
|
|
238
|
+
} else if (message === "ScanPagesComplete") {
|
|
239
|
+
console.log("no more page to scan, scan is finished");
|
|
240
|
+
return false;
|
|
241
|
+
} else {
|
|
242
|
+
console.log(`Unknown eventType: ${message}`);
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
console.log(`Waiting user input: ${i + 1}/${waitMax}`);
|
|
247
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); //wait 1s
|
|
248
|
+
}
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function executeScanJob(
|
|
253
|
+
scanJobSettings: ScanJobSettings,
|
|
254
|
+
inputSource: "Adf" | "Platen",
|
|
255
|
+
folder: string,
|
|
256
|
+
scanCount: number,
|
|
257
|
+
scanJobContent: ScanContent
|
|
258
|
+
) {
|
|
131
259
|
const jobUrl = await HPApi.postJob(scanJobSettings);
|
|
132
260
|
|
|
133
261
|
console.log("New job created:", jobUrl);
|
|
@@ -141,56 +269,219 @@ async function saveScan(event: Event): Promise<void> {
|
|
|
141
269
|
}
|
|
142
270
|
|
|
143
271
|
if (job.jobState === "Processing") {
|
|
144
|
-
|
|
145
|
-
job
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
const folder = await util.promisify(fs.mkdtemp)(
|
|
155
|
-
path.join(os.tmpdir(), "scan-to-pc")
|
|
156
|
-
);
|
|
157
|
-
console.log(`Target folder: ${folder}`);
|
|
158
|
-
|
|
159
|
-
const destinationFilePath = await getNextFile(
|
|
160
|
-
folder,
|
|
161
|
-
job.currentPageNumber
|
|
162
|
-
);
|
|
163
|
-
const filePath = await HPApi.downloadPage(
|
|
164
|
-
job.binaryURL,
|
|
165
|
-
destinationFilePath
|
|
166
|
-
);
|
|
167
|
-
console.log("Page downloaded to:", filePath);
|
|
168
|
-
} else {
|
|
169
|
-
console.log(`Unknown pageState: ${job.pageState}`);
|
|
170
|
-
await delay(200);
|
|
272
|
+
const page = await handleProcessingState(
|
|
273
|
+
job,
|
|
274
|
+
inputSource,
|
|
275
|
+
folder,
|
|
276
|
+
scanCount,
|
|
277
|
+
scanJobContent.elements.length + 1
|
|
278
|
+
);
|
|
279
|
+
if (page != null) {
|
|
280
|
+
scanJobContent.elements.push(page);
|
|
171
281
|
}
|
|
282
|
+
} else if (job.jobState === "Canceled") {
|
|
283
|
+
console.log("Job cancelled by device");
|
|
284
|
+
break;
|
|
172
285
|
} else {
|
|
173
|
-
console.log(`
|
|
286
|
+
console.log(`Unhandled jobState: ${job.jobState}`);
|
|
174
287
|
await delay(200);
|
|
175
288
|
}
|
|
176
289
|
}
|
|
177
|
-
console.log(
|
|
290
|
+
console.log(
|
|
291
|
+
`Job state: ${job.jobState}, totalPages: ${job.totalPageNumber}:`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async function waitScanNewPageRequest(compEventURI: string): Promise<boolean> {
|
|
296
|
+
let startNewScanJob = false;
|
|
297
|
+
let wait = true;
|
|
298
|
+
while (wait) {
|
|
299
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); //wait 1s
|
|
300
|
+
|
|
301
|
+
let walkupScanToCompEvent = await HPApi.getWalkupScanToCompEvent(
|
|
302
|
+
compEventURI
|
|
303
|
+
);
|
|
304
|
+
let message = walkupScanToCompEvent.eventType;
|
|
305
|
+
|
|
306
|
+
if (message === "ScanNewPageRequested") {
|
|
307
|
+
startNewScanJob = true;
|
|
308
|
+
wait = false;
|
|
309
|
+
} else if (message === "ScanPagesComplete") {
|
|
310
|
+
wait = false;
|
|
311
|
+
} else if (message === "ScanRequested") {
|
|
312
|
+
// continue waiting
|
|
313
|
+
} else {
|
|
314
|
+
wait = false;
|
|
315
|
+
console.log(`Unknown eventType: ${message}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return startNewScanJob;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async function executeScanJobs(
|
|
322
|
+
scanJobSettings: ScanJobSettings,
|
|
323
|
+
inputSource: "Adf" | "Platen",
|
|
324
|
+
folder: string,
|
|
325
|
+
scanCount: number,
|
|
326
|
+
scanJobContent: ScanContent,
|
|
327
|
+
firstEvent: Event
|
|
328
|
+
) {
|
|
329
|
+
await executeScanJob(
|
|
330
|
+
scanJobSettings,
|
|
331
|
+
inputSource,
|
|
332
|
+
folder,
|
|
333
|
+
scanCount,
|
|
334
|
+
scanJobContent
|
|
335
|
+
);
|
|
336
|
+
let lastEvent = firstEvent;
|
|
337
|
+
if (
|
|
338
|
+
lastEvent.compEventURI &&
|
|
339
|
+
inputSource !== "Adf" &&
|
|
340
|
+
lastEvent.destinationURI
|
|
341
|
+
) {
|
|
342
|
+
lastEvent = await waitForScanEvent(
|
|
343
|
+
lastEvent.destinationURI,
|
|
344
|
+
lastEvent.agingStamp
|
|
345
|
+
);
|
|
346
|
+
if (!lastEvent.compEventURI) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
let startNewScanJob = await waitScanNewPageRequest(lastEvent.compEventURI);
|
|
350
|
+
while (startNewScanJob) {
|
|
351
|
+
await executeScanJob(
|
|
352
|
+
scanJobSettings,
|
|
353
|
+
inputSource,
|
|
354
|
+
folder,
|
|
355
|
+
scanCount,
|
|
356
|
+
scanJobContent
|
|
357
|
+
);
|
|
358
|
+
if (!lastEvent.destinationURI) {
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
lastEvent = await waitForScanEvent(
|
|
362
|
+
lastEvent.destinationURI,
|
|
363
|
+
lastEvent.agingStamp
|
|
364
|
+
);
|
|
365
|
+
if (!lastEvent.compEventURI) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
startNewScanJob = await waitScanNewPageRequest(lastEvent.compEventURI);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async function mergeToPdf(folder: string, scanCount: number, scanJobContent: ScanContent) {
|
|
374
|
+
const pdfFilePath = PathHelper.getFileForScan(
|
|
375
|
+
folder,
|
|
376
|
+
scanCount,
|
|
377
|
+
program.opts().pattern,
|
|
378
|
+
"pdf"
|
|
379
|
+
);
|
|
380
|
+
await createPdfFrom(scanJobContent, pdfFilePath);
|
|
381
|
+
scanJobContent.elements.forEach((e) => fs.unlink(e.path));
|
|
382
|
+
return pdfFilePath;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function displayPdfScan(pdfFilePath: string, scanJobContent: ScanContent) {
|
|
386
|
+
console.log(
|
|
387
|
+
`The following page(s) have been rendered inside '${pdfFilePath}': `
|
|
388
|
+
);
|
|
389
|
+
scanJobContent.elements.forEach((e) =>
|
|
390
|
+
console.log(
|
|
391
|
+
`\t- page ${e.pageNumber.toString().padStart(3, " ")} - ${e.width}x${
|
|
392
|
+
e.height
|
|
393
|
+
}`
|
|
394
|
+
)
|
|
395
|
+
);
|
|
178
396
|
}
|
|
179
397
|
|
|
398
|
+
function displayJpegScan(scanJobContent: ScanContent) {
|
|
399
|
+
scanJobContent.elements.forEach((e) =>
|
|
400
|
+
console.log(
|
|
401
|
+
`\t- page ${e.pageNumber.toString().padStart(3, " ")} - ${e.width}x${
|
|
402
|
+
e.height
|
|
403
|
+
} - ${e.path}`
|
|
404
|
+
)
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async function saveScan(
|
|
409
|
+
event: Event,
|
|
410
|
+
folder: string,
|
|
411
|
+
scanCount: number
|
|
412
|
+
): Promise<void> {
|
|
413
|
+
if (event.compEventURI) {
|
|
414
|
+
const proceedToScan = await waitScanRequest(event.compEventURI);
|
|
415
|
+
if (!proceedToScan) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const destination = await TryGetDestination(event);
|
|
421
|
+
if (!destination) {
|
|
422
|
+
console.log("No shortcut selected!");
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
console.log("Selected shortcut: " + destination.shortcut);
|
|
426
|
+
|
|
427
|
+
const contentType = destination.getContentType();
|
|
428
|
+
const toPdf =
|
|
429
|
+
destination.shortcut === "SavePDF" || destination.shortcut === "EmailPDF";
|
|
430
|
+
|
|
431
|
+
const scanStatus = await HPApi.getScanStatus();
|
|
432
|
+
console.log("Afd is : " + scanStatus.adfState);
|
|
433
|
+
|
|
434
|
+
let inputSource = scanStatus.getInputSource();
|
|
435
|
+
|
|
436
|
+
let scanJobSettings = new ScanJobSettings(inputSource, contentType);
|
|
437
|
+
|
|
438
|
+
let scanJobContent: ScanContent = { elements: [] };
|
|
439
|
+
|
|
440
|
+
await executeScanJobs(
|
|
441
|
+
scanJobSettings,
|
|
442
|
+
inputSource,
|
|
443
|
+
folder,
|
|
444
|
+
scanCount,
|
|
445
|
+
scanJobContent,
|
|
446
|
+
event
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
console.log(
|
|
450
|
+
`Scan of page(s) completed totalPages: ${scanJobContent.elements.length}:`
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
if (toPdf) {
|
|
454
|
+
const pdfFilePath = await mergeToPdf(folder, scanCount, scanJobContent);
|
|
455
|
+
displayPdfScan(pdfFilePath, scanJobContent);
|
|
456
|
+
} else {
|
|
457
|
+
displayJpegScan(scanJobContent);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
let iteration = 0;
|
|
180
462
|
async function init() {
|
|
463
|
+
const folder = await PathHelper.getOutputFolder(program.opts().directory);
|
|
464
|
+
console.log(`Target folder: ${folder}`);
|
|
465
|
+
|
|
466
|
+
let scanCount = 0;
|
|
467
|
+
|
|
181
468
|
let keepActive = true;
|
|
182
469
|
let errorCount = 0;
|
|
183
470
|
while (keepActive) {
|
|
471
|
+
console.log(`Running iteration: ${iteration} - errorCount: ${errorCount}`);
|
|
184
472
|
try {
|
|
185
473
|
let resourceURI = await register();
|
|
186
474
|
|
|
187
475
|
console.log("Waiting scan event for:", resourceURI);
|
|
188
476
|
const event = await waitForScanEvent(resourceURI);
|
|
189
|
-
|
|
190
|
-
|
|
477
|
+
|
|
478
|
+
scanCount++;
|
|
479
|
+
console.log(`Scan event captured, saving scan #${scanCount}`);
|
|
480
|
+
await saveScan(event, folder, scanCount);
|
|
191
481
|
} catch (e) {
|
|
192
482
|
errorCount++;
|
|
193
483
|
console.error(e);
|
|
484
|
+
console.log(e);
|
|
194
485
|
}
|
|
195
486
|
|
|
196
487
|
if (errorCount === 50) {
|
|
@@ -201,10 +492,6 @@ async function init() {
|
|
|
201
492
|
}
|
|
202
493
|
}
|
|
203
494
|
|
|
204
|
-
interface OfficeJetBonjourService extends Service {
|
|
205
|
-
addresses?: string[];
|
|
206
|
-
}
|
|
207
|
-
|
|
208
495
|
function findOfficejetIp(): Promise<string> {
|
|
209
496
|
return new Promise((resolve) => {
|
|
210
497
|
const bonjour = Bonjour();
|
|
@@ -213,10 +500,10 @@ function findOfficejetIp(): Promise<string> {
|
|
|
213
500
|
{
|
|
214
501
|
type: "http",
|
|
215
502
|
},
|
|
216
|
-
(service
|
|
503
|
+
(service) => {
|
|
217
504
|
console.log(".");
|
|
218
505
|
if (
|
|
219
|
-
service.name.startsWith(
|
|
506
|
+
service.name.startsWith(program.opts().name) &&
|
|
220
507
|
service.port === 80 &&
|
|
221
508
|
service.type === "http" &&
|
|
222
509
|
service.addresses != null
|
|
@@ -233,7 +520,34 @@ function findOfficejetIp(): Promise<string> {
|
|
|
233
520
|
}
|
|
234
521
|
|
|
235
522
|
async function main() {
|
|
236
|
-
|
|
523
|
+
program.option(
|
|
524
|
+
"-ip, --address <ip>",
|
|
525
|
+
"IP address of the printer (this overrides -p)"
|
|
526
|
+
);
|
|
527
|
+
program.option(
|
|
528
|
+
"-n, --name <name>",
|
|
529
|
+
"Name of the printer for service discovery",
|
|
530
|
+
"HP Smart Tank Plus 570 series"
|
|
531
|
+
); //or i.e. 'Deskjet 3520 series'
|
|
532
|
+
program.option(
|
|
533
|
+
"-d, --directory <dir>",
|
|
534
|
+
"Directory where scans are saved (defaults to /tmp/scan-to-pc<random>)"
|
|
535
|
+
);
|
|
536
|
+
program.option(
|
|
537
|
+
"-p, --pattern <pattern>",
|
|
538
|
+
'Pattern for filename (i.e. "scan"_dd.mm.yyyy_hh:MM:ss, without this its scanPage<number>)'
|
|
539
|
+
);
|
|
540
|
+
program.option("-D, --debug", "Enable debug");
|
|
541
|
+
program.parse(process.argv);
|
|
542
|
+
|
|
543
|
+
let ip = program.opts().address || "192.168.1.53";
|
|
544
|
+
if (!ip) {
|
|
545
|
+
ip = await findOfficejetIp();
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const debug = program.opts().debug != null;
|
|
549
|
+
|
|
550
|
+
HPApi.setDebug(debug);
|
|
237
551
|
HPApi.setPrinterIP(ip);
|
|
238
552
|
await init();
|
|
239
553
|
}
|