From 3eabcbee733d65434afc9c7d461236ea731678c3 Mon Sep 17 00:00:00 2001 From: velvettear Date: Fri, 24 Mar 2017 21:23:29 +0100 Subject: [PATCH] finished basic sorting functionality --- badger-am.js | 155 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 61 deletions(-) diff --git a/badger-am.js b/badger-am.js index 1e742f1..1549084 100755 --- a/badger-am.js +++ b/badger-am.js @@ -12,6 +12,9 @@ const metadata = require('musicmetadata'); const progress = require('progress'); const app = require('./package.json'); +// generate timestamp +const start = process.hrtime(); + // general options commander .version(app.version) @@ -41,33 +44,35 @@ commander // parse command line arguments commander.parse(process.argv); -// functions +// sort files function sort(input, output, options) { - const start = process.hrtime(); const concurrency = commander.concurrency; - console.log('--- SORT MODE ---'); - console.log('concurrency: ' + concurrency); - // get files in input directory - recursive(input, [ignoreFilter], function (err, files) { - if (err) { - exit(err); - } - // display progressbar - const bar = createProgressBar(files.length); - // handle each file - async.eachLimit(files, concurrency, function (file, eachCallback) { - handleSource(output, file, function (err) { - bar.tick(); + async.waterfall([ + function (asyncCallback) { + recursive(input, [ignoreFilter], asyncCallback); + }, + function (files, asyncCallback) { + console.log(files.length + ' \'' + options.format + '\' files found'); + // display progressbar + const bar = createProgressBar(files.length); + // handle each file + async.eachLimit(files, concurrency, function (file, eachCallback) { + processFile(output, file, function (err) { + bar.tick(); + if (err) { + return eachCallback(err); + } + eachCallback(); + }); + }, function (err) { if (err) { - return eachCallback(err); + return asyncCallback(err); } - eachCallback(); + asyncCallback(); }); - }, function (err) { - const diff = process.hrtime(start); - console.log('done after ' + (diff[0] * 1000 + diff[1] / 1000000) + ' milliseconds'); - exit(err); - }); + } + ], function (err, result) { + exit(err); }); function ignoreFilter(file, stats) { @@ -75,24 +80,18 @@ function sort(input, output, options) { } } -function exit(err) { - if (err) { - console.error(err); - process.exit(1); - } - console.log('DONE'); - process.exit(0); -} - -function handleSource(output, file, callback) { +// move file to location defined by its metadata +function processFile(output, sourceFile, callback) { async.waterfall([ function (asyncCallback) { - extractMetadata(file, asyncCallback) + extractMetadata(sourceFile, asyncCallback) }, - function (metadata, asyncCallback) { - pathFromMetadata(output, metadata, asyncCallback); + function (sourceFile, metadata, asyncCallback) { + pathFromMetadata(sourceFile, output, metadata, asyncCallback); + }, + function (targetFile, asyncCallback) { + moveFile(sourceFile, targetFile, asyncCallback); } - // TODO: create output directory, append file extension and move file ], function (err, results) { if (err) { return callback(err); @@ -101,20 +100,22 @@ function handleSource(output, file, callback) { }); } -function extractMetadata(file, callback) { - const stream = fs.createReadStream(file); +// extract metadata for further processing +function extractMetadata(sourceFile, callback) { + const stream = fs.createReadStream(sourceFile); metadata(stream, function (err, metadata) { if (err) { return callback(err); } stream.close(); - callback(null, metadata) + callback(null, sourceFile, metadata) }); } -function pathFromMetadata(output, metadata, callback) { +// create path for target file +function pathFromMetadata(file, output, metadata, callback) { // define directory - let directory = path.normalize(path.join(output)); + let filePath = path.normalize(output); if (metadata.albumartist && metadata.albumartist.length > 0) { let tmp; const artistCount = metadata.albumartist.length; @@ -125,45 +126,77 @@ function pathFromMetadata(output, metadata, callback) { tmp = metadata.albumartist[counter]; } } - directory = path.join(directory, tmp); + filePath = path.join(filePath, tmp); } else { - directory = path.join(directory, metadata.artist[0]); + filePath = path.join(filePath, metadata.artist[0]); } if (metadata.album) { - directory = path.join(directory, metadata.album); + filePath = path.join(filePath, metadata.album); } // define filename - let file = ''; + let fileName = ''; if (metadata.disk.no) { - file += frontFill(metadata.disk.no, '0', 2); + fileName += frontFill(metadata.disk.no, '0', 2); } if (metadata.track.no) { - if (file) { - file += '-' + frontFill(metadata.track.no, '0', 2) + ' '; + if (fileName) { + fileName += '-' + frontFill(metadata.track.no, '0', 2) + ' '; } else { - file += frontFill(metadata.track.no, '0', 2) + ' '; + fileName += frontFill(metadata.track.no, '0', 2) + ' '; } } - if (metadata.artist && metadata.albumartist.length > 0) { - file += metadata.artist[0] + ' - '; + if (metadata.artist) { + fileName += metadata.artist[0] + ' - '; } if (metadata.title) { - file += metadata.title; + fileName += metadata.title; } - - callback(null, directory, file); -} - -function frontFill(string, fill, length) { - while (string.length > length) { - string = fill + string; - } - return string; + // append extension + fileName += path.extname(file); + // join directory and name + callback(null, path.join(filePath, fileName)); } +// create a ascii progressbar function createProgressBar(total) { return new progress(':bar | progress: :current/:total (:percent) | elapsed: :elapseds | eta: :etas', { total: total, width: 32 }); +} + +// create target directory and move the file +function moveFile(source, target, callback) { + async.series([ + function (asyncCallback) { + fse.mkdirs(path.dirname(target), asyncCallback); + }, + function (asyncCallback) { + fse.move(source, target, asyncCallback); + } + ], function (err, results) { + if (err) { + return callback(err); + } + callback(); + }); +} + +// fill a string beginning from the front +function frontFill(string, fill, length) { + while (string.toString().length < length) { + string = fill + string; + } + return string; +} + +// shutdown +function exit(err) { + if (err) { + console.error(err); + process.exit(1); + } + const diff = process.hrtime(start); + console.log('exiting after ' + ((diff[0] + (diff[1] / 1000000)) / 1000).toFixed(2) + ' seconds'); + process.exit(0); } \ No newline at end of file