webgme-engine
Version:
WebGME server and Client API without a GUI
230 lines (209 loc) • 9.25 kB
JavaScript
/*eslint-env node*/
/*eslint no-console: 0*/
/**
* @author pmeijer / https://github.com/pmeijer
*/
;
var webgme = require('../../index'),
path = require('path'),
Q = require('q');
/**
* Lists and optionally deletes the projects matching the criteria.
*
* @param {object} [options]
* @param {bool} [options.del=false] - If true will do the deletion.
* @param {bool} [options.list=false] - If true will list all the projects the owner has rights too.
* @param {string} [options.username=gmeConfig.authentication.guestAccount] - User.
* @param {string} [options.daysAgo=10] - Time since last viewed (inclusive).
* @param {string} [options.commits=1] - Maximum number of commits a deleted project can have..
* @param {string} [options.branches=1] - Maximum number of branches a deleted project can have.
* @param {string} [options.regex='.*'] - Project names must match the regex.
*/
function cleanUp(options) {
var gmeConfig = require(path.join(process.cwd(), 'config')),
logger,
gmeAuth,
params = {},
err,
storage;
webgme.addToRequireJsPaths(gmeConfig);
logger = webgme.Logger.create('clean_up', gmeConfig.bin.log, false);
options = options || {};
params.username = options.username || gmeConfig.authentication.guestAccount;
params.daysAgo = typeof options.daysAgo === 'number' ? options.daysAgo : 10;
params.commits = typeof options.commits === 'number' ? options.commits : 1;
params.branches = typeof options.branches === 'number' ? options.branches : 1;
params.del = options.del;
params.list = options.list;
if (options.regex) {
params.regex = new RegExp(options.regex);
} else {
params.regex = new RegExp('.*');
}
return webgme.getGmeAuth(gmeConfig)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
storage = webgme.getStorage(logger, gmeConfig, gmeAuth);
return storage.openDatabase();
})
.then(function () {
return storage.getProjects({
username: params.username,
info: true,
rights: true,
branches: true
});
})
.then(function (projects) {
var now = new Date();
logger.info('Will match project name against "' + params.regex.source + '"');
function getProjectPromise(project) {
var deferred = Q.defer(),
vDate,
branchNames = Object.keys(project.branches),
daysAgo,
result = {
projectId: project._id,
remove: false
};
//logger.info(JSON.stringify(project, null, 2));
//logger.info(project.name, regex.toString());
if (params.list === true) {
logger.info('\nprojectId:', project._id, '\nrights :', project.rights,
'\nbranches :', '' + branchNames);
}
if (project.rights.delete === true &&
params.regex.test(project.name) &&
branchNames.length <= params.branches) {
if (typeof project.info.viewedAt === 'string') {
vDate = new Date(project.info.viewedAt);
} else {
vDate = new Date().setYear(1990); // Way back.
}
daysAgo = Math.round((now - vDate) / 1000 / 3600 / 24);
if (daysAgo >= params.daysAgo) {
if (params.commits > 0) {
storage.getCommits({
projectId: project._id,
username: params.username,
before: now.getTime(),
number: params.commits + 1
})
.then(function (commits) {
if (commits.length <= params.commits) {
result.remove = true;
}
deferred.resolve(result);
})
.catch(deferred.reject);
} else {
result.remove = true;
}
} else {
deferred.resolve(result);
}
} else {
deferred.resolve(result);
}
return deferred.promise;
}
return Q.all(projects.map(getProjectPromise));
})
.then(function (results) {
var deletions = [],
remove = 0,
keep = 0;
results.forEach(function (result) {
if (result.remove === true) {
logger.info('To remove:', result.projectId);
remove += 1;
if (params.del === true) {
deletions.push(storage.deleteProject({
projectId: result.projectId,
username: params.username
})
.then(function (removed) {
return {
removed: removed,
projectId: result.projectId
};
})
.catch(function (err) {
return {
removed: false,
projectId: result.projectId,
err: err
};
})
);
}
} else {
keep += 1;
}
});
logger.info('Remove', remove, 'out of', keep + remove);
return Q.all(deletions);
})
.then(function (results) {
var cnt = 0;
results.forEach(function (res) {
if (res.removed === true) {
cnt += 1;
logger.info('Removed:', res.projectId);
} else {
logger.error('Failed to remove ' + res.projectId, res.err.stack);
}
});
if (params.del === true) {
logger.info('Removed', cnt, 'project(s).');
}
})
.catch(function (err_) {
err = err_;
})
.finally(function () {
logger.debug('Closing database connections...');
return Q.allSettled([storage.closeDatabase(), gmeAuth.unload()])
.finally(function () {
logger.debug('Closed.');
if (err) {
throw err;
}
});
});
}
module.exports = cleanUp;
if (require.main === module) {
var Command = require('commander').Command,
program = new Command();
program
.version('1.6.0')
.option('-d, --del [boolean]', 'If true will do the deletion [false].', false)
.option('-l, --list [boolean]', 'If true will list all the projects this user has access to [false].', false)
.option('-t, --daysAgo [number]', 'Minimum age (last viewed) of a project to delete [10].', 10)
.option('-c, --commits [number]', 'Maximum number of commits (-1 to skip) of a project to delete [1].', 1)
.option('-b, --branches [number]', 'Maximum number of branches of a project to delete [1].', 1)
.option('-r, --regex [string]', 'Project names must match the regexp [.*].', '.*')
.option('-u, --username [string]', 'The user account being used. [guest account]')
.on('--help', function () {
console.log('Use this script to delete projects matching the given criteria. Since the script uses ' +
'the storage API including authorization, the given user must have delete access to the projects.');
console.log();
console.log(' Examples:');
console.log();
console.log(' $ node clean_up.js');
console.log(' $ node clean_up.js --list');
console.log(' $ node clean_up.js --username demo --commits 5 --regex ^demo_ --del');
console.log(' $ node clean_up.js --username demo --commits -1 --branches 20 --daysAgo 7 --del');
console.log(' $ node clean_up.js --regex ^startsWith');
console.log(' $ node clean_up.js --daysAgo 3 --regex contains --branches 2');
})
.parse(process.argv);
program.daysAgo = Math.round(parseFloat(program.daysAgo));
program.commits = Math.round(parseFloat(program.commits));
program.branches = Math.round(parseFloat(program.branches));
cleanUp(program)
.catch(function (err) {
console.error(err.stack);
});
}