mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-11 00:07:30 -05:00
203 lines
6.2 KiB
JavaScript
203 lines
6.2 KiB
JavaScript
var fs = require('fs'),
|
|
path = require('path'),
|
|
merge = require('fmerge'),
|
|
util = require('util'),
|
|
rimraf = require('rimraf'),
|
|
|
|
now,
|
|
testRun
|
|
|
|
var totals = {fileSize: 0, deletedSize:0, files: 0, deleted:0}
|
|
|
|
function isOlder(path, ageSeconds) {
|
|
var stats = fs.statSync(path),
|
|
mtime = stats.mtime.getTime(),
|
|
expirationTime = (mtime + (ageSeconds * 1000))
|
|
|
|
return now > expirationTime
|
|
}
|
|
|
|
function hasMaxLevel(options) {
|
|
return options && options.hasOwnProperty('maxLevel')
|
|
}
|
|
|
|
function getMaxLevel(options) {
|
|
return hasMaxLevel(options) ? options.maxLevel : -1
|
|
}
|
|
|
|
function getAgeSeconds(options) {
|
|
return (options && options.age && options.age.seconds) ? options.age.seconds : null
|
|
}
|
|
|
|
function doDeleteDirectory(currentDir, options, currentLevel) {
|
|
|
|
var doDelete = false
|
|
var dir = options && options.dir
|
|
|
|
if (dir) {
|
|
var ageSeconds = getAgeSeconds(options)
|
|
var basename = path.basename(currentDir)
|
|
|
|
if (util.isArray(dir)) {
|
|
doDelete = (dir.indexOf("*") !== 1) || (dir.indexOf(basename) !== -1)
|
|
} else if (basename === dir || dir === "*") {
|
|
doDelete = true
|
|
}
|
|
|
|
if (doDelete && hasMaxLevel(options) && currentLevel > 0) {
|
|
doDelete = currentLevel <= getMaxLevel(options)
|
|
}
|
|
|
|
if (ageSeconds && doDelete) {
|
|
doDelete = isOlder(currentDir, ageSeconds)
|
|
}
|
|
}
|
|
|
|
return doDelete
|
|
}
|
|
|
|
function doDeleteFile(currentFile, options) {
|
|
// by default it deletes nothing
|
|
var doDelete = false
|
|
|
|
var extensions = (options && options.extensions) ? options.extensions : null
|
|
var files = (options && options.files) ? options.files : null
|
|
var dir = (options && options.dir) ? options.dir : null
|
|
var ignore = (options && options.ignore) ? options.ignore : null
|
|
|
|
// return the last portion of a path, the filename aka basename
|
|
var basename = path.basename(currentFile)
|
|
|
|
if (files) {
|
|
if (util.isArray(files))
|
|
doDelete = (files.indexOf("*.*") !== -1) || (files.indexOf(basename) !== -1)
|
|
else {
|
|
if (files === '*.*') {
|
|
doDelete = true
|
|
} else {
|
|
doDelete = (basename === files)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!doDelete && extensions) {
|
|
var currentExt = path.extname(currentFile)
|
|
|
|
if (util.isArray(extensions)) {
|
|
doDelete = extensions.indexOf(currentExt) !== -1
|
|
} else {
|
|
doDelete = (currentExt === extensions)
|
|
}
|
|
}
|
|
|
|
if (doDelete && ignore) {
|
|
if (util.isArray(ignore))
|
|
doDelete = !(ignore.indexOf(basename) !== -1)
|
|
else
|
|
doDelete = !(basename === ignore)
|
|
}
|
|
|
|
if (doDelete) {
|
|
var ageSeconds = getAgeSeconds(options)
|
|
|
|
if (ageSeconds)
|
|
doDelete = isOlder(currentFile, ageSeconds)
|
|
}
|
|
|
|
return doDelete
|
|
}
|
|
|
|
function isTestRun(options) {
|
|
return (options && options.hasOwnProperty('test')) ? options.test : false
|
|
}
|
|
|
|
/**
|
|
* findRemoveSync(currentDir, options) takes any start directory and searches files from there for removal.
|
|
* the selection of files for removal depends on the given options. when no options are given, or only the maxLevel
|
|
* parameter is given, then everything is removed as if there were no filters.
|
|
*
|
|
* beware: everything happens synchronously.
|
|
*
|
|
*
|
|
* @param {String} currentDir any directory to operate within. it will seek files and/or directories recursively from there.
|
|
* beware that it deletes the given currentDir when no options or only the maxLevel parameter are given.
|
|
* @param options json object with optional properties like extensions, files, ignore, maxLevel and age.seconds.
|
|
* @return {Object} json object of files and/or directories that were found and successfully removed.
|
|
* @api public
|
|
*/
|
|
var findRemoveSync = module.exports = function(currentDir, options, currentLevel) {
|
|
|
|
var removed = {}
|
|
|
|
if (fs.existsSync(currentDir)) {
|
|
|
|
var maxLevel = getMaxLevel(options),
|
|
deleteDirectory = false
|
|
|
|
var removeEmpty = (options && options.removeEmpty);
|
|
if (currentLevel === undefined)
|
|
currentLevel = 0
|
|
else
|
|
currentLevel++
|
|
|
|
if (currentLevel < 1) {
|
|
now = new Date().getTime()
|
|
totals = {fileSize: 0, deletedSize:0, files: 0, deleted:0};
|
|
testRun = isTestRun(options)
|
|
} else {
|
|
// check directories before deleting files inside.
|
|
// this to maintain the original creation time,
|
|
// because linux modifies creation date of folders when files within have been deleted.
|
|
deleteDirectory = doDeleteDirectory(currentDir, options, currentLevel)
|
|
}
|
|
|
|
if (maxLevel === -1 || currentLevel < maxLevel) {
|
|
var filesInDir = fs.readdirSync(currentDir)
|
|
|
|
filesInDir.forEach(function(file) {
|
|
|
|
var currentFile = path.join(currentDir, file)
|
|
var stat = fs.statSync(currentFile);
|
|
if (stat.isDirectory()) {
|
|
// the recursive call
|
|
var result = findRemoveSync(currentFile, options, currentLevel)
|
|
|
|
// merge results
|
|
removed = merge(removed, result)
|
|
} else {
|
|
|
|
if (doDeleteFile(currentFile, options)) {
|
|
if (!testRun)
|
|
fs.unlinkSync(currentFile)
|
|
totals.deletedSize += stat.size
|
|
totals.deleted++;
|
|
removed[currentFile] = true
|
|
} else {
|
|
totals.fileSize += stat.size
|
|
totals.files++
|
|
}
|
|
}
|
|
})
|
|
if (removeEmpty && (filesInDir<1)) {
|
|
deleteDirectory = true;
|
|
}
|
|
}
|
|
|
|
if (deleteDirectory) {
|
|
try {
|
|
if (!testRun)
|
|
rimraf.sync(currentDir)
|
|
|
|
removed[currentDir] = true
|
|
} catch (err) {
|
|
throw err
|
|
}
|
|
}
|
|
}
|
|
if (currentLevel==0) {
|
|
return {removed: removed, totals: totals}
|
|
} else {
|
|
return removed
|
|
}
|
|
}
|