<commit_before>(function (ns, d3, _, $, undefined) {

    var defaults = {
        chart: {
            padding: {
                top: 3,
                bottom: 25,
                left: 30,
                right: 3
            }
        },

        xAxis: {
            rangePadding: 0,
            innerTickSize: 0,
            outerTickSize: 0,
            tickPadding: 6,
            titlePadding: 0,
            firstAndLast: true
        },

        yAxis: {
            min: undefined,
            max: undefined,
            innerTickSize: 6,
            outerTickSize: 6,
            tickPadding: 4,
            titlePadding: 0,
            labels: {
                format: '.0f' // d3 formats
            }
        }
    };

    function merge(array1, array2) {
        if(typeof(array1) === 'number') array1 = [array1];
        if(typeof(array2) === 'number') array2 = [array2];
        if(!array1 || !array1.length) return array2;
        if(!array2 || !array2.length) return array1;

        return [].concat(array1, array2).sort(function (a,b) { return a-b; });
    }

    function roundToNearest(number, multiple){
        return Math.ceil(number / multiple) * multiple;
    }

    function niceRound(val) {
        return Math.ceil(val * 1.10);
        var digits = Math.floor(Math.log(val) / Math.LN10) + 1;
        var fac = Math.pow(10, digits);

        if(val < 1) return roundToNearest(val, 1);

        if(val < fac / 2) return roundToNearest(val, fac / 2);

        return roundToNearest(val, fac);
    }

    function extractScaleDomain(domain, min, max) {
        var dataMax = _.max(domain);
        var dataMin = _.min(domain);

        if (min === undefined && max === undefined) {
            return [dataMin, dataMax];
        }

        if (min === undefined) {
            return [Math.min(dataMin, max), max];
        }

        if (max === undefined) {
            return [min, Math.max(min, dataMax)];
        }

        return [min, max];
    }

    var cartesian = {
        dataSrc: [],

        init: function (options) {

            this.options = $.extend(true, {}, defaults, options);

            if(this.options.xAxis.title || this.options.yAxis.title) {
                this.titleOneEm = Narwhal.utils.textBounds('ABCD', 'axis-title').height;
                if(this.options.xAxis.title) {
                    this.options.chart.padding.bottom += this.titleOneEm; // should be 1em
                }

                if(this.options.yAxis.title) {
                    this.options.chart.padding.left += this.titleOneEm; // should be 1em
                }
            }

            return this;
        },

        computeXScale: function () {
            if (!this.xDomain) throw new Error('You are trying to render without setting data (xDomain).');

            this.scaleGenerator = _.nw.xScaleFactory(this.dataSrc, this.options);
            this.xScale = this.scaleGenerator.scale(this.xDomain);
            this.rangeBand = this.scaleGenerator.rangeBand();
        },

        computeYScale: function () {
            if (!this.yDomain) throw new Error('You are trying to render without setting data (yDomain).');
            var yScaleDomain = extractScaleDomain(this.yDomain, this.options.yAxis.min, this.options.yAxis.max);

            this.yScale = d3.scale.linear()
                .domain(yScaleDomain)
                .range([this.options.chart.plotHeight, 0]);
        },

        computeScales: function () {
            this.adjustDomain();
            this.computeXScale();
            this.computeYScale();

            return this;
        },

        xAxis: function () {
            var y = this.options.chart.plotHeight + this.options.chart.padding.top;
            var xAxis = this.scaleGenerator.axis().orient('bottom');

            this._xAxisGroup = this.svg
                .append('g')
                .attr('class', 'x axis')
                .attr('transform', 'translate(' + this.options.chart.padding.left + ',' + y + ')')
                .call(xAxis);

            this.scaleGenerator.postProcessAxis(this._xAxisGroup);

            return this;
        },

        yAxis: function () {
            var options = this.options.yAxis;
            var tickValues = this._extractTickValues(this.yDomain, options.min, options.max);
            var format = d3.format(options.labels.format);
            var yAxis = d3.svg.axis()
                .scale(this.yScale)
                .tickValues(tickValues)
                .tickFormat(format)
                .tickSize(options.innerTickSize, options.outerTickSize)
                .tickPadding(options.tickPadding)
                .orient('left');

            this._yAxisGroup = this.svg.append('g')
                .attr('class', 'y axis')
                .attr('transform', 'translate(' + this.options.chart.padding.left + ',' + this.options.chart.padding.top + ')');

            this._yAxisGroup.call(yAxis)
                .selectAll('text')
                    .attr('dy', '.9em');

            return this;
        },

        axisLabels: function () {
            var lineHeightAdjustment = this.titleOneEm * 0.25; // add 25% of font-size for a complete line-height

            if (this.options.xAxis.title) {
                this._xAxisGroup.append('text')
                    .attr('class', 'x axis-title')
                    .attr('text-anchor', 'end')
                    .attr('y', this.options.chart.padding.bottom - lineHeightAdjustment)
                    .attr('dx', this.options.chart.plotWidth)
                    .attr('dy', -this.options.xAxis.titlePadding)
                    .text(this.options.xAxis.title);
            }

            if (this.options.yAxis.title) {
                this._yAxisGroup.append('text')
                    .attr('class', 'y axis-title')
                    .attr('text-anchor', 'end')
                    .attr('transform', 'rotate(-90)')
                    .attr('y', -this.options.chart.padding.left + this.titleOneEm - lineHeightAdjustment)
                    .attr('dx', 0)
                    .attr('dy', this.options.yAxis.titlePadding)
                    .text(this.options.yAxis.title);
            }

        },

        render: function () {
            this.composeOptions();

            this.calcMetrics();

            this.computeScales();

            this.baseRender();

            this.xAxis()
                .yAxis()
                .axisLabels();

            this.renderVisualizations();

            return this;
        },

        datum: function (d, index) {
            return {
                y: _.isObject(d) ? d.y : d,
                x: _.isObject(d) ? d.x : this.options.xAxis.categories ? this.options.xAxis.categories[index] : index
            };
        },

        data: function (series) {

            if (series instanceof Array && !series.length) {
                return this;
            } else if (series instanceof Array && !series[0].data) {
                this.dataSrc = _.map(series, _.bind(this.datum, this));
                this.xDomain = this.extractXDomain(this.dataSrc);
                this.yDomain = this.extractYDomain(this.dataSrc);
                this.yMax = this.getYAxisDataMax(this.dataSrc);
                this.yMin = this.getYAxisDataMin(this.dataSrc);
            } else if (series instanceof Array && series[0].data) {
                // we have an array of series
                _.each(series, function (set) { this.data(set.data); }, this);
            }

            return this;
        },

        getYAxisDataMax: function (datums) {
            return Math.max(this.yMax || 0, _.max(_.pluck(datums, 'y')));
        },

        getYAxisDataMin: function (datums) {
            return Math.min(this.yMin || 0, _.min(_.pluck(datums, 'y')));
        },

        extractXDomain: function(datums) {
            return  this.options.xAxis.categories ? this.options.xAxis.categories : _.pluck(datums, 'x');
        },

        extractYDomain: function (datums) {
            var max = this.yDomain ? Math.max(this.yDomain[1], _.max(_.pluck(datums, 'y'))) : _.max(_.pluck(datums, 'y'));
            var min = this.yDomain ? Math.max(this.yDomain[0], _.min(_.pluck(datums, 'y'))) : _.min(_.pluck(datums, 'y'));

            return [min, max];
        },

        adjustDomain: function () {
            this.yDomain = this.yDomain ? [this.yDomain[0], niceRound(this.yDomain[1])] : [0, 10];
            this.xDomain = this.xDomain ? this.xDomain : [];
        },

        _extractTickValues: function (domain, min, max) {
            var adjustedDomain = merge(domain, this.yMax);

            if (min === undefined && max === undefined)
                return adjustedDomain;

            if (min === undefined) {
                return max > this.yMin ? merge([max], adjustedDomain) : [max];
            }

            if (max === undefined) {
                if (min >= this.yMax) return [min];
                adjustedDomain[0] = min;

                return adjustedDomain;
            }

            return merge([min, max], adjustedDomain);
        }

    };

    window[ns].prototype.expose('cartesian', cartesian);

})('Narwhal', window.d3, window._, window.jQuery);
<commit_msg>Fix yDomain calculation with min max and multiple series<commit_after>(function (ns, d3, _, $, undefined) {

    var defaults = {
        chart: {
            padding: {
                top: 3,
                bottom: 25,
                left: 30,
                right: 3
            }
        },

        xAxis: {
            rangePadding: 0,
            innerTickSize: 0,
            outerTickSize: 0,
            tickPadding: 6,
            titlePadding: 0,
            firstAndLast: true
        },

        yAxis: {
            min: undefined,
            max: undefined,
            innerTickSize: 6,
            outerTickSize: 6,
            tickPadding: 4,
            titlePadding: 0,
            labels: {
                format: '.0f' // d3 formats
            }
        }
    };

    function merge(array1, array2) {
        if(typeof(array1) === 'number') array1 = [array1];
        if(typeof(array2) === 'number') array2 = [array2];
        if(!array1 || !array1.length) return array2;
        if(!array2 || !array2.length) return array1;

        return [].concat(array1, array2).sort(function (a,b) { return a-b; });
    }

    function roundToNearest(number, multiple){
        return Math.ceil(number / multiple) * multiple;
    }

    function niceRound(val) {
        return Math.ceil(val * 1.10);
        var digits = Math.floor(Math.log(val) / Math.LN10) + 1;
        var fac = Math.pow(10, digits);

        if(val < 1) return roundToNearest(val, 1);

        if(val < fac / 2) return roundToNearest(val, fac / 2);

        return roundToNearest(val, fac);
    }

    function extractScaleDomain(domain, min, max) {
        var dataMax = _.max(domain);
        var dataMin = _.min(domain);

        if (min === undefined && max === undefined) {
            return [dataMin, dataMax];
        }

        if (min === undefined) {
            return [Math.min(dataMin, max), max];
        }

        if (max === undefined) {
            return [min, Math.max(min, dataMax)];
        }

        return [min, max];
    }

    var cartesian = {
        dataSrc: [],

        init: function (options) {

            this.options = $.extend(true, {}, defaults, options);

            if(this.options.xAxis.title || this.options.yAxis.title) {
                this.titleOneEm = Narwhal.utils.textBounds('ABCD', 'axis-title').height;
                if(this.options.xAxis.title) {
                    this.options.chart.padding.bottom += this.titleOneEm; // should be 1em
                }

                if(this.options.yAxis.title) {
                    this.options.chart.padding.left += this.titleOneEm; // should be 1em
                }
            }

            return this;
        },

        computeXScale: function () {
            if (!this.xDomain) throw new Error('You are trying to render without setting data (xDomain).');

            this.scaleGenerator = _.nw.xScaleFactory(this.dataSrc, this.options);
            this.xScale = this.scaleGenerator.scale(this.xDomain);
            this.rangeBand = this.scaleGenerator.rangeBand();
        },

        computeYScale: function () {
            if (!this.yDomain) throw new Error('You are trying to render without setting data (yDomain).');
            var yScaleDomain = extractScaleDomain(this.yDomain, this.options.yAxis.min, this.options.yAxis.max);

            this.yScale = d3.scale.linear()
                .domain(yScaleDomain)
                .range([this.options.chart.plotHeight, 0]);
        },

        computeScales: function () {
            this.adjustDomain();
            this.computeXScale();
            this.computeYScale();

            return this;
        },

        xAxis: function () {
            var y = this.options.chart.plotHeight + this.options.chart.padding.top;
            var xAxis = this.scaleGenerator.axis().orient('bottom');

            this._xAxisGroup = this.svg
                .append('g')
                .attr('class', 'x axis')
                .attr('transform', 'translate(' + this.options.chart.padding.left + ',' + y + ')')
                .call(xAxis);

            this.scaleGenerator.postProcessAxis(this._xAxisGroup);

            return this;
        },

        yAxis: function () {
            var options = this.options.yAxis;
            var tickValues = this._extractTickValues(this.yDomain, options.min, options.max);
            var format = d3.format(options.labels.format);
            var yAxis = d3.svg.axis()
                .scale(this.yScale)
                .tickValues(tickValues)
                .tickFormat(format)
                .tickSize(options.innerTickSize, options.outerTickSize)
                .tickPadding(options.tickPadding)
                .orient('left');

            this._yAxisGroup = this.svg.append('g')
                .attr('class', 'y axis')
                .attr('transform', 'translate(' + this.options.chart.padding.left + ',' + this.options.chart.padding.top + ')');

            this._yAxisGroup.call(yAxis)
                .selectAll('text')
                    .attr('dy', '.9em');

            return this;
        },

        axisLabels: function () {
            var lineHeightAdjustment = this.titleOneEm * 0.25; // add 25% of font-size for a complete line-height

            if (this.options.xAxis.title) {
                this._xAxisGroup.append('text')
                    .attr('class', 'x axis-title')
                    .attr('text-anchor', 'end')
                    .attr('y', this.options.chart.padding.bottom - lineHeightAdjustment)
                    .attr('dx', this.options.chart.plotWidth)
                    .attr('dy', -this.options.xAxis.titlePadding)
                    .text(this.options.xAxis.title);
            }

            if (this.options.yAxis.title) {
                this._yAxisGroup.append('text')
                    .attr('class', 'y axis-title')
                    .attr('text-anchor', 'end')
                    .attr('transform', 'rotate(-90)')
                    .attr('y', -this.options.chart.padding.left + this.titleOneEm - lineHeightAdjustment)
                    .attr('dx', 0)
                    .attr('dy', this.options.yAxis.titlePadding)
                    .text(this.options.yAxis.title);
            }

        },

        render: function () {
            this.composeOptions();

            this.calcMetrics();

            this.computeScales();

            this.baseRender();

            this.xAxis()
                .yAxis()
                .axisLabels();

            this.renderVisualizations();

            return this;
        },

        datum: function (d, index) {
            return {
                y: _.isObject(d) ? d.y : d,
                x: _.isObject(d) ? d.x : this.options.xAxis.categories ? this.options.xAxis.categories[index] : index
            };
        },

        data: function (series) {

            if (series instanceof Array && !series.length) {
                return this;
            } else if (series instanceof Array && !series[0].data) {
                this.dataSrc = _.map(series, _.bind(this.datum, this));
                this.xDomain = this.extractXDomain(this.dataSrc);
                this.yDomain = this.extractYDomain(this.dataSrc);
                this.yMax = this.getYAxisDataMax(this.dataSrc);
                this.yMin = this.getYAxisDataMin(this.dataSrc);
            } else if (series instanceof Array && series[0].data) {
                // we have an array of series
                _.each(series, function (set) { this.data(set.data); }, this);
            }

            return this;
        },

        getYAxisDataMax: function (datums) {
            return Math.max(this.yMax || 0, _.max(_.pluck(datums, 'y')));
        },

        getYAxisDataMin: function (datums) {
            return Math.min(this.yMin || 0, _.min(_.pluck(datums, 'y')));
        },

        extractXDomain: function(datums) {
            return  this.options.xAxis.categories ? this.options.xAxis.categories : _.pluck(datums, 'x');
        },

        extractYDomain: function (datums) {
            var max = this.yDomain ? Math.max(this.yDomain[1], _.max(_.pluck(datums, 'y'))) : _.max(_.pluck(datums, 'y'));
            var min = this.yDomain ? Math.min(this.yDomain[0], _.min(_.pluck(datums, 'y'))) : _.min(_.pluck(datums, 'y'));

            return [min, max];
        },

        adjustDomain: function () {
            this.yDomain = this.yDomain ? [this.yDomain[0], niceRound(this.yDomain[1])] : [0, 10];
            this.xDomain = this.xDomain ? this.xDomain : [];
        },

        _extractTickValues: function (domain, min, max) {
            var adjustedDomain = merge(domain, this.yMax);

            if (min === undefined && max === undefined)
                return adjustedDomain;

            if (min === undefined) {
                return max > this.yMin ? merge([max], adjustedDomain) : [max];
            }

            if (max === undefined) {
                if (min >= this.yMax) return [min];
                adjustedDomain[0] = min;

                return adjustedDomain;
            }

            return merge([min, max], this.yMax);
        }

    };

    window[ns].prototype.expose('cartesian', cartesian);

})('Narwhal', window.d3, window._, window.jQuery);
<|endoftext|>


<commit_before>var logger = require('util');
var sys = require('sys');
var http = require('http');
var journey = require('journey');
var router = new(journey.Router)();
var paperboy = require('paperboy');
var url = require('url');
var _ = require('underscore')._;

process.on('exit', function () {
  logger.log('Bye bye Statusdashboard.');
});

process.on('uncaughtException', function(err) {
  logger.log(err);
});

String.prototype.startsWith = function(str) {
    return (this.indexOf(str) === 0);
}

// settings
var settings = require('./settings').create();
var api = require('./api');
// router
router.get(/^\/api\/services$/).bind(api.services);
router.get(/^\/api\/services\/([a-z\-]+)$/).bind(api.servicesElement);
router.get(/^\/api\/summarize$/).bind(api.summarize);
router.get(/^\/api\/config\/client$/).bind(api.configClient);
router.get(/^\/api\/plugins\/client$/).bind(api.pluginsClient);
router.get(/^\/api\/uptime$/).bind(api.uptime);

// static
var docRoot = __dirname + '/public';
var pluginsDocRoot = [];

// server
var server = http.createServer(function(req, res) {
  var body = '';
  req.on('data', function(chunk) {
    body += chunk;
  });
  req.on('end', function() {
    router.handle(req, body, function (route) {
      if (route.status === 404) {
        paperboy.deliver(docRoot, req, res).otherwise(function(err) {
          var pathname = url.parse(req.url).pathname;
          var pluginDocRootSelect = _.select(pluginsDocRoot, function(data) { return pathname.toString().startsWith(data.prefix); });
          if (pluginDocRootSelect && pluginDocRootSelect[0]) {
            var pluginDocRoot = pluginDocRootSelect[0];
            req.url = pathname.toString().replace(pluginDocRoot.prefix, "");
            paperboy.deliver(pluginDocRoot.docRoot, req, res).otherwise(function(err) {
              res.writeHead(404);
              res.end('File not found.');
            });
          } else {
            res.writeHead(route.status, route.headers);
            res.end(route.body);
          }
        });
      } else {
        res.writeHead(route.status, route.headers);
        res.end(route.body);
      }
    });
  });
});
server.listen(settings.port, settings.hostname);

var count = 0;
var io = require('socket.io').listen(server);

// https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
io.enable('browser client minification');
io.enable('browser client etag');
io.set('log level', 1);

io.sockets.on('connection', function(socket) {
  count++;
  logger.log('New client connected! (' + count + ')');
  socket.emit('title', settings.title);
  socket.emit('status', api.getStatus());
  socket.broadcast.emit('count', count);

  socket.on('disconnect', function() {
    count--;
    socket.broadcast.emit('count', count);
  });
  api.on("refresh", function(status) {
    socket.emit('status', status);
  });
});

api.on("routeContribution", function(route) {
  router.route(route.method, route.path).bind(route.binding);
});

api.on("staticContribution", function(plugin) {
  logger.log("Add static contribution: " + plugin);
  var docRoot = __dirname + '/plugins/' + plugin + '/public';
  pluginsDocRoot.push( { prefix: "/api/" + plugin, docRoot: docRoot });
  logger.log("Add static contribution: " + sys.inspect(pluginsDocRoot));
});

logger.log('Server started.');
logger.log('Server running at http://' + settings.hostname + ':' + settings.port);

<commit_msg>print client count on disconnect<commit_after>var logger = require('util');
var sys = require('sys');
var http = require('http');
var journey = require('journey');
var router = new(journey.Router)();
var paperboy = require('paperboy');
var url = require('url');
var _ = require('underscore')._;

process.on('exit', function () {
  logger.log('Bye bye Statusdashboard.');
});

process.on('uncaughtException', function(err) {
  logger.log(err);
});

String.prototype.startsWith = function(str) {
    return (this.indexOf(str) === 0);
}

// settings
var settings = require('./settings').create();
var api = require('./api');
// router
router.get(/^\/api\/services$/).bind(api.services);
router.get(/^\/api\/services\/([a-z\-]+)$/).bind(api.servicesElement);
router.get(/^\/api\/summarize$/).bind(api.summarize);
router.get(/^\/api\/config\/client$/).bind(api.configClient);
router.get(/^\/api\/plugins\/client$/).bind(api.pluginsClient);
router.get(/^\/api\/uptime$/).bind(api.uptime);

// static
var docRoot = __dirname + '/public';
var pluginsDocRoot = [];

// server
var server = http.createServer(function(req, res) {
  var body = '';
  req.on('data', function(chunk) {
    body += chunk;
  });
  req.on('end', function() {
    router.handle(req, body, function (route) {
      if (route.status === 404) {
        paperboy.deliver(docRoot, req, res).otherwise(function(err) {
          var pathname = url.parse(req.url).pathname;
          var pluginDocRootSelect = _.select(pluginsDocRoot, function(data) { return pathname.toString().startsWith(data.prefix); });
          if (pluginDocRootSelect && pluginDocRootSelect[0]) {
            var pluginDocRoot = pluginDocRootSelect[0];
            req.url = pathname.toString().replace(pluginDocRoot.prefix, "");
            paperboy.deliver(pluginDocRoot.docRoot, req, res).otherwise(function(err) {
              res.writeHead(404);
              res.end('File not found.');
            });
          } else {
            res.writeHead(route.status, route.headers);
            res.end(route.body);
          }
        });
      } else {
        res.writeHead(route.status, route.headers);
        res.end(route.body);
      }
    });
  });
});
server.listen(settings.port, settings.hostname);

var count = 0;
var io = require('socket.io').listen(server);

// https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
io.enable('browser client minification');
io.enable('browser client etag');
io.set('log level', 1);

io.sockets.on('connection', function(socket) {
  count++;
  logger.log('New client connected! (' + count + ')');
  socket.emit('title', settings.title);
  socket.emit('status', api.getStatus());
  socket.broadcast.emit('count', count);

  socket.on('disconnect', function() {
    count--;
    logger.log('Client disconnect! (' + count + ')');
    socket.broadcast.emit('count', count);
  });
  api.on("refresh", function(status) {
    socket.emit('status', status);
  });
});

api.on("routeContribution", function(route) {
  router.route(route.method, route.path).bind(route.binding);
});

api.on("staticContribution", function(plugin) {
  logger.log("Add static contribution: " + plugin);
  var docRoot = __dirname + '/plugins/' + plugin + '/public';
  pluginsDocRoot.push( { prefix: "/api/" + plugin, docRoot: docRoot });
  logger.log("Add static contribution: " + sys.inspect(pluginsDocRoot));
});

logger.log('Server started.');
logger.log('Server running at http://' + settings.hostname + ':' + settings.port);

<|endoftext|>


<commit_before>'use strict';
// Load modules

var BluebirdPromise = require('Bluebird');
var Path = require('path');
var Hapi = require('hapi');
var Config = require('./config');
//var Vault = require('./secretEnvVars');
var hapiHelpers = require('./hipchatBotApi/hapiHelpers');

var hipchatBotApi = require(Path.join(__dirname, 'hipchatBotApi'));

// Declare internals

var internals = {};

console.log('===================================== NEW RUN =====================================');

var server = new Hapi.Server(~~process.env.PORT || 8112);

server.pack.app.config = Config;

BluebirdPromise.promisifyAll(server);
BluebirdPromise.promisifyAll(server.pack);

var hipchatBotApiOptions = {
    labels: 'api',
    cors: true
};

console.log('Registering plugins...');

return server.pack
    //.registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions}, {select: 'api', route: {prefix: '/hipchatBot/api'}})
    .registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions}, {route: {prefix: '/hipchatBot/api'}})
    //.registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions})
    .then(function () {
        console.log('Starting Server...');
        return server.startAsync();
    })
    .then(function () {
        hapiHelpers.dumpHapiRoutes(server);
        console.log('Server Started! The party is on at: %s', server.info.uri);
        return server;
    })
    .catch(function (error) {
        console.error('createServer has an error!');
        console.error(error);
        console.error(error.stack);
        throw error;
    });

<commit_msg>bluebird case<commit_after>'use strict';
// Load modules

var BluebirdPromise = require('bluebird');
var Path = require('path');
var Hapi = require('hapi');
var Config = require('./config');
//var Vault = require('./secretEnvVars');
var hapiHelpers = require('./hipchatBotApi/hapiHelpers');

var hipchatBotApi = require(Path.join(__dirname, 'hipchatBotApi'));

// Declare internals

var internals = {};

console.log('===================================== NEW RUN =====================================');

var server = new Hapi.Server(~~process.env.PORT || 8112);

server.pack.app.config = Config;

BluebirdPromise.promisifyAll(server);
BluebirdPromise.promisifyAll(server.pack);

var hipchatBotApiOptions = {
    labels: 'api',
    cors: true
};

console.log('Registering plugins...');

return server.pack
    //.registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions}, {select: 'api', route: {prefix: '/hipchatBot/api'}})
    .registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions}, {route: {prefix: '/hipchatBot/api'}})
    //.registerAsync({plugin: hipchatBotApi, options: hipchatBotApiOptions})
    .then(function () {
        console.log('Starting Server...');
        return server.startAsync();
    })
    .then(function () {
        hapiHelpers.dumpHapiRoutes(server);
        console.log('Server Started! The party is on at: %s', server.info.uri);
        return server;
    })
    .catch(function (error) {
        console.error('createServer has an error!');
        console.error(error);
        console.error(error.stack);
        throw error;
    });

<|endoftext|>


<commit_before>'use strict';
(function(module) {
  try {
    module = angular.module('tink.modal');
  } catch (e) {
    module = angular.module('tink.modal', []);
  }
  module.provider('$modal', function() {
    var defaults = this.defaults = {
      element:null,
    };

    var openInstance = null;

     this.$get = function($http,$q,$rootScope,$templateCache,$compile,$animate,$window,$controller,$injector) {
      var bodyElement = angular.element($window.document.body);
      var htmlElement = $('html');

        var $modal = {};
        var options = $modal.$options = angular.extend({}, defaults);
        var linker;

        //for fetching the template that exist
        var fetchPromises = {};
        function fetchTemplate(template) {
          if(fetchPromises[template]) {return fetchPromises[template];}
          return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {
            return res.data;
          }));
        }

        function fetchResolvePromises(resolves) {
          var promisesArr = [];
          angular.forEach(resolves, function (value) {
            if (angular.isFunction(value)) {
              promisesArr.push($q.when($injector.invoke(value)));
            }else{
              promisesArr.push($q.when(value));
            }
          });
          return promisesArr;
        }

        /*$modal.$promise = fetchTemplate(options.template);

        //when the templated is loaded start everyting
        $modal.$promise.then(function(template) {
          linker = $compile(template);
          //$modal.show()
        });*/

        $modal.show = function() {
          $modal.$element = linker(options.scope, function() {});
          enterModal();
        };

        $modal.hide = function() {
          leaveModal();
        };

        $modal.open = function(config){

          //create the promises for opening and result
          var modalResultDeferred = $q.defer();
          var modalOpenedDeferred = $q.defer();

          //Create an instance for the modal
          var modalInstance = {
            result: modalResultDeferred.promise,
            opened: modalOpenedDeferred.promise,
            close: function (result) {
              leaveModal(null).then(function(){
                modalResultDeferred.resolve(result);
              });
            },
            dismiss: function (reason) {
              leaveModal(null).then(function(){
                modalResultDeferred.reject(reason);
              });
            }
          };

          var resolveIter = 1;

          //config variable
          config = angular.extend({}, defaults, config);
          config.resolve = config.resolve || {};
          var templateAndResolvePromise;
          if(angular.isDefined(config.templateUrl)){
            templateAndResolvePromise = $q.all([fetchTemplate(config.templateUrl)].concat(fetchResolvePromises(config.resolve)));
          }else{
            templateAndResolvePromise = $q.all([config.template].concat(fetchResolvePromises(config.resolve)));
          }

          //Wacht op de template en de resloved variable

          templateAndResolvePromise.then(function success(tplAndVars){
            //Get the modal scope or create one
            var modalScope = (config.scope || $rootScope).$new();
            //add the close and dismiss to to the scope
            modalScope.$close = modalInstance.close;
            modalScope.$dismiss = modalInstance.dismiss;

            var ctrlInstance,ctrlConstant={};
            ctrlConstant.$scope = modalScope;
            ctrlConstant.$modalInstance = modalScope;
            angular.forEach(config.resolve, function (value, key) {
                ctrlConstant[key] = tplAndVars[resolveIter++];
            });
            if (config.controller) {
              ctrlInstance = $controller(config.controller, ctrlConstant);
            }
            if (config.controllerAs) {
                modalScope[config.controllerAs] = ctrlInstance;
            }

            enterModal(modalInstance,{
              scope:modalScope,
              content: tplAndVars[0],
              windowTemplateUrl: config.template
            });
          });

          return modalInstance;
        };

        function createModalWindow(content){
          var modelView = angular.element('
'+
            '
'+
              '
'+
              '
'+
            '
'+
          '
');
          modelView.find('.modal-content').html(content);
          return modelView;
        }

        function enterModal(model,instance){

          function show(){
            var linker = $compile(createModalWindow(instance.content));
            var content = linker(instance.scope, function() {});
            model.$element = content;
            $(htmlElement).addClass('has-open-modal');
            bodyElement.bind('keyup',function(e){
              instance.scope.$apply(function(){
                if(e.which === 27){
                  model.dismiss('esc');
                }
              });
            });

            model.$element.bind('click',function(e){
              var view = $(this);
              instance.scope.$apply(function(){
                if(e.target === view.get(0)){
                  model.dismiss('backdrop');
                }
              });
            });

            $animate.enter(content, bodyElement, null);
            openInstance = {element:content,scope:instance.scope};
          }

          if(openInstance !== null){
            leaveModal(openInstance).then(function(){
              show();
            });
          }else{
            show();
          }
        }

        function leaveModal(modal){
          bodyElement.unbind('keyup');
          var q = $q.defer();
          if(modal === null){
            modal = openInstance;
          }
          $(htmlElement).removeClass('has-open-modal');
          $animate.leave(modal.element).then(function() {
            openInstance = null;
            q.resolve('ended');
          });
          return q.promise;
        }
        return $modal;
     };
  });
})();<commit_msg>added backdrop feature<commit_after>'use strict';
(function(module) {
  try {
    module = angular.module('tink.modal');
  } catch (e) {
    module = angular.module('tink.modal', []);
  }
  module.provider('$modal', function() {
    var defaults = this.defaults = {
      element:null,
      backdrop:true
    };

    var openInstance = null;

     this.$get = function($http,$q,$rootScope,$templateCache,$compile,$animate,$window,$controller,$injector) {
      var bodyElement = angular.element($window.document.body);
      var htmlElement = $('html');

        var $modal = {};
        var options = $modal.$options = angular.extend({}, defaults);
        var linker;

        //for fetching the template that exist
        var fetchPromises = {};
        function fetchTemplate(template) {
          if(fetchPromises[template]) {return fetchPromises[template];}
          return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {
            return res.data;
          }));
        }

        function fetchResolvePromises(resolves) {
          var promisesArr = [];
          angular.forEach(resolves, function (value) {
            if (angular.isFunction(value)) {
              promisesArr.push($q.when($injector.invoke(value)));
            }else{
              promisesArr.push($q.when(value));
            }
          });
          return promisesArr;
        }

        /*$modal.$promise = fetchTemplate(options.template);

        //when the templated is loaded start everyting
        $modal.$promise.then(function(template) {
          linker = $compile(template);
          //$modal.show()
        });*/

        $modal.show = function() {
          $modal.$element = linker(options.scope, function() {});
          enterModal();
        };

        $modal.hide = function() {
          leaveModal();
        };

        $modal.open = function(config){

          //create the promises for opening and result
          var modalResultDeferred = $q.defer();
          var modalOpenedDeferred = $q.defer();

          //Create an instance for the modal
          var modalInstance = {
            result: modalResultDeferred.promise,
            opened: modalOpenedDeferred.promise,
            close: function (result) {
              leaveModal(null).then(function(){
                modalResultDeferred.resolve(result);
              });
            },
            dismiss: function (reason) {
              leaveModal(null).then(function(){
                modalResultDeferred.reject(reason);
              });
            }
          };

          var resolveIter = 1;

          //config variable
          config = defaults = angular.extend({}, defaults, config);
          config.resolve = config.resolve || {};
          var templateAndResolvePromise;
          if(angular.isDefined(config.templateUrl)){
            templateAndResolvePromise = $q.all([fetchTemplate(config.templateUrl)].concat(fetchResolvePromises(config.resolve)));
          }else{
            templateAndResolvePromise = $q.all([config.template].concat(fetchResolvePromises(config.resolve)));
          }

          //Wacht op de template en de resloved variable

          templateAndResolvePromise.then(function success(tplAndVars){
            //Get the modal scope or create one
            var modalScope = (config.scope || $rootScope).$new();
            //add the close and dismiss to to the scope
            modalScope.$close = modalInstance.close;
            modalScope.$dismiss = modalInstance.dismiss;

            var ctrlInstance,ctrlConstant={};
            ctrlConstant.$scope = modalScope;
            ctrlConstant.$modalInstance = modalScope;
            angular.forEach(config.resolve, function (value, key) {
                ctrlConstant[key] = tplAndVars[resolveIter++];
            });
            if (config.controller) {
              ctrlInstance = $controller(config.controller, ctrlConstant);
            }
            if (config.controllerAs) {
                modalScope[config.controllerAs] = ctrlInstance;
            }

            enterModal(modalInstance,{
              scope:modalScope,
              content: tplAndVars[0],
              windowTemplateUrl: config.template
            });
          });

          return modalInstance;
        };

        function createModalWindow(content){
          var modelView = angular.element('
'+
            '
'+
              '
'+
              '
'+
            '
'+
          '
');
          modelView.find('.modal-content').html(content);
          return modelView;
        }

        function enterModal(model,instance){

          function show(){
            var linker = $compile(createModalWindow(instance.content));
            var content = linker(instance.scope, function() {});
            model.$element = content;
            $(htmlElement).addClass('has-open-modal');
            bodyElement.bind('keyup',function(e){
              instance.scope.$apply(function(){
                if(e.which === 27){
                  model.dismiss('esc');
                }
              });
            });

            model.$element.bind('click',function(e){
              var view = $(this);
              instance.scope.$apply(function(){
                if(e.target === view.get(0)){
                  if(defaults.backdrop){
                    model.dismiss('backdrop');
                  }
                }
              });
            });

            $animate.enter(content, bodyElement, null);
            openInstance = {element:content,scope:instance.scope};
          }

          if(openInstance !== null){
            leaveModal(openInstance).then(function(){
              show();
            });
          }else{
            show();
          }
        }

        function leaveModal(modal){
          bodyElement.unbind('keyup');
          var q = $q.defer();
          if(modal === null){
            modal = openInstance;
          }
          $(htmlElement).removeClass('has-open-modal');
          $animate.leave(modal.element).then(function() {
            openInstance = null;
            q.resolve('ended');
          });
          return q.promise;
        }
        return $modal;
     };
  });
})();<|endoftext|>


<commit_before>import Service from '@ember/service';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { A } from '@ember/array';
import config from '../config/environment';

const DEBUG = config.dev;
const VERBOSE = false;

export default Service.extend({
    apiHost: config.apiHost,
    tokenHandler: service('token-handler'),
    timeout: 3600,
    source: null,
    store: service(),
    events: A([]),

    showNotificationStream: false,

    /* Connect if not connected, otherwise return existing connection */
    connect() {
        const self = this;
        const source = self.get('source');
        if (source != null) {
            DEBUG && VERBOSE && console.log("Reconnecting...");
            this.close();
        }

        // Only fetch message since our last acknowledgement
        const lastRead = localStorage.getItem('lastRead');
        const tokenQSP = 'token=' + self.get('tokenHandler').getWholeTaleAuthToken();
        const timeoutQSP = 'timeout=' + self.timeout;
        const sinceQSP = lastRead ? 'since=' + encodeURIComponent(lastRead) : ''
        const querystring = `?${tokenQSP}&${timeoutQSP}&${sinceQSP}`;

        // Connect to Girder's notification stream endpoint for SSE
        DEBUG && VERBOSE && console.log("Connecting...");
        const endpoint = self.get('apiHost') + '/api/v1/notification/stream' + querystring;
        const newSource = new EventSource(endpoint);

        newSource.onopen = () => DEBUG && console.log("Connected to event server.");
        newSource.onmessage = self.onMessage.bind(self);
        newSource.onerror = (err) => {
            (console && console.error && console.error("EventSource failed:", err))
                || console.log("EventSource failed:", err);
            self.close();
        };

        self.set('source', newSource);

        return newSource;
    },

    /* Updates "lastRead" to now, then reconnects */
    markAllAsRead() {
        const rightNow = Math.round(new Date().getTime() / 1000);
        DEBUG && console.log('Setting lastRead = ', rightNow);
        localStorage.setItem('lastRead', rightNow);

        // TODO: Maintain a history of acknowledged alerts?
        this.set('events', A([]));
        this.set('showNotificationStream', false);

        // Reconnect with new parameters
        this.connect();
    },

    /* Close if possible, otherwise noop */
    close() {
        const self = this;
        const source = self.get('source');
        if (source != null && source.readyState == EventSource.CLOSED) {
            DEBUG && VERBOSE && console.log('Closing connection...');
            source.close();
        }
    },

    hideMessage(event) {
        event.hidden = true;
    },

    onMessage(event) {
        const self = this;

        // Parse event data (tale) into JSON
        event.json = JSON.parse(event.data);
        event.created = new Date(event.json.time).toLocaleString();
        event.updated = new Date(event.json.updated).toLocaleString();

        // Push new event data
        const events = self.get('events');
        if (event.json.type == 'wt_progress' && event.json.data.resource.type.startsWith('wt_')) {
            console.log(`Notification (${event.json._id}): progress update: ${event.json.data.message} - ${event.json.data.current}/${event.json.data.total}`, event);

            // Attempt to use instanceId/taleId to attach the tale to its related event
            const taleId = event.json.data.resource.tale_id;
            const instanceId = event.json.data.resource.instance_id;
            if (taleId) {
                this.store.findRecord('tale', taleId).then((tale) => {
                    event.json.data.resource.tale = tale;
                });
            } else if (instanceId) {
                this.store.findRecord('instance', instanceId).then((instance) => {
                    this.store.findRecord('tale', instance.taleId).then((tale) => {
                        event.json.data.resource.tale = tale;
                    });
                });
            }

            // Determine if we already have a notification regarding this Tale
            let existing = events.find(evt => event.json._id === evt.json._id);
            if (existing && event.updated > existing.updated) {
                // Overwrite existing event with new one
                const index = events.indexOf(existing);
                events.replace(index, 1, event);
                console.log(`Notification (${event.json._id}): updated event`, events);
            } else if (!existing) {
                // Add a new event
                events.unshiftObject(event);
                console.log(`Notification (${event.json._id}): new event`, events);
            }
            self.set('events', events);
            self.set('showNotificationStream', true);
        } else if (event.json.data.message) {
            // Handle displaying progress updates for tasks
        } else if (event.json.data.text) {
            // Handle build log updates
            // FIXME: Why are these sent as notifications?
            // FIXME: These logs are not displayed in the UI, and are currently fetched on demand when requested
            //console.log(`Notification (${event.json._id}): Log update encountered: ${event.json.data.text}`, event);
        } else {
            //console.log(`Ignored notification (${event.json._id}): Job event (${event.json.data._id}) encountered: ${event.json.data.title} -> ${event.json.data.status}`, event);
        }
    },
});
<commit_msg>Fixed a silly typo.. whoops<commit_after>import Service from '@ember/service';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { A } from '@ember/array';
import config from '../config/environment';

const DEBUG = config.dev;
const VERBOSE = false;

export default Service.extend({
    apiHost: config.apiHost,
    tokenHandler: service('token-handler'),
    timeout: 3600,
    source: null,
    store: service(),
    events: A([]),

    showNotificationStream: false,

    /* Connect if not connected, otherwise return existing connection */
    connect() {
        const self = this;
        const source = self.get('source');
        if (source != null) {
            DEBUG && VERBOSE && console.log("Reconnecting...");
            this.close();
        }

        // Only fetch message since our last acknowledgement
        const lastRead = localStorage.getItem('lastRead');
        const tokenQSP = 'token=' + self.get('tokenHandler').getWholeTaleAuthToken();
        const timeoutQSP = 'timeout=' + self.timeout;
        const sinceQSP = lastRead ? 'since=' + encodeURIComponent(lastRead) : ''
        const querystring = `?${tokenQSP}&${timeoutQSP}&${sinceQSP}`;

        // Connect to Girder's notification stream endpoint for SSE
        DEBUG && VERBOSE && console.log("Connecting...");
        const endpoint = self.get('apiHost') + '/api/v1/notification/stream' + querystring;
        const newSource = new EventSource(endpoint);

        newSource.onopen = () => DEBUG && console.log("Connected to event server.");
        newSource.onmessage = self.onMessage.bind(self);
        newSource.onerror = (err) => {
            (console && console.error && console.error("EventSource failed:", err))
                || console.log("EventSource failed:", err);
            self.close();
        };

        self.set('source', newSource);

        return newSource;
    },

    /* Updates "lastRead" to now, then reconnects */
    markAllAsRead() {
        const rightNow = Math.round(new Date().getTime() / 1000);
        DEBUG && console.log('Setting lastRead = ', rightNow);
        localStorage.setItem('lastRead', rightNow);

        // TODO: Maintain a history of acknowledged alerts?
        this.set('events', A([]));
        this.set('showNotificationStream', false);

        // Reconnect with new parameters
        this.connect();
    },

    /* Close if possible, otherwise noop */
    close() {
        const self = this;
        const source = self.get('source');
        if (source != null && source.readyState != EventSource.CLOSED) {
            DEBUG && VERBOSE && console.log('Closing connection...');
            source.close();
        }
    },

    hideMessage(event) {
        event.hidden = true;
    },

    onMessage(event) {
        const self = this;

        // Parse event data (tale) into JSON
        event.json = JSON.parse(event.data);
        event.created = new Date(event.json.time).toLocaleString();
        event.updated = new Date(event.json.updated).toLocaleString();

        // Push new event data
        const events = self.get('events');
        if (event.json.type == 'wt_progress' && event.json.data.resource.type.startsWith('wt_')) {
            console.log(`Notification (${event.json._id}): progress update: ${event.json.data.message} - ${event.json.data.current}/${event.json.data.total}`, event);

            // Attempt to use instanceId/taleId to attach the tale to its related event
            const taleId = event.json.data.resource.tale_id;
            const instanceId = event.json.data.resource.instance_id;
            if (taleId) {
                this.store.findRecord('tale', taleId).then((tale) => {
                    event.json.data.resource.tale = tale;
                });
            } else if (instanceId) {
                this.store.findRecord('instance', instanceId).then((instance) => {
                    this.store.findRecord('tale', instance.taleId).then((tale) => {
                        event.json.data.resource.tale = tale;
                    });
                });
            }

            // Determine if we already have a notification regarding this Tale
            let existing = events.find(evt => event.json._id === evt.json._id);
            if (existing && event.updated > existing.updated) {
                // Overwrite existing event with new one
                const index = events.indexOf(existing);
                events.replace(index, 1, event);
                console.log(`Notification (${event.json._id}): updated event`, events);
            } else if (!existing) {
                // Add a new event
                events.unshiftObject(event);
                console.log(`Notification (${event.json._id}): new event`, events);
            }
            self.set('events', events);
            self.set('showNotificationStream', true);
        } else if (event.json.data.message) {
            // Handle displaying progress updates for tasks
        } else if (event.json.data.text) {
            // Handle build log updates
            // FIXME: Why are these sent as notifications?
            // FIXME: These logs are not displayed in the UI, and are currently fetched on demand when requested
            //console.log(`Notification (${event.json._id}): Log update encountered: ${event.json.data.text}`, event);
        } else {
            //console.log(`Ignored notification (${event.json._id}): Job event (${event.json.data._id}) encountered: ${event.json.data.title} -> ${event.json.data.status}`, event);
        }
    },
});
<|endoftext|>


<commit_before> #!/usr/bin/env node

if (typeof process.argv[2] !== 'string')
    throw new Error('Usage: etcd_get {key} [--upper]');

var toupper, z = 3;
while (process.argv[z] !== undefined) {
    if (process.argv[z] === '--upper') toupper = true;
    else
        throw new Error('Unrecognized option: ' + process.argv[z]
            + '. Usage: etcd_get {key} [--upper]');
    z++;
}

require('../lib/index').etcd_get(process.argv[2], function (error, result) {
    if (error)
        throw error;

    if (toupper)
        result = upper(result);
    console.log(JSON.stringify(result, null, 2));
});

// Convert object property names to uppercase
function upper(o) {
    var r = {};
    for (var k in o)
        r[k.toUpperCase()] = typeof o[k] === 'object' ? upper(o[k]) : o[k];
    return r;
}
<commit_msg>add shebang to cli, fix<commit_after>#!/usr/bin/env node

if (typeof process.argv[2] !== 'string')
    throw new Error('Usage: etcd_get {key} [--upper]');

var toupper, z = 3;
while (process.argv[z] !== undefined) {
    if (process.argv[z] === '--upper') toupper = true;
    else
        throw new Error('Unrecognized option: ' + process.argv[z]
            + '. Usage: etcd_get {key} [--upper]');
    z++;
}

require('../lib/index').etcd_get(process.argv[2], function (error, result) {
    if (error)
        throw error;

    if (toupper)
        result = upper(result);
    console.log(JSON.stringify(result, null, 2));
});

// Convert object property names to uppercase
function upper(o) {
    var r = {};
    for (var k in o)
        r[k.toUpperCase()] = typeof o[k] === 'object' ? upper(o[k]) : o[k];
    return r;
}
<|endoftext|>


<commit_before>var cloak = require('cloak');
var _ = require('underscore');

cloak.configure({
  port: 8090,
  roomLife: 1000*60*60*3,

  autoJoinLobby: false,
  minRoomMembers: 1,
  pruneEmptyRooms: 1000,
  reconnectWait: 10000,

  messages: {
    registerUsername: function(arg, user) {
      var users = cloak.getUsers();
      var username = arg.username;
      var usernames = _.pluck(users, 'name');
      var success = false;
      console.log(users);
      console.log(usernames);
      if (_.indexOf(usernames, username) === -1) {
        success = true;
        user.name = username;
      }
      user.message('registerUsernameResponse', [success, username]);
    },

    joinLobby: function(arg, user) {
      var success = cloak.getLobby().addMember(user);
      user.message('joinLobbyResponse', success);
      if(success)
        cloak.messageAll('refreshAll');
    },

    listUsers: function(arg, user){
    	user.message('refreshLobby', {
        users: user.room.getMembers(true),
        inLobby: user.room.isLobby,
        roomCount: user.room.getMembers().length,
        roomSize: user.room.size
      });
    },

    listRooms: function(arg, user){
      user.message('refreshRooms', cloak.getRooms(true));
    },

    createRoom: function(arg, user) {
      var room = cloak.createRoom(arg.name, 2);
      var success = room.addMember(user);
      user.message('roomCreated', {
        success: success,
        roomId: room.id
      });
      cloak.messageAll('refreshAll');
    },

    joinRoom: function(id, user) {
      var room = cloak.getRoom(id)
      if (room.getMembers().length < 2)
      {
        room.addMember(user);
        user.message('joinRoomResponse', {
          id: id,
          success: true
        });
      } else {
        user.message('joinRoomResponse', {
          id: id,
          success: false
        });
      }

    },

    leaveRoom: function(arg, user) {
      user.leaveRoom();
    },

    chat: function(msg, user) {
      user.getRoom().messageMembers('chat', [msg, user.name]);
    },

    refreshRoom: function(arg, user) {
      user.message('refreshRoomResponse', user.room.getMembers(true));
    },

    turnDone: function(move, user){
      //move[0] is from and move[1] is to
      // If it's currently the turn of the user and they say they're done, advance the turn
      if (user.team === user.room.turn) {
        user.room.turn = (user.room.turn === 'muon') ? 'antimuon' : 'muon';
      }
      // let the other player know
      var otherPlayer = _.reject(user.room.members, function(member) {
        return member.id === user.id;
      });
      console.log("sending move to player:", otherPlayer[0]);
      user.room.lastMove = {from: move[0], to: move[1]};
      otherPlayer[0].message('performOpponentMove', [move[0],move[1]]);

      user.room.messageMembers('turn', user.room.turn);

    }
  },

  room: {
    init: function() {
      this.turn = 'muon';
      this.lastMove = {};

      this.teams = {
        muon: '',
        antimuon: ''
      };

      console.log('created room ' + this.id);
      this.data.lastReportedAge = 0;
    },

    newMember: function(user) {
      if (this.teams.muon === '') { //host
        this.teams.muon = user.id;
        user.team = 'muon';
        user.message('userMessage', 'your are muons and your id is ' + user.id);
      }
      else if (this.teams.antimuon === '') { //client
        this.teams.antimuon = user.id;
        user.team = 'antimuon';
        user.message('userMessage', 'your team is antimuons and your id is ' + user.id);
      }
      else {
        var msg = 'Um, we tried to assign a team member but all teams were taken for this room.';
        console.log(msg);
        user.team = 'none';
        user.message('userMessage', msg);
      }
      user.message('assignTeam', {
        team: user.team,
        turn: this.turn
      });
    },

    memberLeaves: function(user) {
      // if we have 0 people in the room, close the room
      if (this.getMembers().length <= 0) {
        this.delete();
      }
    },

    pulse: function() {
      // add timed turn stuff here
    },

    close: function() {
      this.messageMembers('you have left ' + this.name);
    }

  }

});

cloak.run();
<commit_msg>added disconnect<commit_after>var cloak = require('cloak');
var _ = require('underscore');

cloak.configure({
  port: 8090,
  roomLife: 1000*60*60*3,

  autoJoinLobby: false,
  minRoomMembers: 1,
  pruneEmptyRooms: 1000,
  reconnectWait: 10000,

  messages: {
    registerUsername: function(arg, user) {
      var users = cloak.getUsers();
      var username = arg.username;
      var usernames = _.pluck(users, 'name');
      var success = false;
      console.log(users);
      console.log(usernames);
      if (_.indexOf(usernames, username) === -1) {
        success = true;
        user.name = username;
      }
      user.message('registerUsernameResponse', [success, username]);
    },

    joinLobby: function(arg, user) {
      var success = cloak.getLobby().addMember(user);
      user.message('joinLobbyResponse', success);
      if(success)
        cloak.messageAll('refreshAll');
    },

    listUsers: function(arg, user){
    	user.message('refreshLobby', {
        users: user.room.getMembers(true),
        inLobby: user.room.isLobby,
        roomCount: user.room.getMembers().length,
        roomSize: user.room.size
      });
    },

    listRooms: function(arg, user){
      user.message('refreshRooms', cloak.getRooms(true));
    },

    createRoom: function(arg, user) {
      var room = cloak.createRoom(arg.name, 2);
      var success = room.addMember(user);
      user.message('roomCreated', {
        success: success,
        roomId: room.id
      });
      cloak.messageAll('refreshAll');
    },

    joinRoom: function(id, user) {
      var room = cloak.getRoom(id)
      if (room.getMembers().length < 2)
      {
        room.addMember(user);
        user.message('joinRoomResponse', {
          id: id,
          success: true
        });
      } else {
        user.message('joinRoomResponse', {
          id: id,
          success: false
        });
      }

    },

    leaveRoom: function(arg, user) {
      user.leaveRoom();
    },

    disconnectUser: function(arg,user){
      user.delete();
    }

    chat: function(msg, user) {
      user.getRoom().messageMembers('chat', [msg, user.name]);
    },

    refreshRoom: function(arg, user) {
      user.message('refreshRoomResponse', user.room.getMembers(true));
    },

    turnDone: function(move, user){
      //move[0] is from and move[1] is to
      // If it's currently the turn of the user and they say they're done, advance the turn
      if (user.team === user.room.turn) {
        user.room.turn = (user.room.turn === 'muon') ? 'antimuon' : 'muon';
      }
      // let the other player know
      var otherPlayer = _.reject(user.room.members, function(member) {
        return member.id === user.id;
      });
      console.log("sending move to player:", otherPlayer[0]);
      user.room.lastMove = {from: move[0], to: move[1]};
      otherPlayer[0].message('performOpponentMove', [move[0],move[1]]);

      user.room.messageMembers('turn', user.room.turn);

    }
  },

  room: {
    init: function() {
      this.turn = 'muon';
      this.lastMove = {};

      this.teams = {
        muon: '',
        antimuon: ''
      };

      console.log('created room ' + this.id);
      this.data.lastReportedAge = 0;
    },

    newMember: function(user) {
      if (this.teams.muon === '') { //host
        this.teams.muon = user.id;
        user.team = 'muon';
        user.message('userMessage', 'your are muons and your id is ' + user.id);
      }
      else if (this.teams.antimuon === '') { //client
        this.teams.antimuon = user.id;
        user.team = 'antimuon';
        user.message('userMessage', 'your team is antimuons and your id is ' + user.id);
      }
      else {
        var msg = 'Um, we tried to assign a team member but all teams were taken for this room.';
        console.log(msg);
        user.team = 'none';
        user.message('userMessage', msg);
      }
      user.message('assignTeam', {
        team: user.team,
        turn: this.turn
      });
    },

    memberLeaves: function(user) {
      // if we have 0 people in the room, close the room
      if (this.getMembers().length <= 0) {
        this.delete();
      }
    },

    pulse: function() {
      // add timed turn stuff here
    },

    close: function() {
      this.messageMembers('you have left ' + this.name);
    }

  }

});

cloak.run();
<|endoftext|>


<commit_before>// a JSON-to-JSON translater used by a migration

function originalToJSLibFigure(figures) {
  return figures.map(originalToJSLibFigure1);
}

function originalToJSLibFigure1(figure) {
  var move_name_baggage = unpackMoveName(figure)
  var move = move_name_baggage['move']
  var params = parameters(move);
  var get_parameter_values = function (param) {
    if (param.name === 'who') {
      return translateWho(figure.who);
    } else if (param.name === 'beats') {
      return figure.beats;
    } else if (param.name === 'bal') {
      return figure.balance || false;
    } else if (param.name === 'hand') {
      return oldMoveIsClockwise(figure.move);
    } else if (param.name === 'circling' || param.name === 'places') {
      return figure.degrees;
    } else if (param.name === 'turn' || param.name === 'shoulder') {
      return move_name_baggage[param.name]
    } else if (param.name === 'custom') {
      return '';
    } else if (param.name === 'facing') {
      return 'forward';         // all old down_the_halls/up_the_halls were this way, I think
    } else if (param.name === 'grip') {
      return undefined;
    } else {
      throw_up("param name '"+param.name+"' missing from originalToJSLibFigure");
    }
  };
  var h = {parameter_values: params.map(get_parameter_values), move: move};
  if (figure.notes) { h.note = figure.notes; }
  if (figure.formation && (figure.formation !== 'square')) {
    h.note = (h.note || '') +
      ' from ' + figure.formation.replace(/_/g, ' '); // if altering this line, also change _formation_note_regexp
  }
  return h;
}

var _unpack_move_name = {
  allemande_left: 'allemande',
  allemande_right: 'allemande',
  circle_left: 'circle',
  circle_right: 'circle',
  gyre_left_shoulder: 'gyre',
  gyre_right_shoulder: 'gyre',
  star_left: 'star',
  star_right: 'star',
  pull_by_left: 'pull by',
  pull_by_right: 'pull by',
  half_a_hey: 'half hey'
}
function unpackMoveName(oldFigure) {
  var oldMove = oldFigure.move;
  if (oldMove === 'custom' && (oldFigure.balance || (oldFigure.who !== 'everybody'))) {
    return { move: 'custom yucky' };
  }
  var h = {move: _unpack_move_name[oldMove] || oldMove.replace(/_/g, ' ')}
  var oldMove_ends_in_left = oldMove.match(/_left(_shoulder)?$/);
  var oldMove_ends_in_right = oldMove.match(/_right(_shoulder)?$/);
  if (oldMove_ends_in_left) { h.turn = true; h.shoulder = false; }
  if (oldMove_ends_in_right) { h.turn = false; h.shoulder = true; }
  return h;
}

var _translate_who = {neighbor: 'neighbors',
                      partner: 'partners',
                      everybody: 'everyone'};

function translateWho(oldWho) {
  return _translate_who[oldWho] || oldWho;
}
function untranslateWho(lfWho) {
  // hash table: ur doing it wrong :D
  for(var oldWho in _translate_who){
    if(_translate_who[oldWho]==lfWho) {
      return oldWho;
    }
  }
  return lfWho;
}

var _old_move_is_clockwise = {
  box_the_gnat: true,
  swat_the_flea: false,
  circle_left: true,
  circle_right: false,
  allemande_left: false,
  allemande_right: true,
  pull_by_right: true,
  pull_by_left: false,
  star_left: false,
  star_right: true,
  star_promenade: false
}

function oldMoveIsClockwise(oldMove) {
  var cw = _old_move_is_clockwise[oldMove];
  if (cw === true || cw === false) {
    return cw;
  } else {
    throw_up("move '"+oldMove+"' missing from oldMoveIsClockwise table");
  }
}

////////////////////////////////////////////////////////////////
// reverse migrator                                           //
////////////////////////////////////////////////////////////////
function jsLibFigureToOriginal(figures) {
  return figures.map(jsLibFigureToOriginal1);
}

function jsLibFigureToOriginal1(figure) {
  var lf_move = figure.move;
  var param_vals = figure.parameter_values;
  var params = parameters(lf_move);
  var h = { who: extractWho(params, param_vals),
            move: findOldMove(figure),
            beats: extractBeats(params, param_vals),
            formation: parseFormationFromNote(figure.note)
          };
  var degrees = extractDegrees(params, param_vals);
  if (degrees) { h.degrees = degrees; }
  if (extractBal(params, param_vals)) { h.balance = true; }
  var restored_note = figure.note ? dropFormationSuffixFromNote(figure.note).trim() : '';
  if (restored_note !== '') { h.notes = restored_note; }
  return h;
}

function extractDegrees(params, param_vals) {
  var index = find_parameter_index_by_name('circling', params);
  if (index < 0) {
    index = find_parameter_index_by_name('places', params);
  }
  return (index >= 0) && param_vals[index];
}

function extractWho(params, param_vals) {
  var index = find_parameter_index_by_name('who', params);
  if (index >= 0) {
    return untranslateWho(param_vals[index]);
  } else {
    return 'everybody';
  }
}
function extractBeats(params, param_vals) {
  var index = find_parameter_index_by_name('beats', params);
  if (index >= 0) {
    return param_vals[index];
  } else {
    throw_up('No beats, should I really return 0?'); // I'm okay with it.
    return 0;
  }
}
function extractBal(params, param_vals) {
  var index = find_parameter_index_by_name('bal', params);
  return (index >= 0) && param_vals[index];
}

function findOldMove(lf_figure) {
  var lf_move = lf_figure.move;
  var param_vals = lf_figure.parameter_values;
  var params = parameters(lf_move);
  var underscore_lf_move = lf_move.replace(/ /g,'_')
  if (oldAtomicMoves[underscore_lf_move]) {
    return underscore_lf_move;
  } else if (underscore_lf_move === 'half_hey') {
    return 'half_a_hey';
  } else if (underscore_lf_move === 'custom_yucky') {
    return 'custom';
  } else if (oldLeftRightMoves[underscore_lf_move]) {
    var              index = find_parameter_index_by_name('turn', params);
    if (index < 0) { index = find_parameter_index_by_name('hand', params); }
    if (index < 0) { index = find_parameter_index_by_name('shoulder', params); }
    if (index < 0) { index = find_parameter_index_by_name('side', params); }
    if (index < 0) { throw_up('can not find a turn, shoulder, or hand for '+lf_move); }
    return oldLeftRightMoves[underscore_lf_move][param_vals[index] ? 0 : 1];
  } else {
    throw_up('can not findOldMove for '+lf_move);
  }
}

var oldLeftRightMoves = {
  allemande: ['allemande_right', 'allemande_left'],
  circle: ['circle_left', 'circle_right'],
  gyre: ['gyre_right_shoulder', 'gyre_left_shoulder'],
  star: ['star_right', 'star_left'],
  pull_by: ['pull_by_right', 'pull_by_left'],
  star_promenade: ['did_not_support_right_handed_star_promenades','star_promenade']
  // unused:
  // gyre_star_ccw_gentlespoons_backing: true,
  // gyre_star_ccw_ladles_backing: true,
  // gyre_star_clockwise_gentlespoons_backing: true,
  // gyre_star_clockwise_ladles_backing: true,

  // roll_away_half_sashay_neighbor: true,
  // roll_away_half_sashay_partner: true,
  // roll_away_neighbor: true,
  // roll_away_partner: true,
  // slide_left_rory_o_moore: true,
  // slide_right_rory_o_moore: true,
};

var oldAtomicMoves = {
  allemande_and_orbit: true,
  arizona_twirl: true,
  balance: true,
  balance_the_ring: true,
  box_circulate: true,
  box_the_gnat: true,
  butterfly_whirl: true,
  california_twirl: true,
  chain: true,
  cross_trails: true,
  custom: true,
  do_si_do: true,
  down_the_hall: true,
  half_a_hey: true,
  hey: true,
  long_lines: true,
  mad_robin: true,
  petronella: true,
  promenade_across: true,
  right_left_through: true,
  see_saw: true,
  star_promenade: true,
  swat_the_flea: true,
  swing: true,
  to_long_wavy_line: true,
  to_ocean_wave: true,
  up_the_hall: true
}

var _formation_note_regexp = /from (short lines|short wavy lines|long wavy lines|long wavy line|custom)$/

function parseFormationFromNote(note) {
  if (!note) { return 'square'; }
  var r = note.match(_formation_note_regexp);
  if (r) {
    return r[1].replace(/ /g, '_');
  } else {
    return 'square';
  }
}

function dropFormationSuffixFromNote(note) {
  if (!note) { return note; }
  var r = note.match(_formation_note_regexp);
  if (r) {
    return note.slice(0, note.length - r[0].length);
  } else {
    return note;
  }
}

function testConverters(figures) {
  return figures.map(function(figure) {
    var retranslated_figure = jsLibFigureToOriginal1(originalToJSLibFigure1(figure));
    return [figure, retranslated_figure];
  });
}
<commit_msg>:) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :O :) :) :) :) :) :) :) :) :) :O :) :) :) :) :O :O :) :) :) :) translate 'promenade across'<commit_after>// a JSON-to-JSON translater used by a migration

function originalToJSLibFigure(figures) {
  return figures.map(originalToJSLibFigure1);
}

function originalToJSLibFigure1(figure) {
  var move_name_baggage = unpackMoveName(figure)
  var move = move_name_baggage['move']
  var params = parameters(move);
  var get_parameter_values = function (param) {
    if (param.name === 'who') {
      return translateWho(figure.who);
    } else if (param.name === 'beats') {
      return figure.beats;
    } else if (param.name === 'bal') {
      return figure.balance || false;
    } else if (param.name === 'hand') {
      return oldMoveIsClockwise(figure.move);
    } else if (param.name === 'circling' || param.name === 'places') {
      return figure.degrees;
    } else if (param.name === 'turn' || param.name === 'shoulder') {
      return move_name_baggage[param.name]
    } else if (param.name === 'custom') {
      return '';
    } else if (param.name === 'facing') {
      return 'forward';         // all old down_the_halls/up_the_halls were this way, barring notes to the contray
    } else if (param.name === 'side') {
      return true;              // all old pass-throughs let the other couple pass on the left
    } else if (param.name === 'grip') {
      return undefined;
    } else {
      throw_up("param name '"+param.name+"' missing from originalToJSLibFigure");
    }
  };
  var h = {parameter_values: params.map(get_parameter_values), move: move};
  if (figure.notes) { h.note = figure.notes; }
  if (figure.formation && (figure.formation !== 'square')) {
    h.note = (h.note || '') +
      ' from ' + figure.formation.replace(/_/g, ' '); // if altering this line, also change _formation_note_regexp
  }
  return h;
}

var _unpack_move_name = {
  allemande_left: 'allemande',
  allemande_right: 'allemande',
  circle_left: 'circle',
  circle_right: 'circle',
  gyre_left_shoulder: 'gyre',
  gyre_right_shoulder: 'gyre',
  star_left: 'star',
  star_right: 'star',
  pull_by_left: 'pull by',
  pull_by_right: 'pull by',
  half_a_hey: 'half hey'
}
function unpackMoveName(oldFigure) {
  var oldMove = oldFigure.move;
  if (oldMove === 'custom' && (oldFigure.balance || (oldFigure.who !== 'everybody'))) {
    return { move: 'custom yucky' };
  }
  var h = {move: _unpack_move_name[oldMove] || oldMove.replace(/_/g, ' ')}
  var oldMove_ends_in_left = oldMove.match(/_left(_shoulder)?$/);
  var oldMove_ends_in_right = oldMove.match(/_right(_shoulder)?$/);
  if (oldMove_ends_in_left) { h.turn = true; h.shoulder = false; }
  if (oldMove_ends_in_right) { h.turn = false; h.shoulder = true; }
  return h;
}

var _translate_who = {neighbor: 'neighbors',
                      partner: 'partners',
                      everybody: 'everyone'};

function translateWho(oldWho) {
  return _translate_who[oldWho] || oldWho;
}
function untranslateWho(lfWho) {
  // hash table: ur doing it wrong :D
  for(var oldWho in _translate_who){
    if(_translate_who[oldWho]==lfWho) {
      return oldWho;
    }
  }
  return lfWho;
}

var _old_move_is_clockwise = {
  box_the_gnat: true,
  swat_the_flea: false,
  circle_left: true,
  circle_right: false,
  allemande_left: false,
  allemande_right: true,
  pull_by_right: true,
  pull_by_left: false,
  star_left: false,
  star_right: true,
  star_promenade: false
}

function oldMoveIsClockwise(oldMove) {
  var cw = _old_move_is_clockwise[oldMove];
  if (cw === true || cw === false) {
    return cw;
  } else {
    throw_up("move '"+oldMove+"' missing from oldMoveIsClockwise table");
  }
}

////////////////////////////////////////////////////////////////
// reverse migrator                                           //
////////////////////////////////////////////////////////////////
function jsLibFigureToOriginal(figures) {
  return figures.map(jsLibFigureToOriginal1);
}

function jsLibFigureToOriginal1(figure) {
  var lf_move = figure.move;
  var param_vals = figure.parameter_values;
  var params = parameters(lf_move);
  var h = { who: extractWho(params, param_vals),
            move: findOldMove(figure),
            beats: extractBeats(params, param_vals),
            formation: parseFormationFromNote(figure.note)
          };
  var degrees = extractDegrees(params, param_vals);
  if (degrees) { h.degrees = degrees; }
  if (extractBal(params, param_vals)) { h.balance = true; }
  var restored_note = figure.note ? dropFormationSuffixFromNote(figure.note).trim() : '';
  if (restored_note !== '') { h.notes = restored_note; }
  return h;
}

function extractDegrees(params, param_vals) {
  var index = find_parameter_index_by_name('circling', params);
  if (index < 0) {
    index = find_parameter_index_by_name('places', params);
  }
  return (index >= 0) && param_vals[index];
}

function extractWho(params, param_vals) {
  var index = find_parameter_index_by_name('who', params);
  if (index >= 0) {
    return untranslateWho(param_vals[index]);
  } else {
    return 'everybody';
  }
}
function extractBeats(params, param_vals) {
  var index = find_parameter_index_by_name('beats', params);
  if (index >= 0) {
    return param_vals[index];
  } else {
    throw_up('No beats, should I really return 0?'); // I'm okay with it.
    return 0;
  }
}
function extractBal(params, param_vals) {
  var index = find_parameter_index_by_name('bal', params);
  return (index >= 0) && param_vals[index];
}

function findOldMove(lf_figure) {
  var lf_move = lf_figure.move;
  var param_vals = lf_figure.parameter_values;
  var params = parameters(lf_move);
  var underscore_lf_move = lf_move.replace(/ /g,'_')
  if (oldAtomicMoves[underscore_lf_move]) {
    return underscore_lf_move;
  } else if (underscore_lf_move === 'half_hey') {
    return 'half_a_hey';
  } else if (underscore_lf_move === 'custom_yucky') {
    return 'custom';
  } else if (oldLeftRightMoves[underscore_lf_move]) {
    var              index = find_parameter_index_by_name('turn', params);
    if (index < 0) { index = find_parameter_index_by_name('hand', params); }
    if (index < 0) { index = find_parameter_index_by_name('shoulder', params); }
    if (index < 0) { index = find_parameter_index_by_name('side', params); }
    if (index < 0) { throw_up('can not find a turn, shoulder, or hand for '+lf_move); }
    return oldLeftRightMoves[underscore_lf_move][param_vals[index] ? 0 : 1];
  } else {
    throw_up('can not findOldMove for '+lf_move);
  }
}

var oldLeftRightMoves = {
  allemande: ['allemande_right', 'allemande_left'],
  circle: ['circle_left', 'circle_right'],
  gyre: ['gyre_right_shoulder', 'gyre_left_shoulder'],
  star: ['star_right', 'star_left'],
  pull_by: ['pull_by_right', 'pull_by_left'],
  star_promenade: ['did_not_support_right_handed_star_promenades','star_promenade']
  // unused:
  // gyre_star_ccw_gentlespoons_backing: true,
  // gyre_star_ccw_ladles_backing: true,
  // gyre_star_clockwise_gentlespoons_backing: true,
  // gyre_star_clockwise_ladles_backing: true,

  // roll_away_half_sashay_neighbor: true,
  // roll_away_half_sashay_partner: true,
  // roll_away_neighbor: true,
  // roll_away_partner: true,
  // slide_left_rory_o_moore: true,
  // slide_right_rory_o_moore: true,
};

var oldAtomicMoves = {
  allemande_and_orbit: true,
  arizona_twirl: true,
  balance: true,
  balance_the_ring: true,
  box_circulate: true,
  box_the_gnat: true,
  butterfly_whirl: true,
  california_twirl: true,
  chain: true,
  cross_trails: true,
  custom: true,
  do_si_do: true,
  down_the_hall: true,
  half_a_hey: true,
  hey: true,
  long_lines: true,
  mad_robin: true,
  petronella: true,
  promenade_across: true,
  right_left_through: true,
  see_saw: true,
  star_promenade: true,
  swat_the_flea: true,
  swing: true,
  to_long_wavy_line: true,
  to_ocean_wave: true,
  up_the_hall: true
}

var _formation_note_regexp = /from (short lines|short wavy lines|long wavy lines|long wavy line|custom)$/

function parseFormationFromNote(note) {
  if (!note) { return 'square'; }
  var r = note.match(_formation_note_regexp);
  if (r) {
    return r[1].replace(/ /g, '_');
  } else {
    return 'square';
  }
}

function dropFormationSuffixFromNote(note) {
  if (!note) { return note; }
  var r = note.match(_formation_note_regexp);
  if (r) {
    return note.slice(0, note.length - r[0].length);
  } else {
    return note;
  }
}

function testConverters(figures) {
  return figures.map(function(figure) {
    var retranslated_figure = jsLibFigureToOriginal1(originalToJSLibFigure1(figure));
    return [figure, retranslated_figure];
  });
}
<|endoftext|>


<commit_before>"use strict";
//server.js

// Bring in external libraries
var fs         = require( 'q-io/fs'     );
var https      = require( 'https'       );
var http       = require( 'http'        );
var path       = require( 'path'        );
var express    = require( 'express'     );
var lodash     = require( 'lodash'      );
var winston    = require( 'winston'     );
var Q          = require( 'q'           );
var bodyParser = require( 'body-parser' );
var onHeaders  = require( 'on-headers'  );
var userAgent  = require( 'express-useragent' );
var moment     = require( 'moment' );

Q.longStackSupport = true;

winston.remove( winston.transports.Console );
winston.add( winston.transports.Console, { level: 'verbose', colorize:true } );

// Setup global variables
var _ = lodash._;

exports.express = express;

// Mixin the underscore.string lib
// Import Underscore.string to separate object, because there are conflict functions (include, reverse, contains)
_.str = require( 'underscore.string' );

// Mix in non-conflict functions to Underscore namespace if you want
_.mixin( _.str.exports() );

var config = require( './src/config' );

// Export important files for bridge configuration and setup
exports.config = config;

// Start the express app
var app = exports.app = express();

// Create the routers that will be used by the bridge app.
var routerOptions = { caseSensitive: true };
app.set( 'privateRouter' , express.Router( routerOptions ) );
app.set( 'publicRouter'  , express.Router( routerOptions ) );

// Determine the port to listen on
var port = config.server.port;
process.env.PORT = port;

var loggerObj  = require( './src/logger' );

// Read in local modules that are to be exported
var regex        = require( './src/regex' );
var bridgeError  = require( './src/error' );
var util         = require( './src/utilities' );
var pdfGenerator = require( './src/html2pdf' );

exports.error        = bridgeError;
exports.regex        = regex;
exports.util         = util;
exports.pdfGenerator = pdfGenerator;

var database    = require( './src/database' );

// Export local files for the API to use
exports.database = database;

// Read in non exported local modules
var bridgeWare = require( './src/middleware' );
var mailer     = require( './src/mailer' );
var routes     = require( './src/bridgeroutes' );

// Prepare server variable
var server = null;

// Setting standard dictionary objects
// database reference
app.set( 'views', config.mailer.templateDirectory );
app.set( 'view engine', 'ejs' );

// Remove the header that displays that express powers the application.
app.disable('x-powered-by');

app.engine( 'html', require( 'ejs' ).renderFile );
app.engine( 'ejs',  require( 'ejs' ).renderFile );

// Tell express that it is behind a proxy
app.enable( 'trust proxy' );

/////////////////////////////////////////////////////////////////////////////////////////
///////    STARTING SETUP OF MIDDLEWARE    //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// Setup the response logger event handler.
app.use( function( req, res, next ) {
    onHeaders( res, function() {
        app.log.verbose( "Sending Response." );
        app.log.silly( 'Response headers: ', res._headers );

        if ( _.isObject( req.bridge ) ) {
            if ( _.isObject( req.bridge.dbLogger ) ) {
                req.bridge.dbLogger.data.responseHeaders = res._headers;
                req.bridge.dbLogger.data.bridgeHeader = req.get( 'bridge' );

                var values = [];

                values.push( req.bridge.dbLogger.userID  );
                values.push( JSON.stringify( req.bridge.dbLogger.data )  );
                values.push( req.bridge.dbLogger.datatype );
                values.push( moment().format( 'YYYY-MM-DD HH:mm:ss' ) );
                values.push( moment().format( 'YYYY-MM-DD HH:mm:ss' ) );
                values.push( 0 );

                database.insertIntoTable( 'actions', values )
                .fail( function( err ) {
                    app.log.warn( "Cannot insert action into the actions table. Error: ", err );
                } );
            }
        }
    } );
    next();
} );

// Setup the cookie parser
app.use( bridgeWare.getCookies() );

app.use( userAgent.express() );

// Setup the request logger
app.use( function ( req, res, next ) {

    app.log.verbose( "Received Request at " + req.path );
    app.log.silly( {
        RequestBody: req.body,
        BridgeHeader: req.get( 'bridge' ),
        Method: req.method,
        Resource: req.path,
        Secure: req.secure,
        XHR: req.xhr,
        Protocol: req.protocol,
        BridgeCookie: req.bridge.cookies.get( 'BridgeAuth' )
    } );

    next();
} );

app.use( bridgeWare.applyDefaultSecuityPolicyHeader );

// Static hosting Middleware
app.use( bridgeWare.staticHostFiles() );

app.use( bridgeWare.prepBridgeObjects );

// Serve the index if it is a GET request for '/'
app.get( '/', routes.serveIndex );

app.get( 'publicRouter' ).use( bridgeWare.prepBridgeObjects );

// Handle an authentication request
app.get( 'publicRouter' ).route( '/authenticate' )
    .post( require( './src/requests/authenticate' ) );

// Automatically parse the body to JSON
app.use( bodyParser.json() );

// Add the CORS headers to the response
app.use( bridgeWare.attachCORSHeaders() );

// Handle CORS Request
app.use( bridgeWare.handleOptionsRequest() );

// Use the public router to send
app.use( config.server.apiRoute, app.get( "publicRouter" ) );

// Use the private router to try to interpret the route
app.use( config.server.apiRoute, app.get( "privateRouter" ) );

// Error Handler
app.use( bridgeWare.bridgeErrorHandler() );

// 404 Handler
app.log.debug( "404 handler setup" );
app.all( '*', function ( req, res, next ) {

    if ( _.has( res, 'finished' ) && res.finished === true ) {

        next();
        return;
    }

    routes.send404( req, res );
    return;
} );

// Setup bridge default router
routes.setup();

/////////////////////////////////////////////////////////////////////////////////////////
///////     MIDDLEWARE SETUP COMPLETE      //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// Setup the server for https mode
if ( config.server.mode === "https" ) {

    var keyFound = false,
        keyContent,
        certFound = false,
        certContent;

    var checkIfKeyAndCertAreLoaded = function () {
        if ( !keyFound || !certFound ) {
            return;
        }

        var credentials = {
            key: keyContent,
            cert: certContent
        };

        server = https.createServer( credentials, app );

        // Listen on the port defined at the beginning of the script
        server.listen( port );
        Q.delay( 100 ).
        then( function() {
            // Log the start of the server
            app.log.info( "Express server listening on port %d in %s mode", port, config.server.environment );
            app.log.info( "Server is now running!" );
        } );
    };

    if (config.server.httpRedirect) {

        var app2 = express();

        var httpServer = http.createServer( app2 );

        app2.get( '*', function ( req, res ) {
            res.redirect( "https://" + config.server.hostname + req.url );
        } );
    }

    var keyDir, certDir;

    if ( config.security.sshKeys.privateKeyfilepath[ 0 ] === '/' ) {
        keyDir = path.resolve( config.security.sshKeys.privateKeyfilepath );
    } else {
        keyDir = path.resolve( path.join( path.dirname( require.main.filename ), config.security.sshKeys.privateKeyfilepath ) );
    }

    if ( config.security.sshKeys.certificatefilepath[ 0 ] === '/' ) {
        certDir = path.resolve( config.security.sshKeys.certificatefilepath );
    } else {
        certDir = path.resolve( path.join( path.dirname( require.main.filename ), config.security.sshKeys.certificatefilepath ) );
    }

    fs.read( keyDir )
        .then( function( content ) {
            keyFound = true;
            keyContent = content;

            checkIfKeyAndCertAreLoaded();
        } )
        .fail( function( err ) {
            app.log.error( 'Failed to load private key file. Check your private key file path. Error: ', err );
        } );

    fs.read( certDir )
        .then( function( content ) {
            certFound = true;
            certContent = content;

            checkIfKeyAndCertAreLoaded();
        } )
        .fail( function( err ) {
            app.log.error( 'Failed to load certificate file. Check your certificate file path. Error: ',
                err );
        } );
}

// Else setup the server for http mode
else if ( config.server.mode === "http" ) {
    server = http.createServer( app );

    // Listen on the port defined at the beginning of the script
    server.listen( port );

    // Log the start of the server
    app.log.info( "Express server listening on port %d in %s mode", port, config.server.environment );
    app.log.info( "Server is now running!" );
}

// Setup the kill state handler
function cleanUp() {
    app.log.info( "Termination signal received. Closing server." );
    database.close();
    mailer.close();
}

process.stdin.resume();//so the program will not close instantly

function exitHandler( options, err ) {
    if ( options.cleanup ) {
        app.log.debug( 'Bridge application closing. Good Bye!' );
    }
    if ( err ) {
        app.log.error( err.stack );
    }
    if ( options.exit ) {
        process.exit();
    }
}

//do something when app is closing
process.on( 'exit', exitHandler.bind( null,           { cleanup: true } ) );

//catches ctrl+c event
process.on( 'SIGINT', exitHandler.bind( null,            { exit: true } ) );

//catches uncaught exceptions
process.on( 'uncaughtException', exitHandler.bind( null, { exit: true } ) );
<commit_msg>added more verbose debugging information to the db error on actions insertion<commit_after>"use strict";
//server.js

// Bring in external libraries
var fs         = require( 'q-io/fs'     );
var https      = require( 'https'       );
var http       = require( 'http'        );
var path       = require( 'path'        );
var express    = require( 'express'     );
var lodash     = require( 'lodash'      );
var winston    = require( 'winston'     );
var Q          = require( 'q'           );
var bodyParser = require( 'body-parser' );
var onHeaders  = require( 'on-headers'  );
var userAgent  = require( 'express-useragent' );
var moment     = require( 'moment' );

Q.longStackSupport = true;

winston.remove( winston.transports.Console );
winston.add( winston.transports.Console, { level: 'verbose', colorize:true } );

// Setup global variables
var _ = lodash._;

exports.express = express;

// Mixin the underscore.string lib
// Import Underscore.string to separate object, because there are conflict functions (include, reverse, contains)
_.str = require( 'underscore.string' );

// Mix in non-conflict functions to Underscore namespace if you want
_.mixin( _.str.exports() );

var config = require( './src/config' );

// Export important files for bridge configuration and setup
exports.config = config;

// Start the express app
var app = exports.app = express();

// Create the routers that will be used by the bridge app.
var routerOptions = { caseSensitive: true };
app.set( 'privateRouter' , express.Router( routerOptions ) );
app.set( 'publicRouter'  , express.Router( routerOptions ) );

// Determine the port to listen on
var port = config.server.port;
process.env.PORT = port;

var loggerObj  = require( './src/logger' );

// Read in local modules that are to be exported
var regex        = require( './src/regex' );
var bridgeError  = require( './src/error' );
var util         = require( './src/utilities' );
var pdfGenerator = require( './src/html2pdf' );

exports.error        = bridgeError;
exports.regex        = regex;
exports.util         = util;
exports.pdfGenerator = pdfGenerator;

var database    = require( './src/database' );

// Export local files for the API to use
exports.database = database;

// Read in non exported local modules
var bridgeWare = require( './src/middleware' );
var mailer     = require( './src/mailer' );
var routes     = require( './src/bridgeroutes' );

// Prepare server variable
var server = null;

// Setting standard dictionary objects
// database reference
app.set( 'views', config.mailer.templateDirectory );
app.set( 'view engine', 'ejs' );

// Remove the header that displays that express powers the application.
app.disable('x-powered-by');

app.engine( 'html', require( 'ejs' ).renderFile );
app.engine( 'ejs',  require( 'ejs' ).renderFile );

// Tell express that it is behind a proxy
app.enable( 'trust proxy' );

/////////////////////////////////////////////////////////////////////////////////////////
///////    STARTING SETUP OF MIDDLEWARE    //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// Setup the response logger event handler.
app.use( function( req, res, next ) {
    onHeaders( res, function() {
        app.log.verbose( "Sending Response." );
        app.log.silly( 'Response headers: ', res._headers );

        if ( _.isObject( req.bridge ) ) {
            if ( _.isObject( req.bridge.dbLogger ) ) {
                req.bridge.dbLogger.data.responseHeaders = res._headers;
                req.bridge.dbLogger.data.bridgeHeader = req.get( 'bridge' );

                var values = [];

                values.push( req.bridge.dbLogger.userID  );
                values.push( JSON.stringify( req.bridge.dbLogger.data )  );
                values.push( req.bridge.dbLogger.datatype );
                values.push( moment().format( 'YYYY-MM-DD HH:mm:ss' ) );
                values.push( moment().format( 'YYYY-MM-DD HH:mm:ss' ) );
                values.push( 0 );

                database.insertIntoTable( 'actions', values )
                .fail( function( err ) {
                    app.log.warn( "Cannot insert action into the actions table. Error: ", err );
                    app.log.debug( "Values", values );
                } );
            }
        }
    } );
    next();
} );

// Setup the cookie parser
app.use( bridgeWare.getCookies() );

app.use( userAgent.express() );

// Setup the request logger
app.use( function ( req, res, next ) {

    app.log.verbose( "Received Request at " + req.path );
    app.log.silly( {
        RequestBody: req.body,
        BridgeHeader: req.get( 'bridge' ),
        Method: req.method,
        Resource: req.path,
        Secure: req.secure,
        XHR: req.xhr,
        Protocol: req.protocol,
        BridgeCookie: req.bridge.cookies.get( 'BridgeAuth' )
    } );

    next();
} );

app.use( bridgeWare.applyDefaultSecuityPolicyHeader );

// Static hosting Middleware
app.use( bridgeWare.staticHostFiles() );

app.use( bridgeWare.prepBridgeObjects );

// Serve the index if it is a GET request for '/'
app.get( '/', routes.serveIndex );

app.get( 'publicRouter' ).use( bridgeWare.prepBridgeObjects );

// Handle an authentication request
app.get( 'publicRouter' ).route( '/authenticate' )
    .post( require( './src/requests/authenticate' ) );

// Automatically parse the body to JSON
app.use( bodyParser.json() );

// Add the CORS headers to the response
app.use( bridgeWare.attachCORSHeaders() );

// Handle CORS Request
app.use( bridgeWare.handleOptionsRequest() );

// Use the public router to send
app.use( config.server.apiRoute, app.get( "publicRouter" ) );

// Use the private router to try to interpret the route
app.use( config.server.apiRoute, app.get( "privateRouter" ) );

// Error Handler
app.use( bridgeWare.bridgeErrorHandler() );

// 404 Handler
app.log.debug( "404 handler setup" );
app.all( '*', function ( req, res, next ) {

    if ( _.has( res, 'finished' ) && res.finished === true ) {

        next();
        return;
    }

    routes.send404( req, res );
    return;
} );

// Setup bridge default router
routes.setup();

/////////////////////////////////////////////////////////////////////////////////////////
///////     MIDDLEWARE SETUP COMPLETE      //////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

// Setup the server for https mode
if ( config.server.mode === "https" ) {

    var keyFound = false,
        keyContent,
        certFound = false,
        certContent;

    var checkIfKeyAndCertAreLoaded = function () {
        if ( !keyFound || !certFound ) {
            return;
        }

        var credentials = {
            key: keyContent,
            cert: certContent
        };

        server = https.createServer( credentials, app );

        // Listen on the port defined at the beginning of the script
        server.listen( port );
        Q.delay( 100 ).
        then( function() {
            // Log the start of the server
            app.log.info( "Express server listening on port %d in %s mode", port, config.server.environment );
            app.log.info( "Server is now running!" );
        } );
    };

    if (config.server.httpRedirect) {

        var app2 = express();

        var httpServer = http.createServer( app2 );

        app2.get( '*', function ( req, res ) {
            res.redirect( "https://" + config.server.hostname + req.url );
        } );
    }

    var keyDir, certDir;

    if ( config.security.sshKeys.privateKeyfilepath[ 0 ] === '/' ) {
        keyDir = path.resolve( config.security.sshKeys.privateKeyfilepath );
    } else {
        keyDir = path.resolve( path.join( path.dirname( require.main.filename ), config.security.sshKeys.privateKeyfilepath ) );
    }

    if ( config.security.sshKeys.certificatefilepath[ 0 ] === '/' ) {
        certDir = path.resolve( config.security.sshKeys.certificatefilepath );
    } else {
        certDir = path.resolve( path.join( path.dirname( require.main.filename ), config.security.sshKeys.certificatefilepath ) );
    }

    fs.read( keyDir )
        .then( function( content ) {
            keyFound = true;
            keyContent = content;

            checkIfKeyAndCertAreLoaded();
        } )
        .fail( function( err ) {
            app.log.error( 'Failed to load private key file. Check your private key file path. Error: ', err );
        } );

    fs.read( certDir )
        .then( function( content ) {
            certFound = true;
            certContent = content;

            checkIfKeyAndCertAreLoaded();
        } )
        .fail( function( err ) {
            app.log.error( 'Failed to load certificate file. Check your certificate file path. Error: ',
                err );
        } );
}

// Else setup the server for http mode
else if ( config.server.mode === "http" ) {
    server = http.createServer( app );

    // Listen on the port defined at the beginning of the script
    server.listen( port );

    // Log the start of the server
    app.log.info( "Express server listening on port %d in %s mode", port, config.server.environment );
    app.log.info( "Server is now running!" );
}

// Setup the kill state handler
function cleanUp() {
    app.log.info( "Termination signal received. Closing server." );
    database.close();
    mailer.close();
}

process.stdin.resume();//so the program will not close instantly

process.stdin.on( 'data', function ( chunk ) {

} );

function exitHandler( options, err ) {
    if ( options.cleanup ) {
        app.log.debug( 'Bridge application closing. Good Bye!' );
    }
    if ( err ) {
        app.log.error( err.stack );
    }
    if ( options.exit ) {
        process.exit();
    }
}

//do something when app is closing
process.on( 'exit', exitHandler.bind( null, { cleanup: true } ) );

//catches ctrl+c event
process.on( 'SIGINT', exitHandler.bind( null, { exit: true } ) );

//catches uncaught exceptions
process.on( 'uncaughtException', exitHandler.bind( null, { exit: true } ) );
<|endoftext|>