node-hp-scan-to 1.5.1 → 1.6.1

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 CHANGED
@@ -26,6 +26,7 @@ Additionally, it has been reported to work on several other HP printer models.
26
26
  - HP DeskJet 3775 All-in-One
27
27
  - HP DeskJet 4670 All-in-One
28
28
  - HP DeskJet 5525
29
+ - HP Envy 4504 All-in-One
29
30
  - HP OfficeJet 3830
30
31
  - HP OfficeJet 5230
31
32
  - HP OfficeJet 5740
@@ -33,6 +34,7 @@ Additionally, it has been reported to work on several other HP printer models.
33
34
  - HP OfficeJet 6950
34
35
  - HP OfficeJet 8010 series
35
36
  - HP OfficeJet 8012
37
+ - HP OfficeJet 8014
36
38
  - HP OfficeJet Pro 7720 Wide Format All-in-One
37
39
  - HP OfficeJet Pro 8025e
38
40
  - HP OfficeJet Pro 9012e
@@ -57,7 +59,7 @@ Please note that the `node-hp-scan-to` project is not endorsed by nor affiliated
57
59
  - ✔️ Customizable resolution
58
60
  - ✔️ Customizable label on the device
59
61
  - ✔️ Multi platform: Linux, Windows and most probably macOS
60
- - ✔️ Folder target or paperless-ngx api upload
62
+ - ✔️ Mutile target supported: folder, [paperless-ngx](https://docs.paperless-ngx.com/) api upload, nextcloud webdav upload
61
63
  - ✔️ Clear all registered target
62
64
  - ✔️ Automatic scan when automatic document feeder is getting loaded
63
65
 
@@ -77,7 +79,13 @@ Please note that the `node-hp-scan-to` project is not endorsed by nor affiliated
77
79
  - `-w` or `--width` followed by an integer, the with in pixel of the scans (default: 2481)
78
80
  - `-h` or `--height` followed by an integer, the height in pixel of the scans (default: 3507)
79
81
  - `-s` or `--paperless-post-document-url` followed by the paperless post document url (example: https://domain.tld/api/documents/post_document/)
80
- - `k` or `--paperless-token` followed by te paperless-ngx api token
82
+ - `-o` or `--paperless-token` followed by te paperless-ngx api token
83
+ - `--nextcloud-url` followed by the nextcloud url (example: https://domain.tld)
84
+ - `--nextcloud-username` followed by the nextcloud username, must have write access to the upload folder
85
+ - `--nextcloud-password` followed by the nextcloud app password for the username. Either this or `nextcloud-password-file` is required. If both are provided, `nextcloud-password-file` is used.
86
+ - `--nextcloud-password-file` File name that contains the nextcloud app password for the username. Either this or `nextcloud-password` is required. If both are provided, `nextcloud-password-file` is used.
87
+ - `--nextcloud-upload-folder` followed by the upload folder where documents or images are uploaded (default: scan)
88
+ - `-k` or `--keep-files`: if set the scanned files will not be deleted, after uploading to paperless-ngx or nextcloud
81
89
  - `-D, --debug"` enables debug logs.
82
90
 
83
91
  #### `listen command`
@@ -122,6 +130,12 @@ Exhaustive list of supported environment variables and their meaning, or corresp
122
130
  - `RESOLUTION`: command-line flag `-r`/`--resolution`
123
131
  - `PAPERLESS_POST_DOCUMENT_URL`: the paperless post document url (if provided with token, a pdf is uploaded to paperless-ngx) for example: `PAPERLESS_POST_DOCUMENT_URL= "http://<paperless-host>:<port>/api/documents/post_document/"`
124
132
  - `PAPERLESS_TOKEN`: the paperless api token for example: `PAPERLESS_TOKEN= "xxxxxxxxxxxx..."`
133
+ - `NEXTCLOUD_URL`: the nextcloud URL, for example `https://nextcloud.example.tld`
134
+ - `NEXTCLOUD_UPLOAD_FOLDER`: upload folder where documents or images are uploaded. User must have write permission on this folder. If not provided, `scan` is used
135
+ - `NEXTCLOUD_USERNAME`: nextcloud user name
136
+ - `NEXTCLOUD_PASSWORD`: password of nextcloud user. Either this or `NEXTCLOUD_PASSWORD_FILE` is required. If both are provided, value of `NEXTCLOUD_PASSWORD_FILE` is used.
137
+ - `NEXTCLOUD_PASSWORD_FILE`: file name containing password of nextcloud user. Either this or `NEXTCLOUD_PASSWORD` is required. If both are provided, this value is used. For example: `NEXTCLOUD_PASSWORD_FILE=./nextcloud_password.secret`. Preferably for use in [docker compose secrets](https://docs.docker.com/reference/compose-file/secrets/)
138
+ - `$KEEP_FILES`: if set the scanned files will not be deleted, after uploading to paperless-ngx or nextcloud
125
139
  - `CMDLINE`: additional command-line flags that will be put at the end of the command.
126
140
 
127
141
  __To enable debug logs set the environment variable `CMDLINE` to `-D`.__
@@ -1,3 +1,3 @@
1
1
  {
2
- "commitId": "4969a0a867d8fb962cb5dab54adab12b7fadbb93"
2
+ "commitId": "691a0d2906379ed370b16a4d804bff34ca6ecf10"
3
3
  }
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ const listening_1 = require("./listening");
40
40
  const scanProcessing_1 = require("./scanProcessing");
41
41
  const commitInfo = __importStar(require("./commitInfo.json"));
42
42
  const healthcheck_1 = require("./healthcheck");
43
+ const fs_1 = __importDefault(require("fs"));
43
44
  let iteration = 0;
44
45
  async function listenCmd(registrationConfig, scanConfig, deviceUpPollingInterval) {
45
46
  // first make sure the device is reachable
@@ -169,7 +170,12 @@ function setupScanParameters(command) {
169
170
  command.option("-o, --paperless-token <paperless_token>", "The paperless token");
170
171
  command.option("--paperless-group-multi-page-scan-into-a-pdf", "Combine multiple scanned images into a single PDF document");
171
172
  command.option("--paperless-always-send-as-pdf-file", "Always convert scan job to pdf before sending to paperless");
172
- command.option("-k, --paperless-keep-files", "Keep the scan files on the file system (default: false)");
173
+ command.option("-k, --keep-files", "Keep the scan files on the file system (default: false)");
174
+ command.option("--nextcloud-url <nextcloud_url>", "The nextcloud url (example: https://domain.tld)");
175
+ command.option("--nextcloud-username <nextcloud_username>", "The nextcloud username");
176
+ command.option("--nextcloud-password <nextcloud_app_password>", "The nextcloud app password for username. Either this or nextcloud-password-file is required");
177
+ command.option("--nextcloud-password-file <nextcloud_app_password_file>", "File name that contains the nextcloud app password for username. Either this or nextcloud-password is required");
178
+ command.option("--nextcloud-upload-folder <nextcloud_upload_folder>", "The upload folder where documents or images are uploaded (default: scan)");
173
179
  return command;
174
180
  }
175
181
  function setupParameterOpts(command) {
@@ -199,13 +205,8 @@ function getPaperlessConfig(parentOption) {
199
205
  const paperlessPostDocumentUrl = parentOption.paperlessPostDocumentUrl ||
200
206
  getConfig("paperless_post_document_url");
201
207
  const configPaperlessToken = parentOption.paperlessToken || getConfig("paperless_token");
202
- const configPaperlessKeepFiles = parentOption.paperlessKeepFiles ||
203
- getConfig("paperless_keep_files") ||
204
- false;
205
208
  if (paperlessPostDocumentUrl && configPaperlessToken) {
206
- const configPaperlessKeepFiles = parentOption.paperlessKeepFiles ||
207
- getConfig("paperless_keep_files") ||
208
- false;
209
+ const configPaperlessKeepFiles = parentOption.keepFiles || getConfig("keep_files") || false;
209
210
  const groupMultiPageScanIntoAPdf = parentOption.paperlessGroupMultiPageScanIntoAPdf ||
210
211
  getConfig("paperless_group_multi_page_scan_into_a_pdf") ||
211
212
  false;
@@ -225,6 +226,36 @@ function getPaperlessConfig(parentOption) {
225
226
  return undefined;
226
227
  }
227
228
  }
229
+ function getNextcloudConfig(parentOption) {
230
+ const configNextcloudUrl = parentOption.nextcloudUrl || getConfig("nextcloud_url");
231
+ const configNextcloudUsername = parentOption.nextcloudUsername || getConfig("nextcloud_username");
232
+ let configNextcloudPassword = parentOption.nextcloudPassword || getConfig("nextcloud_password");
233
+ const configNextcloudPasswordFile = parentOption.nextcloudPasswordFile || getConfig("nextcloud_password_file");
234
+ if (configNextcloudUrl &&
235
+ configNextcloudUsername &&
236
+ (configNextcloudPassword || configNextcloudPasswordFile)) {
237
+ const configNextcloudUploadFolder = parentOption.nextcloudUploadFolder ||
238
+ getConfig("nextcloud_upload_folder") ||
239
+ "scan";
240
+ const configNextcloudKeepFiles = parentOption.keepFiles || getConfig("keep_files") || false;
241
+ if (configNextcloudPasswordFile) {
242
+ configNextcloudPassword = fs_1.default
243
+ .readFileSync(configNextcloudPasswordFile, "utf8")
244
+ .trimEnd();
245
+ }
246
+ console.log(`Nextcloud configuration provided, url: ${configNextcloudUrl}, username: ${configNextcloudUsername}, password length: ${configNextcloudPassword.length}, upload folder: ${configNextcloudUploadFolder}, keepFiles: ${configNextcloudKeepFiles}`);
247
+ return {
248
+ baseUrl: configNextcloudUrl,
249
+ username: configNextcloudUsername,
250
+ password: configNextcloudPassword,
251
+ uploadFolder: configNextcloudUploadFolder,
252
+ keepFiles: configNextcloudKeepFiles,
253
+ };
254
+ }
255
+ else {
256
+ return undefined;
257
+ }
258
+ }
228
259
  function getHealthCheckSetting(option) {
229
260
  const healthCheckEnabled = option.healthCheck || getConfig("enableHealthCheck") === true;
230
261
  let healthCheckPort;
@@ -254,12 +285,14 @@ function getScanConfiguration(option) {
254
285
  ? Number.MAX_SAFE_INTEGER
255
286
  : parseInt(configHeight, 10);
256
287
  const paperlessConfig = getPaperlessConfig(option);
288
+ const nextcloudConfig = getNextcloudConfig(option);
257
289
  const scanConfig = {
258
290
  resolution: parseInt(option.resolution || getConfig("resolution") || "200", 10),
259
291
  width: width,
260
292
  height: height,
261
293
  directoryConfig,
262
294
  paperlessConfig,
295
+ nextcloudConfig,
263
296
  };
264
297
  return scanConfig;
265
298
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// noinspection XmlDeprecatedElement,HtmlDeprecatedTag\n\n\"use strict\";\n\nimport os from \"os\";\nimport { Command, Option, OptionValues, program } from \"commander\";\nimport { Bonjour } from \"bonjour-service\";\nimport config from \"config\";\nimport HPApi from \"./HPApi\";\nimport PathHelper from \"./PathHelper\";\nimport { delay } from \"./delay\";\nimport { readDeviceCapabilities } from \"./readDeviceCapabilities\";\nimport {\n clearRegistrations,\n RegistrationConfig,\n waitScanEvent,\n} from \"./listening\";\nimport {\n AdfAutoScanConfig,\n DirectoryConfig,\n saveScanFromEvent,\n ScanConfig,\n scanFromAdf,\n waitAdfLoaded,\n} from \"./scanProcessing\";\nimport * as commitInfo from \"./commitInfo.json\";\nimport { PaperlessConfig } from \"./paperless/PaperlessConfig\";\nimport { startHealthCheckServer } from \"./healthcheck\";\n\n\nlet iteration = 0;\n\nasync function listenCmd(\n registrationConfig: RegistrationConfig,\n scanConfig: ScanConfig,\n deviceUpPollingInterval: number,\n) {\n // first make sure the device is reachable\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n let deviceUp = true;\n\n const folder = await PathHelper.getOutputFolder(\n scanConfig.directoryConfig.directory,\n );\n console.log(`Target folder: ${folder}`);\n\n const tempFolder = await PathHelper.getOutputFolder(\n scanConfig.directoryConfig.tempDirectory,\n );\n console.log(`Temp folder: ${tempFolder}`);\n\n const deviceCapabilities = await readDeviceCapabilities();\n\n let scanCount = 0;\n let keepActive = true;\n let errorCount = 0;\n while (keepActive) {\n iteration++;\n console.log(`Running iteration: ${iteration} - errorCount: ${errorCount}`);\n try {\n const event = await waitScanEvent(deviceCapabilities, registrationConfig);\n scanCount = await PathHelper.getNextScanNumber(\n folder,\n scanCount,\n scanConfig.directoryConfig.filePattern,\n );\n console.log(`Scan event captured, saving scan #${scanCount}`);\n await saveScanFromEvent(\n event,\n folder,\n tempFolder,\n scanCount,\n deviceCapabilities,\n scanConfig,\n );\n } catch (e) {\n if (await HPApi.isAlive()) {\n console.log(e);\n errorCount++;\n } else {\n if (HPApi.isDebug()) {\n console.log(e);\n }\n deviceUp = false;\n }\n }\n\n if (errorCount === 50) {\n keepActive = false;\n }\n\n if (!deviceUp) {\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n } else {\n await delay(1000);\n }\n }\n}\n\nasync function adfAutoscanCmd(\n adfAutoScanConfig: AdfAutoScanConfig,\n deviceUpPollingInterval: number,\n) {\n // first make sure the device is reachable\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n let deviceUp = true;\n\n const folder = await PathHelper.getOutputFolder(\n adfAutoScanConfig.directoryConfig.directory,\n );\n console.log(`Target folder: ${folder}`);\n\n const tempFolder = await PathHelper.getOutputFolder(\n adfAutoScanConfig.directoryConfig.tempDirectory,\n );\n console.log(`Temp folder: ${tempFolder}`);\n\n const deviceCapabilities = await readDeviceCapabilities();\n\n let scanCount = 0;\n let keepActive = true;\n let errorCount = 0;\n while (keepActive) {\n iteration++;\n console.log(`Running iteration: ${iteration} - errorCount: ${errorCount}`);\n try {\n await waitAdfLoaded(\n adfAutoScanConfig.pollingInterval,\n adfAutoScanConfig.startScanDelay,\n );\n\n scanCount++;\n\n console.log(`Scan event captured, saving scan #${scanCount}`);\n\n await scanFromAdf(\n scanCount,\n folder,\n tempFolder,\n adfAutoScanConfig,\n deviceCapabilities,\n new Date(),\n );\n } catch (e) {\n console.log(e);\n if (await HPApi.isAlive()) {\n errorCount++;\n } else {\n deviceUp = false;\n }\n }\n\n if (errorCount === 50) {\n keepActive = false;\n }\n\n if (!deviceUp) {\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n } else {\n await delay(1000);\n }\n }\n}\n\nasync function clearRegistrationsCmd(cmd: Command) {\n const parentOption = cmd.parent!.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n await clearRegistrations();\n}\n\nfunction findOfficejetIp(deviceNamePrefix: string): Promise<string> {\n return new Promise((resolve) => {\n const bonjour = new Bonjour();\n console.log(\"Searching device...\");\n const browser = bonjour.find(\n {\n type: \"http\",\n },\n (service) => {\n console.log(\".\");\n if (\n service.name.startsWith(deviceNamePrefix) &&\n service.port === 80 &&\n service.type === \"http\" &&\n service.addresses != null\n ) {\n browser.stop();\n bonjour.destroy();\n console.log(`Found: ${service.name}`);\n resolve(service.addresses[0]);\n }\n },\n );\n browser.start();\n });\n}\n\nfunction getConfig<T>(name: string): T | undefined {\n return config.has(name) ? config.get<T>(name) : undefined;\n}\n\nfunction setupScanParameters(command: Command): Command {\n command.option(\n \"-d, --directory <dir>\",\n \"Directory where scans are saved (default: /tmp/scan-to-pcRANDOM)\",\n );\n command.option(\n \"-t, --temp-directory <dir>\",\n \"Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)\",\n );\n command.option(\n \"-p, --pattern <pattern>\",\n 'Pattern for filename (i.e. \"scan\"_dd.mm.yyyy_hh:MM:ss, without this its scanPageNUMBER)',\n );\n command.option(\n \"-r, --resolution <dpi>\",\n \"Resolution in DPI of the scans (default: 200)\",\n );\n command.option(\n \"-w, --width <width>\",\n \"With in pixel of the scans (default: 2481)\",\n );\n command.option(\n \"-h, --height <height>\",\n \"Height in pixel of the scans (default: 3507)\",\n );\n command.option(\n \"-s, --paperless-post-document-url <paperless_post_document_url>\",\n \"The paperless post document url (example: https://domain.tld/api/documents/post_document/)\",\n );\n\n command.option(\n \"-o, --paperless-token <paperless_token>\",\n \"The paperless token\",\n );\n command.option(\n \"--paperless-group-multi-page-scan-into-a-pdf\",\n \"Combine multiple scanned images into a single PDF document\",\n );\n command.option(\n \"--paperless-always-send-as-pdf-file\",\n \"Always convert scan job to pdf before sending to paperless\",\n );\n command.option(\n \"-k, --paperless-keep-files\",\n \"Keep the scan files on the file system (default: false)\",\n );\n return command;\n}\n\nfunction setupParameterOpts(command: Command): Command {\n command.option(\n \"-a, --address <ip>\",\n \"IP address of the device (this overrides -p)\",\n );\n command.option(\n \"--device-up-polling-interval <deviceUpPollingInterval>\",\n \"Device up polling interval in milliseconds\",\n parseFloat,\n );\n command.option(\n \"-n, --name <name>\",\n \"Name of the device for service discovery\",\n ); // i.e. 'Deskjet 3520 series'\n\n command.option(\"-D, --debug\", \"Enable debug\");\n return command;\n}\n\nasync function getDeviceIp(options: OptionValues) {\n let ip = options.address || getConfig(\"ip\");\n if (!ip) {\n const name = options.name || getConfig(\"name\");\n ip = await findOfficejetIp(name || \"HP Smart Tank Plus 570 series\");\n }\n console.log(`Using device ip: ${ip}`);\n return ip;\n}\n\nfunction getIsDebug(options: OptionValues) {\n const debug =\n options.debug != null ? true : getConfig<boolean>(\"debug\") || false;\n\n if (debug) {\n console.log(`IsDebug: ${debug}`);\n }\n return debug;\n}\n\nfunction getPaperlessConfig(\n parentOption: OptionValues,\n): PaperlessConfig | undefined {\n const paperlessPostDocumentUrl: string =\n parentOption.paperlessPostDocumentUrl ||\n getConfig(\"paperless_post_document_url\");\n const configPaperlessToken: string =\n parentOption.paperlessToken || getConfig(\"paperless_token\");\n const configPaperlessKeepFiles =\n parentOption.paperlessKeepFiles ||\n getConfig(\"paperless_keep_files\") ||\n false;\n\n if (paperlessPostDocumentUrl && configPaperlessToken) {\n const configPaperlessKeepFiles: boolean =\n parentOption.paperlessKeepFiles ||\n getConfig(\"paperless_keep_files\") ||\n false;\n const groupMultiPageScanIntoAPdf: boolean =\n parentOption.paperlessGroupMultiPageScanIntoAPdf ||\n getConfig(\"paperless_group_multi_page_scan_into_a_pdf\") ||\n false;\n const alwaysSendAsPdfFile: boolean =\n parentOption.paperlessAlwaysSendAsPdfFile ||\n getConfig(\"paperless_always_send_as_pdf_file\") ||\n false;\n\n console.log(\n `Paperless configuration provided, post document url: ${paperlessPostDocumentUrl}, the token length: ${configPaperlessToken.length}, keepFiles: ${configPaperlessKeepFiles}`,\n );\n return {\n postDocumentUrl: paperlessPostDocumentUrl,\n authToken: configPaperlessToken,\n keepFiles: configPaperlessKeepFiles,\n groupMultiPageScanIntoAPdf: groupMultiPageScanIntoAPdf,\n alwaysSendAsPdfFile: alwaysSendAsPdfFile,\n };\n } else {\n return undefined;\n }\n}\n\nfunction getHealthCheckSetting(option: OptionValues) {\n const healthCheckEnabled: boolean =\n option.healthCheck || getConfig(\"enableHealthCheck\") === true;\n let healthCheckPort: number;\n if (option.healthCheckPort) {\n healthCheckPort = parseInt(option.healthCheckPort, 10);\n } else {\n healthCheckPort = getConfig<number>(\"healthCheckPort\") || 3000;\n }\n return {\n isHealthCheckEnabled: healthCheckEnabled,\n healthCheckPort: healthCheckPort,\n };\n}\n\nfunction getScanConfiguration(option: OptionValues) {\n const directoryConfig: DirectoryConfig = {\n directory: option.directory || getConfig(\"directory\"),\n tempDirectory: option.tempDirectory || getConfig(\"tempDirectory\"),\n filePattern: option.pattern || getConfig(\"pattern\"),\n };\n\n const configWidth = (option.width || getConfig(\"width\") || 0).toString();\n const width =\n configWidth.toLowerCase() === \"max\"\n ? Number.MAX_SAFE_INTEGER\n : parseInt(configWidth, 10);\n\n const configHeight = (option.width || getConfig(\"height\") || \"0\").toString();\n const height =\n configWidth.toLowerCase() === \"max\"\n ? Number.MAX_SAFE_INTEGER\n : parseInt(configHeight, 10);\n\n const paperlessConfig = getPaperlessConfig(option);\n\n const scanConfig: ScanConfig = {\n resolution: parseInt(\n option.resolution || getConfig(\"resolution\") || \"200\",\n 10,\n ),\n width: width,\n height: height,\n directoryConfig,\n paperlessConfig,\n };\n return scanConfig;\n}\n\nfunction getDeviceUpPollingInterval(parentOption: OptionValues) {\n return (\n parentOption.deviceUpPollingInterval ||\n getConfig(\"deviceUpPollingInterval\") ||\n 1000\n );\n}\n\nasync function main() {\n setupParameterOpts(program);\n const cmdListen = program.createCommand(\"listen\");\n setupScanParameters(cmdListen)\n .description(\"Listen the device for new scan job to save to this target\")\n .option(\n \"-l, --label <label>\",\n \"The label to display on the device (the default is the hostname)\",\n )\n .addOption(\n new Option(\"--health-check\", \"Start an http health check endpoint\"),\n )\n .addOption(\n new Option(\n \"--health-check-port <health-check-port>\",\n \"Start an http health check endpoint\",\n ),\n )\n .action(async (options, cmd) => {\n const parentOption = cmd.parent.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n\n const registrationConfig: RegistrationConfig = {\n label: options.label || getConfig(\"label\") || os.hostname(),\n };\n\n const deviceUpPollingInterval = getDeviceUpPollingInterval(parentOption);\n\n const healthCheckSetting = getHealthCheckSetting(options);\n if (healthCheckSetting.isHealthCheckEnabled) {\n startHealthCheckServer(healthCheckSetting.healthCheckPort);\n }\n\n const scanConfig = getScanConfiguration(options);\n\n await listenCmd(registrationConfig, scanConfig, deviceUpPollingInterval);\n });\n program.addCommand(cmdListen, { isDefault: true });\n\n const cmdAdfAutoscan = program.createCommand(\"adf-autoscan\");\n setupScanParameters(cmdAdfAutoscan)\n .addOption(\n new Option(\"--duplex\", \"If specified, the scan will be in duplex\"),\n )\n .addOption(\n new Option(\n \"--pdf\",\n \"If specified, the scan result will be a pdf document, the default is multiple jpeg files\",\n ),\n )\n .addOption(\n new Option(\n \"--pollingInterval <pollingInterval>\",\n \"Time interval in millisecond between each lookup for content in the automatic document feeder\",\n ),\n )\n .description(\n \"Automatically trigger a new scan job to this target once paper is detected in the automatic document feeder (adf)\",\n )\n .addOption(\n new Option(\n \"--start-scan-delay <startScanDelay>\",\n \"Once document are detected to be in the adf, this specify the wait delay in millisecond before triggering the scan\",\n ),\n )\n .addOption(\n new Option(\"--health-check\", \"Start an http health check endpoint\"),\n )\n .addOption(\n new Option(\n \"--health-check-port <port>\",\n \"Start an http health check endpoint\",\n ),\n )\n .description(\n \"Automatically trigger a new scan job to this target once paper is detected in the automatic document feeder (adf)\",\n )\n .action(async (options, cmd) => {\n const parentOption = cmd.parent.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n\n const deviceUpPollingInterval = getDeviceUpPollingInterval(parentOption);\n\n const healthCheckSetting = getHealthCheckSetting(options);\n if (healthCheckSetting.isHealthCheckEnabled) {\n startHealthCheckServer(healthCheckSetting.healthCheckPort);\n }\n\n const scanConfig = getScanConfiguration(options);\n\n const adfScanConfig: AdfAutoScanConfig = {\n ...scanConfig,\n isDuplex: options.isDuplex || getConfig(\"autoscan_duplex\") || false,\n generatePdf: options.pdf || getConfig(\"autoscan_pdf\") || false,\n pollingInterval:\n options.pollingInterval ||\n getConfig(\"autoscan_pollingInterval\") ||\n 1000,\n startScanDelay:\n options.startScanDelay ||\n getConfig(\"autoscan_startScanDelay\") ||\n 5000,\n };\n\n await adfAutoscanCmd(adfScanConfig, deviceUpPollingInterval);\n });\n program.addCommand(cmdAdfAutoscan);\n\n const cmdClearRegistrations = program.createCommand(\"clear-registrations\");\n cmdClearRegistrations\n .description(\"Clear the list or registered target on the device\")\n .action(async (options, cmd) => {\n await clearRegistrationsCmd(cmd);\n });\n program.addCommand(cmdClearRegistrations);\n\n await program.parseAsync(process.argv);\n}\n\nconsole.log(`Current commit ID: ${commitInfo.commitId}`);\nmain().catch((err) => console.log(err));\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// noinspection XmlDeprecatedElement,HtmlDeprecatedTag\n\n\"use strict\";\n\nimport os from \"os\";\nimport { Command, Option, OptionValues, program } from \"commander\";\nimport { Bonjour } from \"bonjour-service\";\nimport config from \"config\";\nimport HPApi from \"./HPApi\";\nimport PathHelper from \"./PathHelper\";\nimport { delay } from \"./delay\";\nimport { readDeviceCapabilities } from \"./readDeviceCapabilities\";\nimport {\n clearRegistrations,\n RegistrationConfig,\n waitScanEvent,\n} from \"./listening\";\nimport {\n AdfAutoScanConfig,\n DirectoryConfig,\n saveScanFromEvent,\n ScanConfig,\n scanFromAdf,\n waitAdfLoaded,\n} from \"./scanProcessing\";\nimport * as commitInfo from \"./commitInfo.json\";\nimport { PaperlessConfig } from \"./paperless/PaperlessConfig\";\nimport { NextcloudConfig } from \"./nextcloud/NextcloudConfig\";\nimport { startHealthCheckServer } from \"./healthcheck\";\nimport fs from \"fs\";\n\nlet iteration = 0;\n\nasync function listenCmd(\n registrationConfig: RegistrationConfig,\n scanConfig: ScanConfig,\n deviceUpPollingInterval: number,\n) {\n // first make sure the device is reachable\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n let deviceUp = true;\n\n const folder = await PathHelper.getOutputFolder(\n scanConfig.directoryConfig.directory,\n );\n console.log(`Target folder: ${folder}`);\n\n const tempFolder = await PathHelper.getOutputFolder(\n scanConfig.directoryConfig.tempDirectory,\n );\n console.log(`Temp folder: ${tempFolder}`);\n\n const deviceCapabilities = await readDeviceCapabilities();\n\n let scanCount = 0;\n let keepActive = true;\n let errorCount = 0;\n while (keepActive) {\n iteration++;\n console.log(`Running iteration: ${iteration} - errorCount: ${errorCount}`);\n try {\n const event = await waitScanEvent(deviceCapabilities, registrationConfig);\n scanCount = await PathHelper.getNextScanNumber(\n folder,\n scanCount,\n scanConfig.directoryConfig.filePattern,\n );\n console.log(`Scan event captured, saving scan #${scanCount}`);\n await saveScanFromEvent(\n event,\n folder,\n tempFolder,\n scanCount,\n deviceCapabilities,\n scanConfig,\n );\n } catch (e) {\n if (await HPApi.isAlive()) {\n console.log(e);\n errorCount++;\n } else {\n if (HPApi.isDebug()) {\n console.log(e);\n }\n deviceUp = false;\n }\n }\n\n if (errorCount === 50) {\n keepActive = false;\n }\n\n if (!deviceUp) {\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n } else {\n await delay(1000);\n }\n }\n}\n\nasync function adfAutoscanCmd(\n adfAutoScanConfig: AdfAutoScanConfig,\n deviceUpPollingInterval: number,\n) {\n // first make sure the device is reachable\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n let deviceUp = true;\n\n const folder = await PathHelper.getOutputFolder(\n adfAutoScanConfig.directoryConfig.directory,\n );\n console.log(`Target folder: ${folder}`);\n\n const tempFolder = await PathHelper.getOutputFolder(\n adfAutoScanConfig.directoryConfig.tempDirectory,\n );\n console.log(`Temp folder: ${tempFolder}`);\n\n const deviceCapabilities = await readDeviceCapabilities();\n\n let scanCount = 0;\n let keepActive = true;\n let errorCount = 0;\n while (keepActive) {\n iteration++;\n console.log(`Running iteration: ${iteration} - errorCount: ${errorCount}`);\n try {\n await waitAdfLoaded(\n adfAutoScanConfig.pollingInterval,\n adfAutoScanConfig.startScanDelay,\n );\n\n scanCount++;\n\n console.log(`Scan event captured, saving scan #${scanCount}`);\n\n await scanFromAdf(\n scanCount,\n folder,\n tempFolder,\n adfAutoScanConfig,\n deviceCapabilities,\n new Date(),\n );\n } catch (e) {\n console.log(e);\n if (await HPApi.isAlive()) {\n errorCount++;\n } else {\n deviceUp = false;\n }\n }\n\n if (errorCount === 50) {\n keepActive = false;\n }\n\n if (!deviceUp) {\n await HPApi.waitDeviceUp(deviceUpPollingInterval);\n } else {\n await delay(1000);\n }\n }\n}\n\nasync function clearRegistrationsCmd(cmd: Command) {\n const parentOption = cmd.parent!.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n await clearRegistrations();\n}\n\nfunction findOfficejetIp(deviceNamePrefix: string): Promise<string> {\n return new Promise((resolve) => {\n const bonjour = new Bonjour();\n console.log(\"Searching device...\");\n const browser = bonjour.find(\n {\n type: \"http\",\n },\n (service) => {\n console.log(\".\");\n if (\n service.name.startsWith(deviceNamePrefix) &&\n service.port === 80 &&\n service.type === \"http\" &&\n service.addresses != null\n ) {\n browser.stop();\n bonjour.destroy();\n console.log(`Found: ${service.name}`);\n resolve(service.addresses[0]);\n }\n },\n );\n browser.start();\n });\n}\n\nfunction getConfig<T>(name: string): T | undefined {\n return config.has(name) ? config.get<T>(name) : undefined;\n}\n\nfunction setupScanParameters(command: Command): Command {\n command.option(\n \"-d, --directory <dir>\",\n \"Directory where scans are saved (default: /tmp/scan-to-pcRANDOM)\",\n );\n command.option(\n \"-t, --temp-directory <dir>\",\n \"Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)\",\n );\n command.option(\n \"-p, --pattern <pattern>\",\n 'Pattern for filename (i.e. \"scan\"_dd.mm.yyyy_hh:MM:ss, without this its scanPageNUMBER)',\n );\n command.option(\n \"-r, --resolution <dpi>\",\n \"Resolution in DPI of the scans (default: 200)\",\n );\n command.option(\n \"-w, --width <width>\",\n \"With in pixel of the scans (default: 2481)\",\n );\n command.option(\n \"-h, --height <height>\",\n \"Height in pixel of the scans (default: 3507)\",\n );\n command.option(\n \"-s, --paperless-post-document-url <paperless_post_document_url>\",\n \"The paperless post document url (example: https://domain.tld/api/documents/post_document/)\",\n );\n\n command.option(\n \"-o, --paperless-token <paperless_token>\",\n \"The paperless token\",\n );\n command.option(\n \"--paperless-group-multi-page-scan-into-a-pdf\",\n \"Combine multiple scanned images into a single PDF document\",\n );\n command.option(\n \"--paperless-always-send-as-pdf-file\",\n \"Always convert scan job to pdf before sending to paperless\",\n );\n command.option(\n \"-k, --keep-files\",\n \"Keep the scan files on the file system (default: false)\",\n );\n\n command.option(\n \"--nextcloud-url <nextcloud_url>\",\n \"The nextcloud url (example: https://domain.tld)\",\n );\n command.option(\n \"--nextcloud-username <nextcloud_username>\",\n \"The nextcloud username\",\n );\n command.option(\n \"--nextcloud-password <nextcloud_app_password>\",\n \"The nextcloud app password for username. Either this or nextcloud-password-file is required\",\n );\n command.option(\n \"--nextcloud-password-file <nextcloud_app_password_file>\",\n \"File name that contains the nextcloud app password for username. Either this or nextcloud-password is required\",\n );\n command.option(\n \"--nextcloud-upload-folder <nextcloud_upload_folder>\",\n \"The upload folder where documents or images are uploaded (default: scan)\",\n );\n return command;\n}\n\nfunction setupParameterOpts(command: Command): Command {\n command.option(\n \"-a, --address <ip>\",\n \"IP address of the device (this overrides -p)\",\n );\n command.option(\n \"--device-up-polling-interval <deviceUpPollingInterval>\",\n \"Device up polling interval in milliseconds\",\n parseFloat,\n );\n command.option(\n \"-n, --name <name>\",\n \"Name of the device for service discovery\",\n ); // i.e. 'Deskjet 3520 series'\n\n command.option(\"-D, --debug\", \"Enable debug\");\n return command;\n}\n\nasync function getDeviceIp(options: OptionValues) {\n let ip = options.address || getConfig(\"ip\");\n if (!ip) {\n const name = options.name || getConfig(\"name\");\n ip = await findOfficejetIp(name || \"HP Smart Tank Plus 570 series\");\n }\n console.log(`Using device ip: ${ip}`);\n return ip;\n}\n\nfunction getIsDebug(options: OptionValues) {\n const debug =\n options.debug != null ? true : getConfig<boolean>(\"debug\") || false;\n\n if (debug) {\n console.log(`IsDebug: ${debug}`);\n }\n return debug;\n}\n\nfunction getPaperlessConfig(\n parentOption: OptionValues,\n): PaperlessConfig | undefined {\n const paperlessPostDocumentUrl: string =\n parentOption.paperlessPostDocumentUrl ||\n getConfig(\"paperless_post_document_url\");\n const configPaperlessToken: string =\n parentOption.paperlessToken || getConfig(\"paperless_token\");\n\n if (paperlessPostDocumentUrl && configPaperlessToken) {\n const configPaperlessKeepFiles: boolean =\n parentOption.keepFiles || getConfig(\"keep_files\") || false;\n const groupMultiPageScanIntoAPdf: boolean =\n parentOption.paperlessGroupMultiPageScanIntoAPdf ||\n getConfig(\"paperless_group_multi_page_scan_into_a_pdf\") ||\n false;\n const alwaysSendAsPdfFile: boolean =\n parentOption.paperlessAlwaysSendAsPdfFile ||\n getConfig(\"paperless_always_send_as_pdf_file\") ||\n false;\n\n console.log(\n `Paperless configuration provided, post document url: ${paperlessPostDocumentUrl}, the token length: ${configPaperlessToken.length}, keepFiles: ${configPaperlessKeepFiles}`,\n );\n return {\n postDocumentUrl: paperlessPostDocumentUrl,\n authToken: configPaperlessToken,\n keepFiles: configPaperlessKeepFiles,\n groupMultiPageScanIntoAPdf: groupMultiPageScanIntoAPdf,\n alwaysSendAsPdfFile: alwaysSendAsPdfFile,\n };\n } else {\n return undefined;\n }\n}\n\nfunction getNextcloudConfig(\n parentOption: OptionValues,\n): NextcloudConfig | undefined {\n const configNextcloudUrl: string =\n parentOption.nextcloudUrl || getConfig(\"nextcloud_url\");\n const configNextcloudUsername: string =\n parentOption.nextcloudUsername || getConfig(\"nextcloud_username\");\n let configNextcloudPassword: string =\n parentOption.nextcloudPassword || getConfig(\"nextcloud_password\");\n const configNextcloudPasswordFile: string =\n parentOption.nextcloudPasswordFile || getConfig(\"nextcloud_password_file\");\n\n if (\n configNextcloudUrl &&\n configNextcloudUsername &&\n (configNextcloudPassword || configNextcloudPasswordFile)\n ) {\n const configNextcloudUploadFolder =\n parentOption.nextcloudUploadFolder ||\n getConfig(\"nextcloud_upload_folder\") ||\n \"scan\";\n const configNextcloudKeepFiles: boolean =\n parentOption.keepFiles || getConfig(\"keep_files\") || false;\n\n if (configNextcloudPasswordFile) {\n configNextcloudPassword = fs\n .readFileSync(configNextcloudPasswordFile, \"utf8\")\n .trimEnd();\n }\n\n console.log(\n `Nextcloud configuration provided, url: ${configNextcloudUrl}, username: ${configNextcloudUsername}, password length: ${configNextcloudPassword.length}, upload folder: ${configNextcloudUploadFolder}, keepFiles: ${configNextcloudKeepFiles}`,\n );\n return {\n baseUrl: configNextcloudUrl,\n username: configNextcloudUsername,\n password: configNextcloudPassword,\n uploadFolder: configNextcloudUploadFolder,\n keepFiles: configNextcloudKeepFiles,\n };\n } else {\n return undefined;\n }\n}\n\nfunction getHealthCheckSetting(option: OptionValues) {\n const healthCheckEnabled: boolean =\n option.healthCheck || getConfig(\"enableHealthCheck\") === true;\n let healthCheckPort: number;\n if (option.healthCheckPort) {\n healthCheckPort = parseInt(option.healthCheckPort, 10);\n } else {\n healthCheckPort = getConfig<number>(\"healthCheckPort\") || 3000;\n }\n return {\n isHealthCheckEnabled: healthCheckEnabled,\n healthCheckPort: healthCheckPort,\n };\n}\n\nfunction getScanConfiguration(option: OptionValues) {\n const directoryConfig: DirectoryConfig = {\n directory: option.directory || getConfig(\"directory\"),\n tempDirectory: option.tempDirectory || getConfig(\"tempDirectory\"),\n filePattern: option.pattern || getConfig(\"pattern\"),\n };\n\n const configWidth = (option.width || getConfig(\"width\") || 0).toString();\n const width =\n configWidth.toLowerCase() === \"max\"\n ? Number.MAX_SAFE_INTEGER\n : parseInt(configWidth, 10);\n\n const configHeight = (option.width || getConfig(\"height\") || \"0\").toString();\n const height =\n configWidth.toLowerCase() === \"max\"\n ? Number.MAX_SAFE_INTEGER\n : parseInt(configHeight, 10);\n\n const paperlessConfig = getPaperlessConfig(option);\n const nextcloudConfig = getNextcloudConfig(option);\n\n const scanConfig: ScanConfig = {\n resolution: parseInt(\n option.resolution || getConfig(\"resolution\") || \"200\",\n 10,\n ),\n width: width,\n height: height,\n directoryConfig,\n paperlessConfig,\n nextcloudConfig,\n };\n return scanConfig;\n}\n\nfunction getDeviceUpPollingInterval(parentOption: OptionValues) {\n return (\n parentOption.deviceUpPollingInterval ||\n getConfig(\"deviceUpPollingInterval\") ||\n 1000\n );\n}\n\nasync function main() {\n setupParameterOpts(program);\n const cmdListen = program.createCommand(\"listen\");\n setupScanParameters(cmdListen)\n .description(\"Listen the device for new scan job to save to this target\")\n .option(\n \"-l, --label <label>\",\n \"The label to display on the device (the default is the hostname)\",\n )\n .addOption(\n new Option(\"--health-check\", \"Start an http health check endpoint\"),\n )\n .addOption(\n new Option(\n \"--health-check-port <health-check-port>\",\n \"Start an http health check endpoint\",\n ),\n )\n .action(async (options, cmd) => {\n const parentOption = cmd.parent.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n\n const registrationConfig: RegistrationConfig = {\n label: options.label || getConfig(\"label\") || os.hostname(),\n };\n\n const deviceUpPollingInterval = getDeviceUpPollingInterval(parentOption);\n\n const healthCheckSetting = getHealthCheckSetting(options);\n if (healthCheckSetting.isHealthCheckEnabled) {\n startHealthCheckServer(healthCheckSetting.healthCheckPort);\n }\n\n const scanConfig = getScanConfiguration(options);\n\n await listenCmd(registrationConfig, scanConfig, deviceUpPollingInterval);\n });\n program.addCommand(cmdListen, { isDefault: true });\n\n const cmdAdfAutoscan = program.createCommand(\"adf-autoscan\");\n setupScanParameters(cmdAdfAutoscan)\n .addOption(\n new Option(\"--duplex\", \"If specified, the scan will be in duplex\"),\n )\n .addOption(\n new Option(\n \"--pdf\",\n \"If specified, the scan result will be a pdf document, the default is multiple jpeg files\",\n ),\n )\n .addOption(\n new Option(\n \"--pollingInterval <pollingInterval>\",\n \"Time interval in millisecond between each lookup for content in the automatic document feeder\",\n ),\n )\n .description(\n \"Automatically trigger a new scan job to this target once paper is detected in the automatic document feeder (adf)\",\n )\n .addOption(\n new Option(\n \"--start-scan-delay <startScanDelay>\",\n \"Once document are detected to be in the adf, this specify the wait delay in millisecond before triggering the scan\",\n ),\n )\n .addOption(\n new Option(\"--health-check\", \"Start an http health check endpoint\"),\n )\n .addOption(\n new Option(\n \"--health-check-port <port>\",\n \"Start an http health check endpoint\",\n ),\n )\n .description(\n \"Automatically trigger a new scan job to this target once paper is detected in the automatic document feeder (adf)\",\n )\n .action(async (options, cmd) => {\n const parentOption = cmd.parent.opts();\n\n const ip = await getDeviceIp(parentOption);\n HPApi.setDeviceIP(ip);\n\n const isDebug = getIsDebug(parentOption);\n HPApi.setDebug(isDebug);\n\n const deviceUpPollingInterval = getDeviceUpPollingInterval(parentOption);\n\n const healthCheckSetting = getHealthCheckSetting(options);\n if (healthCheckSetting.isHealthCheckEnabled) {\n startHealthCheckServer(healthCheckSetting.healthCheckPort);\n }\n\n const scanConfig = getScanConfiguration(options);\n\n const adfScanConfig: AdfAutoScanConfig = {\n ...scanConfig,\n isDuplex: options.isDuplex || getConfig(\"autoscan_duplex\") || false,\n generatePdf: options.pdf || getConfig(\"autoscan_pdf\") || false,\n pollingInterval:\n options.pollingInterval ||\n getConfig(\"autoscan_pollingInterval\") ||\n 1000,\n startScanDelay:\n options.startScanDelay ||\n getConfig(\"autoscan_startScanDelay\") ||\n 5000,\n };\n\n await adfAutoscanCmd(adfScanConfig, deviceUpPollingInterval);\n });\n program.addCommand(cmdAdfAutoscan);\n\n const cmdClearRegistrations = program.createCommand(\"clear-registrations\");\n cmdClearRegistrations\n .description(\"Clear the list or registered target on the device\")\n .action(async (options, cmd) => {\n await clearRegistrationsCmd(cmd);\n });\n program.addCommand(cmdClearRegistrations);\n\n await program.parseAsync(process.argv);\n}\n\nconsole.log(`Current commit ID: ${commitInfo.commitId}`);\nmain().catch((err) => console.log(err));\n"]}
@@ -0,0 +1,7 @@
1
+ export type NextcloudConfig = {
2
+ baseUrl: string;
3
+ username: string;
4
+ password: string;
5
+ uploadFolder: string;
6
+ keepFiles: boolean;
7
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=NextcloudConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NextcloudConfig.js","sourceRoot":"","sources":["../../src/nextcloud/NextcloudConfig.ts"],"names":[],"mappings":"","sourcesContent":["export type NextcloudConfig = {\n baseUrl: string;\n username: string;\n password: string;\n uploadFolder: string;\n keepFiles: boolean;\n};\n"]}
@@ -0,0 +1,4 @@
1
+ import { ScanContent } from "../ScanContent";
2
+ import { NextcloudConfig } from "./NextcloudConfig";
3
+ export declare function uploadImagesToNextcloud(scanJobContent: ScanContent, nextcloudConfig: NextcloudConfig): Promise<void>;
4
+ export declare function uploadPdfToNextcloud(pdfFilePath: string | null, nextcloudConfig: NextcloudConfig): Promise<void>;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.uploadPdfToNextcloud = exports.uploadImagesToNextcloud = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const promises_1 = __importDefault(require("fs/promises"));
9
+ const path_1 = __importDefault(require("path"));
10
+ async function uploadImagesToNextcloud(scanJobContent, nextcloudConfig) {
11
+ await checkFolderAndUpload(nextcloudConfig, async () => {
12
+ for (const element of scanJobContent.elements) {
13
+ const { path: filePath } = element;
14
+ await uploadToNextcloud(filePath, nextcloudConfig);
15
+ }
16
+ });
17
+ }
18
+ exports.uploadImagesToNextcloud = uploadImagesToNextcloud;
19
+ async function uploadPdfToNextcloud(pdfFilePath, nextcloudConfig) {
20
+ await checkFolderAndUpload(nextcloudConfig, async () => {
21
+ if (pdfFilePath) {
22
+ await uploadToNextcloud(pdfFilePath, nextcloudConfig);
23
+ }
24
+ else {
25
+ console.log("Pdf generation has failed, nothing is going to be uploaded to Nextcloud");
26
+ }
27
+ });
28
+ }
29
+ exports.uploadPdfToNextcloud = uploadPdfToNextcloud;
30
+ async function uploadToNextcloud(filePath, nextcloudConfig) {
31
+ const { baseUrl, username, password, uploadFolder } = nextcloudConfig;
32
+ const fileName = path_1.default.basename(filePath);
33
+ const folderUrl = buildFolderUrl(baseUrl, username, uploadFolder);
34
+ const uploadUrl = buildUrl(folderUrl, [fileName]);
35
+ let fileBuffer;
36
+ try {
37
+ fileBuffer = await promises_1.default.readFile(filePath);
38
+ }
39
+ catch (e) {
40
+ console.error("Fail to read file:", e);
41
+ return;
42
+ }
43
+ const auth = { username, password };
44
+ console.log(`Start uploading to Nextcloud: ${fileName}`);
45
+ try {
46
+ const response = await (0, axios_1.default)({
47
+ method: "PUT",
48
+ url: uploadUrl,
49
+ auth,
50
+ data: fileBuffer,
51
+ });
52
+ let action;
53
+ if (response.status === 201) {
54
+ action = "created";
55
+ }
56
+ else {
57
+ action = "updated";
58
+ }
59
+ console.log(`Document successfully ${action} file at Nextcloud. (Folder: ${uploadFolder}, File: ${fileName})`);
60
+ }
61
+ catch (error) {
62
+ console.error("Fail to upload document:", error);
63
+ }
64
+ }
65
+ async function checkFolderAndUpload(nextcloudConfig, uploadFunction) {
66
+ const folderExists = await checkNextcloudFolderExists(nextcloudConfig);
67
+ if (!folderExists) {
68
+ console.log("Upload folder does not exist or user has no permission; skipping upload");
69
+ return;
70
+ }
71
+ await uploadFunction();
72
+ }
73
+ async function checkNextcloudFolderExists(nextcloudConfig) {
74
+ var _a, _b;
75
+ const { baseUrl, username, password, uploadFolder } = nextcloudConfig;
76
+ const folderUrl = buildFolderUrl(baseUrl, username, uploadFolder);
77
+ const auth = { username, password };
78
+ console.log("Check if upload folder exists");
79
+ try {
80
+ // Check if the upload folder exists
81
+ await (0, axios_1.default)({
82
+ method: "PROPFIND",
83
+ url: folderUrl,
84
+ auth,
85
+ headers: { Depth: 0 },
86
+ });
87
+ console.log(`Found upload folder '${uploadFolder}' in Nextcloud`);
88
+ }
89
+ catch (error) {
90
+ const axiosError = error;
91
+ if (((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
92
+ console.warn(`Upload folder '${uploadFolder}' not found in Nextcloud`);
93
+ }
94
+ else if (((_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.status) === 401) {
95
+ console.warn(`User has no permission to access upload folder '${uploadFolder}' in Nextcloud`);
96
+ }
97
+ else {
98
+ console.error("Fail to check upload folder exists:", axiosError.toJSON());
99
+ }
100
+ console.trace("Error response:", axiosError.response);
101
+ return false;
102
+ }
103
+ return true;
104
+ }
105
+ function buildFolderUrl(baseUrl, username, uploadFolder) {
106
+ return buildUrl(baseUrl, [
107
+ "remote.php",
108
+ "dav",
109
+ "files",
110
+ username,
111
+ uploadFolder,
112
+ ]);
113
+ }
114
+ function buildUrl(baseUrl, path) {
115
+ const url = new URL(baseUrl);
116
+ const search = /^\/+|\/+$/g;
117
+ path.forEach((part) => {
118
+ url.pathname = `${url.pathname.replace(search, "")}/${encodeURIComponent(part.replace(search, ""))}`;
119
+ });
120
+ return url.toString();
121
+ }
122
+ //# sourceMappingURL=nextcloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextcloud.js","sourceRoot":"","sources":["../../src/nextcloud/nextcloud.ts"],"names":[],"mappings":"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","sourcesContent":["import axios, { AxiosError } from \"axios\";\nimport { ScanContent } from \"../ScanContent\";\nimport { NextcloudConfig } from \"./NextcloudConfig\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\n\nexport async function uploadImagesToNextcloud(\n scanJobContent: ScanContent,\n nextcloudConfig: NextcloudConfig,\n) {\n await checkFolderAndUpload(nextcloudConfig, async () => {\n for (const element of scanJobContent.elements) {\n const { path: filePath } = element;\n await uploadToNextcloud(filePath, nextcloudConfig);\n }\n });\n}\n\nexport async function uploadPdfToNextcloud(\n pdfFilePath: string | null,\n nextcloudConfig: NextcloudConfig,\n) {\n await checkFolderAndUpload(nextcloudConfig, async () => {\n if (pdfFilePath) {\n await uploadToNextcloud(pdfFilePath, nextcloudConfig);\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to Nextcloud\",\n );\n }\n });\n}\n\nasync function uploadToNextcloud(\n filePath: string,\n nextcloudConfig: NextcloudConfig,\n): Promise<void> {\n const { baseUrl, username, password, uploadFolder } = nextcloudConfig;\n const fileName = path.basename(filePath);\n\n const folderUrl = buildFolderUrl(baseUrl, username, uploadFolder);\n const uploadUrl = buildUrl(folderUrl, [fileName]);\n\n let fileBuffer: Buffer;\n try {\n fileBuffer = await fs.readFile(filePath);\n } catch (e) {\n console.error(\"Fail to read file:\", e);\n return;\n }\n const auth = { username, password };\n\n console.log(`Start uploading to Nextcloud: ${fileName}`);\n try {\n const response = await axios({\n method: \"PUT\",\n url: uploadUrl,\n auth,\n data: fileBuffer,\n });\n\n let action: string;\n if (response.status === 201) {\n action = \"created\";\n } else {\n action = \"updated\";\n }\n console.log(\n `Document successfully ${action} file at Nextcloud. (Folder: ${uploadFolder}, File: ${fileName})`,\n );\n } catch (error) {\n console.error(\"Fail to upload document:\", error);\n }\n}\n\nasync function checkFolderAndUpload(\n nextcloudConfig: NextcloudConfig,\n uploadFunction: () => Promise<void>,\n) {\n const folderExists = await checkNextcloudFolderExists(nextcloudConfig);\n if (!folderExists) {\n console.log(\n \"Upload folder does not exist or user has no permission; skipping upload\",\n );\n return;\n }\n\n await uploadFunction();\n}\n\nasync function checkNextcloudFolderExists(\n nextcloudConfig: NextcloudConfig,\n): Promise<boolean> {\n const { baseUrl, username, password, uploadFolder } = nextcloudConfig;\n const folderUrl = buildFolderUrl(baseUrl, username, uploadFolder);\n const auth = { username, password };\n\n console.log(\"Check if upload folder exists\");\n try {\n // Check if the upload folder exists\n await axios({\n method: \"PROPFIND\",\n url: folderUrl,\n auth,\n headers: { Depth: 0 },\n });\n console.log(`Found upload folder '${uploadFolder}' in Nextcloud`);\n } catch (error) {\n const axiosError = error as AxiosError;\n if (axiosError.response?.status === 404) {\n console.warn(`Upload folder '${uploadFolder}' not found in Nextcloud`);\n } else if (axiosError.response?.status === 401) {\n console.warn(\n `User has no permission to access upload folder '${uploadFolder}' in Nextcloud`,\n );\n } else {\n console.error(\"Fail to check upload folder exists:\", axiosError.toJSON());\n }\n console.trace(\"Error response:\", axiosError.response);\n return false;\n }\n return true;\n}\n\nfunction buildFolderUrl(\n baseUrl: string,\n username: string,\n uploadFolder: string,\n) {\n return buildUrl(baseUrl, [\n \"remote.php\",\n \"dav\",\n \"files\",\n username,\n uploadFolder,\n ]);\n}\n\nfunction buildUrl(baseUrl: string, path: string[]): string {\n const url = new URL(baseUrl);\n const search = /^\\/+|\\/+$/g;\n path.forEach((part) => {\n url.pathname = `${url.pathname.replace(search, \"\")}/${encodeURIComponent(part.replace(search, \"\"))}`;\n });\n return url.toString();\n}\n"]}
@@ -13,10 +13,6 @@ async function uploadImagesAsSeparateDocumentsToPaperless(scanJobContent, paperl
13
13
  for (let i = 0; i < scanJobContent.elements.length; ++i) {
14
14
  const filePath = scanJobContent.elements[i].path;
15
15
  await uploadToPaperless(filePath, paperlessConfig);
16
- if (!paperlessConfig.keepFiles) {
17
- await promises_1.default.unlink(filePath);
18
- console.log(`Image document ${filePath} has been removed from the filesystem`);
19
- }
20
16
  }
21
17
  }
22
18
  exports.uploadImagesAsSeparateDocumentsToPaperless = uploadImagesAsSeparateDocumentsToPaperless;
@@ -49,10 +45,6 @@ exports.mergeToPdfAndUploadAsSingleDocumentToPaperless = mergeToPdfAndUploadAsSi
49
45
  async function uploadPdfToPaperless(pdfFilePath, paperlessConfig) {
50
46
  if (pdfFilePath) {
51
47
  await uploadToPaperless(pdfFilePath, paperlessConfig);
52
- if (!paperlessConfig.keepFiles) {
53
- await promises_1.default.unlink(pdfFilePath);
54
- console.log(`Pdf document ${pdfFilePath} has been removed from the filesystem`);
55
- }
56
48
  }
57
49
  else {
58
50
  console.log("Pdf generation has failed, nothing is going to be uploaded to paperless");
@@ -1 +1 @@
1
- {"version":3,"file":"paperless.js","sourceRoot":"","sources":["../../src/paperless/paperless.ts"],"names":[],"mappings":"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","sourcesContent":["import fsSync from \"fs\";\nimport FormData from \"form-data\";\nimport axios from \"axios\";\nimport { ScanConfig } from \"../scanProcessing\";\nimport { ScanContent } from \"../ScanContent\";\nimport fs from \"fs/promises\";\nimport { convertToPdf, mergeToPdf } from \"../pdfProcessing\";\nimport { PaperlessConfig } from \"./PaperlessConfig\";\n\nexport async function uploadImagesAsSeparateDocumentsToPaperless(\n scanJobContent: ScanContent,\n paperlessConfig: PaperlessConfig,\n) {\n for (let i = 0; i < scanJobContent.elements.length; ++i) {\n const filePath = scanJobContent.elements[i].path;\n await uploadToPaperless(filePath, paperlessConfig);\n if (!paperlessConfig.keepFiles) {\n await fs.unlink(filePath);\n console.log(\n `Image document ${filePath} has been removed from the filesystem`,\n );\n }\n }\n}\n\nexport async function convertImagesToPdfAndUploadAsSeparateDocumentsToPaperless(\n scanJobContent: ScanContent,\n paperlessConfig: PaperlessConfig,\n) {\n for (let i = 0; i < scanJobContent.elements.length; ++i) {\n const pdfFilePath = await convertToPdf(\n scanJobContent.elements[i],\n !paperlessConfig.keepFiles,\n );\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n await fs.unlink(pdfFilePath);\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless for: \" +\n scanJobContent.elements[i].path,\n );\n }\n }\n}\n\nexport async function mergeToPdfAndUploadAsSingleDocumentToPaperless(\n folder: string,\n scanCount: number,\n scanJobContent: ScanContent,\n scanConfig: ScanConfig,\n scanDate: Date,\n paperlessConfig: PaperlessConfig,\n) {\n const pdfFilePath = await mergeToPdf(\n folder,\n scanCount,\n scanJobContent,\n scanConfig.directoryConfig.filePattern,\n scanDate,\n !paperlessConfig.keepFiles,\n );\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n await fs.unlink(pdfFilePath);\n console.log(\n `Pdf document ${pdfFilePath} has been removed from the filesystem`,\n );\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless\",\n );\n }\n}\n\nexport async function uploadPdfToPaperless(\n pdfFilePath: string | null,\n paperlessConfig: PaperlessConfig,\n) {\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n if (!paperlessConfig.keepFiles) {\n await fs.unlink(pdfFilePath);\n console.log(\n `Pdf document ${pdfFilePath} has been removed from the filesystem`,\n );\n }\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless\",\n );\n }\n}\n\nasync function uploadToPaperless(\n filePath: string,\n paperlessConfig: PaperlessConfig,\n): Promise<void> {\n const url = paperlessConfig.postDocumentUrl;\n\n const authToken = paperlessConfig.authToken;\n\n const fileStream = fsSync.createReadStream(filePath);\n\n const form = new FormData();\n form.append(\"document\", fileStream);\n\n console.log(`Start uploading to paperless: ${filePath}`);\n try {\n const response = await axios.post(url, form, {\n headers: {\n ...form.getHeaders(),\n Authorization: `Token ${authToken}`,\n },\n });\n\n console.log(\"Document successfully uploaded to paperless:\", response.data);\n } catch (error) {\n console.error(\"Fail to upload document:\", error);\n }\n fileStream.close();\n}\n"]}
1
+ {"version":3,"file":"paperless.js","sourceRoot":"","sources":["../../src/paperless/paperless.ts"],"names":[],"mappings":"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","sourcesContent":["import fsSync from \"fs\";\nimport FormData from \"form-data\";\nimport axios from \"axios\";\nimport { ScanConfig } from \"../scanProcessing\";\nimport { ScanContent } from \"../ScanContent\";\nimport fs from \"fs/promises\";\nimport { convertToPdf, mergeToPdf } from \"../pdfProcessing\";\nimport { PaperlessConfig } from \"./PaperlessConfig\";\n\nexport async function uploadImagesAsSeparateDocumentsToPaperless(\n scanJobContent: ScanContent,\n paperlessConfig: PaperlessConfig,\n) {\n for (let i = 0; i < scanJobContent.elements.length; ++i) {\n const filePath = scanJobContent.elements[i].path;\n await uploadToPaperless(filePath, paperlessConfig);\n }\n}\n\nexport async function convertImagesToPdfAndUploadAsSeparateDocumentsToPaperless(\n scanJobContent: ScanContent,\n paperlessConfig: PaperlessConfig,\n) {\n for (let i = 0; i < scanJobContent.elements.length; ++i) {\n const pdfFilePath = await convertToPdf(\n scanJobContent.elements[i],\n !paperlessConfig.keepFiles,\n );\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n await fs.unlink(pdfFilePath);\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless for: \" +\n scanJobContent.elements[i].path,\n );\n }\n }\n}\n\nexport async function mergeToPdfAndUploadAsSingleDocumentToPaperless(\n folder: string,\n scanCount: number,\n scanJobContent: ScanContent,\n scanConfig: ScanConfig,\n scanDate: Date,\n paperlessConfig: PaperlessConfig,\n) {\n const pdfFilePath = await mergeToPdf(\n folder,\n scanCount,\n scanJobContent,\n scanConfig.directoryConfig.filePattern,\n scanDate,\n !paperlessConfig.keepFiles,\n );\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n await fs.unlink(pdfFilePath);\n console.log(\n `Pdf document ${pdfFilePath} has been removed from the filesystem`,\n );\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless\",\n );\n }\n}\n\nexport async function uploadPdfToPaperless(\n pdfFilePath: string | null,\n paperlessConfig: PaperlessConfig,\n) {\n if (pdfFilePath) {\n await uploadToPaperless(pdfFilePath, paperlessConfig);\n } else {\n console.log(\n \"Pdf generation has failed, nothing is going to be uploaded to paperless\",\n );\n }\n}\n\nasync function uploadToPaperless(\n filePath: string,\n paperlessConfig: PaperlessConfig,\n): Promise<void> {\n const url = paperlessConfig.postDocumentUrl;\n\n const authToken = paperlessConfig.authToken;\n\n const fileStream = fsSync.createReadStream(filePath);\n\n const form = new FormData();\n form.append(\"document\", fileStream);\n\n console.log(`Start uploading to paperless: ${filePath}`);\n try {\n const response = await axios.post(url, form, {\n headers: {\n ...form.getHeaders(),\n Authorization: `Token ${authToken}`,\n },\n });\n\n console.log(\"Document successfully uploaded to paperless:\", response.data);\n } catch (error) {\n console.error(\"Fail to upload document:\", error);\n }\n fileStream.close();\n}\n"]}
@@ -1,35 +1,60 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.postProcessing = void 0;
4
7
  const pdfProcessing_1 = require("./pdfProcessing");
5
8
  const paperless_1 = require("./paperless/paperless");
9
+ const nextcloud_1 = require("./nextcloud/nextcloud");
10
+ const promises_1 = __importDefault(require("fs/promises"));
6
11
  async function postProcessing(scanConfig, folder, tempFolder, scanCount, scanJobContent, scanDate, toPdf) {
7
- const paperlessConfig = scanConfig.paperlessConfig;
8
12
  if (toPdf) {
9
- const pdfFilePath = await (0, pdfProcessing_1.mergeToPdf)(paperlessConfig ? tempFolder : folder, scanCount, scanJobContent, scanConfig.directoryConfig.filePattern, scanDate, true);
13
+ await handlePdfPostProcessing(folder, tempFolder, scanCount, scanJobContent, scanDate, scanConfig);
14
+ }
15
+ else {
16
+ await handleImagePostProcessing(folder, scanCount, scanJobContent, scanDate, scanConfig);
17
+ }
18
+ }
19
+ exports.postProcessing = postProcessing;
20
+ async function handlePdfPostProcessing(folder, tempFolder, scanCount, scanJobContent, scanDate, scanConfig) {
21
+ const paperlessConfig = scanConfig.paperlessConfig;
22
+ const nextcloudConfig = scanConfig.nextcloudConfig;
23
+ const pdfFilePath = await (0, pdfProcessing_1.mergeToPdf)(paperlessConfig ? tempFolder : folder, scanCount, scanJobContent, scanConfig.directoryConfig.filePattern, scanDate, true);
24
+ if (pdfFilePath != null) {
10
25
  displayPdfScan(pdfFilePath, scanJobContent);
11
26
  if (paperlessConfig) {
12
27
  await (0, paperless_1.uploadPdfToPaperless)(pdfFilePath, paperlessConfig);
13
28
  }
29
+ if (nextcloudConfig) {
30
+ await (0, nextcloud_1.uploadPdfToNextcloud)(pdfFilePath, nextcloudConfig);
31
+ }
32
+ await cleanUpFilesIfNeeded([pdfFilePath], paperlessConfig, nextcloudConfig);
14
33
  }
15
- else {
16
- displayJpegScan(scanJobContent);
17
- if (paperlessConfig) {
18
- if (paperlessConfig.groupMultiPageScanIntoAPdf) {
19
- await (0, paperless_1.mergeToPdfAndUploadAsSingleDocumentToPaperless)(folder, scanCount, scanJobContent, scanConfig, scanDate, paperlessConfig);
34
+ }
35
+ async function handleImagePostProcessing(folder, scanCount, scanJobContent, scanDate, scanConfig) {
36
+ const paperlessConfig = scanConfig.paperlessConfig;
37
+ const nextcloudConfig = scanConfig.nextcloudConfig;
38
+ displayJpegScan(scanJobContent);
39
+ if (paperlessConfig) {
40
+ if (paperlessConfig.groupMultiPageScanIntoAPdf) {
41
+ await (0, paperless_1.mergeToPdfAndUploadAsSingleDocumentToPaperless)(folder, scanCount, scanJobContent, scanConfig, scanDate, paperlessConfig);
42
+ }
43
+ else {
44
+ if (paperlessConfig.alwaysSendAsPdfFile) {
45
+ await (0, paperless_1.convertImagesToPdfAndUploadAsSeparateDocumentsToPaperless)(scanJobContent, paperlessConfig);
20
46
  }
21
47
  else {
22
- if (paperlessConfig.alwaysSendAsPdfFile) {
23
- await (0, paperless_1.convertImagesToPdfAndUploadAsSeparateDocumentsToPaperless)(scanJobContent, paperlessConfig);
24
- }
25
- else {
26
- await (0, paperless_1.uploadImagesAsSeparateDocumentsToPaperless)(scanJobContent, paperlessConfig);
27
- }
48
+ await (0, paperless_1.uploadImagesAsSeparateDocumentsToPaperless)(scanJobContent, paperlessConfig);
28
49
  }
29
50
  }
30
51
  }
52
+ if (nextcloudConfig) {
53
+ await (0, nextcloud_1.uploadImagesToNextcloud)(scanJobContent, nextcloudConfig);
54
+ }
55
+ const filePaths = scanJobContent.elements.map((element) => element.path);
56
+ await cleanUpFilesIfNeeded(filePaths, paperlessConfig, nextcloudConfig);
31
57
  }
32
- exports.postProcessing = postProcessing;
33
58
  function displayPdfScan(pdfFilePath, scanJobContent) {
34
59
  if (pdfFilePath === null) {
35
60
  console.log(`Pdf generated has not been generated`);
@@ -41,4 +66,14 @@ function displayPdfScan(pdfFilePath, scanJobContent) {
41
66
  function displayJpegScan(scanJobContent) {
42
67
  scanJobContent.elements.forEach((e) => console.log(`\t- page ${e.pageNumber.toString().padStart(3, " ")} - ${e.width}x${e.height} - ${e.path}`));
43
68
  }
69
+ async function cleanUpFilesIfNeeded(filePaths, paperlessConfig, nextcloudConfig) {
70
+ var _a, _b;
71
+ let keepFiles = (_b = (_a = paperlessConfig === null || paperlessConfig === void 0 ? void 0 : paperlessConfig.keepFiles) !== null && _a !== void 0 ? _a : nextcloudConfig === null || nextcloudConfig === void 0 ? void 0 : nextcloudConfig.keepFiles) !== null && _b !== void 0 ? _b : true;
72
+ if (!keepFiles) {
73
+ await Promise.all(filePaths.map(async (filePath) => {
74
+ await promises_1.default.unlink(filePath);
75
+ console.log(`File ${filePath} has been removed from the filesystem`);
76
+ }));
77
+ }
78
+ }
44
79
  //# sourceMappingURL=postProcessing.js.map