Skip to content

Instantly share code, notes, and snippets.

@ugate
Last active August 29, 2015 14:11
Show Gist options
  • Save ugate/006cd9b6491de6100406 to your computer and use it in GitHub Desktop.
Save ugate/006cd9b6491de6100406 to your computer and use it in GitHub Desktop.
Organizes files into directories with a yyyy-mm format
//======================================================================================================
// Looks in the current directory for a move directory, cycles all the files moving them to a new or
// existing directory with the format yyyy-mm using the file name as a date indicator. When the file
// is an MP4 it will be moved to yyyy-mm-VIDS
//
// Can be batched in a Windows organize.bat using the following:
//
// node /your/path/to/files/and/organize.js --stack
// PAUSE
//
//======================================================================================================
var fs = require('fs');
var path = require('path');
var bdir = process.cwd();
var fdir = path.join(bdir, 'move');
var failed = 0, copied = 0, moved = 0, open = 0, total = 0, mkdirs = [], mvs = [], mv = 100, cnt = 0;
console.log('Organizing pictures/videos in %s to YEAR-MONTH format in %s', fdir, bdir);
fs.readdir(fdir, function rd(err, files) {
if (err) throw err;
total = files.length;
console.log('Checking %s files...', total);
for (var i=0; i<total; i++) {
handleFile(files[i]);
}
});
function handleFile(file) {
var prts = file.split('_');
if (prts.length < 2) {
console.log('Skipping %s', file);
return;
}
date = prts[1];
var exts = file.split('.');
var toDir = path.join(bdir, date.substr(0, 4) + '-' + date.substr(4, 2) + (exts.length > 1 && exts[1].toLowerCase() === 'mp4' ? '-VIDS' : ''));
var pths = { from: path.join(fdir, file), to: path.join(toDir, file) };
//console.error('FROM %s TO %s', pths.from, pths.to);
if (mkdirs[toDir]) {
if (mkdirs[toDir].ready) {
moveFile(pths);
} else {
return mkdirs[toDir].push(pths);
}
} else {
mkdirs[toDir] = [pths];
}
fs.exists(toDir, function existCb(exists) {
if (exists) {
moveFiles();
} else {
fs.mkdir(toDir, function mkdirCb(err) {
if (err) {
console.error('Unable to create %s', toDir);
console.error(err);
mkdirs[toDir].error = err;
failed += mkdirs[toDir].length;
} else {
moveFiles();
}
});
}
});
function moveFiles() {
mkdirs[toDir].ready = true;
for (var i=0, m=mkdirs[toDir], l=m.length; i<l; i++) {
cnt++;
moveFile(m[i]);
}
}
}
function moveFile(pths) {
if (open > mv) {
return mvs.push(pths);
}
open++;
var src = fs.createReadStream(pths.from), dest = fs.createWriteStream(pths.to);
src.on('end', srcDone).on('error', function onError(err) {
console.error('Failed while copying %s to %s (%s failures)', pths.from, pths.to, ++failed);
console.error(err);
});
src.pipe(dest);
function srcDone(err) {
--open;
var s = !err ? ++copied : copied, e = err ? ++failed : failed;
logStatus();
fs.unlink(pths.from, function (err) {
if (err) {
console.error('Unable to remove %s', to);
console.error(err);
} else {
++moved;
logStatus();
}
});
//console.log('Copied %s files, %s failures', copied, failed);
var ci = mvs.indexOf(pths);
if (ci >= 0) {
mvs.splice(ci, 1);
}
if (mvs.length) {
moveFile(mvs.shift());
}
}
}
function logStatus(pths) {
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(copied + '/' + moved + ' copied/moved, ' + failed + ' failures (' + mvs.length + ' in queue, ' + open + ' in progress, TOTAL: ' + cnt + ') ' + (pths ? pths.from + ' -> ' + pths.to : ''));
if (open === 0 && mvs.length === 0) {
process.stdout.write('\x07');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment