Add automatic mode

This commit is contained in:
Benjamin Bädorf 2023-02-08 17:32:05 +01:00
parent 215649dc32
commit c99f2209fc
No known key found for this signature in database
GPG key ID: 4406E80E13CD656C
3 changed files with 47 additions and 30 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
tags tags
.direnv .direnv
_site _site
result

View file

@ -17,10 +17,13 @@ final: prev:
python39Packages.img2pdf python39Packages.img2pdf
]; ];
additionalDenoFlags = "--allow-write --allow-env --allow-run";
# TODO: Find out why allow does not work here
allow = { allow = {
"write" = true; write = true;
"env" = true; env = true;
"run" = true; run = true;
}; };
}; };
}; };

View file

@ -3,44 +3,46 @@ import { iterateReader } from "std/streams/iterate_reader";
const getRandomString = () => `${+(new Date())}-${Math.round(Math.random() * 100000)}`; const getRandomString = () => `${+(new Date())}-${Math.round(Math.random() * 100000)}`;
(async () => { const decoder = new TextDecoder();
const tempDir = await Deno.makeTempDir(); const encoder = new TextEncoder();
(async () => {
const args = parse(Deno.args); const args = parse(Deno.args);
if (args.help || args.h) { if (args.help || args.h) {
console.log(` console.log(`Usage: scan2paperless [OPTION] [NAME]
Usage: scan2paperless [OPTION] [NAME]
Scan one or multiple pages into a PDF document ready for consumption by paperless Scan one or multiple pages into a PDF document ready for consumption by paperless
NAME will be the name of the document without extension. NAME will be the name of the document without extension.
Available options: Available options:
-d | --device=DEVICE Scanner device to use. Check \`scanimage -L\` for available devices. -d | --device=DEVICE Scanner device to use. Check \`scanimage -L\` for available devices.
This defaults to \$SCANNER_DEFAULT_DEVICE This defaults to \$SCANNER_DEFAULT_DEVICE
-n | --pages=NUMBER Number of pages to scan. If you don't specify this, scan2paperless
will ask you if you want to continue.
-a | --auto Don't pause between pages. Only has an effect if --pages is set.
-o | --output-dir=DIR Directory to write final PDF to. This defaults to \$SCANNER_OUTPUT_DIR -o | --output-dir=DIR Directory to write final PDF to. This defaults to \$SCANNER_OUTPUT_DIR
-h | --help show this help message -h | --help show this help message
Example: Example:
scan2paperless \ scan2paperless \\
-d hp3900:libusb:005:002 \ -d hp3900:libusb:005:002 \\
-n 5 \ -n 5 \\
-o /var/lib/paperless/consume \ -o /var/lib/paperless/consume \\
bank-statement-01-2023 bank-statement-01-2023
`); `);
Deno.exit(0); Deno.exit(0);
} }
const tempDir = await Deno.makeTempDir();
const device = args.d || args.device || Deno.env.get('SCANNER_DEFAULT_DEVICE'); const device = args.d || args.device || Deno.env.get('SCANNER_DEFAULT_DEVICE');
const outputDir = args.d || args.device || Deno.env.get('SCANNER_OUTPUT_DIR'); const outputDir = args.d || args.device || Deno.env.get('SCANNER_OUTPUT_DIR');
const outputName = args._[0] || getRandomString(); const outputName = args._[0] || getRandomString();
/*
const pagesToScanStr = args.n || args.pages; const pagesToScanStr = args.n || args.pages;
const pagesToScan = (() => { const pagesToScan = (() => {
if (!pagesToScanStr) { if (!pagesToScanStr) {
return Infinity; return Infinity;
@ -55,13 +57,19 @@ const getRandomString = () => `${+(new Date())}-${Math.round(Math.random() * 10
return pagesToScanInt; return pagesToScanInt;
})(); })();
let pagesScanned = 0;
*/ const automatic = (!!(args.a || args.auto) && pagesToScan < Infinity);
const files = []; const files = [];
let pagesScanned = 0;
let cancelled = false; let cancelled = false;
do { do {
const fileName = `${tempDir}/${getRandomString()}.jpg`; const fileName = `${tempDir}/${getRandomString()}.jpg`;
console.log(`Start scanning page ${pagesScanned + 1}`);
console.log(`Writing to ${fileName}`);
const scanimageProcess = Deno.run({ const scanimageProcess = Deno.run({
cmd: [ cmd: [
"scanimage", "scanimage",
@ -75,18 +83,21 @@ const getRandomString = () => `${+(new Date())}-${Math.round(Math.random() * 10
stderr: 'piped', stderr: 'piped',
}); });
const decoder = new TextDecoder();
const encoder = new TextEncoder();
let inScan = false; let inScan = false;
for await (const chunk of iterateReader(scanimageProcess.stderr)) { for await (const chunk of iterateReader(scanimageProcess.stderr)) {
const line = decoder.decode(chunk); const line = decoder.decode(chunk);
if (!inScan && line.startsWith('Progress: ')) { if (
!automatic
&& pagesScanned !== 0
&& !inScan
&& line.startsWith('Progress: ')
) {
inScan = true; inScan = true;
Deno.kill(scanimageProcess.pid, 'SIGSTOP'); Deno.kill(scanimageProcess.pid, 'SIGSTOP');
const answer = prompt("Scan next page? [Y/n]"); const answer = prompt(`Run another scan? (number ${pagesScanned + 1}) [Y/n]`);
if (answer && !['y', 'yes'].includes(answer.toLowerCase())) { if (answer && !['y', 'yes'].includes(answer.toLowerCase())) {
Deno.kill(scanimageProcess.pid, 'SIGKILL'); Deno.kill(scanimageProcess.pid, 'SIGKILL');
@ -108,10 +119,12 @@ const getRandomString = () => `${+(new Date())}-${Math.round(Math.random() * 10
console.error('Scan seems to have failed with status ', status.code); console.error('Scan seems to have failed with status ', status.code);
} }
pagesScanned++;
if (!cancelled) { if (!cancelled) {
files.push(fileName); files.push(fileName);
} }
} while(!cancelled); } while(!cancelled && (automatic ? pagesScanned < pagesToScan : true));
const pdfFile = `${outputDir}/${outputName}.pdf`; const pdfFile = `${outputDir}/${outputName}.pdf`;
const img2pdfProcess = Deno.run({ const img2pdfProcess = Deno.run({