Remove unused file
This commit is contained in:
parent
fa238c37d1
commit
4959ba404f
401
test.ts
401
test.ts
|
@ -1,401 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
// This code was bundled using `deno bundle` and it's not recommended to edit it manually
|
|
||||||
|
|
||||||
class DenoStdInternalError extends Error {
|
|
||||||
constructor(message){
|
|
||||||
super(message);
|
|
||||||
this.name = "DenoStdInternalError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function assert(expr, msg = "") {
|
|
||||||
if (!expr) {
|
|
||||||
throw new DenoStdInternalError(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { hasOwn } = Object;
|
|
||||||
function get(obj, key) {
|
|
||||||
if (hasOwn(obj, key)) {
|
|
||||||
return obj[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getForce(obj, key) {
|
|
||||||
const v = get(obj, key);
|
|
||||||
assert(v != null);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
function isNumber(x) {
|
|
||||||
if (typeof x === "number") return true;
|
|
||||||
if (/^0x[0-9a-f]+$/i.test(String(x))) return true;
|
|
||||||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
|
|
||||||
}
|
|
||||||
function hasKey(obj, keys) {
|
|
||||||
let o = obj;
|
|
||||||
keys.slice(0, -1).forEach((key)=>{
|
|
||||||
o = get(o, key) ?? {};
|
|
||||||
});
|
|
||||||
const key = keys[keys.length - 1];
|
|
||||||
return hasOwn(o, key);
|
|
||||||
}
|
|
||||||
function parse(args, { "--": doubleDash = false , alias ={} , boolean: __boolean = false , default: defaults = {} , stopEarly =false , string =[] , collect =[] , negatable =[] , unknown =(i)=>i } = {}) {
|
|
||||||
const aliases = {};
|
|
||||||
const flags = {
|
|
||||||
bools: {},
|
|
||||||
strings: {},
|
|
||||||
unknownFn: unknown,
|
|
||||||
allBools: false,
|
|
||||||
collect: {},
|
|
||||||
negatable: {}
|
|
||||||
};
|
|
||||||
if (alias !== undefined) {
|
|
||||||
for(const key in alias){
|
|
||||||
const val = getForce(alias, key);
|
|
||||||
if (typeof val === "string") {
|
|
||||||
aliases[key] = [
|
|
||||||
val
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
aliases[key] = val;
|
|
||||||
}
|
|
||||||
for (const alias1 of getForce(aliases, key)){
|
|
||||||
aliases[alias1] = [
|
|
||||||
key
|
|
||||||
].concat(aliases[key].filter((y)=>alias1 !== y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__boolean !== undefined) {
|
|
||||||
if (typeof __boolean === "boolean") {
|
|
||||||
flags.allBools = !!__boolean;
|
|
||||||
} else {
|
|
||||||
const booleanArgs = typeof __boolean === "string" ? [
|
|
||||||
__boolean
|
|
||||||
] : __boolean;
|
|
||||||
for (const key1 of booleanArgs.filter(Boolean)){
|
|
||||||
flags.bools[key1] = true;
|
|
||||||
const alias2 = get(aliases, key1);
|
|
||||||
if (alias2) {
|
|
||||||
for (const al of alias2){
|
|
||||||
flags.bools[al] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (string !== undefined) {
|
|
||||||
const stringArgs = typeof string === "string" ? [
|
|
||||||
string
|
|
||||||
] : string;
|
|
||||||
for (const key2 of stringArgs.filter(Boolean)){
|
|
||||||
flags.strings[key2] = true;
|
|
||||||
const alias3 = get(aliases, key2);
|
|
||||||
if (alias3) {
|
|
||||||
for (const al1 of alias3){
|
|
||||||
flags.strings[al1] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (collect !== undefined) {
|
|
||||||
const collectArgs = typeof collect === "string" ? [
|
|
||||||
collect
|
|
||||||
] : collect;
|
|
||||||
for (const key3 of collectArgs.filter(Boolean)){
|
|
||||||
flags.collect[key3] = true;
|
|
||||||
const alias4 = get(aliases, key3);
|
|
||||||
if (alias4) {
|
|
||||||
for (const al2 of alias4){
|
|
||||||
flags.collect[al2] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (negatable !== undefined) {
|
|
||||||
const negatableArgs = typeof negatable === "string" ? [
|
|
||||||
negatable
|
|
||||||
] : negatable;
|
|
||||||
for (const key4 of negatableArgs.filter(Boolean)){
|
|
||||||
flags.negatable[key4] = true;
|
|
||||||
const alias5 = get(aliases, key4);
|
|
||||||
if (alias5) {
|
|
||||||
for (const al3 of alias5){
|
|
||||||
flags.negatable[al3] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const argv = {
|
|
||||||
_: []
|
|
||||||
};
|
|
||||||
function argDefined(key, arg) {
|
|
||||||
return flags.allBools && /^--[^=]+$/.test(arg) || get(flags.bools, key) || !!get(flags.strings, key) || !!get(aliases, key);
|
|
||||||
}
|
|
||||||
function setKey(obj, name, value, collect = true) {
|
|
||||||
let o = obj;
|
|
||||||
const keys = name.split(".");
|
|
||||||
keys.slice(0, -1).forEach(function(key) {
|
|
||||||
if (get(o, key) === undefined) {
|
|
||||||
o[key] = {};
|
|
||||||
}
|
|
||||||
o = get(o, key);
|
|
||||||
});
|
|
||||||
const key = keys[keys.length - 1];
|
|
||||||
const collectable = collect && !!get(flags.collect, name);
|
|
||||||
if (!collectable) {
|
|
||||||
o[key] = value;
|
|
||||||
} else if (get(o, key) === undefined) {
|
|
||||||
o[key] = [
|
|
||||||
value
|
|
||||||
];
|
|
||||||
} else if (Array.isArray(get(o, key))) {
|
|
||||||
o[key].push(value);
|
|
||||||
} else {
|
|
||||||
o[key] = [
|
|
||||||
get(o, key),
|
|
||||||
value
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setArg(key, val, arg = undefined, collect) {
|
|
||||||
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
|
||||||
if (flags.unknownFn(arg, key, val) === false) return;
|
|
||||||
}
|
|
||||||
const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
|
|
||||||
setKey(argv, key, value, collect);
|
|
||||||
const alias = get(aliases, key);
|
|
||||||
if (alias) {
|
|
||||||
for (const x of alias){
|
|
||||||
setKey(argv, x, value, collect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function aliasIsBoolean(key) {
|
|
||||||
return getForce(aliases, key).some((x)=>typeof get(flags.bools, x) === "boolean");
|
|
||||||
}
|
|
||||||
let notFlags = [];
|
|
||||||
if (args.includes("--")) {
|
|
||||||
notFlags = args.slice(args.indexOf("--") + 1);
|
|
||||||
args = args.slice(0, args.indexOf("--"));
|
|
||||||
}
|
|
||||||
for(let i = 0; i < args.length; i++){
|
|
||||||
const arg = args[i];
|
|
||||||
if (/^--.+=/.test(arg)) {
|
|
||||||
const m = arg.match(/^--([^=]+)=(.*)$/s);
|
|
||||||
assert(m != null);
|
|
||||||
const [, key5, value] = m;
|
|
||||||
if (flags.bools[key5]) {
|
|
||||||
const booleanValue = value !== "false";
|
|
||||||
setArg(key5, booleanValue, arg);
|
|
||||||
} else {
|
|
||||||
setArg(key5, value, arg);
|
|
||||||
}
|
|
||||||
} else if (/^--no-.+/.test(arg) && get(flags.negatable, arg.replace(/^--no-/, ""))) {
|
|
||||||
const m1 = arg.match(/^--no-(.+)/);
|
|
||||||
assert(m1 != null);
|
|
||||||
setArg(m1[1], false, arg, false);
|
|
||||||
} else if (/^--.+/.test(arg)) {
|
|
||||||
const m2 = arg.match(/^--(.+)/);
|
|
||||||
assert(m2 != null);
|
|
||||||
const [, key6] = m2;
|
|
||||||
const next = args[i + 1];
|
|
||||||
if (next !== undefined && !/^-/.test(next) && !get(flags.bools, key6) && !flags.allBools && (get(aliases, key6) ? !aliasIsBoolean(key6) : true)) {
|
|
||||||
setArg(key6, next, arg);
|
|
||||||
i++;
|
|
||||||
} else if (/^(true|false)$/.test(next)) {
|
|
||||||
setArg(key6, next === "true", arg);
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
setArg(key6, get(flags.strings, key6) ? "" : true, arg);
|
|
||||||
}
|
|
||||||
} else if (/^-[^-]+/.test(arg)) {
|
|
||||||
const letters = arg.slice(1, -1).split("");
|
|
||||||
let broken = false;
|
|
||||||
for(let j = 0; j < letters.length; j++){
|
|
||||||
const next1 = arg.slice(j + 2);
|
|
||||||
if (next1 === "-") {
|
|
||||||
setArg(letters[j], next1, arg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next1)) {
|
|
||||||
setArg(letters[j], next1.split(/=(.+)/)[1], arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next1)) {
|
|
||||||
setArg(letters[j], next1, arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
|
||||||
setArg(letters[j], arg.slice(j + 2), arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const [key7] = arg.slice(-1);
|
|
||||||
if (!broken && key7 !== "-") {
|
|
||||||
if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1]) && !get(flags.bools, key7) && (get(aliases, key7) ? !aliasIsBoolean(key7) : true)) {
|
|
||||||
setArg(key7, args[i + 1], arg);
|
|
||||||
i++;
|
|
||||||
} else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
|
|
||||||
setArg(key7, args[i + 1] === "true", arg);
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
setArg(key7, get(flags.strings, key7) ? "" : true, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|
||||||
argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
|
|
||||||
}
|
|
||||||
if (stopEarly) {
|
|
||||||
argv._.push(...args.slice(i + 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [key8, value1] of Object.entries(defaults)){
|
|
||||||
if (!hasKey(argv, key8.split("."))) {
|
|
||||||
setKey(argv, key8, value1);
|
|
||||||
if (aliases[key8]) {
|
|
||||||
for (const x of aliases[key8]){
|
|
||||||
setKey(argv, x, value1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const key9 of Object.keys(flags.bools)){
|
|
||||||
if (!hasKey(argv, key9.split("."))) {
|
|
||||||
const value2 = get(flags.collect, key9) ? [] : false;
|
|
||||||
setKey(argv, key9, value2, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const key10 of Object.keys(flags.strings)){
|
|
||||||
if (!hasKey(argv, key10.split(".")) && get(flags.collect, key10)) {
|
|
||||||
setKey(argv, key10, [], false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doubleDash) {
|
|
||||||
argv["--"] = [];
|
|
||||||
for (const key11 of notFlags){
|
|
||||||
argv["--"].push(key11);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const key12 of notFlags){
|
|
||||||
argv._.push(key12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return argv;
|
|
||||||
}
|
|
||||||
const DEFAULT_BUFFER_SIZE = 32 * 1024;
|
|
||||||
async function* iterateReader(r, options) {
|
|
||||||
const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE;
|
|
||||||
const b = new Uint8Array(bufSize);
|
|
||||||
while(true){
|
|
||||||
const result = await r.read(b);
|
|
||||||
if (result === null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
yield b.slice(0, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const getRandomString = ()=>`${+new Date()}-${Math.round(Math.random() * 100000)}`;
|
|
||||||
(async ()=>{
|
|
||||||
const tempDir = await Deno.makeTempDir();
|
|
||||||
const args = parse(Deno.args);
|
|
||||||
if (args.help || args.h) {
|
|
||||||
console.log(`
|
|
||||||
Usage: scan2paperless [OPTION] [NAME]
|
|
||||||
|
|
||||||
Scan one or multiple pages into a PDF document ready for consumption by paperless
|
|
||||||
|
|
||||||
NAME will be the name of the document without extension.
|
|
||||||
|
|
||||||
Available options:
|
|
||||||
-d | --device=DEVICE Scanner device to use. Check \`scanimage -L\` for available devices.
|
|
||||||
This defaults to \$SCANNER_DEFAULT_DEVICE
|
|
||||||
-o | --output-dir=DIR Directory to write final PDF to. This defaults to \$SCANNER_OUTPUT_DIR
|
|
||||||
-h | --help show this help message
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
scan2paperless \
|
|
||||||
-d hp3900:libusb:005:002 \
|
|
||||||
-n 5 \
|
|
||||||
-o /var/lib/paperless/consume \
|
|
||||||
bank-statement-01-2023
|
|
||||||
`);
|
|
||||||
Deno.exit(0);
|
|
||||||
}
|
|
||||||
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 outputName = args._[0] || getRandomString();
|
|
||||||
const files = [];
|
|
||||||
let cancelled = false;
|
|
||||||
do {
|
|
||||||
const fileName = `${tempDir}/${getRandomString()}.jpg`;
|
|
||||||
const scanimageProcess = Deno.run({
|
|
||||||
cmd: [
|
|
||||||
"scanimage",
|
|
||||||
"-d",
|
|
||||||
device,
|
|
||||||
"--format=jpeg",
|
|
||||||
"--resolution",
|
|
||||||
"300",
|
|
||||||
"--progress",
|
|
||||||
"-o",
|
|
||||||
fileName,
|
|
||||||
],
|
|
||||||
stderr: 'piped'
|
|
||||||
});
|
|
||||||
const decoder = new TextDecoder();
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
let inScan = false;
|
|
||||||
for await (const chunk of iterateReader(scanimageProcess.stderr)){
|
|
||||||
const line = decoder.decode(chunk);
|
|
||||||
if (!inScan && line.startsWith('Progress: ')) {
|
|
||||||
inScan = true;
|
|
||||||
Deno.kill(scanimageProcess.pid, 'SIGSTOP');
|
|
||||||
const answer = prompt("Scan next page? [Y/n]");
|
|
||||||
if (answer && ![
|
|
||||||
'y',
|
|
||||||
'yes'
|
|
||||||
].includes(answer.toLowerCase())) {
|
|
||||||
Deno.kill(scanimageProcess.pid, 'SIGKILL');
|
|
||||||
cancelled = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
Deno.kill(scanimageProcess.pid, 'SIGCONT');
|
|
||||||
cancelled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Deno.stdout.write(encoder.encode(`\r${line}`));
|
|
||||||
}
|
|
||||||
const status = await scanimageProcess.status();
|
|
||||||
scanimageProcess.stderr.close();
|
|
||||||
if (!cancelled && status.code !== 0) {
|
|
||||||
console.error('Scan seems to have failed with status ', status.code);
|
|
||||||
}
|
|
||||||
if (!cancelled) {
|
|
||||||
files.push(fileName);
|
|
||||||
}
|
|
||||||
}while (!cancelled)
|
|
||||||
const pdfFile = `${outputDir}/${outputName}.pdf`;
|
|
||||||
const img2pdfProcess = Deno.run({
|
|
||||||
cmd: [
|
|
||||||
"img2pdf",
|
|
||||||
"--output",
|
|
||||||
pdfFile,
|
|
||||||
...files,
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const pdfStatus = await img2pdfProcess.status();
|
|
||||||
if (pdfStatus.code !== 0) {
|
|
||||||
console.error('Error writing PDF');
|
|
||||||
Deno.exit(2);
|
|
||||||
}
|
|
||||||
console.log(`PDF written to ${pdfFile}`);
|
|
||||||
})();
|
|
||||||
|
|
Loading…
Reference in a new issue