Commit 0c22bf90 authored by Leo Iannacone's avatar Leo Iannacone

used js2coffee to translation

parent 3ce80b56
#!/usr/bin/env nodejs
'use strict';
/**
* Module dependencies.
*/
var http = require('http'),
express = require('express'),
serve_static = require('serve-static'),
serve_index = require('serve-index'),
errorhandler = require('errorhandler'),
routes = require('./routes'),
config = require('./lib/config.js'),
utils = require('./lib/utils.js'),
Client = require('./lib/client.js'),
Broadcaster = require('./lib/broadcaster.js');
var app = module.exports = express(),
server = http.createServer(app),
io = require('socket.io')(server),
env = process.env.NODE_ENV || 'development';
if ('development' == env) {
app.use(errorhandler({
dumpExceptions: true,
showStack: true
}));
} else if ('production' == env) {
app.use(errorhandler());
}
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
// index page
app.get('/', routes.index);
// distibution page
app.get(config.routes.distribution, routes.distribution);
// parefernces page
if (config.routes.preferences)
app.get(config.routes.preferences, routes.preferences);
// commands page
if (config.routes.commands)
app.get(config.routes.commands, routes.commands);
// debomatic static page
if (config.routes.debomatic) {
app.all(config.routes.debomatic + '*', function (req, res, next) {
// send 403 status when users want to browse the chroots:
// - unstable/unstable
// - unstable/build/*
// this prevents system crashes
var base = config.routes.debomatic;
base += base[base.length - 1] != '/' ? '/' : ''; // append /
var match = req.url.replace(base, '').split('/');
if (match[match.length - 1] === '') match.pop();
if (match.length >= 2 && (
(match[0] == match[1]) || /* case unstable/unstable */
(match[1] == 'build' && match.length > 2) /* case unstable/build/* */
)) {
res.status(403).send('<h1>403 Forbidden</h1>');
} else
next(); // call next() here to move on to next middleware/router
});
app.use(config.routes.debomatic, serve_static(config.debomatic.path));
app.use(config.routes.debomatic, serve_index(config.debomatic.path, {
'view': 'details',
'icons': true
}));
}
// serve stylesheet-javascript
app.use(serve_static(__dirname + '/public'));
// serve dsc files as octet-stream
serve_static.mime.define({
'application/octet-stream': ['dsc']
});
// Listening
server.listen(config.port, config.host, null, function (err) {
// Checking nodejs with sudo:
// Find out which user used sudo through the environment variable
// and set his user id
var uid = parseInt(process.env.SUDO_UID);
if (uid) {
console.log('Please do not run nodejs with sudo. Changing user to %d', uid);
process.setgid(uid);
process.setuid(uid);
}
// statuses
var status = [];
var broadcast = new Broadcaster(io.sockets, status);
io.sockets.on('connection', function (socket) {
var client = new Client(socket);
client.start();
if (status.length > 0)
client.send_status(status);
client.send_status_debomatic();
});
console.log('Debomatic-webui listening on %s:%d in %s mode', server.address().address, server.address().port, app.settings.env);
});
server.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use %s:%d. Exit.', config.host, config.port);
process.exit(1);
} else {
console.error(e);
}
});
'use strict';
var config = require('./config.js'),
fs = require('fs'),
utils = require('./utils.js'),
Tail = require('./tail.js');
function __watch_status_check_same_obj(obj1, obj2) {
if (obj1.status == obj2.status) {
if (obj1.distribution == obj2.distribution) {
if (obj1.hasOwnProperty('package') &&
obj2.hasOwnProperty('package')) {
if (obj1.package == obj2.package)
return true;
return false;
}
return true;
}
}
return false;
}
// watcher on build_status
function __watch_status(socket, status) {
var watcher = new Tail(config.debomatic.jsonfile);
watcher.on('line', function (new_content) {
var data = null;
try {
data = JSON.parse(new_content);
} catch (err) {
utils.errors_handler('Broadcaster:__watch_status:JSON.parse(new_content) - ', err, socket);
return;
}
// looking for same status already in statuses lists
if (data.hasOwnProperty('success')) {
for (var i = 0; i < status.length; i++) {
if (__watch_status_check_same_obj(data, status[i])) {
status.splice(i, 1);
break;
} else
continue;
}
} else {
status.push(data);
}
socket.emit(config.events.broadcast.status_update, data);
});
watcher.on('error', function (msg) {
socket.emit(config.events.error, msg);
});
}
// watcher on new distributions
function __watch_distributions(socket) {
fs.watch(config.debomatic.path, {
persistent: true
}, function (event, fileName) {
// wait half a second to get pool subdir created
setTimeout(function () {
utils.send_distributions(socket);
}, 500);
});
}
function __watch_pidfile(socket) {
fs.watchFile(config.debomatic.pidfile, {
persistent: false,
interval: 1007
},
function (curr, prev) {
var status_debomatic = {
"running": curr.ino !== 0 // if === 0 means pidfile does not exists
};
try {
socket.emit(socket.emit(config.events.broadcast.status_debomatic, status_debomatic));
} catch (err) {}
});
}
function Broadcaster(sockets, status) {
__watch_status(sockets, status);
__watch_distributions(sockets);
__watch_pidfile(sockets);
return {
};
}
module.exports = Broadcaster;
'use strict';
var fs = require('fs'),
path = require('path'),
config = require('./config.js'),
utils = require('./utils.js');
var _e = config.events.client;
function __get_files_list_from_package(data, callback) {
var package_path = utils.get_package_path(data);
utils.get_files_list(package_path, false, function (files) {
data.package.files = [];
data.package.debs = [];
data.package.sources = [];
files.forEach(function (f) {
var file = {};
file.path = path.join(package_path, f).replace(config.debomatic.path, config.routes.debomatic);
file.orig_name = f;
file.name = f.split('_')[0];
file.extension = f.split('.').pop();
if (config.debomatic.excluded_files.indexOf(file.extension) >= 0)
return;
if (file.extension == 'deb' || file.extension == 'ddeb' || file.extension == 'udeb') {
data.package.debs.push(file);
} else if (f.indexOf('.tar') >= 0 || file.extension == 'changes' || file.extension == 'dsc') {
file.name = f.replace(data.package.name + '_' + data.package.version + '.', '');
if (file.extension == 'changes')
file.name = file.extension;
else if (f.indexOf('.tar') >= 0 && f.indexOf('.orig.') > 0)
file.name = 'orig.' + f.split('.orig.').pop();
data.package.sources.push(file);
} else {
file.name = file.extension;
data.package.files.push(file);
}
});
callback(data);
});
}
function __send_package_files_list(event_name, socket, data) {
__get_files_list_from_package(data, function (new_data) {
socket.emit(event_name, new_data);
});
}
function __read_package_status(data, cb) {
var package_path = utils.get_package_path(data);
var package_json = path.join(package_path, data.package.orig_name + '.json');
fs.readFile(package_json, {
encoding: 'utf8'
}, function (err, content) {
if (err) {
utils.errors_handler('Client:__read_package_status:', err);
return;
}
try {
content = JSON.parse(content);
} catch (parse_err) {
utils.errors_handler('Client:__read_package_status:parse_err:', parse_err);
return;
}
cb(content);
});
}
function __send_package_info(socket, data) {
__read_package_status(data, function (content) {
socket.emit(_e.package_info, content);
});
}
function __send_package_status(socket, data) {
__read_package_status(data, function (content) {
socket.emit(_e.distribution_packages_status, content);
});
}
function __send_distribution_packages(event_name, socket, data) {
var distro_path = utils.get_distribution_pool_path(data);
utils.get_files_list(distro_path, true, function (packages) {
data.distribution.packages = [];
packages.forEach(function (p) {
var pack = {};
var info = p.split('_');
pack.name = info[0];
pack.version = info[1];
pack.orig_name = p;
__send_package_status(socket, {
distribution: data.distribution,
package: pack
});
data.distribution.packages.push(pack);
});
socket.emit(event_name, data);
});
}
function __send_file(event_name, socket, data, last_lines) {
var file_path = utils.get_file_path(data);
fs.readFile(file_path, 'utf8', function (err, content) {
if (err) {
utils.errors_handler('client:__send_file', err, socket);
return;
}
data.file.orig_name = file_path.split('/').pop();
if (last_lines > 0)
data.file.content = content.split('\n').slice(-last_lines).join('\n');
else
data.file.content = content;
data.file.path = file_path.replace(config.debomatic.path, config.routes.debomatic);
socket.emit(event_name, data);
});
}
function __handler_get_file(socket, data) {
var file_path = utils.get_file_path(data);
utils.watch_path_onsocket(_e.file_newcontent, socket, data, file_path, function (event_name, socket, data) {
data.file.content = null;
socket.emit(event_name, data);
});
if (config.web.file.preview.indexOf(data.file.name) >= 0 && !data.file.force)
__send_file(_e.file, socket, data, config.web.file.num_lines);
else
__send_file(_e.file, socket, data);
}
function Client(socket) {
this.start = function () {
// init send distributions
utils.send_distributions(socket);
// init events
socket.on(_e.distribution_packages, function (data) {
if (!utils.check_data_distribution(data))
return;
var distribution_path = path.join(config.debomatic.path, data.distribution.name, 'pool');
utils.generic_handler_watcher(_e.distribution_packages, socket, data, distribution_path, __send_distribution_packages);
data = null;
});
socket.on(_e.package_files_list, function (data) {
if (!utils.check_data_package(data))
return;
var package_path = utils.get_package_path(data);
utils.generic_handler_watcher(_e.package_files_list, socket, data, package_path, __send_package_files_list);
data = null;
});
socket.on(_e.file, function (data) {
if (!utils.check_data_file(data))
return;
__handler_get_file(socket, data);
data = null;
});
socket.on(_e.package_info, function (data) {
if (!utils.check_data_package(data))
return;
__send_package_info(socket, data);
data = null;
});
// on client disconnection close all watchers
socket.on('disconnect', function () {
var socket_watchers = socket.watchers;
if (!socket_watchers)
return;
for (var key in socket_watchers) {
try {
socket_watchers[key].close();
} catch (error_watch) {
utils.errors_handler('client:disconnect', error_watch);
}
}
});
};
this.send_status = function (status) {
socket.emit(_e.status, status);
};
this.send_status_debomatic = function () {
fs.exists(config.debomatic.pidfile, function (exists) {
socket.emit(config.events.broadcast.status_debomatic, {
'running': exists
});
});
};
}
module.exports = Client;
'use strict';
/*
* Please DO NOT edit this file.
*
* Edit auto-generated 'user.config.js' file instead.
*
*/
// #start config-auto-export
var config = {};
/*
* Configure host and port.
* Please for ports < 1000 use authbind. DO NOT RUN nodejs as root.
* $ authbind nodejs index.js
*/
config.host = 'localhost';
config.port = 3000;
config.debomatic = {};
config.debomatic.path = '/srv/debomatic-amd64';
config.debomatic.jsonfile = '/var/log/debomatic-json.log';
config.routes = {};
config.routes.debomatic = '/debomatic';
config.routes.distribution = '/distribution';
config.routes.preferences = '/preferences';
config.routes.commands = '/commands';
// web configuration
config.web = {};
// debomatic configuration exportable for web
config.web.debomatic = {};
config.web.debomatic.admin = {};
config.web.debomatic.admin.name = 'Your Name';
config.web.debomatic.admin.email = 'you AT debian DOT org'; // please use this SPAMFREE form - it will be converted client side by javascript
config.web.debomatic.architecture = 'amd64';
config.web.debomatic.dput = {};
config.web.debomatic.dput.incoming = config.debomatic.path;
config.web.debomatic.dput.host = config.host;
config.web.debomatic.dput.login = 'debomatic';
config.web.debomatic.dput.method = 'scp';
config.web.debomatic.dput.unsigned_uploads = false;
// header title and description
config.web.title = 'Deb-o-Matic web.ui';
config.web.description = 'This is a web interface for debomatic over ' + config.web.debomatic.architecture;
// list of files get preview
config.web.file = {};
config.web.file.preview = ['buildlog'];
config.web.file.num_lines = 25;
// default ui settings
config.web.preferences = {};
config.web.preferences.autoscroll = true;
config.web.preferences.header = true;
config.web.preferences.sidebar = true;
config.web.preferences.glossy_theme = true;
config.web.preferences.file_background = true;
config.web.preferences.file_fontsize = 13; // valid values are [13..16]
config.web.preferences.debug = 0; // debug level - 0 means disabled
// #end config-auto-export
// DO NOT TOUCH these ones
config.version = '0.6.0';
config.debomatic.excluded_files = ['datestamp', 'json'];
config.events = {};
config.events.error = 'server-error';
config.events.broadcast = {};
config.events.broadcast.distributions = 'b.distributions';
config.events.broadcast.status_update = 'b.status_update';
config.events.broadcast.status_debomatic = 'b.status_debomatic';
config.events.client = {};
config.events.client.distribution_packages = 'c.distribution_packages';
config.events.client.distribution_packages_status = 'c.distribution_packages_status';
config.events.client.package_files_list = 'c.package_files_list';
config.events.client.package_info = 'c.package_info';
config.events.client.file = 'c.file';
config.events.client.file_newcontent = 'c.file_newcontent';
config.events.client.status = 'c.status';
// debomatic status according with JSONLogger.py module
config.status = {};
config.status.build = 'build';
config.status.create = 'create';
config.status.update = 'update';
config.status.success = true;
config.status.fail = false;
// read user configuration and merge it
/*
* update object1 with object2 values
*/
function _merge(object1, object2) {
var result = {};
for (var p in object1) {
if (object2.hasOwnProperty(p)) {
if (typeof object1[p] === 'object' && typeof object2[p] === 'object') {
result[p] = _merge(object1[p], object2[p]);
} else {
result[p] = object2[p];
}
} else {
result[p] = object1[p];
}
}
return result;
}
try {
var Parser = require('./parser.js');
var parser = new Parser();
var user_config = parser.getUserConfig();
if (user_config) {
console.log('Reading user configutation ...');
config = _merge(config, require(user_config));
} else {
console.log('No user config specified. Using global settings.');
}
} catch (err) {
if (err.code == 'MODULE_NOT_FOUND') {
console.log('File %s not found.', user_config);
process.exit(1);
} else {
console.error('Error reading user configutation', err);
process.exit(1);
}
} finally {
// export some variable
config.web.paths = config.routes;
config.web.events = config.events;
config.web.status = config.status;
config.web.host = config.host;
// calculate pidfile
config.debomatic.pidfile = "/var/run/debomatic-" +
require('crypto')
.createHash('sha256')
.update(config.debomatic.path)
.digest('hex');
module.exports = config;
}
/*jshint multistr: true */
'use strict';
function Parser() {
var args = process.argv.slice(2);
var help = function () {
console.log('\
Usage: %s [-c config]\n\
-h print this help \n\
-c set user configuration file',
process.argv[1].split('/').pop());
process.exit(0);
};
this.getUserConfig = function () {
var configFile = null;
args.forEach(function (val, index) {
if (val == '-c') {
configFile = args[index + 1];
return;
}
});
if (configFile)
return process.cwd() + '/' + configFile;
else
return null;
};
args.forEach(function (val, index) {
if (val == '-h') {
help();
}
});
}
module.exports = Parser;
'use strict';
var fs = require('fs'),
Tail = require('tail').Tail;
Tail.prototype.watchEvent = function (e) {
var _this = this;
if (e === 'change') {
return fs.stat(this.filename, function (err, stats) {
if (err) {
_this.emit('error', err);
return;
}
if (stats.size < _this.pos) {
_this.pos = stats.size;
}
if (stats.size > _this.pos) {
_this.queue.push({
start: _this.pos,
end: stats.size
});
_this.pos = stats.size;
if (_this.queue.length === 1) {
return _this.internalDispatcher.emit('next');
}
}
});
} else if (e === 'rename') {
this.unwatch();
_this.emit('error', 'File ' + this.filename + ' deleted.');
}
};
Tail.prototype.close = function () {
this.unwatch();
};
module.exports = Tail;
'use strict';
var path = require('path'),
fs = require('fs'),
config = require('./config.js'),
Tail = require('./tail.js');
function __errors_handler(from, err, socket) {
if (!socket)
from = 'NO SOCKET: ' + from;
console.error(from, err.message);
if (socket)
socket.emit(config.events.error, err.message);
}
function __check_no_backward(backward_path) {
try {
return backward_path.indexOf('..') < 0;
} catch (err) {
return true;
}
}
function __check_data_distribution(data) {
return __check_no_backward(data) && __check_no_backward(data.distribution) && __check_no_backward(data.distribution.name);
}
function __check_data_package(data) {
return __check_data_distribution(data) && __check_no_backward(data.package) && __check_no_backward(data.package.name) && __check_no_backward(data.package.version);
}
function __check_data_file(data) {
return __check_data_package(data) && __check_no_backward(data.file) && __check_no_backward(data.file.name);
}
function __get_distribution_pool_path(data) {
return path.join(config.debomatic.path, data.distribution.name, 'pool');
}
function __get_package_path(data) {
return path.join(__get_distribution_pool_path(data), data.package.name + '_' + data.package.version);
}
function __get_file_path(data) {
return path.join(__get_package_path(data), data.package.name + '_' + data.package.version + '.' + data.file.name);
}
function __get_files_list(dir, onlyDirectories, callback) {
fs.readdir(dir, function (err, files) {
var result = [];
if (err) {
__errors_handler('__get_files_list', err);
return;
}
files.forEach(function (f) {
try {
var complete_path = path.join(dir, f);
var stat = fs.statSync(complete_path);
if (onlyDirectories) {
if (stat.isDirectory()) {
result.push(f);
}
} else {
if (stat.isFile()) {
result.push(f);
}
}
} catch (fs_error) {
__errors_handler('__get_files_list:forEach', fs_error);
return;
}
});
callback(result);
});
}
function __watch_path_onsocket(event_name, socket, data, watch_path, updater) {
var socket_watchers = socket.watchers || {};
try {
var watcher = socket_watchers[event_name];
if (watcher)
watcher.close();
fs.stat(watch_path, function (err, stats) {
if (err) {
__errors_handler('__watch_path_onsocket:fs.stat', err, socket);
return;
}
if (stats.isDirectory()) {
watcher = fs.watch(watch_path, {
persistent: true
}, function (event, fileName) {
if (event == 'rename')
updater(event_name, socket, data);
});
} else if (stats.isFile()) {
watcher = new Tail(watch_path);
watcher.on('line', function (new_content, tailInfo) {
data.file.new_content = new_content + '\n';
updater(event_name, socket, data);
});
watcher.on('error', function (msg) {
socket.emit(config.events.error, msg);
});
}
socket_watchers[event_name] = watcher;
socket.watchers = socket_watchers;
});
} catch (err) {
__errors_handler('__watch_path_onsocket <- ' + arguments.callee.caller.name, err, socket);
return;
}
}
function __generic_handler_watcher(event_name, socket, data, watch_path, callback) {
callback(event_name, socket, data);
__watch_path_onsocket(event_name, socket, data, watch_path, callback);
}
function __send_distributions(socket) {
__get_files_list(config.debomatic.path, true, function (directories) {
var distributions = [];
directories.forEach(function (dir) {
var data = {};
data.distribution = {};
data.distribution.name = dir;
var pool_path = __get_distribution_pool_path(data);
if (fs.existsSync(pool_path)) {
distributions.push(dir);
}
});
socket.emit(config.events.broadcast.distributions, distributions);
});
}
var utils = {
check_data_distribution: function (data) {
return __check_data_distribution(data);
},
check_data_package: function (data) {
return __check_data_package(data);
},
check_data_file: function (data) {
return __check_data_file(data);
},
get_distribution_pool_path: function (data) {
return __get_distribution_pool_path(data);
},
get_package_path: function (data) {
return __get_package_path(data);
},
get_file_path: function (data) {
return __get_file_path(data);
},
get_files_list: function (dir, onlyDirectories, callback) {
return __get_files_list(dir, onlyDirectories, callback);
},
watch_path_onsocket: function (event_name, socket, data, watch_path, updater) {
return __watch_path_onsocket(event_name, socket, data, watch_path, updater);
},
generic_handler_watcher: function (event_name, socket, data, watch_path, callback) {
return __generic_handler_watcher(event_name, socket, data, watch_path, callback);
},
send_distributions: function (socket) {
return __send_distributions(socket);
},
errors_handler: function (from, error, socket) {
return __errors_handler(from, error, socket);
}
};
module.exports = utils;
'use strict';
var config = require('../lib/config.js');
exports.index = function (req, res) {
res.render('index', config);
};
exports.distribution = function (req, res) {
res.render('distribution', config);
};
exports.preferences = function (req, res) {
res.render('preferences', config);
};
exports.commands = function (req, res) {
res.render('commands', config);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment