finished basic sorting functionality
This commit is contained in:
parent
5f220204b3
commit
3eabcbee73
1 changed files with 94 additions and 61 deletions
155
badger-am.js
155
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);
|
||||
}
|
Loading…
Reference in a new issue