domotz-remote-pawn
Version:
Domotz Agent
232 lines (215 loc) • 7.65 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz Ltd
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
*
* Created by Iacopo Papalini <ipapalini@domotz.com> on 16/06/15.
*/
var factory = function (fs, q) {
function rename(src, dst, async) {
if (async) {
throw new Error('Not Implemented');
} else {
fs.renameSync(src, dst);
}
}
function readFile(fileName, parse, async) {
console.debug("FILE - (%s): %synchronous reading", fileName, async ? 'As' : 'S');
var content;
if (async) {
var deferred = q.defer();
fs.readFile(fileName, function (err, data) {
if (err) {
deferred.reject(err);
} else {
data = parse ? parse(data.toString()) : data.toString();
deferred.resolve(data);
}
});
return deferred.promise;
} else {
try {
content = fs.readFileSync(fileName).toString();
if (parse) {
content = parse(content);
}
}
catch (e) {
console.warn('FILE - (%s): Failure in reading --> %s', fileName, e.message);
content = undefined;
}
}
return content;
}
function writeFileSafe(fileName, data, async) {
console.debug("FILE - (%s): %synchronous safe writing", fileName, async ? 'As' : 'S');
if (async) {
throw new Error('Not Implemented');
} else {
try {
var file_prefix = ".tmp-write";
fs.writeFileSync(fileName+file_prefix, data);
fs.renameSync(fileName+file_prefix, fileName);
}
catch (e) {
console.warn('FILE - (%s): Failure in safe writing --> %s', fileName, e.message);
}
}
}
function writeFile(fileName, data, async) {
console.debug("FILE - (%s): %synchronous writing", fileName, async ? 'As' : 'S');
if (async) {
var deferred = q.defer();
fs.writeFile(fileName, data, function (err) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve('Saved ' + fileName);
}
});
return deferred.promise;
} else {
try {
fs.writeFileSync(fileName, data);
}
catch (e) {
console.warn('FILE - (%s): Failure in safe writing --> %s', fileName, e.message);
}
}
}
function appendFile(fileName, data) {
console.debug('FILE - (%s): Appending %s bytes', fileName, data.length);
try {
fs.appendFileSync(fileName, data);
}
catch (e) {
console.warn('FILE - (%s): Failure in appending --> %s', fileName, e.message);
}
}
function replaceInFile(fileName, replacements) {
console.info("FILE - (%s): Patching", fileName);
var data = fs.readFileSync(fileName, 'utf-8');
replacements.forEach(function (replace) {
var key = replace[0];
var regExp = new RegExp('^' + key + '=.*$', 'm');
if (!regExp.test(data)) {
console.warn('FILE - (%s): No match found for regexp: %s', fileName, regExp);
} else {
var value = String(replace[1]);
console.debug('FILE - (%s): Replacing %s with %s in file ',
fileName, key, value);
data = data.replace(regExp, key + '=' + value);
}
});
fs.writeFileSync(fileName, data);
}
function deleteFile(fileName) {
console.debug("FILE - (%s): Removing", fileName);
try {
fs.unlinkSync(fileName);
} catch (e) {
console.warn('FILE - (%s): Failure in removing', fileName);
}
}
function getFileStats(fileName) {
var stats;
try {
stats = fs.statSync(fileName);
} catch (err) {
/**
* stat is an operation used also to check the existence of a file.
* A failure is note a real issue, so the "DEBUG" level
*/
console.debug('FILE - Recover stats for ' + fileName + '. ' +
'Error Code: ' + err.code);
return undefined;
}
return stats;
}
function getSize(fileName) {
var stats = getFileStats(fileName);
return stats ? stats.size : 0;
}
// http://www.geedew.com/remove-a-directory-that-is-not-empty-in-nodejs/
function rmdirAsync(path, callback) {
fs.readdir(path, function (err, files) {
if (err) {
// Pass the error on to callback
callback(err, []);
return;
}
var wait = files.length,
count = 0,
folderDone = function (err) {
count++;
// If we cleaned out all the files, continue
if (count >= wait || err) {
fs.rmdir(path, callback);
}
};
// Empty directory to bail early
if (!wait) {
folderDone();
return;
}
// Remove one or more trailing slash to keep from doubling up
path = path.replace(/\/+$/, "");
files.forEach(function (file) {
var curPath = path + "/" + file;
fs.lstat(curPath, function (err, stats) {
if (err) {
callback(err, []);
return;
}
if (stats.isDirectory()) {
rmdirAsync(curPath, folderDone);
} else {
fs.unlink(curPath, folderDone);
}
});
});
});
}
function listDir(path, options, async) {
if (typeof options === 'boolean') {
async = options;
}
if (async) {
var deferred = q.defer();
fs.readdir(path, options, function(err, out) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(out);
}
});
return deferred.promise;
} else {
return fs.readdirSync(path, options);
}
}
return {
rename: rename,
readFile: readFile,
writeFile: writeFile,
writeFileSafe: writeFileSafe,
appendFile: appendFile,
deleteFile: deleteFile,
getFileStats: getFileStats,
replaceInFile: replaceInFile,
getSize: getSize,
listDir: listDir
};
};
module.exports.factory = factory;