Reputation: 1030
The script below is working fantastically when monitoring a folder for new .ogg files. It successfully creates a folder with the new filename and then renames the file according to the file according to its created date/
However, the issues arise when I add multiple files at the same time as the script attempts to create a folder that already exists, suggesting it is mixing up the two filenames somehow. Has anyone any suggestions as to what I might be doing incorrectly? I presume its simple code structure although I'm not able to work out why.
var baseDir = './',
path = require('path'),
fs = require('fs');
// watch the directory for new files
fs.watch(baseDir, function(event, file) {
var ext = path.extname(file)
basename = path.basename(file).substring(0, path.basename(file).length - ext.length);
// check it wasnt a delete action
fs.exists(baseDir + file, function(exists) {
// check we have the right file type
if(exists && ext === '.ogg'){
// get the created date
fs.stat(baseDir + file, function (err, stats){
if (err)
throw err;
var year = stats.ctime.getFullYear();
var month = stats.ctime.getMonth()+1;
var day = stats.ctime.getDate();
var hour = stats.ctime.getHours();
var sec = stats.ctime.getSeconds();
if(month < 10){
month = '0' + month;
}
if(day < 10){
day = '0' + day;
}
if(hour < 10){
hour = '0' + hour;
}
if(sec < 10){
sec = '0' + sec;
}
var name = year + '' + month + '' + day + '' + hour + '' + sec;
// does the basename directory exist?
fs.exists(baseDir + '/' + basename, function(exists) {
// if the directory doesnt exist
if(!exists){
// make the directory
fs.mkdir(baseDir + '/' + basename, 0777, function (err, stats){
if (err)
throw err;
moveFile(file, basename, name, ext);
});
} else {
moveFile(file, basename, name, ext);
}
});
});
}
});
});
function moveFile(file, basename, name, ext){
// move the file to the new directory
fs.rename(baseDir + file, baseDir + '/' + basename + '/' + name + ext, function (err) {
if (err)
throw err;
// console.log('Rename complete');
});
}
Upvotes: 0
Views: 206
Reputation: 6602
Ok, so I had a few extra minutes and decided to have a look for you. I refactored your code a little, but the basic structure should be easy to recognize.
var baseDir = './test', path = require('path'), fs = require('fs'); // watch the directory for new files fs.watch(baseDir, function(event, file) { var ext = path.extname(file), basename = path.basename(file).substring(0, path.basename(file).length - ext.length); // check it wasnt a delete action // check we have the right file type var filePath = path.join(baseDir, file); if(fs.existsSync(filePath) && ext === '.ogg'){ // get the created date var stats = fs.statSync(filePath); var name = getName(stats); // if the directory doesnt exist var baseDirPath = path.join(baseDir, basename); if(!fs.existsSync(baseDirPath)){ // make the directory fs.mkdirSync(baseDirPath, 0777); } moveFile(file, basename, name, ext); } }); function getName (stats) { var year = stats.ctime.getFullYear(); var month = stats.ctime.getMonth()+1; var day = stats.ctime.getDate(); var hour = stats.ctime.getHours(); // need minutes! var minutes = stats.ctime.getMinutes(); var sec = stats.ctime.getSeconds(); if(month %lt 10){ month = '0' + month; } if(day < 10){ day = '0' + day; } if(hour < 10){ hour = '0' + hour; } if(minutes < 10){ minutes = '0' + minutes; } if(sec < 10){ sec = '0' + sec; } // missing the minute, previously return year + '' + month + '' + day + '' + hour + '' + minutes + '' + sec; } function moveFile(file, basename, name, ext){ // move the file to the new directory var src = path.join(baseDir, file), dest = path.join(baseDir, basename, name+ext); console.log("Moving ", src, "-", dest); fs.renameSync(src, dest); }
Some tips/corrections:
Stick with the synchronous fs
methods that end in Sync when working on simple scripts like this. While node.js is famous for it's asynchronous ability, it's a bit of a premature optimization IMO. If you need to embed this in a high-performance webserver, for instance, optimize at that point, not before.
You were missing a minutes
variable when you create the new filename. This has a pretty good chance of causing a name collision, so I corrected it.
Try to use the path
library (like path.join
) more to your advantage, as manually joining strings for paths can often lead to brittle code.
There are still several edge cases where this can crash. Creating a file without an extension that will have the same name as a directory you will create based on another file. (Files can't become directories, and you can't move a file inside another file.). If you plan to go into a production environment, you will want to harden the code with at least a few unit tests.
Cheers,
Dan
Upvotes: 1