Example #1
0
    "xml": "text/xml"
};

var cfg = {
    ssl: false,
    port: 8060,
    ssl_key: '/home/janson/projects/nodejs/ws/examples/tmp/privatekey.pem',
    ssl_cert: '/home/janson/projects/nodejs/ws/examples/tmp/certificate.pem'
};

var http = null;
var app = null;
if(cfg.ssl) {
    http = require("https");
    app = express.createServer({
        key: fileSystem.readFileSync( cfg.ssl_key ),
        cert: fileSystem.readFileSync( cfg.ssl_cert )
    });
} else {
    http = require("http");
    app = express.createServer();
}

var userMap = new HashMap();
var userMgrMax = 512;
var protocolHeaderLen = 16;

//负责处理Web请求
var httpProcessor = (function () {
    function HttpProcessor(req, res, seq) {
        this.req = req;
        this.res = res;
Example #2
0
* Please see the LICENSE file for more information.
*
*/

/**
 * web server/service to wrap interactions w/ GitHub API
 */

var fs = require('fs'),
    url = require('url'),
    express = require('express'),
    connect = require('connect'),
    request = require('request'),
    dbox = require('dropbox').DropboxClient,
    app = express.createServer(
                    connect.bodyParser(),
                    connect.cookieParser()),
    locker = require('../../Common/node/locker.js'),
    lfs = require('../../Common/node/lfs.js');

var me;

app.set('views', __dirname);
app.get('/', handleIndex);

var dapp=false;
function handleIndex(req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    if(dapp)
    {
        res.end(fs.readFileSync(__dirname + '/ui/index.html'));
 * Ukážková real-time webová aplikácia pre bakalársku prácu s témou real-time webové aplikácie
 * určená k demonštrácii real-time komunikácie klienta so serverom transporným spôsobom uvedeným vyššie.
 *
 * Aplikácia má implementované iba dve funkcie - pridanie novej úlohy a získanie úloh zo servera.
 * Aplikácia neobsahuje všetky potrebné prvky, ktoré by boli pokryté v produkčnej aplikácii, 
 * ako overovanie hodnôt získaných od užívateľa a podobne.
 *
 * Pozn. úlohy nie sú ukladané do databázy preto je ich životnosť iba po dobu spustenia aplikácie.
 *
 * @author Matej Paulech <matej.paulech@gmail.com>
 */

// Závislosti (moduly)

var express = require('express');
var app = module.exports = express.createServer();
var Todo = require('./todo');
var Todos = require('./todos');

// Vytvorenie objektu so zoznamom úloh a pridanie 2 ukážkových úloh

var todos = new Todos();
todos.add('Nakúpiť mlieko');
todos.add('Dopísať bakalárku');

// Nastavenia

// Funkcia pre vlastný formátu času v logoch
express.logger.format('date', function () { 
	var date = new Date();
	return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
Example #4
0
exports.createServer = function () {
	var app = express.createServer();

	global.backend = require('./backend');
	global.io = socket.listen(app);
	
	// TODO: move to the right position
	var RedisStore = require('connect-redis')(express);

	// Configuration

	app.configure(function() {
		app.set('views', __dirname + '/views');
		app.set('view engine', 'jade');
		app.set('view options', { layout : false });
		app.use(express.bodyParser());
		app.use(express.methodOverride());
		app.use(express.cookieParser());
		// TODO: move to the right position - use a general way with the given backend
		app.use(express.session({ store: new RedisStore({ client: global.db }), secret: 'UsMohsaEkB14iwuterECSv29HEbJ407h' }));
		app.use(app.router);
		app.use(express.static(__dirname + '/public', { maxAge: 24*60*60*1000 }));
	});

	app.configure('development', function(){
		app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
	});

	app.configure('production', function(){
		app.use(express.errorHandler());
	});

	// Routes

	var routes = require('./routes');

	app.setStart = function(path) {
		app.get('/', function(req,res) {
			res.redirect(path);
		});
	}

	app.addViewer = function () {
		app.get('/projector', function(req, res) {
			res.render('showProjector', {});
		});

		app.get('/timer', function(req, res) {
			res.render('showTimer', {});
		});

		global.projectorSocket	= io.registerProjector();
		global.timerSocket	= io.registerTimers();
		global.agendaSocket	= io.registerAgenda();
		global.motionSocket	= io.registerMotions();
		global.electionSocket	= io.registerElections();
		global.ballotSocket	= io.registerBallots();
		global.votesSocket	= io.registerVotes();
	}

	// callback is temporary out of usage. will fix this later
	app.addAdmin = function(callback) {
		function generateCallback(route) {
			return route;
		}

		app.get('/admin', generateCallback(function (req, res) {
			res.render('admin');
		}));

		app.get('/votes', generateCallback(function (req, res) {
			res.render('postVotes');
		}));

		app.post('/votes', generateCallback(routes.votes.setVotes));

		app.post('/identify-projectors',	generateCallback(routes.projectors.identify) );

		app.put('/agenda/:slideid/save',	generateCallback(routes.agenda.save) );
		app.post('/agenda/:slideid/delete',	generateCallback(routes.agenda.delete) );
		app.post('/agenda/:slideid/move',	generateCallback(routes.agenda.move) );

		app.put('/projectors',			generateCallback(routes.projectors.setDefault) );
		app.put('/projectors/:projectorid/save',	generateCallback(routes.projectors.save) );
		app.post('/projectors/:projectorid/delete',	generateCallback(routes.projectors.delete) );
		app.post('/projectors/:projectorid/showtimer',	generateCallback(routes.projectors.showTimer) );
		app.post('/projectors/:projectorid/hidetimer',	generateCallback(routes.projectors.hideTimer) );
		app.post('/projectors/:projectorid/flash',	generateCallback(routes.projectors.flash) );

		app.put('/timers/:timerid/save',	generateCallback(routes.timers.save) );
		app.post('/timers/:timerid/delete',	generateCallback(routes.timers.delete) );
		app.post('/timers/:timerid/start',	generateCallback(routes.timers.start) );
		app.post('/timers/:timerid/pause',	generateCallback(routes.timers.pause) );
		app.post('/timers/:timerid/stop',	generateCallback(routes.timers.stop) );

		app.put('/motionclasses/:motionclassid/save',		generateCallback(routes.motionclasses.save) );
		app.post('/motionclasses/:motionclassid/delete',	generateCallback(routes.motionclasses.delete) );
		app.post('/motionclasses/:motionclassid/move',		generateCallback(routes.motionclasses.move) );

		app.put('/motions/:motionid/save',		generateCallback(routes.motions.save) );
		app.post('/motions/:motionid/delete',		generateCallback(routes.motions.delete) );
		app.post('/motions/:motionid/move',		generateCallback(routes.motions.move) );
		app.put('/motions/:motionid/addBallot',		generateCallback(routes.motions.addBallot) );
		app.post('/motions/:motionid/deleteBallot',	generateCallback(routes.motions.deleteBallot) );

		app.put('/elections/:electionid/save',		generateCallback(routes.elections.save) );
		app.post('/elections/:electionid/delete',	generateCallback(routes.elections.delete) );
		app.put('/elections/:electionid/addBallot',	generateCallback(routes.elections.addBallot) );
		app.post('/elections/:electionid/deleteBallot',	generateCallback(routes.elections.deleteBallot) );

		app.put('/ballots/:ballotid/save',	generateCallback(routes.ballots.save) );
		app.put('/ballots/:ballotid/addOption',		generateCallback(routes.ballots.addOption) );
		app.post('/ballots/:ballotid/moveOption',	generateCallback(routes.ballots.moveOption) );
		app.post('/ballots/:ballotid/deleteOption',	generateCallback(routes.ballots.deleteOption) );

		app.put('/options/:optionid/save',	generateCallback(routes.options.save) );

		app.put('/pollsites/:pollsiteid/save',		generateCallback(routes.pollsites.save) );
		app.post('/pollsites/:pollsiteid/delete',	generateCallback(routes.pollsites.delete) );

		global.pollsiteSocket =	io.registerPollsites();
	}

	// Showtime!

	app.start = function() {
		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/libs/jquery-miniColors/jquery.miniColors.css",
				"public/libs/bootstrap/css/bootstrap.min.css",
				"public/libs/bootstrap/css/bootstrap-responsive.min.css",
				"public/stylesheets/admin.css"
			],
			fileOut: "public/min/admin.css"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/libs/jquery-1.7.2.min.js",
				"public/libs/jquery-ui-1.8.21.custom.min.js",
				"public/libs/jquery.mjs.nestedSortable.js",
				"public/libs/jquery-miniColors/jquery.miniColors.min.js",
				"public/libs/jquery.cookie.js",
				"public/libs/treeTable.js",
				"public/libs/sortedList.js",
				"public/libs/viewerOptions.js",
				"public/javascript/admin/selectProjector.js",
				"public/libs/bootstrap/js/bootstrap.min.js",
				"public/apiClient/timerClient.js",
				"public/apiClient/index.js",
				"public/apiClient/projectors.js",
				"public/apiClient/agenda.js",
				"public/apiClient/timers.js",
				"public/apiClient/motionclasses.js",
				"public/apiClient/motions.js",
				"public/apiClient/pollsites.js",
				"public/apiClient/elections.js",
				"public/apiClient/ballots.js",
				"public/apiClient/options.js",
				"public/apiClient/votes.js",
				"public/javascript/admin/index.js",
				"public/javascript/admin/navigation.js",
				"public/javascript/admin/projectors.js",
				"public/javascript/admin/flashmessages.js",
				"public/javascript/admin/agenda.js",
				"public/javascript/admin/timers.js",
				"public/javascript/admin/motions.js",
				"public/javascript/admin/pollsites.js",
				"public/javascript/admin/elections.js",
				"public/javascript/admin/ballots.js"
			],
			fileOut: "public/min/admin.js"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/stylesheets/showProjector.css"
			],
			fileOut: "public/min/showProjector.css"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/libs/jquery-1.7.2.min.js",
				"public/libs/jquery-ui-1.8.21.custom.min.js",
				"public/libs/jquery.properMenu.js",
				"public/libs/sortedList.js",
				"public/libs/viewerOptions.js",
				"public/apiClient/index.js",
				"public/apiClient/projectors.js",
				"public/apiClient/agenda.js",
				"public/apiClient/timers.js",
				"public/apiClient/motionclasses.js",
				"public/apiClient/motions.js",
				"public/apiClient/elections.js",
				"public/apiClient/ballots.js",
				"public/apiClient/options.js",
				"public/apiClient/timerClient.js",
				"public/apiClient/votes.js",
				"public/javascript/viewer/index.js",
				"public/javascript/viewer/navigation.js",
				"public/javascript/viewer/viewerdata.js",
				"public/javascript/viewer/currenttime.js",
				"public/javascript/viewer/defaultprojector.js",
				"public/javascript/viewer/projectors.js",
				"public/javascript/viewer/agenda.js",
				"public/javascript/viewer/motions.js",
				"public/javascript/viewer/elections.js",
				"public/javascript/viewer/ballots.js"
			],
			fileOut: "public/min/showProjector.js"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/stylesheets/showTimer.css"
			],
			fileOut: "public/min/showTimer.css"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/libs/jquery-1.7.2.min.js",
				"public/libs/jquery-ui-1.8.21.custom.min.js",
				"public/libs/viewerOptions.js",
				"public/apiClient/index.js",
				"public/apiClient/projectors.js",
				"public/apiClient/agenda.js",
				"public/apiClient/timers.js",
				"public/apiClient/motionclasses.js",
				"public/apiClient/motions.js",
				"public/apiClient/elections.js",
				"public/apiClient/ballots.js",
				"public/apiClient/options.js",
				"public/apiClient/timerClient.js",
				"public/apiClient/votes.js",
				"public/javascript/showTimer/index.js",
				"public/javascript/showTimer/navigation.js",
				"public/javascript/showTimer/currenttime.js",
				"public/javascript/showTimer/defaultprojector.js",
				"public/javascript/showTimer/projectors.js",
				"public/javascript/showTimer/timers.js"
			],
			fileOut: "public/min/showTimer.js"
		});

		new compressor.minify({
			type: 'no-compress',
			fileIn: [
				"public/libs/jquery-1.7.2.min.js",
				"public/libs/jquery-ui-1.8.21.custom.min.js",
				"public/apiClient/timerClient.js",
				"public/apiClient/index.js",
				"public/apiClient/projectors.js",
				"public/apiClient/agenda.js",
				"public/apiClient/timers.js",
				"public/apiClient/motionclasses.js",
				"public/apiClient/motions.js",
				"public/apiClient/pollsites.js",
				"public/apiClient/elections.js",
				"public/apiClient/ballots.js",
				"public/apiClient/options.js",
				"public/apiClient/votes.js",
				"public/javascript/postVotes/index.js"
			],
			fileOut: "public/min/postVotes.js"
		});

		app.listen(config.port, config.host, function() {
			if (process.getuid() == 0) {
				process.setgid(config.setgid);
				process.setuid(config.setuid);
			}
		});
		console.log("Express server listening on http://%s:%d/ in mode %s", config.host || "localhost", config.port, app.settings.env);
	}

	return app;
}
db.init(function() {
    db.ensureUser('benny@hill.org', 'benny');
    db.ensureUser('johnny@bravo.net', 'johnny');
    db.ensureUser('terry@pratchet.com', 'terry');
    db.ensureUser('sheerun@sher.pl', 'sheerun');
    db.ensureFollower('johnny@bravo.net', 'benny@hill.org');
    db.ensureFollower('johnny@bravo.net', 'terry@pratchet.com');
    db.ensureFollower('benny@hill.org', 'terry@pratchet.com');
    db.ensureFollower('sheerun@sher.pl', 'terry@pratchet.com');

    var err = function(err) {
        console.log(err);
    };
    db.getUserByEmail('johnny@bravo.net', function(user) {
        if (user) {
            db.addTweet(user.id, 'Johhny says hi @' + new Date(), function() {
                console.log("Added tweet " + user.email);
            }, err);
        }
    }, err);
    db.getUserByEmail('benny@hill.org', function(user) {
        if (user) {
            db.addTweet(user.id, 'Benny says hi @' + new Date(), function() {
                console.log("Added tweet " + user.email);
            }, err);
        }
    }, err);
    db.getUserByEmail('terry@pratchet.com', function(user) {
        if (user) {
            db.addTweet(user.id, 'Terry says hi @' + new Date(), function() {
                console.log("Added tweet " + user.email);
            }, err);
        }
    }, err);
	
    var app = module.exports = express.createServer();

    app.configure(function(){
        app.set('views', __dirname + '/views');
        app.set('view engine', 'ejs');
        app.use(express.cookieParser());
        app.use(express.session({
            secret: "muhahahahah"
        }));
        app.use(express.static(__dirname + '/public'));
        app.use(express.bodyParser());
        app.use(express.methodOverride());
        app.use(app.router);
        
    });
	
    app.configure('development', function(){
        app.use(express.errorHandler({
            dumpExceptions: true, 
            showStack: true
        })); 
    });
	
    app.configure('production', function(){
        app.use(express.errorHandler()); 
    });

    // Routes
        
    app.all('*', function(req, res, next){
        var errorFlashes = [];
        var infoFlashes = [];
        
        var parentRender = res.render;
        res.render = function(tpl, data) {
            arguments[1] = arguments[1] || {};
            arguments[1].error = (function() {
                var errors = req.flash('error');
                if (errors.length) {
                    errorFlashes.push.apply(errorFlashes, errors);
                }
                return errorFlashes.join('<br/>');
            })();
            if (!arguments[1].error.length) {
                delete arguments[1].error;
            }
            arguments[1].info = (function(){
                var infos = req.flash('info');
                if (infos.length) {
                    infoFlashes.push.apply(infoFlashes, infos);
                }
                return infoFlashes.join('<br/>');
            })();
            
            if (!arguments[1].info.length) {
                delete arguments[1].info;
            }
            return parentRender.apply(res,_.toArray(arguments));
        }
        if(req.session && req.session.userid) {
            db.getUserById(req.session.userid, function(user) {
                res.local('user', user);
                next();
            });
        } else {
            if (req.url !== '/login') {
                res.redirect('/login');
                return;
            }
            next();
        }
    });
	
    app.get('/', function(req, res, next) {
        var user = res.local('user');
        var followed = user.followed;
        followed.push(user.id);
        db.getTweetsOfUsers(followed, 10, function(tweets) {
            ;
            res.render('tweets', {
                title: 'Tweets',
                tweets: tweets
            });     
        }, function(err) {
            next(err);
        });
    });

    app.get('/logout', function(req, res){
        delete req.session.userid;
        res.redirect('/');
    });
    app.get('/login', function(req, res, next){
        var tplData = {
            title: 'Twitter - Get the fuck sign in'
        };
        res.render('login', tplData);
    });
    
    app.post('/login', function(req, res, next){
        var tplData = {
            title: 'Twitter - Get the fuck sign in',
            content: 'Foobar'
        };
        
        var email = req.param('email');
        var password = req.param('password');
        if (email && password && email.length && password.length && email.indexOf('@') !== -1 && email.indexOf('@') !== 0 && email.indexOf('@') !== (email.length - 1)) {
            tplData.email = email;
            db.getUserByEmail(email, function(user) {
                if (user === null) {
                	db.addUser(email, password, function(user_id) {
                		req.session.userid = user_id;
                		req.flash('info', 'Hello mrs. "' + email + '" :)');
                		res.redirect('/');
                	}, function(err) { next(err); });
                    return;
                }
                if (user.password !== password) {
                    req.flash('error', 'Bad password bitch!');
                    res.render('login', tplData);
                    return;
                }
                
                req.session.userid = user.id;
                req.flash('info', 'Hello mrs. "'+user.email+'" :)');
                res.redirect('/');
            }, function(){
                req.flash('error', 'WAA!!! Everything crash!')
            });
        } else {
            res.render('login', tplData);
        } 
    });

    app.get('/tweets', function(req, res){
        db.getAllTweets(100, function (tweets) { 
            res.render("tweets", {
                tweets: tweets, 
                title: "Tweets"
            });
        }, function () {
            res.redirect('/500');	 
        });
    });
	
    app.post('/tweet', function(req, res){
        var new_tweet = sanitizer.sanitize(req.body.body);
				if (new_tweet.trim().length == 0)
				{
					req.flash('error', "Tweet is empty.");
					res.redirect('/');
					return;
				}
        db.addTweet(res.local("user").id, new_tweet, function () { 
            req.flash('info', 'nigga has been appended to farm');
            res.redirect('/');
        }, function () {
            req.flash('error', "We're sorry, but posting your tweet was unsuccessful");
            res.redirect('/');	 
        });
    });

		app.get('/user/:user_id', function(req, res){
				db.getUserById(req.params.user_id, function(user) {
					db.getTweetsOfUser(req.params.user_id, 100, function (tweets) { 
						res.render("tweets", { 
							tweets: tweets,
							can_follow: res.local('user').followed.indexOf(user.id) === -1,
							title: "Tweets", 
							current_user: user });
					}, function () {
						res.redirect('/500');	 
					});
				});
		});

    app.get('/user/:followee_id/follow', function(req, res){
				if (res.local("user").followed.some ( function (id) { return id == req.params.followee_id } ))
				{
					req.flash('info', "You're already following this user.");
					res.redirect('/user/' + req.params.followee_id);
					return;
				}
        db.followUser(res.local("user").id, req.params.followee_id, function () {
            req.flash('info', 'Watching nigga at work BEGIN!');
						res.redirect('/user/' + req.params.followee_id);
        }, function () {
            req.flash('error', "We're sorry, but attempt to follow '" + req.params.followee_id + "' was unsuccessful");
						res.redirect('/user/' + req.params.followee_id);
        });
    });

    app.get('/user/:followee_id/unfollow', function(req, res){
				if (!res.local("user").followed.some ( function (id) { return id == req.params.followee_id } ))
				{
					req.flash('info', "You have already stopped following this user.");
					res.redirect('/user/' + req.params.followee_id);
					return;
				}
        db.unfollowUser(res.local("user").id, req.params.followee_id, function () {
            req.flash('info', 'Stopping watching nigga at work BEGIN!');
						res.redirect('/user/' + req.params.followee_id);
        }, function () {
            req.flash('error', "We're sorry, but attempt to unfollow '" + req.params.followee_id + "' was unsuccessful");
						res.redirect('/user/' + req.params.followee_id);
        });
    });
	
    app.listen(3000);
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
}, function(error) {
Example #6
0
var Monitor = module.exports = function Monitor(options) {
    this.options = options || {port: 8081, stats: {}, path: '/'};
    this.stats = this.options.stats;

    var app = express.createServer();

    var self = this;
    app.set('views', __dirname + '/../public/views');
    app.use(express.static(__dirname + '/../public'));
    app.set('view engine', 'html');

    app.get(this.options.path, function (req, res) {
        var accept = (req.headers || {}).accept || '';
        if(accept.search('json') > 0) {
            res.contentType('application/json');
            res.send(JSON.stringify(getStats(self.stats, req.connection)));
        }
        else {
            res.render('index.ejs', getStats(self.stats, req.connection));
        }
    });

    app.get(/^\/logs?(?:\/(\d+)(?:\.\.(\d+))?)?/, function (req, res) {
        var root, paths, logs, stats;
        var file = process.cwd() + req.url;
        if(req.url === '/logs') {
            root = process.cwd() + '/logs';
            paths = fs.readdirSync(root);
            logs = [];
            paths.forEach(function (filename) {
                stats = fs.statSync(root + '/' + filename);
                logs.push({
                    filename: filename,
                    stats: stats
                })
            });
            var data = getStats(self.stats, req.connection);
            data.logs = logs;
            res.render('logs.ejs', data);
        }
        else {
            var stat = fs.statSync(file);
            res.writeHead(200, {
                'Content-Type': 'text/plain',
                'Content-Length': stat.size
            });
            var readStream = fs.createReadStream(file);
            util.pump(readStream, res, function (e) {
                if(e) {
                    console.log(e.stack || e);
                }
                res.end();
            });
        }
    });

    app.get('/deps', function(req, res) {
        npm.load({}, function() {
            npm.commands.ls({}, true, function(e, data) {
                res.writeHead(200, {
                    'Content-Type': 'application/json'
                });

                var seen = [];
                var out = JSON.stringify(data, function (k, o) {
                    if(typeof o === "object") {
                        if(-1 !== seen.indexOf(o)) return '[Circular]';
                        seen.push(o);
                    }
                    return o;
                }, 2);
                res.end(out);
            });
        });
    });

    return app;
}
Example #7
0
var connect = require('connect');
var logger = require('logger').logger('worker');
var taskman = require('taskman');
var ijod = require('ijod');
var lconfig = require('lconfig');
var lutil = require('lutil');
var dal = require('dal');
var os = require('os');

var tstarted;

var SOURCE_VERSION = 'Unknown';
var CONFIG_VERSION = 'Unknown';

var worker = express.createServer(
  connect.bodyParser(),
  connect.cookieParser()
);

worker.get('/', function(req, res) {
  var cnt = 0;
  var tot = 0;

  taskman.stats().last.forEach(function(task) {
    cnt++;
    tot += (task.tdone - task.tstart);
  });

  var ret = {
    sourceVersion: SOURCE_VERSION,
    configVersion: CONFIG_VERSION,
    active: Object.keys(taskman.stats().workers).length,
Example #8
0
// Node.js Endpoint for ProjectRazor Image Service

var razor_bin = __dirname + "/razor"; // Set project_razor.rb path
var execFile = require("child_process").execFile; // create our execFile object
var express = require('express'); // include our express libs
var mime = require('mime');
var fs = require('fs');
var path = require('path');
var http_range_req = require('./http_range_req.js');
var common = require('./common.js');
var InvalidURIPathError = common.InvalidURIPathError;
var urlDecode = common.urlDecode;
var returnError = common.returnError;
var image_svc_path;

app = express.createServer(); // our express server

app.get('/razor/image/*', function(req, res) {
    try {
        var args = req.path.split('/');
        args.splice(0, 3);
        if (args.length > 0) {
            if (args[args.length - 1] == '')
                // Path ended with slash. Just skip this one
                args.pop();
            for ( var i = 0; i < args.length; ++i)
                args[i] = urlDecode(args[i]);
        }
        var absPath = path.resolve(image_svc_path + args.join('/'));
        if(absPath.indexOf(image_svc_path) != 0)
        	throw new InvalidURIPathError("Illegal path: '" + path + "'");
Example #9
0
  .signingKey(nconf.get("azure:signingKey"))
  .realm(nconf.get("azure:realm"))
  .homeRealm('') // if you want to use a default idp (like google/liveid)
  .tokenFormat('swt') // only swt supported for now
  .findOrCreateUser(function(session, userMetadata) {
        var promise = this.Promise();
        users.findOrCreateUser(userMetadata, promise);

        return promise;
	})
	.redirectPath('/');

var app = express.createServer(
	express.bodyParser(),
	express.static(__dirname + "/public"),
	express.cookieParser(),
	express.session( {secret: nconf.get("sessionKey")}),
	everyauth.middleware()
);
app.set('view engine', 'jade');

app.get('/', function(req, res) {
    res.render('main.jade', {req: req, everyauth: everyauth});
});

app.get('/getLanguages', function(req, res) {
    var term = req.query.term;
    languages.findMatchingLanguages(term, res);
});

var port = nconf.get("port");
Example #10
0
File: app.js Project: deemaHD/todo
var express = require('express'),
    path = require('path'),
    MongoClient = require('mongodb').MongoClient,
    app = module.exports = express.createServer(); /* зачем здесь это? "module.exports" ты ничего не экспортишь */

// Configuration
app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'html');   /* раз уж это написал, тогда в срт. 40 res.render('./public/index'); */
  app.use(express.bodyParser()); /* не используется нигде, пока что)) */
  app.use(express.static(__dirname + '/public'));
  app.use(express.static(__dirname + '/node_modules')); /* не хорошо что у тебя все зависимости в одном, для фронта нужно ставить отдельно, в publick'е */
});

/**
 *  Заварачивать весь сервак в коллбек монги плохая идея, тк. если нет соединения, сервер просто не стартонет, а должен сохранить весь функционал, просто не отображать никаких данных
 *  в идеале отправлять ошибку, при запросе, типа "нет соединения с БД".
 */

MongoClient.connect('mongodb://localhost:27017/TravelList', function(err, db){
  if (err){
    throw err;
  }else

    var collection = db.collection('travelTask'),
        tasks; /* обьявил, но не инициализировал, непонятно что за тип данных */

    collection.find().toArray(function(err, docs){
      if (err) {
        throw err;
Example #11
0
  d = d.toString(16); 
  while (d.length < digits) {
		d = '0' + d;
	}
	  
  return d;
}
function h2d(h) {
  return parseInt(h,16);
}

/******************* END UTFGrid Functions ******************/




var app = Express.createServer();

app.use(Connect.compress()); // compression

app.get('/', function(req, res){
  res.send(fs.readFileSync('./views/leaflet.html', 'utf8'));
});
app.get('/sf_tile.jsonp', function(req, res){
  res.send(fs.readFileSync('./views/sf_tile.jsonp', 'utf8'));
});
app.get('/tiles/:zoom/:col/:row', tile);

app.get('/utfgrids/:zoom/:col/:row', utfgrid);

app.listen(port);
Example #12
0
  //initalize the http server
  function (callback)
  {
    //create server
    var app = express.createServer();
    
    //load modules that needs a initalized db
    readOnlyManager = require("./db/ReadOnlyManager");
    exporthtml = require("./utils/ExportHtml");
    exportHandler = require('./handler/ExportHandler');
    importHandler = require('./handler/ImportHandler');
    apiHandler = require('./handler/APIHandler');
    padManager = require('./db/PadManager');
    securityManager = require('./db/SecurityManager');
    socketIORouter = require("./handler/SocketIORouter");
    
    //install logging      
    var httpLogger = log4js.getLogger("http");
    app.configure(function() 
    {
      // If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
      // Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
      if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR"))
        app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'}));
      app.use(express.cookieParser());
    });
    
    //serve static files
    app.get('/static/*', function(req, res)
    { 
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/.." +
                                    req.url.replace(/\.\./g, '').split("?")[0]);
      res.sendfile(filePath, { maxAge: exports.maxAge });
    });
    
    //serve minified files
    app.get('/minified/:id', function(req, res, next)
    { 
      res.header("Server", serverName);
      
      var id = req.params.id;
      
      if(id == "pad.js" || id == "timeslider.js")
      {
        minify.minifyJS(req,res,id);
      }
      else
      {
        next();
      }
    });
    
    //checks for padAccess
    function hasPadAccess(req, res, callback)
    {
      securityManager.checkAccess(req.params.pad, req.cookies.sessionid, req.cookies.token, req.cookies.password, function(err, accessObj)
      {
        if(err) throw err;
        
        //there is access, continue
        if(accessObj.accessStatus == "grant")
        {
          callback();
        }
        //no access
        else
        {
          res.send("403 - Can't touch this", 403);
        }
      });
    }
    
    //serve read only pad
    app.get('/ro/:id', function(req, res)
    { 
      res.header("Server", serverName);
      
      var html;
      var padId;
      var pad;
      
      async.series([
        //translate the read only pad to a padId
        function(callback)
        {
          readOnlyManager.getPadId(req.params.id, function(err, _padId)
          {
            padId = _padId;
            
            //we need that to tell hasPadAcess about the pad  
            req.params.pad = padId; 
            
            callback(err);
          });
        },
        //render the html document
        function(callback)
        {
          //return if the there is no padId
          if(padId == null)
          {
            callback("notfound");
            return;
          }
          
          hasPadAccess(req, res, function()
          {
            //render the html document
            exporthtml.getPadHTMLDocument(padId, null, false, function(err, _html)
            {
              html = _html;
              callback(err);
            });
          });
        }
      ], function(err)
      {
        //throw any unexpected error
        if(err && err != "notfound")
          throw err;
          
        if(err == "notfound")
          res.send('404 - Not Found', 404);
        else
          res.send(html);
      });
    });
        
    //serve pad.html under /p
    app.get('/p/:pad', function(req, res, next)
    {    
      //ensure the padname is valid and the url doesn't end with a /
      if(!padManager.isValidPadId(req.params.pad) || /\/$/.test(req.url))
      {
        res.send('Such a padname is forbidden', 404);
        return;
      }
      
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/../static/pad.html");
      res.sendfile(filePath, { maxAge: exports.maxAge });
    });
    
    //serve timeslider.html under /p/$padname/timeslider
    app.get('/p/:pad/timeslider', function(req, res, next)
    {
      //ensure the padname is valid and the url doesn't end with a /
      if(!padManager.isValidPadId(req.params.pad) || /\/$/.test(req.url))
      {
        res.send('Such a padname is forbidden', 404);
        return;
      }
      
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/../static/timeslider.html");
      res.sendfile(filePath, { maxAge: exports.maxAge });
    });
    
    //serve timeslider.html under /p/$padname/timeslider
    app.get('/p/:pad/export/:type', function(req, res, next)
    {
      //ensure the padname is valid and the url doesn't end with a /
      if(!padManager.isValidPadId(req.params.pad) || /\/$/.test(req.url))
      {
        res.send('Such a padname is forbidden', 404);
        return;
      }
    
      var types = ["pdf", "doc", "txt", "html", "odt"];
      //send a 404 if we don't support this filetype
      if(types.indexOf(req.params.type) == -1)
      {
        next();
        return;
      }
      
      //if abiword is disabled, and this is a format we only support with abiword, output a message
      if(settings.abiword == null && req.params.type != "html" && req.params.type != "txt" )
      {
        res.send("Abiword is not enabled at this Etherpad Lite instance. Set the path to Abiword in settings.json to enable this feature");
        return;
      }
      
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Server", serverName);
      
      hasPadAccess(req, res, function()
      {
        exportHandler.doExport(req, res, req.params.pad, req.params.type);
      });
    });
    
    //handle import requests
    app.post('/p/:pad/import', function(req, res, next)
    {
      //ensure the padname is valid and the url doesn't end with a /
      if(!padManager.isValidPadId(req.params.pad) || /\/$/.test(req.url))
      {
        res.send('Such a padname is forbidden', 404);
        return;
      }
    
      //if abiword is disabled, skip handling this request
      if(settings.abiword == null)
      {
        next();
        return; 
      }
      
      res.header("Server", serverName);
      
      hasPadAccess(req, res, function()
      {
        importHandler.doImport(req, res, req.params.pad);
      });
    });
    
    var apiLogger = log4js.getLogger("API");
    
    //This is a api call, collect all post informations and pass it to the apiHandler
    app.get('/api/1/:func', function(req, res)
    {
      res.header("Server", serverName);
      res.header("Content-Type", "application/json; charset=utf-8");
    
      apiLogger.info("REQUEST, " + req.params.func + ", " + JSON.stringify(req.query));
      
      //wrap the send function so we can log the response
      res._send = res.send;
      res.send = function(response)
      {
        response = JSON.stringify(response);
        apiLogger.info("RESPONSE, " + req.params.func + ", " + response);
        
        //is this a jsonp call, if yes, add the function call
        if(req.query.jsonp)
          response = req.query.jsonp + "(" + response + ")";
        
        res._send(response);
      }
      
      //call the api handler
      apiHandler.handle(req.params.func, req.query, req, res);
    });
    
    //The Etherpad client side sends information about how a disconnect happen
    app.post('/ep/pad/connection-diagnostic-info', function(req, res)
    {
      new formidable.IncomingForm().parse(req, function(err, fields, files) 
      { 
        console.log("DIAGNOSTIC-INFO: " + fields.diagnosticInfo);
        res.end("OK");
      });
    });
    
    //The Etherpad client side sends information about client side javscript errors
    app.post('/jserror', function(req, res)
    {
      new formidable.IncomingForm().parse(req, function(err, fields, files) 
      { 
        console.error("CLIENT SIDE JAVASCRIPT ERROR: " + fields.errorInfo);
        res.end("OK");
      });
    });
    
    //serve index.html under /
    app.get('/', function(req, res)
    {
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/../static/index.html");
      res.sendfile(filePath, { maxAge: exports.maxAge });
    });
    
    //serve robots.txt
    app.get('/robots.txt', function(req, res)
    {
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/../static/robots.txt");
      res.sendfile(filePath, { maxAge: exports.maxAge });
    });
    
    //serve favicon.ico
    app.get('/favicon.ico', function(req, res)
    {
      res.header("Server", serverName);
      var filePath = path.normalize(__dirname + "/../static/custom/favicon.ico");
      res.sendfile(filePath, { maxAge: exports.maxAge }, function(err)
      {
        //there is no custom favicon, send the default favicon
        if(err)
        {
          filePath = path.normalize(__dirname + "/../static/favicon.ico");
          res.sendfile(filePath, { maxAge: exports.maxAge });
        }
      });
    });
    
    //let the server listen
    app.listen(settings.port, settings.ip);
    console.log("Server is listening at " + settings.ip + ":" + settings.port);

    var onShutdown = false;
    var gracefulShutdown = function(err)
    {
      if(err && err.stack)
      {
        console.error(err.stack);
      }
      else if(err)
      {
        console.error(err);
      }
      
      //ensure there is only one graceful shutdown running
      if(onShutdown) return;
      onShutdown = true;
    
      console.log("graceful shutdown...");
      
      //stop the http server
      app.close();

      //do the db shutdown
      db.db.doShutdown(function()
      {
        console.log("db sucessfully closed.");
        
        process.exit(0);
      });
      
      setTimeout(function(){
        process.exit(1);
      }, 3000);
    }

    //connect graceful shutdown with sigint and uncaughtexception
    if(os.type().indexOf("Windows") == -1)
    {
      //sigint is so far not working on windows
      //https://github.com/joyent/node/issues/1553
      process.on('SIGINT', gracefulShutdown);
    }
    
    process.on('uncaughtException', gracefulShutdown);

    //init socket.io and redirect all requests to the MessageHandler
    var io = socketio.listen(app);
    
    //this is only a workaround to ensure it works with all browers behind a proxy
    //we should remove this when the new socket.io version is more stable
    io.set('transports', ['xhr-polling']);
    
    var socketIOLogger = log4js.getLogger("socket.io");
    io.set('logger', {
      debug: function (str)
      {
        socketIOLogger.debug(str);
      }, 
      info: function (str)
      {
        socketIOLogger.info(str);
      },
      warn: function (str)
      {
        socketIOLogger.warn(str);
      },
      error: function (str)
      {
        socketIOLogger.error(str);
      },
    });
    
    //minify socket.io javascript
    if(settings.minify)
      io.enable('browser client minification');
    
    var padMessageHandler = require("./handler/PadMessageHandler");
    var timesliderMessageHandler = require("./handler/TimesliderMessageHandler");
    
    //Initalize the Socket.IO Router
    socketIORouter.setSocketIO(io);
    socketIORouter.addComponent("pad", padMessageHandler);
    socketIORouter.addComponent("timeslider", timesliderMessageHandler);
    
    callback(null);  
  }
Example #13
0
express.createServer(function (request, response) {
//app.get('/', function(request, response) {

    console.log('GET request at: '+ request.url);
    var rootPath = './angular',
        defaultPath = './angular/default.html',
        filePath = request.url ==="/"? 
                        defaultPath : 
                        rootPath + request.url;

    fs.exists(filePath, function(exists) {
        console.log('exists '+ filePath);
        if (exists) {
            fs.readFile(filePath, function(error, content) {
                if (error) {
                    console.log('500 '+ filePath);

                    response.send(500);
                }
                else {
                    console.log('mime '+ filePath);
                    var contentType = mimeLookup.lookup(filePath);
                    // response.set('Content-Type',contentType);
                    // response.send(200,content);

                    console.log('200 '+ filePath);
                    response.writeHead(200, { 'Content-Type': contentType });
                    response.end(content, 'utf-8');
                }
            });
        }
        else {
            console.log('404 '+ filePath);
            response.status(404).send('Not found');
            //response.send(404, filePath);
        }
    });
}).listen(port);
Example #14
0
    RedisStore =  require('socket.io/lib/stores/redis'),
    redis = require('heroku-redis-client');



var ObjectID = mongodb.ObjectID;

var port = process.env.PORT || 8080,
    sessionSecret = process.env.SESSION_SECRET || "fdasfkjlsadfkljsdah";


// Express
var app = express.createServer(
  express.logger(),
  express.static(__dirname + '/public'),
  express.bodyParser(),
  express.cookieParser(),
  express.session({ secret: sessionSecret, store: new ConnectRedisStore({ client: redis.createClient() }) })
);

app.register('.haml', require('hamljs'));


// Socket.io
var io = require('socket.io').listen(app);

io.set('store', new RedisStore({
  redisPub: redis.createClient(),
  redisSub: redis.createClient(),
  redisClient: redis.createClient()
}));
Example #15
0
var facebook = require(__dirname + '/../lib/facebook-wrapper');
var express = require('express');
var fs = require('fs');
var config_file = __dirname + '/config.json';

var options = JSON.parse(fs.readFileSync(config_file));

var server = express.createServer(
	express.logger(),
	express.bodyParser(),
	express.cookieParser(),
	express.session({ secret: process.env.SESSION_SECRET || 'secret123' }),
	facebook.auth(options)
);

server.post('/*', function (req, res) {
	res.writeHead(200, {'Content-Type': 'text/html'});
	req.facebook.graph('/me?fields=id', function (id) {
		id = id.id;
		req.facebook.fql('select name, pic_small from user where uid=me()', function (data) {
			data = data[0];
			res.end('Hello, ' + data.name + ' (' + id + '). Have a picture of yourself: <img src=\"' + data.pic_small + '\" />');
		});
	});
});
server.listen(8000);

console.log('All is well');
Example #16
0
//setup Dependencies
var connect = require('connect')
    , express = require('express')
    , io = require('socket.io')
    , port = (process.env.PORT || 8081);

//Setup Express
var server = express.createServer();
server.configure(function(){
    server.set('views', __dirname + '/views');
    server.set('view options', { layout: false });
    server.use(connect.bodyParser());
    server.use(express.cookieParser());
    server.use(express.session({ secret: "shhhhhhhhh!"}));
    server.use(connect.static(__dirname + '/static'));
    server.use(server.router);
});

//setup the errors
server.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.jade', { locals: {
            title : '404 - Not Found'
            ,description: ''
            ,author: ''
            ,analyticssiteid: 'XXXXXXX'
        },status: 404 });
    } else {
        res.render('500.jade', { locals: {
            title : 'The Server Encountered an Error'
            ,description: ''
Example #17
0
    db.connect({}, function(err) {

        var useHTTPS = _(config).has('key'),
            useBounce = _(config).has('bounce') && config.bounce,
            app,
            io,
            bounce,
            dialbackClient,
            requestLogger = function(log) {
                return function(req, res, next) {
                    var weblog = log.child({"req_id": uuid.v4(), component: "web"});
                    var end = res.end,
                        startTime = Date.now();
                    req.log = weblog;
                    res.end = function(chunk, encoding) {
                        var rec, endTime;
                        res.end = end;
                        res.end(chunk, encoding);
                        endTime = Date.now();
                        rec = {req: req, res: res, serverTime: endTime - startTime};
                        if (_(req).has("principal")) {
                            rec.principal = req.principal;
                        }
                        if (_(req).has("client")) {
                            rec.client = req.client;
                        }
                        weblog.info(rec);
                    };
                    next();
                };
            };

        if (err) {
            log.error(err);
            callback(err, null);
            return;
        }

        if (useHTTPS) {
            log.info("Setting up HTTPS server.");
            app = express.createServer({key: fs.readFileSync(config.key),
                                        cert: fs.readFileSync(config.cert)});

            if (useBounce) {
                log.info("Setting up micro-HTTP server to bounce to HTTPS.");
                bounce = express.createServer(function(req, res, next) {
                    var host = req.header('Host');
                    res.redirect('https://'+host+req.url, 301);
                });
            }

        } else {
            log.info("Setting up HTTP server.");
            app = express.createServer();
        }

        app.config = config;

        if (config.smtpserver) {
            // harmless flag
            config.haveEmail = true;
            Mailer.setup(config, log);
        }

        var cleanup = config.cleanup || 600000;
        var dbstore = new DatabankStore(db, log, cleanup);

        if (!_(config).has("noweb") || !config.noweb) {
            app.session = express.session({secret: (_(config).has('sessionSecret')) ? config.sessionSecret : "insecure",
                                           store: dbstore});
        }

        // Configuration

        app.configure(function() {

            var serverVersion = 'pump.io/'+version + ' express/'+express.version + ' node.js/'+process.version,
                versionStamp = function(req, res, next) {
                    res.setHeader('Server', serverVersion);
                    next();
                },
                canonicalHost = function(req, res, next) {
                    var host = req.header('Host'),
                        urlHost,
                        addressHost;

                    if (!config.redirectToCanonical || !host) {
                        next();
                        return;
                    }

                    urlHost = URLMaker.makeHost();

                    if (host == urlHost) {
                        next();
                        return;
                    }

                    if (!config.redirectAddressToCanonical) {

                        addressHost = URLMaker.makeHost(address, port);

                        if (host == addressHost) {
                            next();
                            return;
                        }
                    }

                    res.redirect(URLMaker.makeURL(req.url), 301);
                };

            // Templates are in public
            app.set("views", __dirname + "/../public/template");
            app.set("view engine", "utml");

            app.use(requestLogger(log));

            if (config.redirectToCanonical) {
                app.use(canonicalHost);
            }

            app.use(rawBody);

            app.use(express.bodyParser());
            app.use(express.cookieParser());
            app.use(express.query());
            app.use(express.methodOverride());
            app.use(express.favicon());

            if (config.compress) {
                app.use(express.compress());
            }

            app.use(versionStamp);

            app.provider = new Provider(log, config.clients);

            // Initialize scripts

            _.each(config.plugins, function(pluginName) {
                var script;
                if (_.isFunction(plugins[pluginName].getScript)) {
                    script = plugins[pluginName].getScript();
                    log.info({plugin: pluginName, script: script}, "Adding script");
                    config.scripts.push(script);
                }
            });

            app.use(function(req, res, next) {
                res.local("config", config);
                res.local("data", {});
                res.local("page", {url: req.originalUrl});
                res.local("template", {});
                // Initialize null
                res.local("principalUser", null);
                res.local("principal", null);
                res.local("user", null);
                res.local("client", null);
                res.local("nologin", false);
                res.local("version", version);
                res.local("messages", {items: []});
                res.local("notifications", {items: []});
                next();
            });

            app.use(auth([auth.Oauth({name: "client",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: null,
                                      authorize_provider: null,
                                      authorization_finished_provider: null
                                     }),
                          auth.Oauth({name: "user",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: oauth.authenticate,
                                      authorize_provider: oauth.authorize,
                                      authorization_finished_provider: oauth.authorizationFinished
                                     })
                         ]));

            app.use(express["static"](__dirname + "/../public"));

            app.use(app.router);

        });

        app.error(function(err, req, res, next) {
            log.error(err);
            if (err instanceof HTTPError) {
                if (req.xhr || req.originalUrl.substr(0, 5) === '/api/') {
                    res.json({error: err.message}, err.code);
                } else if (req.accepts("html")) {
                    res.status(err.code);
                    res.render("error", {page: {title: "Error"},
                                         error: err});
                } else {
                    res.writeHead(err.code, {"Content-Type": "text/plain"});
                    res.end(err.message);
                }
            } else {
                next(err);
            }
        });

        // Routes

        api.addRoutes(app);
        webfinger.addRoutes(app);
        clientreg.addRoutes(app);
        shared.addRoutes(app);

        if (_.has(config, "uploaddir")) {
            // Simple boolean flag
            config.canUpload = true;
            uploads.addRoutes(app);
            Image.uploadDir = config.uploaddir;
        }

        if (config.requireEmail) {
            confirm.addRoutes(app);
        }

        // Use "noweb" to disable Web site (API engine only)

        if (!_(config).has("noweb") || !config.noweb) {
            web.addRoutes(app);
        } else {
            // A route to show the API doc at root
            app.get("/", function(req, res, next) {

                var Showdown = require("showdown"),
                    converter = new Showdown.converter();

                Step(
                    function() {
                        fs.readFile(path.join(__dirname, "..", "API.md"), this);
                    },
                    function (err, data) {
                        var html, markdown;
                        if (err) {
                            next(err);
                        } else {
                            markdown = data.toString();
                            html = converter.makeHtml(markdown);
                            res.render("doc", {page: {title: "API"},
                                               html: html});
                        }
                    }
                );
            });
        }

        DatabankObject.bank = db;

        URLMaker.hostname = hostname;
        URLMaker.port = (config.urlPort) ? config.urlPort : port;
        URLMaker.path = config.urlPath;

        Distributor.log = log.child({component: "distributor"});

        Distributor.plugins = _.filter(plugins, function(plugin) {
            return _.isFunction(plugin.distributeActivity) || _.isFunction(plugin.distributeToPerson);
        });

        if (_(config).has('serverUser')) {
            app.on('listening', function() {
                process.setuid(config.serverUser);
            });
        }

        if (config.sockjs) {
            pumpsocket.connect(app, log);
        }

        if (config.firehose) {
            log.info({firehose: config.firehose}, "Setting up firehose");
            Firehose.setup(config.firehose, log);
        }

        if (config.spamhost) {
            if (!config.spamclientid ||
                !config.spamclientsecret) {
                throw new Error("Need client ID and secret for spam host");
            }
            log.info({spamhost: config.spamhost}, "Configuring spam host");
            ActivitySpam.init({
                host: config.spamhost,
                clientID: config.spamclientid,
                clientSecret: config.spamclientsecret,
                logger: log
            });
        }

        dialbackClient = new DialbackClient({
            hostname: hostname,
            bank: db,
            app: app,
            url: "/api/dialback"
        });

        Credentials.dialbackClient = dialbackClient;

        // Each worker takes a turn cleaning up, so *this* worker does
        // its cleanup once every config.workers cleanup periods

        var workers = config.workers || 1;
        var cleanupTime = 1200 * workers * 1000;

        // We set a timer so we start with an offset, instead of having
        // all workers start at almost the same time

        setTimeout(function() {
            log.info("Cleaning up old OAuth nonces");
            Nonce.cleanup();
            setInterval(function() {
                log.info("Cleaning up old OAuth nonces");
                Nonce.cleanup();
            }, cleanupTime);
        }, Math.floor(Math.random() * cleanupTime));

        app.run = function(callback) {
            var self = this,
                removeListeners = function() {
                    self.removeListener("listening", listenSuccessHandler);
                    self.removeListener("err", listenErrorHandler);
                },
                listenErrorHandler = function(err) {
                    removeListeners();
                    log.error(err);
                    callback(err);
                },
                listenSuccessHandler = function() {
                    var removeBounceListeners = function() {
                        bounce.removeListener("listening", bounceSuccess);
                        bounce.removeListener("err", bounceError);
                    },
                        bounceError = function(err) {
                            removeBounceListeners();
                            log.error(err);
                            callback(err);
                        },
                        bounceSuccess = function() {
                            log.info("Finished setting up bounce server.");
                            removeBounceListeners();
                            callback(null);
                        };

                    log.info("Finished setting up main server.");

                    removeListeners();
                    if (useBounce) {
                        bounce.on("error", bounceError);
                        bounce.on("listening", bounceSuccess);
                        bounce.listen(80, address);
                    } else {
                        callback(null);
                    }
                };
            this.on("error", listenErrorHandler);
            this.on("listening", listenSuccessHandler);
            log.info("Listening on "+port+" for host " + address);
            this.listen(port, address);
        };

        // So they can add their own routes or other stuff to the app

        _.each(plugins, function(plugin, name) {
            if (_.isFunction(plugin.initializeApp)) {
                log.info({plugin: name}, "Initializing app.");
                plugin.initializeApp(app);
            }
        });

        callback(null, app);
    });
Example #18
0
function serveExpress (port, path, cb) {

    // Create an `EventEmitter` for test-related events.
    var tests = new events.EventEmitter;

    var app = express.createServer();

    app.set("views", __dirname + "/views");
    app.set("view engine", "jade");

    // Use our version of Jade.
    app.register(".jade", require("jade"));

    app.get("/", function (req, res) {
        tests.emit("visitor", req.ua);
        var json = jsonize(req, ["transport", "timeout"]);

        res.header("Expires", "0");
        res.header("Pragma", "no-cache");
        res.header("Cache-Control", "no-cache");

        res.render("index", {
            locals : {
                bootstrap : "YETI.start(" + json + ")",
                yeti_version : pkg.readPackageSync().version
            }
        });
    });

    var testIds = {};
    var testResults = {};
    var testQueue = {};

    // Add a new test. Called by the CLI in `app.js`.
    app.put("/tests/add", function (req, res) {
        if (!req.body.tests.length) return res.send(500);

        var urls = [];
        var id = makeId();

        req.body.tests.forEach(function (url) {
            urls.push("/project/" + id + url);
        });
        ui.debug("/tests/add: registered batch", id);

        if (tests.listeners("add").length) {
            tests.emit("add", id, urls);
        } else {
            testQueue[id] = urls;
        }

        res.send(id);
    });

    // Comet middleware.
    // Sends a response when a test comes in.
    function wait (req, responseCallback) {
        function ADDCB (id, urls) {
            ui.debug("/tests/wait: send", urls);
            responseCallback({
                tests : urls
            });
            testIds[id] = 1;
        }

        function SHUTDOWNCB (cb) {
            ui.debug("/tests/wait: shutdown!", port);
            req.on("end", cb);
            // Prevent browsers from reconnecting.
            responseCallback({shutdown:true});
            req.emit("end");
        }

        tests.on("add", ADDCB);
        tests.on("shutdown", SHUTDOWNCB);

        // create a run-once function
        var CLEANUPCB = (function () {
            var once = false;
            return function () {
                if (!once) return;
                once = true;
                // No longer able to write data here.
                tests.removeListener("add", ADDCB);
                tests.removeListener("shutdown", SHUTDOWNCB);
            }
        })();

        // Thanks to IE, we must listen to both.
        // IE sends a RST, other browsers FIN ACK.
        // Just respond to whatever happens sooner.
        req.connection.on("end", CLEANUPCB);
        req.connection.on("close", CLEANUPCB);

        // TODO: Delete stale tests from testQueue?
        if (testQueue) {
            for (
                var id in testQueue
            ) tests.emit("add", id, testQueue[id]);
            testQueue = {};
        }
    }

    // EventSource-powered Comet, called by the browser.
    app.get("/tests/wait", function (req, res) {
        res.writeHead(200, {
            "Content-Type" : "text/event-stream"
        });
        wait(req, function (data) {
            res.write("data: " + JSON.stringify(data) + "\n\n");
        });
    });

    // XMLHttpRequest-powered Comet, called by the browser.
    app.post("/tests/wait", function (req, res) {
        wait(req, function (data) {
            res.send(data);
        });
    });

    // Respond when test results for the given batch ID arrive.
    // Called by the CLI in `app.js`.
    app.get("/status/:id", function (req, res) {
        var id = req.params.id;
        if (id in testIds) {
            if (id in testResults) {
                var results = testResults[id].shift();
                if (results) {
                    return res.send(results);
                } else {
                    // nothing in the queue
                    delete testResults[id];
                    // fallthrough to the test listener
                }
            }
            tests.on(id, function (results) {
                res.send(results);
            });
        } else {
            res.send("Nothing is listening to this batch. At least one browser should be pointed at the Yeti server.", 404);
        }
    });

    // Recieves test results from the browser.
    app.post("/results", function (req, res) {

        var result = JSON.parse(req.body.results);
        result.ua = req.body.useragent;
        var id = req.body.id;

        ui.debug("/results:", id, " has results from: " + result.ua);

        if (id in testIds) {
            if (tests.listeners(id).length) {
                tests.emit(id, result);
            } else {
                if ( ! (id in testResults) ) {
                    testResults[id] = [];
                }
                testResults[id].push(result);
            }
        } else {
            ui.results(result);
        }

        // Advance to the next test immediately.
        // We do this here because determining if an iframe has loaded
        // is much harder on the client side. Takes advantage of the
        // fact that we're on the same domain as the parent page.
        res.send("<script>parent.parent.YETI.next()</script>");

    });

    // #### File Server

    var projectSend = function (res, file, appendString, nocache, prependString) {
        sendfiles.call(
            res,
            [file],
            appendString,
            null, // callback
            {
                prependString : prependString,
                cache : !nocache
            }
        );
    };

    app.get('/project/*', function (req, res) {

        var nocache = false;
        var splat = req.params.pop().split("/");
        if (splat[0] in testIds) {
            splat.shift();
            nocache = true; // using a unique url
        }
        if (splat[0] === "") splat.shift(); // stupid leading slashes
        splat = splat.join("/");

        var file = "/" + decodeURIComponent(splat);

        // The requested file must begin with our cwd.
        if (file.indexOf(path) !== 0) {
            // The file is outside of our cwd.
            // Reject the request.
            ui.log(ui.color.red("[!]")
                + " Rejected " + file
                + ", run in the directory to serve"
                + " or specify --path.");
            return res.send(403);
        }

        if (/^.*\.html?$/.test(req.url)) {
            // Inject a test reporter into the test page.
            projectSend(
                res, file,
                "<script src=\"/dyn/" + cachebuster
                + "/inject.js\"></script><script>"
                + "$yetify({url:\"/results\"});</script>",
                nocache
            );
        } else {
            // Everything else goes untouched.
            projectSend(res, file, "", nocache);
        }

    });

    var incSend = function (res, name, nocache) {
        sendfiles.call(
            res,
            [__dirname + "/../inc/" + name],
            "", // appendString
            null, // callback
            {
                cache : !nocache
            }
        );
    };

    app.get("/inc/*", function (req, res) {
        incSend(res, req.params);
    });

    app.get("/dyn/:cachebuster/*", function (req, res) {
        incSend(res, req.params, true);
    });

    app.get("/favicon.ico", function (req, res) {
        incSend(res, "favicon.ico", true);
    });

    // Start the server.
    // Workaround Express and/or Connect bugs
    // that strip out the `host` and `callback` args.
    // n.b.: Express's `run()` sets up view reloading
    // and sets the `env` to `process.env.ENV`, etc.
    // We are bypassing all of that by using http directly.
    http.Server.prototype.listen.call(app, port, null, cb);

    // Publish the `tests` emitter.
    emitterRegistry[port] = tests;

    return app;

}
Example #19
0
var dbName = process.env[ 'GRUMBLE_DB' ] != null ? process.env[ 'GRUMBLE_DB' ] : 'grumble';

var mongoose = require( 'mongoose' );
mongoose.connect( dbHost, dbName, dbPort );

var mongo = require( 'mongodb' );
var sessionDb = new mongo.Db( dbName, new mongo.Server( dbHost, dbPort, { auto_reconnect: true } ), {} );
var mongoStore = require( 'connect-mongodb' );

var sessionSecret = process.env[ 'GRUMBLE_SECRET' ] != null ? sha1( process.env[ 'GRUMBLE_SECRET' ] ) : sha1( __dirname + __filename + process.env[ 'USER' ] );

var app = express.createServer(
    express.static( __dirname + '/static' ),
    express.bodyParser(),
    express.cookieParser(),
    express.session({
        cookie: { maxAge: 60000 * 60 * 24 * 30 }, // 30 days
        secret: sessionSecret,
        store: new mongoStore( { db: sessionDb } )
    })
);

var apiModules = [
    require( './api/Sessions.js' ),
    require( './api/Users.js' ),
    require( './api/Rooms.js' ),
    require( './api/Messages.js' )
];

for ( var moduleIndex = 0; moduleIndex < apiModules.length; ++moduleIndex )
{
    apiModules[ moduleIndex ].bind( app );
Example #20
0
function TerminusServer(settings) {
    var self = {};

    var app = express.createServer();
    var io = sio.listen(app);

    var factories = {}

    io.set('log level', 1);
    app.set("view options", {layout: false});
    app.register(".tpl", mustache_templater);

    self.register_configuration = function (type, cfg) {
        cfg.type = type;
        var factory = TTYFactory(cfg, {
            data: function (data) {
                if (this.socket) {
                    this.socket.emit('data', data.toString());
                }
                else {
                    this.backlog += data;
                }
            },
            exit: function () {
                if (this.socket) {
                    this.socket.emit('exit');
                }
                this.parent.terminate(this.id);
            }
        });

        factories[type] = factory;

        app.get('/' + type, function (req, res) {
            var id = factory.create();
            res.redirect('/' + type + '/' + id);
        });

        app.get('/' + type + '/:id', function (req, res) {
            var id = req.params.id;
            console.log('Requesting: ' + type + "/" + id);
            if (!factory[id]) {
                factory.make(id);
            }
            else {
                factory.notimeout(id);
            }
            var client_settings = cfg.settings;
            if (typeof(client_settings) != "string") {
                throw "a list of settings is unsupported"
            }
            else {
                client_settings = '/resources/settings/' + client_settings;
            }
            res.render(path.join(settings.path,
                                 'page',
                                 cfg.template),
                       {termtype: type,
                        id: id,
                        magic: 12345678,
                        style: cfg.style,
                        settings: client_settings,
                        server: settings.host,
                        port: settings.port})
        });
    }

    process.env.HOSTNAME = os.hostname()
    self.register_filesystem = function (name, mountpoint) {
        name = expand_env(name);
        app.get('/f/' + name + "/*", function (req, res) {
            var file = req.params[0];
            res.sendfile(file, {root: mountpoint});
            // var fullpath = path.join(mountpoint, file);
            // res.sendfile(fullpath, {root: ""});
            // res.sendfile(fullpath);
        });
        console.log('mounted ' + mountpoint + ' on /' + name);
    }

    if (settings.fileserve) {
        for (var name in settings.fileserve) {
            self.register_filesystem(name, settings.fileserve[name]);
        }
    }

    app.get('/resources/*', function (req, res) {
        var file = req.params[0]
        res.sendfile(file, {root: settings.path});
        // res.sendfile(path.join(settings.path, file));
    });

    for (var type in settings.configurations) {
        self.register_configuration(type, settings.configurations[type]);
    }

    io.sockets.on('connection', function (socket) {

        var command = null;
        var id = null;

        socket.on('connect_to', function (data) {
            console.log('connect to: ' + data.command + '/' + data.id);
            command = data.command;
            id = data.id;
            factories[command].set_socket(id, socket);
        });

        socket.on('setsize', function (data) {
            if (command != null) {
                console.log('from ' + command + "#" + id + ' -> setsize: ' + data.h + "x" + data.w);
                factories[command][id].set_window_size(data.h, data.w);
            }
        });

        socket.on('data', function (data) {
            if (command != null) {
                factories[command][id].send(data);
            }
        });

        socket.on('disconnect', function () {
            if (command != null) {
                factories[command].schedule_terminate(id);
            }
        });
    });

    app.listen(settings.port, settings.host);
    console.log('Terminus serving on http://' + settings.host + ":" + settings.port)

    return self;
}
Example #21
0
// Post a SYSTEM message saying the chat restarted
chatLog.push({
	userid: -1000,
	name: 'SYSTEM',
	color: '#dc50ff',
	time: (new Date().getTime()),
	text: 'The chat system was restarted successfully.',
	gameid: -1000
});

var sslKey = fs.readFileSync('[].key');
var sslCert = fs.readFileSync('[].crt');
var sslCa = fs.readFileSync('[].crt');

var http_app = express.createServer( );
http_app.listen( 80, config.localbackendip );
var http_io = socketio.listen( http_app );
register( http_app, http_io );

var https_app = express.createServer({ key: sslKey, cert: sslCert, ca: sslCa });
https_app.listen( 443, config.localbackendip );
var https_io = socketio.listen( https_app );
register( https_app, https_io );






Example #22
0
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var fs = require('fs'),
    privateKey = fs.readFileSync('pem/key.pem').toString(),
    certificate = fs.readFileSync('pem/certificate.pem').toString(),
    express = require('express'),
    app = process.env.PRODUCTION ? express.createServer() : express.createServer({key: privateKey, cert: certificate}),
    path = require('path'),
    WS = require('ws').Server,
    mongoose = require('mongoose'),
    chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';

var DataStore = (function(){
    var init, store, connection, TestSuiteModel;

    init = function(mongoose, isProduction, connectionString) {
        console.log('Connecting to Mongo [isProduction: ' + isProduction + ']');
        if (isProduction) {
            connection = mongoose.connect(connectionString);
        }
        else {
            connection = mongoose.connect('mongodb://localhost/wsperf');
Example #23
0
var _http = require('http');
var _url = require('url');
var _qs = require('querystring');
var _fs = require('fs');
var _express = require('express');
var app = _express.createServer();

app.get('/', function (req, res) {
	res.send('discovery root');
});


function requestPrivateAddressDelay (delay, next) {
	requestPrivateAddress(function(error, address) {
		if (error) {
			setTimeout(function () {
				requestPrivateAddress(next);
			}, delay);
			return;
		}
		return next(null, address);
	});
}

function requestPrivateAddress (next) {
	var address = null;
	var _os = require('os');
	var ifces = _os.networkInterfaces();

	var ifce_key = app.set('discovery interface');
( function () {

var http = require( 'http' ),
	express = require( 'express' ),
	sqlite = require( 'sqlite3' ),
	dbStack = [], dbFlag = false,
	argv = require( 'optimist' ).argv,
	db = new sqlite.Database( argv._[0] || '/mnt/rtserver/pages.db' ),
	// The maximum number of tries per article
	maxTries = 6,
	// The maximum number of fetch retries per article
	maxFetchRetries = 6,
	// "Random" estimate of how many pending pages we have in the db
	pendingPagesEstimate = 500;

// ----------------- Prepared queries --------------
var dbGetTitle = db.prepare(
	'SELECT pages.id, pages.title ' +
	'FROM pages ' +
	'LEFT JOIN claims ON pages.id = claims.page_id AND claims.commit_hash = ? ' +
	'LEFT JOIN stats ON stats.id = pages.latest_result ' +
	'WHERE num_fetch_errors < ? AND ' +
	'( claims.id IS NULL OR ' +
	'( claims.has_errorless_result = 0 AND claims.num_tries <= ? AND claims.timestamp < ? ) ) ' +
	'ORDER BY stats.score DESC, ' +
	'claims.timestamp ASC LIMIT 1 OFFSET ? ' );

var dbGetTitleRandom = db.prepare(
	'SELECT pages.id, pages.title ' +
	'FROM pages ' +
	'LEFT JOIN claims ON pages.id = claims.page_id AND claims.commit_hash = ? ' +
	'LEFT JOIN stats ON stats.id = pages.latest_result ' +
	'WHERE num_fetch_errors < ? AND ' +
	'( claims.id IS NULL OR ' +
	'( claims.has_errorless_result = 0 AND claims.num_tries <= ? AND claims.timestamp < ? ) ) ' +
	'ORDER BY stats.score DESC, ' +
	'claims.timestamp ASC, RANDOM() LIMIT 1' );

var dbIncrementFetchErrorCount = db.prepare(
	'UPDATE pages SET num_fetch_errors = num_fetch_errors + 1 WHERE title = ?');

var dbClearFetchErrorCount = db.prepare(
	'UPDATE pages SET num_fetch_errors = 0 WHERE title = ?');

var dbInsertCommit = db.prepare(
	'INSERT OR IGNORE INTO commits ( hash, timestamp ) ' +
	'VALUES ( ?, ? )' );

var dbFindClaimByPageId = db.prepare(
	'SELECT claims.id, claims.num_tries FROM claims ' +
	'WHERE claims.page_id = ? AND claims.commit_hash = ?');

var dbFindClaimByTitle = db.prepare(
	'SELECT claims.id, claims.num_tries, claims.page_id FROM claims ' +
	'JOIN pages ON pages.id = claims.page_id AND pages.title = ? ' +
	'WHERE claims.commit_hash = ? AND claims.has_errorless_result = 0');

var dbInsertClaim = db.prepare(
	'INSERT INTO claims ( page_id, commit_hash, timestamp ) ' +
	'VALUES ( ?, ?, ? )');

var dbUpdateClaim = db.prepare(
	'UPDATE claims SET timestamp = ?, num_tries = num_tries + 1 WHERE id = ?');

var dbUpdateClaimResult = db.prepare(
	'UPDATE claims SET has_errorless_result = 1 WHERE id = ?');

var dbFindStatRow = db.prepare(
	'SELECT id FROM stats WHERE page_id = ? AND commit_hash = ?');

var dbInsertResult = db.prepare(
	'INSERT INTO results ( claim_id, result ) ' +
	'VALUES ( ?, ? )');

var dbUpdateResult = db.prepare(
	'UPDATE results SET result = ? WHERE claim_id = ?');

var dbInsertClaimStats = db.prepare(
	'INSERT INTO stats ' +
	'( skips, fails, errors, score, page_id, commit_hash ) ' +
	'VALUES ( ?, ?, ?, ?, ?, ? ) ' );

var dbUpdateClaimStats = db.prepare(
	'UPDATE stats ' +
	'SET skips = ?, fails = ?, errors = ?, score = ? ' +
	'WHERE page_id = ? AND commit_hash = ?' );

var dbUpdateLatestResult = db.prepare(
	'UPDATE pages ' +
	'SET latest_result = ( SELECT id from stats ' +
    'WHERE stats.commit_hash = ? AND page_id = pages.id ) ' +
    'WHERE id = ?' );

var dbLatestCommitHash = db.prepare(
	'SELECT hash FROM commits ORDER BY timestamp DESC LIMIT 1');

var dbSecondLastCommitHash = db.prepare(
	'SELECT hash FROM commits ORDER BY timestamp DESC LIMIT 1 OFFSET 1');

// IMPORTANT: node-sqlite3 library has a bug where it seems to cache
// invalid results when a prepared statement has no variables.
// Without this dummy variable as a workaround for the caching bug,
// stats query always fails after the first invocation.  So, if you
// do upgrade the library, please test before removing this workaround.
var dbStatsQuery = db.prepare(
	'SELECT ? AS cache_bug_workaround, ' +
	'(select hash from commits order by timestamp desc limit 1) as maxhash, ' +
	'(select count(*) from stats where stats.commit_hash = ' +
		'(select hash from commits order by timestamp desc limit 1)) as maxresults, ' +
	'(select avg(stats.errors) from stats join pages on ' +
		'pages.latest_result = stats.id) as avgerrors, ' +
	'(select avg(stats.fails) from stats join pages on ' +
		'pages.latest_result = stats.id) as avgfails, ' +
	'(select avg(stats.skips) from stats join pages on ' +
		'pages.latest_result = stats.id) as avgskips, ' +
	'(select avg(stats.score) from stats join pages on ' +
		'pages.latest_result = stats.id) as avgscore, ' +
	'count(*) AS total, ' +
	'count(CASE WHEN stats.errors=0 THEN 1 ELSE NULL END) AS no_errors, ' +
	'count(CASE WHEN stats.errors=0 AND stats.fails=0 '+
		'then 1 else null end) AS no_fails, ' +
	'count(CASE WHEN stats.errors=0 AND stats.fails=0 AND stats.skips=0 '+
		'then 1 else null end) AS no_skips, ' +
	// get regression count between last two commits
	'(SELECT count(*) ' +
	'FROM pages p ' +
	'JOIN stats AS s1 ON s1.page_id = p.id ' +
	'JOIN stats AS s2 ON s2.page_id = p.id ' +
	'WHERE s1.commit_hash = (SELECT hash ' +
	                        'FROM commits ORDER BY timestamp DESC LIMIT 1 ) ' +
        'AND s2.commit_hash = (SELECT hash ' +
                              'FROM commits ORDER BY timestamp DESC LIMIT 1 OFFSET 1) ' +
	'AND s1.score > s2.score ) as numregressions, ' +
	// get fix count between last two commits
	'(SELECT count(*) ' +
        'FROM pages ' +
        'JOIN stats AS s1 ON s1.page_id = pages.id ' +
        'JOIN stats AS s2 ON s2.page_id = pages.id ' +
        'WHERE s1.commit_hash = (SELECT hash FROM commits ORDER BY timestamp DESC LIMIT 1 ) ' +
	'AND s2.commit_hash = (SELECT hash FROM commits ORDER BY timestamp DESC LIMIT 1 OFFSET 1 ) ' +
	'AND s1.score < s2.score ) as numfixes '  +

	'FROM pages JOIN stats on pages.latest_result = stats.id');

var dbFailsQuery = db.prepare(
	'SELECT pages.title, commits.hash, stats.errors, stats.fails, stats.skips ' +
	'FROM stats ' +
	'JOIN (' +
	'	SELECT MAX(id) AS most_recent FROM stats GROUP BY page_id' +
	') AS s1 ON s1.most_recent = stats.id ' +
	'JOIN pages ON stats.page_id = pages.id ' +
	'JOIN commits ON stats.commit_hash = commits.hash ' +
	'ORDER BY stats.score DESC ' +
	'LIMIT 40 OFFSET ?' );

var dbGetOneResult = db.prepare(
	'SELECT result FROM results ' +
	'JOIN claims ON results.claim_id = claims.id ' +
	'JOIN commits ON claims.commit_hash = commits.hash ' +
	'JOIN pages ON pages.id = claims.page_id ' +
	'WHERE pages.title = ? ' +
	'ORDER BY commits.timestamp DESC LIMIT 1' );

var dbGetResultWithCommit = db.prepare(
    'SELECT result FROM results ' +
    'JOIN claims ON results.claim_id = claims.id ' +
    'AND claims.commit_hash = ? ' +
    'JOIN pages ON pages.id = claims.page_id ' +
    'WHERE pages.title = ?' );

var dbFailedFetches = db.prepare(
	'SELECT title FROM pages WHERE num_fetch_errors >= ?');

var dbRegressedPages = db.prepare(
	'SELECT pages.title, ' +
	's1.commit_hash AS new_commit, s1.errors AS new_errors, s1.fails AS new_fails, s1.skips AS new_skips, ' +
	's2.commit_hash AS old_commit, s2.errors AS old_errors, s2.fails AS old_fails, s2.skips AS old_skips ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.id = pages.latest_result ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s2.id != s1.id AND s1.score > s2.score ' +
	'GROUP BY pages.id ' + // picks a "random" past hash from which we regressed
	'ORDER BY s1.score - s2.score DESC ' +
	'LIMIT 40 OFFSET ?');

var dbFixedPages = db.prepare(
	'SELECT pages.title, ' +
	's1.commit_hash AS new_commit, s1.errors AS new_errors, s1.fails AS new_fails, s1.skips AS new_skips, ' +
	's2.commit_hash AS old_commit, s2.errors AS old_errors, s2.fails AS old_fails, s2.skips AS old_skips ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.id = pages.latest_result ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s2.id != s1.id AND s1.score < s2.score ' +
	'GROUP BY pages.id ' + // picks a "random" past hash from which we regressed
	'ORDER BY s1.score - s2.score ASC ' +
	'LIMIT 40 OFFSET ?');

var dbFailsDistribution = db.prepare(
	'SELECT ? AS caching_bug_workaround, fails, count(*) AS num_pages ' +
	'FROM stats ' +
	'JOIN pages ON pages.latest_result = stats.id ' +
	'GROUP by fails');

var dbSkipsDistribution = db.prepare(
	'SELECT ? AS caching_bug_workaround, skips, count(*) AS num_pages ' +
	'FROM stats ' +
	'JOIN pages ON pages.latest_result = stats.id ' +
	'GROUP by skips');

var dbCommits = db.prepare(
	'SELECT ? AS caching_bug_workaround, hash, timestamp, ' +
	//// get the number of fixes column
	//	'(SELECT count(*) ' +
	//	'FROM pages ' +
	//		'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	//		'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	//	'WHERE s1.commit_hash = (SELECT hash FROM commits c2 where c2.timestamp < c1.timestamp ORDER BY timestamp DESC LIMIT 1 ) ' +
	//		'AND s2.commit_hash = c1.hash AND s1.score < s2.score) as numfixes, ' +
	//// get the number of regressions column
	//	'(SELECT count(*) ' +
	//	'FROM pages ' +
	//		'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	//		'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	//	'WHERE s1.commit_hash = (SELECT hash FROM commits c2 where c2.timestamp < c1.timestamp ORDER BY timestamp DESC LIMIT 1 ) ' +
	//		'AND s2.commit_hash = c1.hash AND s1.score > s2.score) as numregressions, ' +
	//// get the number of tests for this commit column
		'(select count(*) from stats where stats.commit_hash = c1.hash) as numtests ' +
	'FROM commits c1 ' +
	'ORDER BY timestamp DESC');

var dbFixesBetweenRevs = db.prepare(
	'SELECT pages.title, ' +
	's1.commit_hash AS new_commit, s1.errors AS new_errors, s1.fails AS new_fails, s1.skips AS new_skips, ' +
	's2.commit_hash AS old_commit, s2.errors AS old_errors, s2.fails AS old_fails, s2.skips AS old_skips ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s1.commit_hash = ? AND s2.commit_hash = ? AND s1.score < s2.score ' +
	'ORDER BY s1.score - s2.score ASC ' +
	'LIMIT 40 OFFSET ?');

var dbNumFixesBetweenRevs = db.prepare(
	'SELECT count(*) as numFixes ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s1.commit_hash = ? AND s2.commit_hash = ? AND s1.score < s2.score ');

var dbRegressionsBetweenRevs = db.prepare(
	'SELECT pages.title, ' +
	's1.commit_hash AS new_commit, s1.errors AS new_errors, s1.fails AS new_fails, s1.skips AS new_skips, ' +
	's2.commit_hash AS old_commit, s2.errors AS old_errors, s2.fails AS old_fails, s2.skips AS old_skips ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s1.commit_hash = ? AND s2.commit_hash = ? AND s1.score > s2.score ' +
	'ORDER BY s1.score - s2.score DESC ' +
	'LIMIT 40 OFFSET ?');

var dbNumRegressionsBetweenRevs = db.prepare(
	'SELECT count(*) as numRegressions ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s1.commit_hash = ? AND s2.commit_hash = ? AND s1.score > s2.score ');

var dbNumRegressionsBetweenLastTwoRevs = db.prepare(
	'SELECT count(*) as numRegressions ' +
	'FROM pages ' +
	'JOIN stats AS s1 ON s1.page_id = pages.id ' +
	'JOIN stats AS s2 ON s2.page_id = pages.id ' +
	'WHERE s1.commit_hash = (SELECT hash ' +
	                        'FROM commits ORDER BY timestamp DESC LIMIT 1 ) ' +
        'AND s2.commit_hash = (SELECT hash ' +
                              'FROM commits ORDER BY timestamp DESC LIMIT 1 OFFSET 1) ' +
        'AND s1.score > s2.score ');


function dbUpdateErrCB(title, hash, type, msg, err) {
	if (err) {
		console.error("Error inserting/updating " + type + " for page: " + title + " and hash: " + hash);
		if (msg) {
			console.error(msg);
		}
		console.error("ERR: " + err);
	}
}

function titleCallback( req, res, retry, commitHash, cutOffTimestamp, err, row ) {
	if ( err && !retry ) {
		res.send( 'Error! ' + err.toString(), 500 );
	} else if ( err === null && row ) {
		db.serialize( function () {
			// SSS FIXME: what about error checks?
			dbInsertCommit.run( [ commitHash, decodeURIComponent( req.query.ctime ) ] );
			dbFindClaimByPageId.get( [ row.id, commitHash ], function ( err, claim ) {
				if (claim) {
					// Ignoring possible duplicate processing
					// Increment the # of tries, update timestamp
					dbUpdateClaim.run([Date.now(), claim.id],
						dbUpdateErrCB.bind(null, row.title, commitHash, "claim", null));

					if (claim.num_tries >= maxTries) {
						// Too many failures.  Insert an error stats entry and retry fetch
						console.log( ' CRASHER? ' + row.title);
						var stats = [0, 0, 1, statsScore(0,0,1), claim.page_id, commitHash];
						dbInsertClaimStats.run( stats, function ( err ) {
							if (err) {
								// Try updating the stats instead of inserting if we got an error
								// Likely a sql constraint error
								dbUpdateClaimStats.run(stats, function (err) {
									dbUpdateErrCB( row.title, commitHash, 'stats', null, err );
								});
							}
						} );
						fetchPage(commitHash, cutOffTimestamp, req, res);
					} else {
						console.log( ' -> ' + row.title);
						res.send( row.title );
					}
				} else {
					// Claim doesn't exist
					dbInsertClaim.run( [ row.id, commitHash, Date.now() ], function(err) {
						if (!err) {
							console.log( ' -> ' + row.title);
							res.send( row.title );
						} else {
							console.error(err);
							console.error("Multiple clients trying to access the same title: " + row.title);
							// In the rare scenario that some other client snatched the
							// title before us, get a new title (use the randomized ordering query)
							dbGetTitleRandom.get( [ commitHash, maxFetchRetries, maxTries, cutOffTimestamp ],
								titleCallback.bind( null, req, res, false, commitHash, cutOffTimestamp ) );
						}
					});
				}
			});
		});
	} else if ( retry ) {
		// Try again with the slow DB search method
		dbGetTitleRandom.get( [ commitHash, maxFetchRetries, maxTries, cutOffTimestamp ],
			titleCallback.bind( null, req, res, false, commitHash, cutOffTimestamp ) );
	} else {
		res.send( 'no available titles that fit those constraints', 404 );
	}
}

function fetchPage( commitHash, cutOffTimestamp, req, res ) {
	// This query picks a random page among the first 'pendingPagesEstimate' pages
	var rowOffset = Math.floor(Math.random() * pendingPagesEstimate);
	dbGetTitle.get([ commitHash, maxFetchRetries, maxTries, cutOffTimestamp, rowOffset ],
		titleCallback.bind( null, req, res, true, commitHash, cutOffTimestamp ) );
}

var getTitle = function ( req, res ) {
	res.setHeader( 'Content-Type', 'text/plain; charset=UTF-8' );

	// Select pages that were not claimed in the 10 minutes.
	// If we didn't get a result from a client 10 minutes after
	// it got a rt claim on a page, something is wrong with the client
	// or with parsing the page.
	//
	// Hopefully, no page takes longer than 10 minutes to parse. :)
	fetchPage(req.query.commit, Date.now() - 600, req, res);
},

statsScore = function(skipCount, failCount, errorCount) {
	// treat <errors,fails,skips> as digits in a base 1000 system
	// and use the number as a score which can help sort in topfails.
	return errorCount*1000000+failCount*1000+skipCount;
}

receiveResults = function ( req, res ) {
	var title = decodeURIComponent( req.params[0] ),
		result = req.body.results,
		skipCount = result.match( /\<skipped/g ),
		failCount = result.match( /\<failure/g ),
		errorCount = result.match( /\<error/g );

	skipCount = skipCount ? skipCount.length : 0;
	failCount = failCount ? failCount.length : 0;
	errorCount = errorCount ? errorCount.length : 0;

	res.setHeader( 'Content-Type', 'text/plain; charset=UTF-8' );

	var commitHash = req.body.commit;
	//console.warn("got: " + JSON.stringify([title, commitHash, result, skipCount, failCount, errorCount]));
	if ( errorCount > 0 && result.match( 'DoesNotExist' ) ) {
		console.log( 'XX', title );
		dbIncrementFetchErrorCount.run([title],
			dbUpdateErrCB.bind(null, title, commitHash, "page fetch error count", "null"));

		// NOTE: the last db update may not have completed yet
		// For now, always sending HTTP 200 back to client.
		res.send( '', 200 );
	} else {
		dbFindClaimByTitle.get( [ title, commitHash ], function ( err, claim ) {
			if (!err && claim) {
				db.serialize( function () {
					dbClearFetchErrorCount.run([title],
						dbUpdateErrCB.bind(null, title, commitHash, "page fetch error count", "null"));

					// Insert/update result and stats depending on whether this was
					// the first try or a subsequent retry -- prevents duplicates
					dbInsertResult.run([claim.id, result],
						dbUpdateErrCB.bind(null, title, commitHash, "result", "null"));

					var stats = [skipCount, failCount, errorCount, statsScore(skipCount,failCount,errorCount)];
					dbInsertClaimStats.run(stats.concat([claim.page_id, commitHash]), function ( err ) {
						if ( err ) {
							dbUpdateErrCB( title, commitHash, 'stats', null, err );
						} else {
							dbUpdateLatestResult.run( commitHash, claim.page_id,
								dbUpdateErrCB.bind(null, title, commitHash, 'latest result', null ) );
						}
					} );

					// Mark the claim as having a result. Used to be
					// error-free result, but now we are using it to track if
					// we have a result already.
					dbUpdateClaimResult.run([claim.id],
						dbUpdateErrCB.bind(null, title, commitHash, "claim result", "null"));


					console.log( '<-  ' + title + ': ', skipCount, failCount,
							errorCount, commitHash.substr(0,7) );
					// NOTE: the last db update may not have completed yet
					// For now, always sending HTTP 200 back to client.
					res.send( '', 200 );
				});
			} else {
				var msg = "Did not find claim for title: " + title;
				msg = err ? msg + "\n" + err.toString() : msg;
				res.send(msg, 500);
			}
		} );
	}
},

indexLinkList = function () {
	return '<p>More details:</p>\n<ul>' +
		'<li><a href="/topfails">Results by title</a></li>\n' +
		'<li><a href="/regressions">Top regressions</a></li>\n' +
		'<li><a href="/topfixes">Top fixes</a></li>\n' +
		'<li><a href="/stats/failedFetches">Non-existing test pages</a></li>\n' +
		'<li><a href="/stats/failsDistr">Histogram of failures</a></li>\n' +
		'<li><a href="/stats/skipsDistr">Histogram of skips</a></li>\n' +
		'<li><a href="/commits">List of all tested commits</a></li>\n' +
		'</ul>';
},

statsWebInterface = function ( req, res ) {
	function displayRow(res, title, val) {
		// round numeric data, but ignore others
		if(!isNaN(Math.round(val*100)/100)) {
			val = Math.round(val*100)/100;
		}
		res.write( '<tr style="font-weight:bold"><td style="padding-left:20px;">' +
					title + '</td><td style="padding-left:20px; text-align:right">' +
					val + '</td></tr>' );
	}

	// Fetch stats for commit
	dbStatsQuery.get([-1], function ( err, row ) {
		if ( err || !row ) {
			var msg = "Stats query returned nothing!";
			msg = err ? msg + "\n" + err.toString() : msg;
			console.error("Error: " + msg);
			res.send( msg, 500 );
		} else {
			res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
			res.status( 200 );
			res.write( '<html><body>' );

			var tests = row.total,
			errorLess = row.no_errors,
			skipLess = row.no_skips,
			numRegressions = row.numregressions,
			numFixes = row.numfixes,
			noErrors = Math.round( 100 * 100 * errorLess / tests ) / 100,
			perfects = Math.round( 100* 100 * skipLess / tests ) / 100,
			syntacticDiffs = Math.round( 100 * 100 *
				( row.no_fails / tests ) ) / 100;

			res.write( '<p>We have run roundtrip-tests on <b>' +
				tests +
				'</b> articles, of which <ul><li><b>' +
				noErrors +
				'%</b> parsed without crashes </li><li><b>' +
				syntacticDiffs +
				'%</b> round-tripped without semantic differences, and </li><li><b>' +
				perfects +
				'%</b> round-tripped with no character differences at all.</li>' +
				'</ul></p>' );

			var width = 800;

			res.write( '<table><tr height=60px>');
			res.write( '<td width=' +
					( width * perfects / 100 || 0 ) +
					'px style="background:green" title="Perfect / no diffs"></td>' );
			res.write( '<td width=' +
					( width * ( syntacticDiffs - perfects ) / 100 || 0 ) +
					'px style="background:yellow" title="Syntactic diffs"></td>' );
			res.write( '<td width=' +
					( width * ( 100 - syntacticDiffs ) / 100 || 0 ) +
					'px style="background:red" title="Semantic diffs"></td>' );
			res.write( '</tr></table>' );

			res.write( '<p>Latest revision:' );
			res.write( '<table><tbody>');
			displayRow(res, "Git SHA1", row.maxhash);
			displayRow(res, "Test Results", row.maxresults);
			displayRow(res, "Regressions", numRegressions);
			displayRow(res, "Fixes", numFixes);
			res.write( '</tbody></table></p>' );

			res.write( '<p>Averages (over the latest results):' );
			res.write( '<table><tbody>');
			displayRow(res, "Errors", row.avgerrors);
			displayRow(res, "Fails", row.avgfails);
			displayRow(res, "Skips", row.avgskips);
			displayRow(res, "Score", row.avgscore);
			res.write( '</tbody></table></p>' );
			res.write( indexLinkList() );

			res.end( '</body></html>' );
		}
	});
},

failsWebInterface = function ( req, res ) {
	console.log( 'GET /topfails/' + req.params[0] );
	var page = ( req.params[0] || 0 ) - 0,
		offset = page * 40;

	dbFailsQuery.all( [ offset ],
		function ( err, rows ) {
			var i, row, output, matches, total = {};

			if ( err ) {
				res.send( err.toString(), 500 );
			} else if ( rows.length <= 0 ) {
				res.send( 'No entries found', 404 );
			} else {
				res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
				res.status( 200 );
				res.write( '<html><body>' );

				res.write( '<p>' );
				if ( page > 0 ) {
					res.write( '<a href="/topfails/' + ( page - 1 ) + '">Previous</a> | ' );
				} else {
					res.write( 'Previous | ' );
				}
				res.write( '<a href="/topfails/' + ( page + 1 ) + '">Next</a>' );
				res.write( '</p>' );

				res.write( '<table><tr><th>Title</th><th>Commit</th><th>Syntactic diffs</th><th>Semantic diffs</th><th>Errors</th></tr>' );

				for ( i = 0; i < rows.length; i++ ) {
					res.write( '<tr><td style="padding-left: 0.4em; border-left: 5px solid ' );
					row = rows[i];

					if ( row['stats.skips'] === 0 && row['stats.fails'] === 0 && row['stats.errors'] === 0 ) {
						res.write( 'green' );
					} else if ( row['stats.errors'] > 0 ) {
						res.write( 'red' );
					} else if ( row['stats.fails'] === 0 ) {
						res.write( 'orange' );
					} else {
						res.write( 'red' );
					}

					res.write( '"><a target="_blank" href="http://parsoid.wmflabs.org/_rt/en/' +
						row.title + '">' +
						row.title + '</a> | ' +
						'<a target="_blank" href="http://localhost:8000/_rt/en/' + row.title +
						'">@lh</a> | ' +
						'<a target="_blank" href="/latestresult/' + row.title + '">latest result</a>' +
						'</td>' );
					res.write( '<td>' + makeCommitLink( row.hash, row.title ) + '</td>' );
					res.write( '<td>' + row.skips + '</td><td>' + row.fails + '</td><td>' + ( row.errors === null ? 0 : row.errors ) + '</td></tr>' );
				}
				res.end( '</table></body></html>' );
			}
		}
	);
},

resultsWebInterface = function ( req, res ) {
	db.all( 'SELECT result FROM results', function ( err, rows ) {
		var i;
		if ( err ) {
			console.error( err );
			res.send( err.toString(), 500 );
		} else {
			if ( rows.length === 0 ) {
				res.send( '', 404 );
			} else {
				res.setHeader( 'Content-Type', 'text/xml; charset=UTF-8' );
				res.status( 200 );
				res.write( '<?xml-stylesheet href="/static/result.css"?>\n' );
				res.write( '<testsuite>' );
				for ( i = 0; i < rows.length; i++ ) {
					res.write( rows[i].result );
				}

				res.end( '</testsuite>' );
			}
		}
	} );
};

function resultWebCallback( req, res, err, row ) {
	if ( err ) {
		console.error( err );
		res.send( err.toString(), 500 );
	} else if ( row ) {
		res.setHeader( 'Content-Type', 'text/xml; charset=UTF-8' );
		res.status( 200 );
		res.write( '<?xml-stylesheet href="/static/result.css"?>\n' );
		res.end( row.result );
	} else {
		res.send( 'no results for that page at the requested revision', 404 );
	}
}

function resultWebInterface( req, res ) {
	var commit = req.params[1] ? req.params[0] : null;
	var title = commit === null ? req.params[0] : req.params[1];

	if ( commit !== null ) {
		dbGetResultWithCommit.get( commit, title, resultWebCallback.bind( null, req, res ) );
	} else {
		dbGetOneResult.get( title, resultWebCallback.bind( null, req, res ) );
	}
}

function GET_failedFetches( req, res ) {
	dbFailedFetches.all( [maxFetchRetries], function ( err, rows ) {
		if ( err ) {
			console.error( err );
			res.send( err.toString(), 500 );
		} else {
			var n = rows.length;
			res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
			res.status( 200 );
			res.write( '<html><body>' );
			if (n === 0) {
				res.write('No titles returning 404!  All\'s well with the world!');
			} else {
				res.write('<h1> The following ' + n + ' titles return 404</h1>');
				res.write('<ul>');
				for (var i = 0; i < n; i++) {
					res.write('<li> ' + rows[i].title + ' </li>');
				}
				res.write( '</ul>');
			}
			res.end('</body></html>' );
		}
	} );
}

function GET_failsDistr( req, res ) {
	dbFailsDistribution.all([-1], function ( err, rows ) {
		if ( err ) {
			console.error( err );
			res.send( err.toString(), 500 );
		} else {
			var n = rows.length;
			res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
			res.status( 200 );
			res.write( '<html><body>' );
			res.write('<h1> Distribution of semantic errors </h1>');
			res.write('<table><tbody>');
			res.write('<tr><th># errors</th><th># pages</th></tr>');
			for (var i = 0; i < n; i++) {
				var r = rows[i];
				res.write('<tr><td>' + r.fails + '</td><td>' + r.num_pages + '</td></tr>');
			}
			res.end('</table></body></html>' );
		}
	} );
}

function GET_skipsDistr( req, res ) {
	dbSkipsDistribution.all([-1], function ( err, rows ) {
		if ( err ) {
			console.error( err );
			res.send( err.toString(), 500 );
		} else {
			var n = rows.length;
			res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
			res.status( 200 );
			res.write( '<html><body>' );
			res.write('<h1> Distribution of syntactic errors </h1>');
			res.write('<table><tbody>');
			res.write('<tr><th># errors</th><th># pages</th></tr>');
			for (var i = 0; i < n; i++) {
				var r = rows[i];
				res.write('<tr><td>' + r.skips + '</td><td>' + r.num_pages + '</td></tr>');
			}
			res.end('</table></body></html>' );
		}
	} );
}

function makeCommitLink( commit, title ) {
	return '<a href="/result/' +
		commit + '/' + title +
		'">' + commit.substr( 0, 7 ) +
		'</a>';
}

function displayPageList(res, urlPrefix, page, header, err, rows) {
	console.log( 'GET ' + urlPrefix + "/" + page );
	if ( err ) {
		res.send( err.toString(), 500 );
	} else if ( !rows || rows.length <= 0 ) {
		res.send( 'No entries found', 404 );
	} else {
		res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
		res.status( 200 );
		res.write('<html>');
		res.write('<head><style type="text/css">');
		res.write('th { padding: 0 10px }');
		res.write('td { text-align: center; }');
		res.write('td.title { text-align: left; }');
		res.write('</style></head>');
		res.write('<body>');

		if (header) {
			res.write("<b>" + header + "</b>");
		}

		res.write('<p>');
		if ( page > 0 ) {
			res.write( '<a href="' + urlPrefix + "/" + ( page - 1 ) + '">Previous</a> | ' );
		} else {
			res.write( 'Previous | ' );
		}
		if (rows.length === 40) {
			res.write('<a href="' + urlPrefix + "/" + ( page + 1 ) + '">Next</a>');
		}
		res.write('</p>');

		res.write('<table>');
		res.write('<tr><th>Title</th><th>New Commit</th><th>Errors|Fails|Skips</th><th>Old Commit</th><th>Errors|Fails|Skips</th></tr>' );

		for (var i = 0; i < rows.length; i++ ) {
			var r = rows[i];
			res.write('<tr>');
			res.write('<td class="title"><a href="http://parsoid.wmflabs.org/_rt/en/' +
					r.title.replace(/"/g, '&quot;') +
					'">' + r.title + '</a></td>');
			res.write('<td>' + makeCommitLink( r.new_commit, r.title ) + '</td>');
			res.write('<td>' + r.new_errors + "|" + r.new_fails + "|" + r.new_skips + '</td>');
			res.write('<td>' + makeCommitLink( r.old_commit, r.title ) + '</td>');
			res.write('<td>' + r.old_errors + "|" + r.old_fails + "|" + r.old_skips + '</td>');
			res.write('</tr>');
		}
		res.end( '</table></body></html>' );
	}
}

function GET_regressions ( req, res ) {
	var page, offset, urlPrefix;
	if (req.params.length > 1) {
		var r1 = req.params[0];
		var r2 = req.params[1];
		urlPrefix = "/regressions/between/" + r1 + "/" + r2;
		page = (req.params[2] || 0) - 0;
		offset = page * 40;
		dbNumRegressionsBetweenRevs.get([r2,r1], function(err, row) {
			if (err || !row) {
				res.send( err.toString(), 500 );
			} else {
				var topfixesLink = "/topfixes/between/" + r1 + "/" + r2,
					header = "Total regressions between selected revisions: " +
							row.numRegressions +
							' | <a href="' + topfixesLink + '">topfixes</a>';
				dbRegressionsBetweenRevs.all([r2, r1, offset ],
					displayPageList.bind(null, res, urlPrefix, page, header));
			}
		});
	} else {
		urlPrefix = "/regressions";
		page = ( req.params[0] || 0 ) - 0;
		offset = page * 40;
		dbRegressedPages.all([ offset ], displayPageList.bind(null, res, urlPrefix, page, null));
	}
}

function GET_topfixes ( req, res ) {
	var page, offset, urlPrefix;
	if (req.params.length > 1) {
		var r1 = req.params[0];
		var r2 = req.params[1];
		urlPrefix = "/topfixes/between/" + r1 + "/" + r2;
		page = (req.params[2] || 0) - 0;
		offset = page * 40;
		dbNumFixesBetweenRevs.get([r2,r1], function(err, row) {
			if (err || !row) {
				res.send( err.toString(), 500 );
			} else {
				var regressionLink = "/regressions/between/" + r1 + "/" + r2,
					header = "Total fixes between selected revisions: " + row.numFixes +
						' | <a href="' + regressionLink + '">regressions</a>';
				dbFixesBetweenRevs.all([r2, r1, offset ],
					displayPageList.bind(null, res, urlPrefix, page, header));
			}
		});
	} else {
		urlPrefix = "/topfixes";
		page = ( req.params[0] || 0 ) - 0;
		offset = page * 40;
		dbFixedPages.all([ offset ], displayPageList.bind(null, res, urlPrefix, page, null));
	}
}

function GET_commits( req, res ) {
	dbCommits.all([-1], function ( err, rows ) {
		if ( err ) {
			console.error( err );
			res.send( err.toString(), 500 );
		} else {
			var n = rows.length;
			res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
			res.status( 200 );
			res.write( '<html><body>' );
			res.write('<h1> List of all commits </h1>');
			res.write('<table><tbody>');
			res.write('<tr><th>Commit hash</th><th>Timestamp</th>' +
				  //'<th>Regressions</th><th>Fixes</th>' +
				  '<th>Tests</th>' +
				  '<th>-</th><th>+</th></tr>');
			for (var i = 0; i < n; i++) {
				var r = rows[i];
				res.write('<tr><td>' + r.hash + '</td><td>' + r.timestamp + '</td>');
				//res.write('<td>' + r.numregressions + '</td>');
				//res.write('<td>' + r.numfixes + '</td>');
				res.write('<td>' + r.numtests + '</td>');
				if ( i + 1 < n ) {
					res.write('<td><a href="/regressions/between/' + rows[i+1].hash +
						'/' + r.hash + '"><b>-</b></a></td>' );
					res.write('<td><a href="/topfixes/between/' + rows[i+1].hash +
						'/' + r.hash + '"><b>+</b></a></td>' );
				} else {
					res.write('<td></td><td></td>');
				}
				res.write('</tr>');
			}
			res.end('</table></body></html>' );
		}
	} );
}

// Make an app
var app = express.createServer();

// Make the coordinator app
var coordApp = express.createServer();

// Add in the bodyParser middleware (because it's pretty standard)
app.use( express.bodyParser() );
coordApp.use( express.bodyParser() );

// Main interface
app.get( /^\/results$/, resultsWebInterface );

// Results for a title (on latest commit)
app.get( /^\/latestresult\/(.*)$/, resultWebInterface );

// Results for a title on any commit
app.get( /^\/result\/([a-f0-9]*)\/(.*)$/, resultWebInterface );

// List of failures sorted by severity
app.get( /^\/topfails\/(\d+)$/, failsWebInterface );
// 0th page
app.get( /^\/topfails$/, failsWebInterface );

// Overview of stats
app.get( /^\/$/, statsWebInterface );
app.get( /^\/stats$/, statsWebInterface );

// Failed fetches
app.get( /^\/stats\/failedFetches$/, GET_failedFetches );

// Regressions -- 0th and later pages
app.get( /^\/regressions$/, GET_regressions );
app.get( /^\/regressions\/(\d+)$/, GET_regressions );
app.get( /^\/regressions\/between\/([^\/]+)\/([^\/]+)(?:\/(\d+))?$/, GET_regressions );

// Topfixes -- 0th and later pages
app.get( /^\/topfixes$/, GET_topfixes );
app.get( /^\/topfixes\/(\d+)$/, GET_topfixes );
app.get( /^\/topfixes\/between\/([^\/]+)\/([^\/]+)(?:\/(\d+))?$/, GET_topfixes );

// Distribution of fails
app.get( /^\/stats\/failsDistr$/, GET_failsDistr );

// Distribution of fails
app.get( /^\/stats\/skipsDistr$/, GET_skipsDistr );

// List of all commits
app.use( '/commits', GET_commits );

app.use( '/static', express.static( __dirname + '/static' ) );

// Clients will GET this path if they want to run a test
coordApp.get( /^\/title$/, getTitle );

// Receive results from clients
coordApp.post( /^\/result\/([^\/]+)/, receiveResults );

// Start the app
app.listen( 8001 );
coordApp.listen( 8002 );

}() );
Example #25
0
var express = require('express'),
	sio = require('socket.io');

var app = express.createServer(
		express.bodyParser(),
		express.static('public')
	);

// app.use(express.bodyParser());
// app.use(express.static('public'));

app.listen(3000);

var io = sio.listen(app);

io.sockets.on('connection', function(socket){
	// console.log('Someone connected');
	socket.on('join', function(name) {
		socket.nickname = name;
		socket.broadcast.emit('announcement', name + ' joined the chat');		// 广播消息给其他用户
	});

	socket.on('text', function(msg,fn){
		socket.broadcast.emit('text', socket.nickname, msg);

		// 确认消息已经接收
		fn(Date.now());
	});
});
Example #26
0
// merge contacts from journals
var fs = require('fs'),
    sys = require('sys'),
    http = require('http'),
    url = require('url'),
    lfs = require('../../Common/node/lfs.js'),
    crypto = require('crypto');


var lockerInfo;


var express = require('express'),connect = require('connect');
var app = express.createServer(connect.bodyDecoder(), connect.cookieDecoder(), connect.session({secret : "locker"}));

// Process the startup JSON object
process.stdin.resume();
process.stdin.on("data", function(data) {
    lockerInfo = JSON.parse(data);
    if (!lockerInfo || !lockerInfo["workingDirectory"]) {
        process.stderr.write("Was not passed valid startup information."+data+"\n");
        process.exit(1);
    }
    process.chdir(lockerInfo.workingDirectory);
    app.listen(lockerInfo.port, "localhost", function() {
        sys.debug(data);
        process.stdout.write(data);
        gatherContacts();
    });
});
Example #27
0
var express = require('express');
var app = express.createServer(express.logger());

var fs = require("fs");

var app = express.createServer(express.logger());
app.configure(function(){
  app.use('/static', express.static(__dirname + '/static'));
});

app.get('/', function(req, res) {
  var buf = new Buffer(fs.readFileSync('index.html'), 'utf-8');
  res.send(buf.toString());
});

var port = process.env.PORT || 8080;
app.listen(port, function() {
  console.log("Listening on " + port);
});
Example #28
0
    mailer = require('mailer'),
    markdown = require('markdown').markdown,
    models = require('./models'),
    sys = require('sys'),
    path = require('path'),
    fs = require('fs'),
    db,
    Friends,
    User,
    Video,
    LoginToken,
    Settings = { development: {}, test: {}, production: {} },
    emails;
     
     
var app = module.exports = express.createServer(form({ keepExtensions: true }));

function renderJadeFile(template, options) {
  var fn = jade.compile(template, options);
  return fn(options.locals);
}

// Configuration
var pub = __dirname + '/public';

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.bodyParser());
  //app.use(connectTimeout({ time: 10000 }));
Example #29
0
var express = require('express'),
app = express.createServer(),
io = require('socket.io').listen(app),
fs = require('fs');

app.get('/', function(req, res){
  io.sockets.emit('reload');
  res.send('ok');
});

app.get('/delayed', function(req, res){
  setTimeout(function(){
    io.sockets.emit('reload');
    res.send('ok');
  }, 1000);
});

app.configure(function(){
  app.use(express.methodOverride());
  app.use(express.bodyParser());
  app.use(express.static(__dirname + '/public'));
  app.use(express.errorHandler({
    dumpExceptions: true,
    showStack: true
  }));
  app.use(app.router);
});


app.listen(17001);
Example #30
0
(function() {

	// init vars
	var config
	  , version = '0.1.0a'
	// get modules
	  , fs = require('fs')
	  , git = require('gitty')
	// get os module
	  , os = require('os')
	  , qs = require('querystring')
	// get middleware
	  , express = require('express')
	  , app = express.createServer()
	  , http = require('http')
	  , jade = require('jade')
	// create socket connection
	  , io = require('socket.io').listen(app)
	  , port = 1337
	  , nslookup = require('dns').lookup
	  , netIp
	  , launched_apps = {};
	
	// console output colors
	var red = '\u001b[31m'
	  , blue = '\u001b[34m'
	  , reset = '\u001b[0m';
	
	var ipFlag = false;
	console.log('Starting NodeTV...');
	console.log('Resolving network IP...');
	resolveIp(os.hostname());	
	
	function resolveIp(hostname) {
		// determine network ip from hostname
		nslookup(hostname, function(err, addr, fam) {
			// if failed
			if (err) {
				// if there is a domain in the hostname
				if (os.hostname().split('.').length === 3) {
					// let the user know
					console.log(red + '!!! ' + reset + 'NodeTV has detected a potential issue while resolving your IP, applying workaround...');
					ipFlag = true;
					// try again without it
					var hostNoDomain = os.hostname().split('.')[0] + '.' + os.hostname().split('.')[2];
					resolveIp(hostNoDomain);
				} else {
					// otherwise tell the user something's up
					console.log(red + 'There was a problem resolving the network IP from the server\'s hostname.' + reset);
					// and quit
					process.exit();
				}
			} else {
				if (ipFlag) {
					console.log(red + '!!! ' + reset + 'NodeTV applied a workaround for an issue and may exhibit unexpected behavior.');
				}
				// all is good give NodeTV the resolved IP
				netIp = addr;
				// once IP is resolved, start the server
				// this nslookup fixes an issue for devices that are unable
				// to resolve a hostname over LAN, like Android
				init();
			}
		});
	}
	
	function init() {
		// load modules
		require('./remote.js')(io);
	
		// config server
		app.configure(function() {

			// set view directory and engine
			app.set('views', __dirname + '/views');
			app.set('view engine', 'jade');

			// methodOverride checks req.body.method for the HTTP method override
			// bodyParser parses the request body and populates req.body
			app.use(express.methodOverride());
			app.use(express.bodyParser());

			// use cookie parser
			app.use(express.cookieParser());

			// set public directory for static files
			app.use(express.static(__dirname + '/public'));

			// use router for non-static files
			app.use(app.router);

		});

		// dev env
		app.configure('development', function(){
			app.use(express.errorHandler({
				dumpExceptions: true, 
				showStack: true 
			}));
		});

		// prod env
		app.configure('production', function(){
			app.use(express.errorHandler());
		});
		
		/*
		 * http routes
		 */
	
		// render app
		app.get('/', function(req, res) {
			res.render('index', { 
				layout : 'layout',
				netIp : 'http://' + netIp,
				version : version
			});
		});
		
		// give client the app list
		app.get('/applist', function(req, res) {
			// generate a temporary unique id for each app
			var appId = function() {
				var chars = 'abcdefghijklmnopqrstuvwxyz1234567890'
				  , id = '';
				for (var i = 0; i < 10; i++) {
					id += chars.charAt((Math.random() * chars.length - 1).toFixed());
				}
				return id;
			};
			
			// get app list, create array, and send to client
			fs.readdir(__dirname + '/apps', function(err, files) {
				if (err || !files.length) {
					// if an error is thrown log it and tell the client
					console.log(err || red + '!!! ' + reset + 'No apps installed. Failed.');
					res.writeHead(500);
					res.write('Error reading app directory or no apps are installed.');
					res.end();
				} else {
					// otherwise lets serve up some apps
					var applist = [];
					// construct app object from manifest file
					files.forEach(function(val, key) {
						var appname = val
						// get manifest path
						  , manifest = __dirname + '/apps/' + appname + '/manifest.json'
						  , appconfig = JSON.parse(fs.readFileSync(manifest));
						// resolve paths to public route  
						appconfig.icon = '/apps/' + appname + appconfig.icon;
						// do the same for each script
						appconfig.scripts.forEach(function(val, key) {
							appconfig.scripts[key] = '/apps/' + appname + val;
						});
						// give id
						appconfig.id = appname + ':' + appId();
						// add to list
						applist.push(appconfig);
					});
					
					res.writeHead(200);
					res.write(JSON.stringify(applist));
					res.end();
				}
			});
		});
		
		// resolve static content for apps
		app.get('/apps/:appname/:directory/:file', function(req, res) {
			// get params
			var params = req.params
			  , appname = params.appname
			  , dir = params.directory
			  , file = params.file
			  , path = __dirname + '/apps/' + appname + '/' + dir + '/' + file;
			// determine if file is valid
			fs.exists(path, function(valid) {
				if (valid) {
					// read the file
					var asset = fs.readFileSync(path);
					// and serve it up
					res.writeHead(200);
					res.end(asset);
				} else {
					// fail
					res.writeHead(404);
					res.write('File not found.');
					res.end();
				}
			});
		});
		
		// app launcher/ui server
		app.post('/launch/:appname', function(req, res) {
		    var appname = req.params.appname
              , app_dir = __dirname + '/apps/' + appname
              , appconfig
              , manifest = app_dir + '/manifest.json';
            // sanity check
            if (fs.existsSync(manifest)) {
                appconfig = JSON.parse(fs.readFileSync(manifest));
                // determine if the view should be rendered or sent
                var splitup = appconfig.home.split('.')
                  , last = splitup.length - 1;
                // render jade template
                if (splitup[last] == 'jade') {
                    res.render(app_dir + appconfig.home, {
                        layout: false
                    });
                // render static html
                } else if (splitup[last] == 'html') {
                    res.writeHead(200);
                    fs.readFile(app_dir + appconfig.home, function(err, data) {
                        res.write(data);
                        res.end();
                    });
                }
                // require server side code
                if (appconfig.init && !(launched_apps[appname])) {
                    require(app_dir + appconfig.init)(app);
                    launched_apps[appname] = true
                }
            } else {
                res.writeHead(404);
                res.end();
            }
		});
		
		// get mounted drives
		app.get('/getMountedDisks', function(req, res) {
		    // determine os type
		    var platform = os.platform()
		      , disks = []
		      , paths = {
		      		'darwin' : '/Volumes',
		      		'linux' : '/mnt'
		      };
		    // find and parse mounted disks
		    fs.readdir(paths[platform], function(err, data) {
		    	if (err) {
		    		res.writeHead(500);
		    		res.end();
		    	} else {
		    		data.forEach(function(val, key) {
		    			var disk = {
		    				name : val,
		    				path : paths[platform] + '/' + val
		    			};
		    			disks.push(disk);
		    		});
		    		res.write(JSON.stringify(disks));
		    		res.end();
		    	}
		    });		    
		});
		
		// finds subdirectories of the passed path and returns them in an array
		app.get('/listDirectories', function(req, res) {		
			// get the path var
			var path = qs.parse(req.url.split('?')[1]).path
			  , dirs = [];
			// if the path is good then get it's dirs
			if (fs.existsSync(path)) {
				fs.readdir(path, function(err, files) {
					files.forEach(function(val,key) {
						if (fs.lstatSync(path + '/' + val).isDirectory() && val.charAt(0) !== '.') {
							dirs.push(val);
						}
					});
					res.write(JSON.stringify(dirs));
					res.end();
				});
			// otherwise fail	
			} else {
				res.writeHead(500);
				res.write('Invalid path.');
				res.end();
			}
		});
		
		// index library
		app.post('/indexLibrary', function(req, res) {
			var path = qs.parse(req.url.split('?')[1]).path;
		    // scan path for movies, music, and pictures
		    require('./indexlib.js')(path, io, function(data) {
		        // respond with library
		        res.write(JSON.stringify(data));
		        res.end();
		    }, function(err) {
		        res.writeHead(500);
		        res.end();
		    });
		});
		
		// send the media request by the path
		app.get('/play', function(req, res) {
		    var path = qs.parse(req.url.split('?')[1]).path;
		    // retrieve media and respond with it
		});

		/*
		 * start server
		 */

		app.listen(port, function() {
			console.log('NodeTV running at ' + netIp + ':' + port);
		});
	}

})();