From bd19e86008e2b405959ca27646f8bf4f829cc3fa Mon Sep 17 00:00:00 2001 From: walcutt Date: Tue, 24 Jun 2025 14:21:44 -0400 Subject: [PATCH] Integrate with actual filesystem for first functional draft --- index.js | 9 ----- src/command-config.js | 4 +-- src/commands/extract-to-se.js | 56 ++++++++++++++++++++++++++++- src/commands/finalize-filenames.js | 6 +++- src/constants/folders.js | 5 +++ src/pipeline.js | 58 +++++++++++++++++++++++++++--- 6 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 src/constants/folders.js diff --git a/index.js b/index.js index 251d84e..acc487d 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,6 @@ -import { getAllCommands } from "./src/parsing/parse-commands.js"; import { CreatePipeline } from "./src/pipeline.js"; -console.log("Raw params:"); -console.log(process); const params = process.argv.slice(2); -console.log("Executed with params:"); -console.log(params); -console.log("Got commands:"); -console.log(getAllCommands(params)); const pipeline = CreatePipeline(params); - -console.log("Running commands!"); await pipeline.run(); \ No newline at end of file diff --git a/src/command-config.js b/src/command-config.js index acebf82..c845c88 100644 --- a/src/command-config.js +++ b/src/command-config.js @@ -3,13 +3,13 @@ import { finalizeFileNames } from "./commands/finalize-filenames.js"; export const CommandConfig = [ { - name: 'ExtractToEpisodeNumber', + name: 'Extract To Episode Number', commands: ['-x'], params: [], func: extractToEpisodeNumber, }, { - name: 'FinalizeFileNames', + name: 'Finalize File Names', commands: ['-o'], params: ['ShowName'], func: finalizeFileNames, diff --git a/src/commands/extract-to-se.js b/src/commands/extract-to-se.js index f509533..16b28cd 100644 --- a/src/commands/extract-to-se.js +++ b/src/commands/extract-to-se.js @@ -1,3 +1,57 @@ +import fs from 'fs'; + +const acceptedPatternMappings = [ + { + name: 'Full match', + pattern: /([Ss][0-9]+[Ee][0-9]+)/, + mapper: (matches) => `${matches[0]}`, + }, + { + name: 'Space separated single number', + pattern: / ([0-9][0-9]+) /, + mapper: (matches) => `S01E${matches[0]}`, + }, + { + name: 'End of filename number, leading space', + pattern: / ([0-9][0-9]+)\./, + mapper: (matches) => `S01E${matches[0]}`, + }, + { + name: 'Underscore separated number', + pattern: /_([0-9][0-9]+)_/, + mapper: (matches) => `S01E${matches[0]}`, + }, + { + name: 'End of filename number, leading underscore', + pattern: /_([0-9][0-9]+)\./, + mapper: (matches) => `S01E${matches[0]}`, + }, + { + name: 'Any number >= 2 characters', + pattern: /([0-9][0-9]+)/, + mapper: (matches) => `S01E${matches[0]}`, + }, +]; + +const extensionPattern = /(\..*)$/; + export async function extractToEpisodeNumber(inputDir, inputFile, outputDir, options) { - console.log("Mapping!"); + await new Promise(resolve => setTimeout(resolve, 5000)); + for(let i = 0; i < acceptedPatternMappings.length; i++) { + const matches = inputFile.match(acceptedPatternMappings[i].pattern); + if(matches?.length > 0) { + const outputFileName = acceptedPatternMappings[i].mapper(matches); + + const extensionMatches = inputFile.match(extensionPattern); + + const extension = extensionMatches ? extensionMatches[0] : ''; + + const toWrite = `${outputDir}${outputFileName}${extension}`; + + fs.cpSync(`${inputDir}${inputFile}`, `${toWrite}`); + return true; + } + } + + return false; } \ No newline at end of file diff --git a/src/commands/finalize-filenames.js b/src/commands/finalize-filenames.js index b5771bf..09ae442 100644 --- a/src/commands/finalize-filenames.js +++ b/src/commands/finalize-filenames.js @@ -1,3 +1,7 @@ +import fs from 'fs'; + export async function finalizeFileNames(inputDir, inputFile, outputDir, { ShowName }) { - console.log(`Outputting as ${outputDir}/${ShowName} ${inputFile}`); + const toWrite = `${outputDir}${ShowName} ${inputFile}`; + + fs.cpSync(`${inputDir}${inputFile}`, `${toWrite}`); } \ No newline at end of file diff --git a/src/constants/folders.js b/src/constants/folders.js new file mode 100644 index 0000000..3518d0d --- /dev/null +++ b/src/constants/folders.js @@ -0,0 +1,5 @@ +export const Folders = { + INPUT: 'inputs/', + OUTPUT: 'outputs/', + TEMP: 'temp/', +}; \ No newline at end of file diff --git a/src/pipeline.js b/src/pipeline.js index 7aefd4c..1a655e8 100644 --- a/src/pipeline.js +++ b/src/pipeline.js @@ -1,4 +1,6 @@ +import { Folders } from "./constants/folders.js"; import { getAllCommands } from "./parsing/parse-commands.js"; +import fs from 'fs'; export function CreatePipeline(inputParams) { const commands = getAllCommands(inputParams); @@ -6,25 +8,71 @@ export function CreatePipeline(inputParams) { commands: commands, async run() { // Create /temp/Step-0 + if(fs.existsSync(Folders.TEMP)) { + fs.rmSync(Folders.TEMP, { recursive: true, force: true}); + } + fs.mkdirSync(Folders.TEMP); + // Copy /input/* -> /temp/Step-0 + fs.cpSync(Folders.INPUT, getTempFolderName(0), { recursive: true }); for(let i = 0; i < this.commands.length; i++) { - const inputDir = `/temp/Step-${i}`; - const outputDir = `/temp/Step-${i+1}`; - const files = ['S01E01.mkv', 'S01E02.mkv']; // Get from file system + const inputDir = getTempFolderName(i); + const outputDir = getTempFolderName(i + 1); + + fs.mkdirSync(outputDir); + + const fileEnts = fs.readdirSync(inputDir, { encoding: 'utf-8', withFileTypes: true }); + + const files = fileEnts.filter( + (ent) => ent.isFile() + ).map( + (ent) => ent.name + ); const func = this.commands[i].func; const params = this.commands[i].parameters; - - for(let k = 0; k < files.length; k++) { + process.stdout.write(`${getStatus(this.commands[i].command, k, files.length)}\r`); const result = await func(inputDir, files[k], outputDir, params); } + process.stdout.write(`${getStatus(this.commands[i].command, files.length, files.length)}\n`); } // Copy /temp/Step-L/* -> /output + if(fs.existsSync(Folders.OUTPUT)) { + fs.rmSync(Folders.OUTPUT, { recursive: true, force: true }); + } + + fs.cpSync(getTempFolderName(this.commands.length), Folders.OUTPUT, { recursive: true }); + // remove /temp/* + fs.rmSync(Folders.TEMP, { recursive: true, force: true }); }, }; +} + +function getTempFolderName(i) { + return `${Folders.TEMP}step-${i}/`; +} + +function getStatus(stepName, currentIndex, size) { + const BAR_SIZE = 15; + let bar = `[`; + let ratio = currentIndex / size; + const percent = Math.floor(ratio * 100); + + for(let i = 0; i < BAR_SIZE; i++) { + let charRatio = (i / BAR_SIZE); + if(charRatio < ratio) { + bar += '='; + } else { + bar += ' '; + } + } + + bar += ']'; + + return `${stepName}: ${bar} ${percent}%`; } \ No newline at end of file