I'm trying to write a script which should sort files in a folder in a particular way.
Code: Select all
import fs from "fs";
import path from "path";
import tmp from 'tmp-promise';
function naturalSort(arr: String[]){
return arr.map(v => {
let processedName = [];
let str = v;
for(let i = 0; i < str.length; i++) {
let isNum = Number.isInteger(Number(str[i]));
let j;
for(j = i + 1; j < str.length; j++) {
if(Number.isInteger(Number(str[j])) != isNum) {
break;
}
}
processedName.push(isNum ? Number(str.slice(i, j)) : str.slice(i, j));
i = j - 1;
}
return processedName;
}).sort((a, b ) => {
let len = Math.min(a.length, b.length);
for(let i = 0; i < len; i++) {
if(a[i] != b[i]) {
let isNumA = Number.isInteger(a[i]);
let isNumB = Number.isInteger(b[i]);
if(isNumA && isNumB) {
return Number(a[i]) - Number(b[i]);
} else if(isNumA) {
return -1;
} else if(isNumB) {
return 1;
} else {
return a[i] < b[i] ? -1 : 1 ;
}
}
}
// in case of one string being a prefix of the other
return a.length - b.length;
}).map(v => v.join(''));
}
async function getFiles(dir: string) {
const items = await fs.promises.readdir(dir);
const files = [];
for (const item of items) {
const itemPath = path.join(dir, item);
const itemStat = await fs.promises.stat(itemPath);
if (itemStat.isDirectory()) {
return false;
} else {
files.push(itemPath);
}
}
return files;
}
async function jobArrived(s: Switch, flowElement: FlowElement, job: Job) {
try {
const jobPath = await job.get(AccessLevel.ReadOnly);
if (job.isFile()) {
job.fail('You can only sort the contents of a job folder. Nothing can be done to single files.');
return;
} else {
let files = await getFiles(jobPath);
if (!files) {
job.fail('Nested folders are unsupported, please supply a folder of loose files only.');
return;
} else {
files = naturalSort(files);
}
// Calculate how many zeros we need to pad the filenames with - this is the length of the number of items rather than the number of items itself.
const padding = String(files.length).length;
// Set a counter to add to the new filenames.
let counter = 1;
tmp.withDir(async o => {
await Promise.all(
// @ts-ignore
files.map(async (file: string) => {
const newPath = path.join(o.path, `${String(counter).padStart(padding, '0')}_${path.basename(file)}`);
counter++;
await fs.promises.copyFile(file, newPath);
})
);
// Once we have copied all of the files, convert the new folder to a job and pass it to the flow.
const newJobFolder = await job.createChild(o.path);
await newJobFolder.sendToSingle();
// Discard the original files.
await job.log(LogLevel.Info, "'%1' was sent to null.", [job.getName()]);
// await job.sendToNull();
}, { unsafeCleanup: true, prefix: 'SORT' });
}
} catch (e) {
job.fail("Failed to process the job '%1': %2", [job.getName(), (e as Error).message]);
}
}
I try to run the debugger to find out where the issue is but my breakpoints are completely ignored and the only way to stop Switch to stop processing my test folder is to force quit Switch all together.The script execution has ended while an async function or callback in the script might not have finished yet. Please check the script code for unresolved promises or missing await statements.
Can anyone offer any advice as to why this isn't working?
Thanks