cloudcmd/lib/server/dir.js
2013-04-08 10:34:39 -04:00

104 lines
No EOL
3.8 KiB
JavaScript

/* inspired by http://procbits.com/2011/10/29/a-node-js-experiment-thinking-asynchronously-recursion-calculate-file-size-directory */
(function(){
'use strict';
if(!global.cloudcmd)
return console.log(
'# dir.js' + '\n' +
'# -----------' + '\n' +
'# Module is part of Cloud Commander,' + '\n' +
'# used for getting dir size.' + '\n' +
'# If you wont to see at work' + '\n' +
'# try GET /api/v1/fs/etc?size or' + '\n' +
'# dir.getSize(\'/etc, function(err, size){' + '\n' +
'# });' + '\n' +
'# http://coderaiser.github.com/cloudcmd' + '\n');
var main = global.cloudcmd.main,
fs = main.fs,
Util = main.util,
path = main.path;
exports.getSize = function(pDir, pCallBack) {
var lTotal = 0;
function calcSize(pParams){
var lStat = pParams.stat,
lSize = lStat && lStat.size || 0;
lTotal += lSize;
}
processDir(pDir, calcSize, function(){
Util.log(pDir + ' -> ' + lTotal);
Util.exec(pCallBack, null, lTotal);
});
};
function processDir(pDir, pFunc, pCallBack){
var lAsyncRunning = 0,
lFileCounter = 1;
function getDirInfo(pDir) {
/* The lstat() function shall be equivalent to stat(),
except when path refers to a symbolic link. In that case lstat()
shall return information about the link, while stat() shall return
information about the file the link references. */
fs.lstat(pDir, Util.call(getStat, {
name: pDir
}));
}
function getStat(pParams) {
var lRet = Util.checkObj(pParams, ['params']);
if(lRet){
var p = pParams,
d = p.params,
lStat = p.data,
lPath = d.name;
--lFileCounter;
if (!p.error) {
if ( lStat.isFile() )
Util.exec(pFunc, {
name: d.name,
stat: lStat
});
else if ( lStat.isDirectory() ) {
++lAsyncRunning;
fs.readdir(lPath, function(pError, pFiles) {
lAsyncRunning--;
var lDirPath, n;
if (!pError){
n = pFiles.length;
lFileCounter += n;
for (var i = 0; i < n; i++) {
lDirPath = path.join(lPath, pFiles[i]);
process.nextTick( Util.retExec(getDirInfo, lDirPath) );
}
}
if(!n)
execCallBack();
});
}
}
}
execCallBack();
}
function execCallBack(){
if (!lFileCounter && !lAsyncRunning)
Util.exec(pCallBack);
}
getDirInfo(pDir);
}
})();