Skip to content

Instantly share code, notes, and snippets.

@pmunin
Last active December 20, 2022 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmunin/1bb9991eabeb65eb1ec1c84fc47c42ed to your computer and use it in GitHub Desktop.
Save pmunin/1bb9991eabeb65eb1ec1c84fc47c42ed to your computer and use it in GitHub Desktop.
Script allowing to Sort double sided scanned files. Requires Node.js 10+ to be installed and convert files (pdj->jpg)
node %~dp0convert-2jpg.js %*
pause
// Need to install the following in order to run this script:
// 1) http://www.imagemagick.org/script/download.php#windows
// 2) https://www.ghostscript.com/releases/gsdnld.html
/*
1) Select scanned files in your Windows Explorer.
2) Drag and drop selected files on the convert-pdf2png.bat file
*/
const fs = require('fs');
const path = require('path');
const process = require('process');
const stdin = process.stdin;
const readline = require('readline');
const { spawn, execSync } = require('child_process')
function getKeypress() {
return new Promise(resolve => {
const stdin = process.stdin;
stdin.setRawMode(true);
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
stdin.resume();
// i don't want binary, do you?
stdin.setEncoding('utf8');
// on any data into stdin
stdin.once('data', function(key) {
if (key === '\u0003') process.exit();
resolve(key);
});
})
}
function readLineAsync(question){
return new Promise((resolve, reject)=>{
const rl = readline.createInterface({ input: stdin })
const answer = rl.question(question, answer=>{
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
resolve(answer);
});
})
}
async function choseProfile()
{
const defaultProfiles = [
{
"output-name-suffix": "-%04d",
"output-ext":".jpg",
"magick-args":[
"-quality 80",
"-density 200",
]
},
{
"output-name-suffix": "-%04d",
"output-ext":".jpg",
"magick-args":[
"-quality 80",
]
},
{
"output-name-suffix": "-%04d",
"output-ext":".png",
"magick-args":[
"-quality 80",
"-density 200",
]
},
]
let profiles = defaultProfiles
const currentDir = __dirname
const profilesFileName = 'convert-2jpg.profiles.json'
console.log("Reading convert-2jpg.profile.json from current directory", currentDir)
if(fs.existsSync(path.resolve(currentDir, profilesFileName)))
profiles = JSON.parse(fs.readFileSync(profilesFileName, 'utf8'))
console.log("Chose profile:")
profiles.forEach((profile, index) => {
console.log(`${index+1}:\n`, profile)
})
const profileNum = Number.parseInt(await readLineAsync("Which profile?"))-1 || 0
console.log("Selected profile", profiles[profileNum])
return profiles[profileNum]
}
(async() => {
// readline.emitKeypressEvents(process.stdin);
// process.stdin.setRawMode(true);
const profile = await choseProfile()
const files = process.argv.slice(2).sort();
console.log(`Files to convert:`);
const zeroPad = (num, places) => String(num).padStart(places, '0')
var renames = files.map((filePath, index) => {
const fileParsed = path.parse(filePath)
const newName = path.format({
...fileParsed,
base: undefined,
name: fileParsed.name+profile['output-name-suffix'],
ext: profile['output-ext']
})
return { file: filePath, newName };
});
console.log('=== Conversions: ===');
console.log(renames.map(ren => {
return `${ren.file} => ${path.parse(ren.newName).base}`;
}).join('\n'));
console.log("Press a key to proceed...")
await getKeypress();
renames.forEach(ren => {
console.log('Converting', ren.file, 'to', ren.newName, '...')
const bat = execSync(`magick convert ${profile['magick-args'].join(' ')} \"${ren.file}\" \"${ren.newName}\"`, { stdio: 'inherit' })
});
console.log("Successfully finished");
})().catch(e => {
console.error(e);
throw e;
})
.finally(() => {
process.exit();
});
node %~dp0sort2sidedScans.js %*
pause
/*
1) Select scanned files in your Windows Explorer.
2) Drag and drop selected files on the sort2sidedScans.bat file
*/
(async() => {
const fs = require('fs');
const process = require('process');
const path = require('path');
const readline = require('readline');
// readline.emitKeypressEvents(process.stdin);
// process.stdin.setRawMode(true);
function getKeypress() {
return new Promise(resolve => {
const stdin = process.stdin;
stdin.setRawMode(true);
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
stdin.resume();
// i don't want binary, do you?
stdin.setEncoding('utf8');
// on any data into stdin
stdin.once('data', function(key) {
if (key === '\u0003') process.exit();
resolve(key);
});
})
}
const files = process.argv.slice(2).sort();
if (files.length % 2 !== 0) throw new Error(`The amount of files should be even. Passed amount of files: ${files.length}. The following files are passed:${files.join('\n')}`)
console.log(`Files to sort (${files.length}):\n`, files.join('\n'));
const sideAFiles = files.slice(0, files.length / 2);
let sideBFiles = files.slice(files.length / 2);
console.log('Files of side A:\n', sideAFiles.join('\n'));
console.log('Files of side B:\n', sideBFiles.join('\n'));
sideBFiles = sideBFiles.reverse();
var resFiles = sideAFiles.flatMap((aFile, index) => [aFile, sideBFiles[index]]);
const zeroPad = (num, places) => String(num).padStart(places, '0')
var renames = resFiles.map((filePath, index) => {
const ext = path.extname(filePath);
return { file: filePath, newName: `${zeroPad(index+1, 4)}${ext}` };
});
console.log('=== New file names: ===');
console.log(renames.map(ren => {
return `${ren.file} => ${ren.newName}`;
}).join('\n'));
console.log("Press a key to proceed creating renamed copies...")
await getKeypress();
renames.forEach(ren => {
let dest = path.join(path.dirname(ren.file), ren.newName);
fs.copyFileSync(ren.file, dest);
});
console.log("Successfully finished");
// files.forEach((val, index, array) => {
// console.log(`${index}:` + val + "\n");
// });
})().catch(e => {
console.error(e);
throw e;
})
.finally(() => {
process.exit();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment