<commit_before>/* jshint node: true, esversion: 6 */
'use strict';
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');

const app = express();
const config = require('./webpack.config.babel.js');
const compiler = webpack(config);
const port = 3000;

const http = require('http');
const finalhandler = require('finalhandler');
const Router = require('router');
const headerSettings = {
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': '*/*',
    'Access-Control-Allow-Origin': 'http://159.65.75.193/' //was 3001?

}

const creds = require('./config');
const M = creds.pnetConfig.methods;
const gateway = require('./gateway');
const utilities = require('./utilities');

// Dummy data:
let container;
const venueid = 100;
let showid = 1253142331;
let name = "Trey Anastasio";

function queryComposer(name, value) {
    this.name = name;
    this.value = value;
    this.queryString = `&${name}=${value}`;
}

const queryToPass = [];

// Webpack (dev only)
// app.use(webpackDevMiddleware(compiler, {
//     publicPath: config.output.publicPath,
//     stats: { colors: true }
// }));

app.listen(port, () => {
    console.log(`Express server running on port: ${port}`);
});

// Pnet v3 Get setlist info from showid
app.get('/setlistinfo/:showid', async(req, res) => {
    res.set(headerSettings);
    let showid = req.params.showid;
    let pnetData = await gateway.getSetlistByShowId(showid);
    console.log("setlistinfo: " + pnetData);
    res.write(JSON.stringify(pnetData));
    res.end();
});

// Pnet v2 Get all shows by username
app.get('/usershows/:username', async(req, res) => {
    res.set(headerSettings);
    let username = req.params.username;
    let pnetData = await gateway.getShowsByUsername(username);
    res.write(JSON.stringify(pnetData));
    res.end();
});

// Phish.in API, get show info by show date
app.get('/phishin/shows/:showdate', async(req, res) => {
    res.set(headerSettings);
    let showDate = req.params.showdate;
    console.log("phishin usa!" + showDate)
    let showDateData = await gateway.getMp3ShowInfoByShowDate(showDate);
    if (!showDateData) {
        console.log("Handle this error better (server.js)");
        return; // Clean this up somehow
    }
    res.write(JSON.stringify(showDateData));
    res.end();
})

// Google Geo API, get show by Venue, City, State
app.get('/geodata/:showstring', async(req, res) => {
    res.set(headerSettings);
    let showString = req.params.showstring;
    let geoData = await gateway.getGeoData(showString);
    if (!geoData) {
        console.log("Handle this error better (server.js)");
        return; // Clean this up somehow
    }
    res.write(JSON.stringify(geoData));
    res.end();
})

/*Unused right now */
// app.get('/venueshows/:venue', async(req, res) => {
//     res.set(headerSettings);
//     let venueName = req.params.venue;
//     let allVenueShows = gateway.getVenueByVenueId(venueName);
//     // get shows by venueid
//     res.write(JSON.stringify(coords));
//     res.end();
// })

//END ROUTES

//gateway.makeRequest(M.getPeopleByShowId, queryToPass);

// looks like old request still works!
//gateway.oldRequest("destiny_unhinged");

/**Think about the factories, before the industrial revolution. Only the skilled, specialized
 * workers could operate the machinery, be part of the team by crafting componentry
 * with complex equipment.
 *
 * Later, the industrial revolution would become synonymous with the turning point
 * of american work culture, becoming far more automated, only being operated by the
 * worker class. Today's programming culture is mirroring that with the increase in
 * programming-training, bootcamps, etc.
*/<commit_msg>change to webroot3<commit_after>/* jshint node: true, esversion: 6 */
'use strict';
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');

const app = express();
const config = require('./webpack.config.babel.js');
const compiler = webpack(config);
const port = 3000;

const http = require('http');
const finalhandler = require('finalhandler');
const Router = require('router');
const headerSettings = {
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': '*/*',
    'Access-Control-Allow-Origin': 'http://159.65.75.193/' //was 3001?

}

const creds = require('./config');
const M = creds.pnetConfig.methods;
const gateway = require('./gateway');
const utilities = require('./utilities');

// Dummy data:
let container;
const venueid = 100;
let showid = 1253142331;
let name = "Trey Anastasio";

function queryComposer(name, value) {
    this.name = name;
    this.value = value;
    this.queryString = `&${name}=${value}`;
}

const queryToPass = [];

// Webpack (dev only)
app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
    stats: { colors: true }
}));

app.listen(port, () => {
    console.log(`Express server running on port: ${port}`);
});

// Pnet v3 Get setlist info from showid
app.get('/setlistinfo/:showid', async(req, res) => {
    res.set(headerSettings);
    let showid = req.params.showid;
    let pnetData = await gateway.getSetlistByShowId(showid);
    console.log("setlistinfo: " + pnetData);
    res.write(JSON.stringify(pnetData));
    res.end();
});

// Pnet v2 Get all shows by username
app.get('/usershows/:username', async(req, res) => {
    res.set(headerSettings);
    let username = req.params.username;
    let pnetData = await gateway.getShowsByUsername(username);
    res.write(JSON.stringify(pnetData));
    res.end();
});

// Phish.in API, get show info by show date
app.get('/phishin/shows/:showdate', async(req, res) => {
    res.set(headerSettings);
    let showDate = req.params.showdate;
    console.log("phishin usa!" + showDate)
    let showDateData = await gateway.getMp3ShowInfoByShowDate(showDate);
    if (!showDateData) {
        console.log("Handle this error better (server.js)");
        return; // Clean this up somehow
    }
    res.write(JSON.stringify(showDateData));
    res.end();
})

// Google Geo API, get show by Venue, City, State
app.get('/geodata/:showstring', async(req, res) => {
    res.set(headerSettings);
    let showString = req.params.showstring;
    let geoData = await gateway.getGeoData(showString);
    if (!geoData) {
        console.log("Handle this error better (server.js)");
        return; // Clean this up somehow
    }
    res.write(JSON.stringify(geoData));
    res.end();
})

/*Unused right now */
// app.get('/venueshows/:venue', async(req, res) => {
//     res.set(headerSettings);
//     let venueName = req.params.venue;
//     let allVenueShows = gateway.getVenueByVenueId(venueName);
//     // get shows by venueid
//     res.write(JSON.stringify(coords));
//     res.end();
// })

//END ROUTES

//gateway.makeRequest(M.getPeopleByShowId, queryToPass);

// looks like old request still works!
//gateway.oldRequest("destiny_unhinged");

/**Think about the factories, before the industrial revolution. Only the skilled, specialized
 * workers could operate the machinery, be part of the team by crafting componentry
 * with complex equipment.
 *
 * Later, the industrial revolution would become synonymous with the turning point
 * of american work culture, becoming far more automated, only being operated by the
 * worker class. Today's programming culture is mirroring that with the increase in
 * programming-training, bootcamps, etc.
*/<|endoftext|>


<commit_before>var hookshot = require('hookshot'),
	fs         = require('fs'),
	sh         = require('execSync'),
	request    = require('request');

var config      = require('../config.json'),
		sh_commands = require('./sh-commands.js');

function verifyAccount(incoming_repo){
	if (incoming_repo == config.github_listener.account_name) return true;
	return false;
}
function checkIfCommitterIsDeployer(members, committer){
	members.some(function(member){
		return member.name === committer;
	})
}
function verifyCommitter(last_commit, cb){
	// You only need to verify the deployer if you're using teams, otherwise disable it and always allow anyone pushing to that repo to deploy.
	if (!config.verify_committer.enabled){
		cb(true);
	}else{
		var committer = last_commit.committer.username;
		request('https://api.github.com/teams/' + config.verify_committer.team_id + '/members?access_token=' + config.verify_committer.access_token, function (error, response, body) {
		  if (!error && response.statusCode == 200) {
		  	var committer_is_deployer = checkIfCommitterIsDeployer(JSON.parse(body), committer);
		    cb(committer_is_deployer);
		  }
		})
	}
}

function createDirGitInit(info){
	var repo_name = info.repository.name;

	fs.mkdirSync('./repositories/' + repo_name);

	var create_statement = sh_commands.createGitRepoAndRemotes(repo_name, info.repository.url);
  sh.run(create_statement);
}
function pullLatest(info){
	var repo_name = info.repository.name,
		branch_name = info.ref.split('/')[2], // `ref: "refs/heads/<branchname>` => `branchname`
		delete_branch;

	if (!fs.existsSync('./repositories/' + repo_name)){
		createDirGitInit(info);
	}

	var fetch_statement = sh_commands.fetchLatest(repo_name);
	sh.run(fetch_statement);

	// If its "after" sha is all zeros, then consider that branch deleted
	if (!+info.after) {
		delete_branch = sh_commands.deleteBranch(repo_name, branch_name);
		sh.run(delete_branch);
	}

	var track_all_branches = sh_commands.trackAllBranches(repo_name);
	sh.run(track_all_branches);
}
function checkForDeployMsg(last_commit){
	var commit_msg = last_commit.message,
	    cp_deploy_regx   = new RegExp(config.s3.hard_deploy.trigger),
	    sync_deploy_regx = new RegExp(config.s3.sync_deploy_trigger);

	if (config.s3.hard_deploy.enabled && cp_deploy_regx.exec(commit_msg)) return 'cp';
	if (sync_deploy_regx.exec(commit_msg)) return 'sync';
	return false;
}
function deployToS3(deploy_type, info){
	var repo_name = info.repository.name,
	    path      = (config.s3.path) ? config.s3.path : '';

	var deploy_statement = sh_commands.deploy(deploy_type, repo_name, config.s3.bucket_name, path, config.s3.exclude);
	var deploy_result = sh.exec(deploy_statement);
	// Log deployment result
	console.log(deploy_result.stdout);
}

hookshot(function(info){
	// Is this request coming from the specified GitHub Account?
	var is_account_verified = verifyAccount(info.repository.owner.name);
	// Is there a deploy message present?
	var most_recent_commit,
			deploy_status;
	// The last commit in the array is the most recent
	// But `info.commits` will be an empty array if you pushed a new branch with no commits
	if (info.commits.length) {
		most_recent_commit  = info.commits[info.commits.length - 1];
		deploy_status       = checkForDeployMsg(most_recent_commit);
	}
	// Is this coming from the whitelisted GitHub account?
	if (is_account_verified){
		pullLatest(info);

		// Are we deploying? Has that option been enabled and does the commit have the appropriate message?
		if (config.s3.enabled && deploy_status){
			verifyCommitter(most_recent_commit, function(committer_approved){

				// Does the committer have deploy? privileges?
				if (committer_approved) deployToS3(deploy_status, info);

			});
		}

	}
}).listen(config.github_listener.port);

console.log('Listening on port... ' + config.github_listener.port);	<commit_msg>better branch deletion tracking<commit_after>var hookshot = require('hookshot'),
	fs         = require('fs'),
	sh         = require('execSync'),
	request    = require('request');

var config      = require('../config.json'),
		sh_commands = require('./sh-commands.js');

function verifyAccount(incoming_repo){
	if (incoming_repo == config.github_listener.account_name) return true;
	return false;
}
function checkIfCommitterIsDeployer(members, committer){
	members.some(function(member){
		return member.name === committer;
	})
}
function verifyCommitter(last_commit, cb){
	// You only need to verify the deployer if you're using teams, otherwise disable it and always allow anyone pushing to that repo to deploy.
	if (!config.verify_committer.enabled){
		cb(true);
	}else{
		var committer = last_commit.committer.username;
		request('https://api.github.com/teams/' + config.verify_committer.team_id + '/members?access_token=' + config.verify_committer.access_token, function (error, response, body) {
		  if (!error && response.statusCode == 200) {
		  	var committer_is_deployer = checkIfCommitterIsDeployer(JSON.parse(body), committer);
		    cb(committer_is_deployer);
		  }
		})
	}
}

function createDirGitInit(info){
	var repo_name = info.repository.name;

	fs.mkdirSync('./repositories/' + repo_name);

	var create_statement = sh_commands.createGitRepoAndRemotes(repo_name, info.repository.url);
  sh.run(create_statement);
}
function pullLatest(info){
	var repo_name = info.repository.name,
		branch_name = info.ref.split('/')[2], // `ref: "refs/heads/<branchname>` => `branchname`
		delete_branch;

	if (!fs.existsSync('./repositories/' + repo_name)){
		createDirGitInit(info);
	}

	var fetch_statement = sh_commands.fetchLatest(repo_name);
	sh.run(fetch_statement);

	// If it's deleted, delete it!
	if (info.deleted) {
		delete_branch = sh_commands.deleteBranch(repo_name, branch_name);
		sh.run(delete_branch);
	}

	var track_all_branches = sh_commands.trackAllBranches(repo_name);
	sh.run(track_all_branches);
}
function checkForDeployMsg(last_commit){
	var commit_msg = last_commit.message,
	    cp_deploy_regx   = new RegExp(config.s3.hard_deploy.trigger),
	    sync_deploy_regx = new RegExp(config.s3.sync_deploy_trigger);

	if (config.s3.hard_deploy.enabled && cp_deploy_regx.exec(commit_msg)) return 'cp';
	if (sync_deploy_regx.exec(commit_msg)) return 'sync';
	return false;
}
function deployToS3(deploy_type, info){
	var repo_name = info.repository.name,
	    path      = (config.s3.path) ? config.s3.path : '';

	var deploy_statement = sh_commands.deploy(deploy_type, repo_name, config.s3.bucket_name, path, config.s3.exclude);
	var deploy_result = sh.exec(deploy_statement);
	// Log deployment result
	console.log(deploy_result.stdout);
}

hookshot(function(info){
	// Is this request coming from the specified GitHub Account?
	var is_account_verified = verifyAccount(info.repository.owner.name);
	// Is there a deploy message present?
	var most_recent_commit,
			deploy_status;
	// The last commit in the array is the most recent
	// But `info.commits` will be an empty array if you pushed a new branch with no commits
	if (info.commits.length) {
		most_recent_commit  = info.commits[info.commits.length - 1];
		deploy_status       = checkForDeployMsg(most_recent_commit);
	}
	// Is this coming from the whitelisted GitHub account?
	if (is_account_verified){
		pullLatest(info);

		// Are we deploying? Has that option been enabled and does the commit have the appropriate message?
		if (config.s3.enabled && deploy_status){
			verifyCommitter(most_recent_commit, function(committer_approved){

				// Does the committer have deploy? privileges?
				if (committer_approved) deployToS3(deploy_status, info);

			});
		}

	}
}).listen(config.github_listener.port);

console.log('Listening on port... ' + config.github_listener.port);	<|endoftext|>


<commit_before>(function (require, module) {
  'use strict';

  var serverModule = {
    starting: false,
    started: false,
    server: null
  };

  serverModule.start = function (next) {

    if (serverModule.started) {
      console.log('The server has already started.'.green);
      return next(null, serverModule.server);
    }

    if (serverModule.starting) {
      return next(new Error(
        'An instance of the server is already attempting to start.'.yellow
      ));
    }

    serverModule.starting = true;

    /**
     * Module dependencies.
     */

    var config = require('./shared/config.js');
    var express = require('express');
    var userApi = require('./server/userApi.js');
    var projectApi = require('./server/projectApi.js');
    var profileApi = require('./server/profileApi.js');
    var deviceApi = require('./server/deviceApi.js');
    var http = require('http');
    var path = require('path');
    var colors = require('colors');
    var passport = require('passport');
    var auth = require('./server/auth.js');
    var dbAccess = require('./server/dbAccess');
    var utils = require('./shared/utils');
    var i18n = require('i18next');

    /**
     * Main application
     */

    i18n.init({
      ns: { namespaces: ['ns.app'], defaultNs: 'ns.app'},
      resSetPath: 'locales/__lng__/new.__ns__.json',
      saveMissing: true,
      debug: true,
      sendMissingTo: 'fallback',
      supportedLngs: 'en-US',
      lng: config.locale
    });

    var app = express();

    // all environments
    app.set('port', config.listen_port || process.env.PORT || 3000);
    app.set('views', path.join(__dirname, '../views'));
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session({
      secret: 'keyboard cat'
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    auth.init();

    // If the apikey is set, use it rather than a persistant
    // login (i.e. browser)
    app.use(auth.apiKeyAuthoriser);

    app.use(i18n.handle);
    app.use(app.router);
    app.use(express.static(path.join(__dirname, '../public')));

    // development only
    if (config.show_friendly_errors) {
      app.use(express.errorHandler());
    }

    dbAccess.init(function (err) {
      if (err) {
        console.log(
          'Error: Database is required to run. Halting application'
          .red);
        next(err);
      }
    });

    i18n.registerAppHelper(app);

    //
    // User API
    //
    app.param('user', userApi.pUser);

    app.get('/users/:user/', userApi.getUser);
    app.del('/users/:user/', userApi.deleteUser);
    app.put('/users/:user/', userApi.putUser);
    app.post('/users/:user/password/', userApi.changePassword);
    app.post('/users/:user/resetpassword/', userApi.resetPassword);
    app.get('/logout/', userApi.logout);
    app.post('/login/', userApi.login);
    if (config.enable_test_exts) {
      app.get('/test/user_api/reset/', userApi.resetTests);
      app.post('/test/user_api/expirePassword/:user/',
        userApi.expireTempPassword);
    }

    //
    // Project API
    //
    app.param('projectId', projectApi.pProjectId);

    app.get('/projects/', projectApi.listProjects);
    app.get('/projects/:projectId/', projectApi.getProject);
    app.del('/projects/:projectId/', projectApi.removeProject);
    app.put('/projects/', projectApi.addProject);
    app.put('/projects/:projectId/users/:user/',
      projectApi.addProjectUser);
    app.del('/projects/:projectId/users/:user/',
      projectApi.removeProjectUser);
    app.put('/projects/:projectId/admins/:user/',
      projectApi.addProjectAdmin);
    app.del('/projects/:projectId/admins/:user/',
      projectApi.removeProjectAdmin);
    if (config.enable_test_exts) {
      app.get('/test/project_api/reset/', projectApi.resetTests);
    }

    //
    // Profile API
    //
    app.param('profileId', profileApi.pProfileId);

    app.get('/projects/:projectId/profiles/',
      profileApi.getProfiles);
    app.get('/projects/:projectId/profiles/:profileId/',
      profileApi.getProfile);
    app.del('/projects/:projectId/profiles/:profileId/',
      profileApi.deleteProfile);
    app.put('/projects/:projectId/profiles/',
      profileApi.saveProfile);
    if (config.enable_test_exts) {
      app.get('/test/profile_api/reset/', profileApi.resetTests);
    }

    //
    // Device API
    //
    app.param('deviceMacAddr', deviceApi.pDeviceMacAddr);
    app.put('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.registerDevice);
    app.get('/projects/:projectId/devices/', deviceApi.listDevices);
    app.get('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.getDevice);
    app.del('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.deregisterDevice);
    app.get('/projects/:projectId/devices/' +
      ':deviceMacAddr/schema/', deviceApi.getSchema);
    app.put('/projects/:projectId/sessions/' +
      ':deviceMacAddr/', deviceApi.startSession);
    app.del('/projects/:projectId/sessions/' +
      ':deviceMacAddr/', deviceApi.stopSession);
    app.post('/projects/:projectId/sessions/' +
      ':deviceMacAddr/updates', deviceApi.queueUpdate);
    app.get('/projects/:projectId/sessions/' +
      ':deviceMacAddr/updates', deviceApi.getUpdates);
    if (config.enable_test_exts) {
      app.get('/test/device_api/reset/', deviceApi.resetTests);
    }

    // Rendered HTML pages
    app.get('/views/auth', function (req, res) {
      res.render('auth');
    });

    app.get('/views/test', function (req, res) {
      res.render('test');
    });

    app.get('/views/dashboard', function (req, res) {
      res.render('dashboard');
    });

    app.get('/views/partials/login', function (req, res) {
      res.render('partials/login');
    });

    app.get('/views/partials/createAccount', function (req, res) {
      res.render('partials/createAccount');
    });

    app.get('/views/partials/listProjects', function (req, res) {
      res.render('partials/listProjects');
    });

    var server = http.createServer(app);

    server.listen(app.get('port'), function () {
      console.log('Express server listening on port ' + app.get('port')
        .toString()
        .blue);
      serverModule.started = true;
      next(null, serverModule.server);
    });

    serverModule.server = server;
  };

  serverModule.stop = function () {
    if (serverModule.started) {
      serverModule.server.close(function () {
        serverModule.started = false;
      });
    }
  };

  module.exports = serverModule;

})(require, module);
<commit_msg>Turned i18n debugging off to reduce log spam.<commit_after>(function (require, module) {
  'use strict';

  var serverModule = {
    starting: false,
    started: false,
    server: null
  };

  serverModule.start = function (next) {

    if (serverModule.started) {
      console.log('The server has already started.'.green);
      return next(null, serverModule.server);
    }

    if (serverModule.starting) {
      return next(new Error(
        'An instance of the server is already attempting to start.'.yellow
      ));
    }

    serverModule.starting = true;

    /**
     * Module dependencies.
     */

    var config = require('./shared/config.js');
    var express = require('express');
    var userApi = require('./server/userApi.js');
    var projectApi = require('./server/projectApi.js');
    var profileApi = require('./server/profileApi.js');
    var deviceApi = require('./server/deviceApi.js');
    var http = require('http');
    var path = require('path');
    var colors = require('colors');
    var passport = require('passport');
    var auth = require('./server/auth.js');
    var dbAccess = require('./server/dbAccess');
    var utils = require('./shared/utils');
    var i18n = require('i18next');

    /**
     * Main application
     */

    i18n.init({
      ns: {
        namespaces: ['ns.app'],
        defaultNs: 'ns.app'
      },
      resSetPath: 'locales/__lng__/new.__ns__.json',
      saveMissing: true,
      debug: false, // Set to true for very verbose messages
      sendMissingTo: 'fallback',
      supportedLngs: 'en-US',
      lng: config.locale
    });

    var app = express();

    // all environments
    app.set('port', config.listen_port || process.env.PORT || 3000);
    app.set('views', path.join(__dirname, '../views'));
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session({
      secret: 'keyboard cat'
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    auth.init();

    // If the apikey is set, use it rather than a persistant
    // login (i.e. browser)
    app.use(auth.apiKeyAuthoriser);

    app.use(i18n.handle);
    app.use(app.router);
    app.use(express.static(path.join(__dirname, '../public')));

    // development only
    if (config.show_friendly_errors) {
      app.use(express.errorHandler());
    }

    dbAccess.init(function (err) {
      if (err) {
        console.log(
          'Error: Database is required to run. Halting application'
          .red);
        next(err);
      }
    });

    i18n.registerAppHelper(app);

    //
    // User API
    //
    app.param('user', userApi.pUser);

    app.get('/users/:user/', userApi.getUser);
    app.del('/users/:user/', userApi.deleteUser);
    app.put('/users/:user/', userApi.putUser);
    app.post('/users/:user/password/', userApi.changePassword);
    app.post('/users/:user/resetpassword/', userApi.resetPassword);
    app.get('/logout/', userApi.logout);
    app.post('/login/', userApi.login);
    if (config.enable_test_exts) {
      app.get('/test/user_api/reset/', userApi.resetTests);
      app.post('/test/user_api/expirePassword/:user/',
        userApi.expireTempPassword);
    }

    //
    // Project API
    //
    app.param('projectId', projectApi.pProjectId);

    app.get('/projects/', projectApi.listProjects);
    app.get('/projects/:projectId/', projectApi.getProject);
    app.del('/projects/:projectId/', projectApi.removeProject);
    app.put('/projects/', projectApi.addProject);
    app.put('/projects/:projectId/users/:user/',
      projectApi.addProjectUser);
    app.del('/projects/:projectId/users/:user/',
      projectApi.removeProjectUser);
    app.put('/projects/:projectId/admins/:user/',
      projectApi.addProjectAdmin);
    app.del('/projects/:projectId/admins/:user/',
      projectApi.removeProjectAdmin);
    if (config.enable_test_exts) {
      app.get('/test/project_api/reset/', projectApi.resetTests);
    }

    //
    // Profile API
    //
    app.param('profileId', profileApi.pProfileId);

    app.get('/projects/:projectId/profiles/',
      profileApi.getProfiles);
    app.get('/projects/:projectId/profiles/:profileId/',
      profileApi.getProfile);
    app.del('/projects/:projectId/profiles/:profileId/',
      profileApi.deleteProfile);
    app.put('/projects/:projectId/profiles/',
      profileApi.saveProfile);
    if (config.enable_test_exts) {
      app.get('/test/profile_api/reset/', profileApi.resetTests);
    }

    //
    // Device API
    //
    app.param('deviceMacAddr', deviceApi.pDeviceMacAddr);
    app.put('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.registerDevice);
    app.get('/projects/:projectId/devices/', deviceApi.listDevices);
    app.get('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.getDevice);
    app.del('/projects/:projectId/devices/' +
      ':deviceMacAddr/', deviceApi.deregisterDevice);
    app.get('/projects/:projectId/devices/' +
      ':deviceMacAddr/schema/', deviceApi.getSchema);
    app.put('/projects/:projectId/sessions/' +
      ':deviceMacAddr/', deviceApi.startSession);
    app.del('/projects/:projectId/sessions/' +
      ':deviceMacAddr/', deviceApi.stopSession);
    app.post('/projects/:projectId/sessions/' +
      ':deviceMacAddr/updates', deviceApi.queueUpdate);
    app.get('/projects/:projectId/sessions/' +
      ':deviceMacAddr/updates', deviceApi.getUpdates);
    if (config.enable_test_exts) {
      app.get('/test/device_api/reset/', deviceApi.resetTests);
    }

    // Rendered HTML pages
    app.get('/views/auth', function (req, res) {
      res.render('auth');
    });

    app.get('/views/test', function (req, res) {
      res.render('test');
    });

    app.get('/views/dashboard', function (req, res) {
      res.render('dashboard');
    });

    app.get('/views/partials/login', function (req, res) {
      res.render('partials/login');
    });

    app.get('/views/partials/createAccount', function (req, res) {
      res.render('partials/createAccount');
    });

    app.get('/views/partials/listProjects', function (req, res) {
      res.render('partials/listProjects');
    });

    var server = http.createServer(app);

    server.listen(app.get('port'), function () {
      console.log('Express server listening on port ' + app.get('port')
        .toString()
        .blue);
      serverModule.started = true;
      next(null, serverModule.server);
    });

    serverModule.server = server;
  };

  serverModule.stop = function () {
    if (serverModule.started) {
      serverModule.server.close(function () {
        serverModule.started = false;
      });
    }
  };

  module.exports = serverModule;

})(require, module);
<|endoftext|>


<commit_before>'use strict';
const fetch = require('node-fetch');
const Request = fetch.Request;
const Response = fetch.Response;
const Headers = fetch.Headers;
const stream = require('stream');
const FetchMock = require('./fetch-mock');
const http = require('http');

module.exports = new FetchMock({
	theGlobal: GLOBAL,
	Request: Request,
	Response: Response,
	Headers: Headers,
	stream: stream,
	statusTextMap: http.STATUS_CODES
});
<commit_msg>referencing global instead of GLOBAL to fix #79<commit_after>'use strict';
const fetch = require('node-fetch');
const Request = fetch.Request;
const Response = fetch.Response;
const Headers = fetch.Headers;
const stream = require('stream');
const FetchMock = require('./fetch-mock');
const http = require('http');

module.exports = new FetchMock({
	theGlobal: global,
	Request: Request,
	Response: Response,
	Headers: Headers,
	stream: stream,
	statusTextMap: http.STATUS_CODES
});
<|endoftext|>


<commit_before>/**
 * The high-level logic for our serving endpoints (api routes).
 */

'use strict';

const bodyParser = require("body-parser");
const express = require("express");
const logging = require("winston");

const cache = require("./cache.js");
const fetchPackage = require("./fetch_package.js");
const render = require("./render.js");
const renderSecret = require("./secret.js");

const app = express();
app.use(bodyParser.json());

/**
 * Server-side render a react component.
 *
 * The contents to render are sent in the request body as json, in
 * the following format:
 * {
 *    "urls": [
 *        "http://kastatic.org/genfiles/javascript/en/corelibs-package-xx.js",
 *        "http://kastatic.org/genfiles/javascript/en/shared-package-xx.js",
 *        "http://kastatic.org/genfiles/javascript/en/content-library-xx.js"
 *    ],
 *    "path": "./javascript/content-library-package/components/link.jsx",
 *    "props": {
 *        "href": "http://www.google.com",
 *        "children": "Google"
 *    },
 *    "secret": "...."
 * }
 *
 * 'urls' should be specified in topological-sort order; they are
 * executed in the order listed here.
 *
 * 'path' is a path in nodejs require() format, which exports the react
 * component we wish to render.  It must be included in one of the files
 * specified in 'urls'.
 *
 * 'props' are passed as the props to the react component being rendered.
 *
 * 'secret' is a shared secret.  It must equal the value of the 'secret'
 * file in the server's base-directory, or the server will deny the request.
 * NOTE: In dev mode, the secret field is ignored.
 *
 * The return format is also json:
 * {
 *     "html": "Google",
 *     "css": {
 *         content: ".link141{backgroundColor:transparent;}",
 *         renderedClassNames: ["link141"]
 *     }
 * }
 *
 * css will only be returned if the component makes use of Aphrodite
 * (https://github.com/Khan/aphrodite).
 */
app.post('/render', (req, res) => {
    // Validate the input.
    let err;
    if (!renderSecret.matches(req.body.secret)) {
        err = 'Missing or invalid secret';
    } else if (!Array.isArray(req.body.urls) || req.body.urls.length === 0 ||
               !req.body.urls.every(e => typeof e === 'string') ||
               !req.body.urls.every(e => e.indexOf('http') === 0)) {
        err = ('Missing "urls" keyword in POST JSON input, ' +
               'or "urls" is not a list of full urls');
    } else if (typeof req.body.path !== 'string' ||
               req.body.path.indexOf("./") !== 0) {
        err = ('Missing "path" keyword in POST JSON input, ' +
               'or "path" does not start with "./"');
    } else if (typeof req.body.props !== 'object' ||
               Array.isArray(req.body.props)) {
        err = ('Missing "props" keyword in POST JSON input, ' +
               'or "props" is not an object, or it has non-string keys.');
    }
    if (err) {
        res.status(400).json({error: err});
        return;
    }

    const fetchPromises = req.body.urls.map(
        url => fetchPackage(url).then(contents => [url, contents])
    );

    Promise.all(fetchPromises).then(
        (fetchBodies) => {
            const renderedState = render(fetchBodies,
                                         req.body.path,
                                         req.body.props);
            res.json(renderedState);
        },
        (err) => {
            // Error handler for fetching failures.
            if (err.response && err.response.error) {
                logging.error('Fetching failure: ' + err.response.error + ': ',
                              err.stack);
                res.status(500).json({error: err});
            } else {
                logging.error('Fetching failure: ', err.stack);
                res.status(500).json({error: err.toString(),
                                      // TODO(csilvers): remove 'key' once
                                      // we've debugged error types better.
                                      keys: Object.keys(err)});
            }
        })
        .catch((err) => {
            // Error handler for rendering failures
            logging.error('Rendering failure:', err.stack);
            res.status(500).json({error: err.toString()});
        });
});

/**
 * Flush all the caches.
 *
 * This can be useful when there's weird errors that may be due to bad
 * caching, or for testing.
 *
 * The post data is sent in the request body as json, in the following format:
 * {
 *    "secret": "...."
 * }
 *
 * 'secret' is a shared secret.  It must equal the value of the 'secret'
 * file in the server's base-directory, or the server will deny the request.
 * NOTE: In dev mode, the secret field is ignored.
 *
 * We respond with the instance that was flushed.
 * TODO(csilvers): how do we flush *all* the instances??
 */
app.post('/flush', (req, res) => {
    if (!renderSecret.matches(req.body.secret)) {
        res.status(400).json({error: 'Missing or invalid secret'});
        return;
    }
    cache.reset();
    res.send((process.env['GAE_MODULE_INSTANCE'] || 'dev') + '\n');
});

app.get('/_api/ping', (req, res) => { res.send('pong!\n'); });

app.get('/_api/version', (req, res) => {
    // This will return the module version ID we set when deploying.
    res.send((process.env['GAE_MODULE_VERSION'] || 'dev') + '\n');
});

// These are used by the Managed VM lifecycle functions:
// https://cloud.google.com/appengine/docs/managed-vms/custom-runtimes#lifecycle_events
app.get('/_ah/health', (req, res) => { res.send('ok!\n'); });
app.get('/_ah/start', (req, res) => { res.send('ok!\n'); });
app.get('/_ah/stop', (req, res) => { res.send('ok!\n'); });

module.exports = app;

<commit_msg>Handle timeout errors better.<commit_after>/**
 * The high-level logic for our serving endpoints (api routes).
 */

'use strict';

const bodyParser = require("body-parser");
const express = require("express");
const logging = require("winston");

const cache = require("./cache.js");
const fetchPackage = require("./fetch_package.js");
const render = require("./render.js");
const renderSecret = require("./secret.js");

const app = express();
app.use(bodyParser.json());

/**
 * Server-side render a react component.
 *
 * The contents to render are sent in the request body as json, in
 * the following format:
 * {
 *    "urls": [
 *        "http://kastatic.org/genfiles/javascript/en/corelibs-package-xx.js",
 *        "http://kastatic.org/genfiles/javascript/en/shared-package-xx.js",
 *        "http://kastatic.org/genfiles/javascript/en/content-library-xx.js"
 *    ],
 *    "path": "./javascript/content-library-package/components/link.jsx",
 *    "props": {
 *        "href": "http://www.google.com",
 *        "children": "Google"
 *    },
 *    "secret": "...."
 * }
 *
 * 'urls' should be specified in topological-sort order; they are
 * executed in the order listed here.
 *
 * 'path' is a path in nodejs require() format, which exports the react
 * component we wish to render.  It must be included in one of the files
 * specified in 'urls'.
 *
 * 'props' are passed as the props to the react component being rendered.
 *
 * 'secret' is a shared secret.  It must equal the value of the 'secret'
 * file in the server's base-directory, or the server will deny the request.
 * NOTE: In dev mode, the secret field is ignored.
 *
 * The return format is also json:
 * {
 *     "html": "Google",
 *     "css": {
 *         content: ".link141{backgroundColor:transparent;}",
 *         renderedClassNames: ["link141"]
 *     }
 * }
 *
 * css will only be returned if the component makes use of Aphrodite
 * (https://github.com/Khan/aphrodite).
 */
app.post('/render', (req, res) => {
    // Validate the input.
    let err;
    if (!renderSecret.matches(req.body.secret)) {
        err = 'Missing or invalid secret';
    } else if (!Array.isArray(req.body.urls) || req.body.urls.length === 0 ||
               !req.body.urls.every(e => typeof e === 'string') ||
               !req.body.urls.every(e => e.indexOf('http') === 0)) {
        err = ('Missing "urls" keyword in POST JSON input, ' +
               'or "urls" is not a list of full urls');
    } else if (typeof req.body.path !== 'string' ||
               req.body.path.indexOf("./") !== 0) {
        err = ('Missing "path" keyword in POST JSON input, ' +
               'or "path" does not start with "./"');
    } else if (typeof req.body.props !== 'object' ||
               Array.isArray(req.body.props)) {
        err = ('Missing "props" keyword in POST JSON input, ' +
               'or "props" is not an object, or it has non-string keys.');
    }
    if (err) {
        res.status(400).json({error: err});
        return;
    }

    const fetchPromises = req.body.urls.map(
        url => fetchPackage(url).then(contents => [url, contents])
    );

    Promise.all(fetchPromises).then(
        (fetchBodies) => {
            const renderedState = render(fetchBodies,
                                         req.body.path,
                                         req.body.props);
            res.json(renderedState);
        },
        (err) => {
            // Error handler for fetching failures.
            if (err.response && err.response.error) {
                logging.error('Fetching failure: ' + err.response.error + ': ',
                              err.stack);
                res.status(500).json({error: err});
            } else if (err.error) {        // set for timeouts, in particular
                logging.error(err.error);
                res.status(500).json(err);
            } else {
                logging.error('Fetching failure: ', err.stack);
                res.status(500).json({error: err.toString(),
                                      // TODO(csilvers): remove 'key' once
                                      // we've debugged error types better.
                                      keys: Object.keys(err)});
            }
        })
        .catch((err) => {
            // Error handler for rendering failures
            logging.error('Rendering failure:', err.stack);
            res.status(500).json({error: err.toString()});
        });
});

/**
 * Flush all the caches.
 *
 * This can be useful when there's weird errors that may be due to bad
 * caching, or for testing.
 *
 * The post data is sent in the request body as json, in the following format:
 * {
 *    "secret": "...."
 * }
 *
 * 'secret' is a shared secret.  It must equal the value of the 'secret'
 * file in the server's base-directory, or the server will deny the request.
 * NOTE: In dev mode, the secret field is ignored.
 *
 * We respond with the instance that was flushed.
 * TODO(csilvers): how do we flush *all* the instances??
 */
app.post('/flush', (req, res) => {
    if (!renderSecret.matches(req.body.secret)) {
        res.status(400).json({error: 'Missing or invalid secret'});
        return;
    }
    cache.reset();
    res.send((process.env['GAE_MODULE_INSTANCE'] || 'dev') + '\n');
});

app.get('/_api/ping', (req, res) => { res.send('pong!\n'); });

app.get('/_api/version', (req, res) => {
    // This will return the module version ID we set when deploying.
    res.send((process.env['GAE_MODULE_VERSION'] || 'dev') + '\n');
});

// These are used by the Managed VM lifecycle functions:
// https://cloud.google.com/appengine/docs/managed-vms/custom-runtimes#lifecycle_events
app.get('/_ah/health', (req, res) => { res.send('ok!\n'); });
app.get('/_ah/start', (req, res) => { res.send('ok!\n'); });
app.get('/_ah/stop', (req, res) => { res.send('ok!\n'); });

module.exports = app;

<|endoftext|>


<commit_before>'use strict';

const io = require('socket.io')(3333);
const redis = require("redis");
const adapter = require('socket.io-redis');

const host = 'localhost'
const port = process.env.REDIS_PORT ? process.env.REDIS_PORT : 6379;

let pub = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });
let sub = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });
let client = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });

io.adapter(adapter({ pubClient: pub, subClient: sub }));

sub.on('message', (channel, data) => {
  io.sockets.in(channel).emit('message', channel, data);
});

io.on('connection', function (socket) {
  console.log("Client connected from", socket.request.connection._peername);

  socket.on('subscribe', function (event) {
    sub.subscribe(event.channel);
    socket.join(event.channel);
    console.log("Client joined channel", event.channel);

    client.get(event.channel, (err, res) => {
      socket.emit('subscribed', event.channel, res);
    });

    socket.on('message', function (a) {
      const e = JSON.parse(a);
      console.log(e, a)
      if(e.channel === event.channel) {
        pub.publish(e.channel, e.message);
        client.set(e.channel, e.message);
      }
    });
  });

  socket.on('unsubscribe', function (event) {
    socket.leave(event.channel);
    console.log("Client left channel", event.channel);
  });

  socket.on('disconnect', function () {
  });
});

console.log("Started");
<commit_msg>Remove debug message<commit_after>'use strict';

const io = require('socket.io')(3333);
const redis = require("redis");
const adapter = require('socket.io-redis');

const host = 'localhost'
const port = process.env.REDIS_PORT ? process.env.REDIS_PORT : 6379;

let pub = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });
let sub = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });
let client = redis.createClient({ host: host, port: port, auth_pass: process.env.REDIS_PASSWORD });

io.adapter(adapter({ pubClient: pub, subClient: sub }));

sub.on('message', (channel, data) => {
  io.sockets.in(channel).emit('message', channel, data);
});

io.on('connection', function (socket) {
  console.log("Client connected from", socket.request.connection._peername);

  socket.on('subscribe', function (event) {
    sub.subscribe(event.channel);
    socket.join(event.channel);
    console.log("Client joined channel", event.channel);

    client.get(event.channel, (err, res) => {
      socket.emit('subscribed', event.channel, res);
    });

    socket.on('message', function (a) {
      const e = JSON.parse(a);
      if(e.channel === event.channel) {
        pub.publish(e.channel, e.message);
        client.set(e.channel, e.message);
      }
    });
  });

  socket.on('unsubscribe', function (event) {
    socket.leave(event.channel);
    console.log("Client left channel", event.channel);
  });

  socket.on('disconnect', function () {
  });
});

console.log("Started");
<|endoftext|>


<commit_before>import Express from 'express';
import React from 'react';
import ReactDOM from 'react-dom/server';
import config from './config';
import favicon from 'serve-favicon';
import compression from 'compression';
import httpProxy from 'http-proxy';
import cookieParser from 'cookie-parser';
import path from 'path';
import createStore from './redux/create';
import ApiClient from './helpers/ApiClient';
import Html from './helpers/Html';
import PrettyError from 'pretty-error';
import http from 'http';
import https from 'https';

import { match } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { ReduxAsyncConnect, loadOnServer } from 'redux-async-connect';
import createHistory from 'react-router/lib/createMemoryHistory';
import {Provider} from 'react-redux';
import getRoutes from './routes';

const loopbackApiUrl = config.apiHost + '/api';
const pretty = new PrettyError();
const app = new Express();
const server = new http.Server(app);
const proxy = httpProxy.createProxyServer({
  target: loopbackApiUrl,
  ws: true,
  changeOrigin: true
});

app.use(compression());
app.use(favicon(path.join(__dirname, '..', 'static', 'favicon.ico')));

app.use(Express.static(path.join(__dirname, '..', 'static')));

// Proxy to API server
app.use('/api', (req, res) => {
  proxy.web(req, res, { target: loopbackApiUrl });
});

setInterval(() => {
  https.get('https://cerebral-app.herokuapp.com');
  https.get('https://cerebral-api.herokuapp.com');
  console.log('PING => https://cerebral-app.herokuapp.com');
  console.log('PING => https://cerebral-api.herokuapp.com');
}, 3000); // every 5 minutes (300000)
app.use(cookieParser());

// added the error handling to avoid https://github.com/nodejitsu/node-http-proxy/issues/527
proxy.on('error', (error, req, res) => {
  let json;
  if (error.code !== 'ECONNRESET') {
    console.error('proxy error', error);
  }
  if (!res.headersSent) {
    res.writeHead(500, { 'content-type': 'application/json' });
  }

  json = { error: 'proxy_error', reason: error.message };
  res.end(JSON.stringify(json));
});

app.use((req, res) => {
  if (__DEVELOPMENT__) {
    // Do not cache webpack stats: the script file would change since
    // hot module replacement is enabled in the development env
    webpackIsomorphicTools.refresh();
  }
  const client = new ApiClient(req);
  const memoryHistory = createHistory(req.originalUrl);
  const store = createStore(memoryHistory, client);
  const history = syncHistoryWithStore(memoryHistory, store);
  const token = req.cookies && req.cookies.token;

  function hydrateOnClient() {
    res.send('<!doctype html>\n' +
      ReactDOM.renderToString(<Html assets={webpackIsomorphicTools.assets() } store={store}/>));
  }

  if (__DISABLE_SSR__) {
    hydrateOnClient();
    return;
  }

  match({ history, routes: getRoutes(store, token), location: req.originalUrl }, (error, redirectLocation, renderProps) => {
    if (redirectLocation) {
      res.redirect(redirectLocation.pathname + redirectLocation.search);
    } else if (error) {
      console.error('ROUTER ERROR:', pretty.render(error));
      res.status(500);
      hydrateOnClient();
    } else if (renderProps) {
      const notFound = renderProps.routes.filter((route) => (route.path === '*' && route.status === 404));
      const pathLogin = renderProps.routes.filter((route) => (route.path === 'login'));
      if (pathLogin.length > 0) {
        console.log(renderProps.routes[0].path);
        res.clearCookie('token');
      }
      loadOnServer({...renderProps, store, helpers: { client }}).then(() => {
        const component = (
          <Provider store={store} key="provider">
            <ReduxAsyncConnect {...renderProps} />
          </Provider>
        );
        if (notFound.length > 0) {
          res.status(404);
        } else {
          res.status(200);
        }

        global.navigator = { userAgent: req.headers['user-agent'] };

        res.send('<!doctype html>\n' +
          ReactDOM.renderToString(<Html assets={webpackIsomorphicTools.assets() } component={component} store={store}/>));
      });
    } else {
      res.status(404).send('Not found');
    }
  });
});

if (config.port) {
  server.listen(config.port, (err) => {
    if (err) {
      console.error(err);
    }
    console.info('----\n==> ✅  %s is running, talking to API server', config.app.title);
    console.info('==> 💻  Open http://%s:%s in a browser to view the app.', config.host, config.port);
  });
} else {
  console.error('==>     ERROR: No PORT environment variable has been specified');
}
<commit_msg>chore(project) add pinger to keep dyno awake<commit_after>import Express from 'express';
import React from 'react';
import ReactDOM from 'react-dom/server';
import config from './config';
import favicon from 'serve-favicon';
import compression from 'compression';
import httpProxy from 'http-proxy';
import cookieParser from 'cookie-parser';
import path from 'path';
import createStore from './redux/create';
import ApiClient from './helpers/ApiClient';
import Html from './helpers/Html';
import PrettyError from 'pretty-error';
import http from 'http';
import https from 'https';

import { match } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { ReduxAsyncConnect, loadOnServer } from 'redux-async-connect';
import createHistory from 'react-router/lib/createMemoryHistory';
import {Provider} from 'react-redux';
import getRoutes from './routes';

const loopbackApiUrl = config.apiHost + '/api';
const pretty = new PrettyError();
const app = new Express();
const server = new http.Server(app);
const proxy = httpProxy.createProxyServer({
  target: loopbackApiUrl,
  ws: true,
  changeOrigin: true
});

app.use(compression());
app.use(favicon(path.join(__dirname, '..', 'static', 'favicon.ico')));

app.use(Express.static(path.join(__dirname, '..', 'static')));

// Proxy to API server
app.use('/api', (req, res) => {
  proxy.web(req, res, { target: loopbackApiUrl });
});

setInterval(() => {
  https.get('https://cerebral-app.herokuapp.com');
  https.get('https://cerebral-api.herokuapp.com');
  console.log('PING => https://cerebral-app.herokuapp.com');
  console.log('PING => https://cerebral-api.herokuapp.com');
}, 300000); // every 5 minutes (300000)
app.use(cookieParser());

// added the error handling to avoid https://github.com/nodejitsu/node-http-proxy/issues/527
proxy.on('error', (error, req, res) => {
  let json;
  if (error.code !== 'ECONNRESET') {
    console.error('proxy error', error);
  }
  if (!res.headersSent) {
    res.writeHead(500, { 'content-type': 'application/json' });
  }

  json = { error: 'proxy_error', reason: error.message };
  res.end(JSON.stringify(json));
});

app.use((req, res) => {
  if (__DEVELOPMENT__) {
    // Do not cache webpack stats: the script file would change since
    // hot module replacement is enabled in the development env
    webpackIsomorphicTools.refresh();
  }
  const client = new ApiClient(req);
  const memoryHistory = createHistory(req.originalUrl);
  const store = createStore(memoryHistory, client);
  const history = syncHistoryWithStore(memoryHistory, store);
  const token = req.cookies && req.cookies.token;

  function hydrateOnClient() {
    res.send('<!doctype html>\n' +
      ReactDOM.renderToString(<Html assets={webpackIsomorphicTools.assets() } store={store}/>));
  }

  if (__DISABLE_SSR__) {
    hydrateOnClient();
    return;
  }

  match({ history, routes: getRoutes(store, token), location: req.originalUrl }, (error, redirectLocation, renderProps) => {
    if (redirectLocation) {
      res.redirect(redirectLocation.pathname + redirectLocation.search);
    } else if (error) {
      console.error('ROUTER ERROR:', pretty.render(error));
      res.status(500);
      hydrateOnClient();
    } else if (renderProps) {
      const notFound = renderProps.routes.filter((route) => (route.path === '*' && route.status === 404));
      const pathLogin = renderProps.routes.filter((route) => (route.path === 'login'));
      if (pathLogin.length > 0) {
        console.log(renderProps.routes[0].path);
        res.clearCookie('token');
      }
      loadOnServer({...renderProps, store, helpers: { client }}).then(() => {
        const component = (
          <Provider store={store} key="provider">
            <ReduxAsyncConnect {...renderProps} />
          </Provider>
        );
        if (notFound.length > 0) {
          res.status(404);
        } else {
          res.status(200);
        }

        global.navigator = { userAgent: req.headers['user-agent'] };

        res.send('<!doctype html>\n' +
          ReactDOM.renderToString(<Html assets={webpackIsomorphicTools.assets() } component={component} store={store}/>));
      });
    } else {
      res.status(404).send('Not found');
    }
  });
});

if (config.port) {
  server.listen(config.port, (err) => {
    if (err) {
      console.error(err);
    }
    console.info('----\n==> ✅  %s is running, talking to API server', config.app.title);
    console.info('==> 💻  Open http://%s:%s in a browser to view the app.', config.host, config.port);
  });
} else {
  console.error('==>     ERROR: No PORT environment variable has been specified');
}
<|endoftext|>


<commit_before>'use strict';

var
	debug = require('debug')('bag-tracer:server'),
	express = require('express'),
	app = express();

var
	refreshRate = 30;

app.get('/:airline/:ref/:name', (req, res) => {

	trace(
		req.params.airline,
		req.params.ref,
		req.params.name,
		(output) => {
			res.send(`

				Refresh in
				${refreshRate}s

${output}

			`);
		}
	);
});

app.get('/ping/:airline/:ref/:name', (req, res) => {
	trace(
		req.params.airline,
		req.params.ref,
		req.params.name,
		(output) => {
			res.send(`<pre>${output}</pre><br>`);
		}
	);
});

if (require.main === module) {
	let server = app.listen(4000, () => {
		let
			host = server.address().address,
			port = server.address().port;

		debug('listening at http://%s:%s', host, port);
	});
}
<commit_msg>use a different port<commit_after>'use strict';

var
	debug = require('debug')('bag-tracer:server'),
	express = require('express'),
	app = express();

var
	refreshRate = 30;

app.get('/:airline/:ref/:name', (req, res) => {

	trace(
		req.params.airline,
		req.params.ref,
		req.params.name,
		(output) => {
			res.send(`

				Refresh in
				${refreshRate}s

${output}

			`);
		}
	);
});

app.get('/ping/:airline/:ref/:name', (req, res) => {
	trace(
		req.params.airline,
		req.params.ref,
		req.params.name,
		(output) => {
			res.send(`<pre>${output}</pre><br>`);
		}
	);
});

if (require.main === module) {
	let server = app.listen(8080, () => {
		let
			host = server.address().address,
			port = server.address().port;

		debug('listening at http://%s:%s', host, port);
	});
}
<|endoftext|>


<commit_before>/*
 * SimpleJS v0.0.1
 *
 * Copyright (c) 2012 Tyler O'Brien
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * */

/*
 * AJAX fallback for IE6.
 * Might not work for IE5 and earlier.
 * */
if (typeof XMLHttpRequest === 'undefined') {
	var XMLHttpRequest = function() {
		return new ActiveXObject('Microsoft.XMLHTTP');
	};
	XMLHttpRequest.prototype.isActiveX = true;
} else {
	XMLHttpRequest.prototype.isActiveX = false;
}

/*
 * send_s() returns nothing
 * Input: Object
    * A "safe" version of XMLHttpRequest.send().
	* Is compatible with both ActiveX-based AJAX and otherwise.
    * */
XMLHttpRequest.prototype.send_s = function(args) {
	if (typeof args === 'undefined' || args === null) {
		if (this.isActiveX) this.send();
		else this.send(null);
	} else if ('method' in args && 'queryString' in args && args.method === 'POST') {
		this.send(args.queryString);
	} else {
		this.send_s();
	}
}

/*
 * decodeQueryString() returns Object
 * Input: nothing
    * Converts the string to an Object that represents a query string.
    * Example format:
      * ?id=42&email=foo@bar.com&type=helloworld
    * */
String.prototype.decodeQueryString = function() {
	var buffer;
	var queryString = this.replace('+', ' ');
	var regex = /[?&]?([^&=]+)=?([^&]+)?/g;
	var result = {};

	while (buffer = regex.exec(queryString)) {
		result[decodeURIComponent(buffer[1])] = decodeURIComponent(buffer[2]);
	}

	return result;
};

var Simple = {
	AJAX: function(args) {
		var ajaxRequest = new Simple.AJAXRequest(args);

		ajaxRequest.http.open(ajaxRequest.method, ajaxRequest.urlToOpen, true);
		ajaxRequest.http.setRequestHeader('Content-type', ajaxRequest.contentType+'; charset='+ajaxRequest.charset);

		if (ajaxRequest.method === 'POST') {
			ajaxRequest.http.setRequestHeader('Content-length', ajaxRequest.queryString.length);
			ajaxRequest.http.setRequestHeader('Connection', 'close');
		}

		ajaxRequest.http.onreadystatechange = function(){
			switch (ajaxRequest.http.readyState) {
				case 1:
					ajaxRequest.timeBegin = new Date().getTime();
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onConnect);
				break;
				case 2:
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onRequest);
				break;
				case 3:
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onProcess);
				break;
				case 4:
					if (typeof ajaxRequest.timeout !== 'undefined') {
						clearTimeout(ajaxRequest.timeout);
					}

					ajaxRequest.timeEnd = new Date().getTime();
					ajaxRequest.timeDifference = (ajaxRequest.timeEnd - ajaxRequest.timeBegin);

					switch (ajaxRequest.http.status) {
						case 200:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onSuccess, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
						break;
						case 404:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onNotFound, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
						default:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onError, ajaxRequest.http.status, ajaxRequest.timeDifference);
						break;
					}
				break;
			}
		};

		/*
		 * Add a new timeout if one is given.
		 * The time is assumed to be milliseconds.
		 * */
		if ('timeout' in args && args['timeout'] === true) {
			ajaxRequest.timeout = setTimeout(function() {
				ajaxRequest.http.abort();
				Simple.AJAXHandler.CallIfExists(ajaxRequest.onTimeout);
			}, args['timeout']);
		}

		ajaxRequest.http.send_s(ajaxRequest);
	},

	/*
	 * AJAXHandler
	 * This object contains boilerplate functions that help organise the code of Simple AJAX.
	 * These probably won't need to be used outside of the AjaxRequest constructor function.
	 * Note:
		* These functions are also where the default values are assigned.
	 * */
	AJAXHandler: {
		/*
		 * CallIfExists() returns nothing
		 * Input: Function, Mixed, Mixed
			* Takes a callback, and up to two optional parameters.
			* Depending on the number of parameters given will make one of three different calls.
			* */
		CallIfExists: function(callback, param1, param2) {
			if (typeof callback === 'function') {
				if (typeof param2 !== 'undefined') callback(param1, param2);
				else if (typeof param1 !== 'undefined') callback(param1);
				else callback();
			}
		},

		/*
		 * GetCarset() returns String
		 * Input: String
			* Takes a passed object, assumed String.
			* If NULL or UNDEFINED is passed then a default value is returned.
			* Otherwise the passed value is returned back.
			* */
		GetCharset: function(charset) {
			return (typeof charset === 'string') ? charset : 'utf-8';
		},

		/*
		 * GetContentType() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetContentType: function(contentType) {
			return (typeof contentType === 'string') ? contentType : 'application/x-www-form-urlencoded';
		},

		/*
		 * GetMethod() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetMethod: function(method) {
			return (typeof method === 'string') ? method : 'GET';
		},

		/*
		 * GetQueryString() returns String
		 * Input: Object
		 * Takes an object of (key=>value) pairs and converts them to a query string.
		 * For example:
			* The object {a:1,b:2,c:3} would become "a=1&b=2&c=3".
			* Note that the question mark is not appended to the beginning.
		 * */
		GetQueryString: function(data) {
			var output = '';

			if (typeof data !== 'undefined') {
				var output = '';

				for (var key in data) {
					output = (output + key +'='+ data[key] + '&');
				}

				// Trim off the extra ampersand.
				output = output.substring(0, output.length-1);
			}

			return output;
		},

		/*
		 * GetUrl() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetUrl: function(url) {
			return (typeof url === 'string') ? url : '/';
		},

		/*
		 * GetUrlToOpen() returns String
		 * Input: String, String, String
			* Returns the value that will be passed to the XMLHttpRequest.open() function.
			* If the method is a GET it will be the entire URL, as well as the query string.
			* If the method is a POST then it will only be the query string.
			* */
		GetUrlToOpen: function(url, queryString, method) {
			return (method === 'POST') ? url : (url + '?' + queryString);
		}
	},

	AJAXRequest: function(args) {
		this.charset = Simple.AJAXHandler.GetCharset(args['charset']);
		this.contentType = Simple.AJAXHandler.GetContentType(args['contentType']);
		this.http = new XMLHttpRequest();
		this.method = Simple.AJAXHandler.GetMethod(args['method']);
		this.onConnect = args['onConnect'];
		this.onError = args['onError'];
		this.onNotFound = args['onNotFound'];
		this.onProcess = args['onProcess'];
		this.onRequest = args['onRequest'];
		this.onSuccess = args['onSuccess'];
		this.onTimeout = args['onTimeout'];
		this.queryString = Simple.AJAXHandler.GetQueryString(args['data']);
		this.timeBegin = 0;
		this.timeDifference = 0;
		this.timeEnd = 0;
		this.timeout = null;
		this.url = Simple.AJAXHandler.GetUrl(args['url']);
		this.urlToOpen = Simple.AJAXHandler.GetUrlToOpen(this.url, this.queryString, this.method);
	},

	Cookie: {
		data: {},

		DoUpdateData: function() {
			this.data = {};

			var arr = document.cookie.split('; ');
			var buffer = null;
			var cookie = null;
			var regex = /([^=]+)=(.*)/;

			Simple.Each(arr, function(){
				cookie = regex.exec(this);
				Simple.Cookie.data[escape(cookie[1])] = escape(cookie[2]);
			});
		},

		Get: function(name) {
			if (this.data === null) {
				this.DoUpdateData();
			}
			return Simple.Cookie.data[name];
		},

		Set: function(name, value, expiration) {
			document.cookie = (name+'='+value+';') + (expiration ? ' expires=0;' : '');
			this.DoUpdateData();
		}
	},

	/*
	 * Each() returns nothing
	 * Input: Array|Object, Function
	    *
	    * */
	Each: function (haystack, callback) {
		if (typeof haystack !== 'undefined' && haystack !== null) {
			var iterator = {
				i: null,
				parent: haystack,
				value: null
			};
			if (haystack.forEach !== undefined) {
				var end = haystack.length;
				for (var i = 0; i < end; i++) {
					iterator.value = haystack[i];
					if (callback.call(iterator.value, iterator) === false) {
						break;
					}
				}
			} else {
				for (iterator.i in haystack) {
					iterator.value = haystack[iterator.i];
					if (callback.call(iterator.value, iterator) === false) {
						break;
					}
				}
			}
		}
	},

	/*
	 * Equals() returns Boolean
	 * Input: Mixed, Mixed
	    * Compares each element of both passed objects, checking for strict equality.
	    * */
	Equals: function(first, second) {
		var result = true;

		Simple.Each(first, function(itr) {
			if (itr.value !== second[itr.index]) {
				return result = false;
			}
		});

		return result;
	},

	/*
	 * Exists() returns Mixed
	 * Input: Mixed, Mixed, Boolean
	    *
	    * */
	Exists: function(value, override, doReturnBoolean) {
		var output;

		if (typeof value !== 'undefined') {
			output = value;
		} else if (typeof doReturnBoolean !== 'undefined' && doReturnBoolean === true) {
			output = false;
		} else {
			output = override;
		}

		return output;
	},

	DOM: {
		callbacks: [], // The array of each callback function to be called when the DOM is ready.
		isReady: false, // This boolean is used to ensure that DOM.OnReady is only called once.

		/*
		 * OnDOMContentLoaded() returns Nothing
		 * Input: Nothing
		    * The function called by the event listeners.
		    * Because of the legacy event listener this may be called twice.
		    * */
		OnDOMContentLoaded: function() {
			if (typeof document.addEventListener !== 'undefined') {
				document.removeEventListener('DOMContentLoaded', Simple.DOM.OnDOMContentLoaded, false);
				Simple.DOM.OnReady();
			} else if (typeof document.attachEvent !== 'undefined' && document.readyState === 'complete' && document.body !== null) {
				document.detachEvent('onreadystatechange', Simple.DOM.OnDOMContentLoaded);
				Simple.DOM.OnReady();
			}
		},

		/*
		 * OnReady() returns Nothing
		 * Input: Nothing
		    * The function called when the DOM has finished loading/is ready.
		    * Uses a boolean to prevent multiple calls because it may be called twice by
		    * the event listener and legacy event listener.
		    * */
		OnReady: function() {
			if (Simple.DOM.isReady === false) {
				if (Simple.DOM.callbacks.length > 0) {
					Simple.Each(Simple.DOM.callbacks, function(){
						this.call(null);
					});
				}
				Simple.DOM.isReady = true;
			}
		},

		/*
		 * WhenReady() returns Nothing
		 * Input: Function
		    * Adds the passed callback to the array of callbacks that are called when
		    * the DOM is ready.
		    * */
		WhenReady: function(callback) {
			if (Simple.DOM.isReady === false) {
				Simple.DOM.callbacks.push(callback);
			}
		}
	},

	GET: document.location.search.decodeQueryString()
};

Simple.Cookie.DoUpdateData();

if (typeof document.addEventListener !== 'undefined') {
	document.addEventListener('DOMContentLoaded', Simple.DOM.OnDOMContentLoaded, false);
	window.addEventListener('load', Simple.DOM.OnReady, false);
} else if (typeof document.attachEvent !== 'undefined') {
	document.attachEvent('onreadystatechange', Simple.DOM.OnDOMContentLoaded);
	window.attachEvent('onload', Simple.DOM.OnReady, false);
} else {
	window.onload = Simple.DOM.OnReady;
}<commit_msg>Adjusted various comments<commit_after>/*
 * SimpleJS v0.0.1
 *
 * Copyright (c) 2012 Tyler O'Brien
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * */

/*
 * AJAX fallback for IE6.
 * Might not work for IE5 and earlier.
 * */
if (typeof XMLHttpRequest === 'undefined') {
	var XMLHttpRequest = function() {
		return new ActiveXObject('Microsoft.XMLHTTP');
	};
	XMLHttpRequest.prototype.isActiveX = true;
} else {
	XMLHttpRequest.prototype.isActiveX = false;
}

/*
 * send_s() returns Nothing
 * Input: Object
    * A "safe" version of XMLHttpRequest.send().
	* Is compatible with both ActiveX-based AJAX and otherwise.
    * */
XMLHttpRequest.prototype.send_s = function(args) {
	if (typeof args === 'undefined' || args === null) {
		if (this.isActiveX) this.send();
		else this.send(null);
	} else if ('method' in args && 'queryString' in args && args.method === 'POST') {
		this.send(args.queryString);
	} else {
		this.send_s();
	}
}

/*
 * decodeQueryString() returns Object
 * Input: Nothing
    * Converts the string to an Object that represents a query string.
    * Example format:
      * ?id=42&email=foo@bar.com&type=helloworld
    * */
String.prototype.decodeQueryString = function() {
	var buffer;
	var queryString = this.replace('+', ' ');
	var regex = /[?&]?([^&=]+)=?([^&]+)?/g;
	var result = {};

	while (buffer = regex.exec(queryString)) {
		result[decodeURIComponent(buffer[1])] = decodeURIComponent(buffer[2]);
	}

	return result;
};

var Simple = {
	AJAX: function(args) {
		var ajaxRequest = new Simple.AJAXRequest(args);

		ajaxRequest.http.open(ajaxRequest.method, ajaxRequest.urlToOpen, true);
		ajaxRequest.http.setRequestHeader('Content-type', ajaxRequest.contentType+'; charset='+ajaxRequest.charset);

		if (ajaxRequest.method === 'POST') {
			ajaxRequest.http.setRequestHeader('Content-length', ajaxRequest.queryString.length);
			ajaxRequest.http.setRequestHeader('Connection', 'close');
		}

		ajaxRequest.http.onreadystatechange = function(){
			switch (ajaxRequest.http.readyState) {
				case 1:
					ajaxRequest.timeBegin = new Date().getTime();
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onConnect);
				break;
				case 2:
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onRequest);
				break;
				case 3:
					Simple.AJAXHandler.CallIfExists(ajaxRequest.onProcess);
				break;
				case 4:
					if (typeof ajaxRequest.timeout !== 'undefined') {
						clearTimeout(ajaxRequest.timeout);
					}

					ajaxRequest.timeEnd = new Date().getTime();
					ajaxRequest.timeDifference = (ajaxRequest.timeEnd - ajaxRequest.timeBegin);

					switch (ajaxRequest.http.status) {
						case 200:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onSuccess, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
						break;
						case 404:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onNotFound, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
						default:
							Simple.AJAXHandler.CallIfExists(ajaxRequest.onError, ajaxRequest.http.status, ajaxRequest.timeDifference);
						break;
					}
				break;
			}
		};

		/*
		 * Add a new timeout if one is given.
		 * The time is assumed to be milliseconds.
		 * */
		if ('timeout' in args && args['timeout'] === true) {
			ajaxRequest.timeout = setTimeout(function() {
				ajaxRequest.http.abort();
				Simple.AJAXHandler.CallIfExists(ajaxRequest.onTimeout);
			}, args['timeout']);
		}

		ajaxRequest.http.send_s(ajaxRequest);
	},

	/*
	 * AJAXHandler
	 * This object contains boilerplate functions that help organise the code of Simple AJAX.
	 * These probably won't need to be used outside of the AjaxRequest constructor function.
	 * Note:
		* These functions are also where the default values are assigned.
	 * */
	AJAXHandler: {
		/*
		 * CallIfExists() returns Nothing
		 * Input: Function, Mixed, Mixed
			* Takes a callback, and up to two optional parameters.
			* Depending on the number of parameters given will make one of three different calls.
			* */
		CallIfExists: function(callback, param1, param2) {
			if (typeof callback === 'function') {
				if (typeof param2 !== 'undefined') callback(param1, param2);
				else if (typeof param1 !== 'undefined') callback(param1);
				else callback();
			}
		},

		/*
		 * GetCarset() returns String
		 * Input: String
			* Takes a passed object, assumed String.
			* If NULL or UNDEFINED is passed then a default value is returned.
			* Otherwise the passed value is returned back.
			* */
		GetCharset: function(charset) {
			return (typeof charset === 'string') ? charset : 'utf-8';
		},

		/*
		 * GetContentType() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetContentType: function(contentType) {
			return (typeof contentType === 'string') ? contentType : 'application/x-www-form-urlencoded';
		},

		/*
		 * GetMethod() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetMethod: function(method) {
			return (typeof method === 'string') ? method : 'GET';
		},

		/*
		 * GetQueryString() returns String
		 * Input: Object
		 * Takes an object of (key=>value) pairs and converts them to a query string.
		 * For example:
			* The object {a:1,b:2,c:3} would become "a=1&b=2&c=3".
			* Note that the question mark is not appended to the beginning.
		 * */
		GetQueryString: function(data) {
			var output = '';

			if (typeof data !== 'undefined') {
				var output = '';

				for (var key in data) {
					output = (output + key +'='+ data[key] + '&');
				}

				// Trim off the extra ampersand.
				output = output.substring(0, output.length-1);
			}

			return output;
		},

		/*
		 * GetUrl() returns String
		 * Input: String
			* See GetCharset().
			* */
		GetUrl: function(url) {
			return (typeof url === 'string') ? url : '/';
		},

		/*
		 * GetUrlToOpen() returns String
		 * Input: String, String, String
			* Returns the value that will be passed to the XMLHttpRequest.open() function.
			* If the method is a GET it will be the entire URL, as well as the query string.
			* If the method is a POST then it will only be the query string.
			* */
		GetUrlToOpen: function(url, queryString, method) {
			return (method === 'POST') ? url : (url + '?' + queryString);
		}
	},

	AJAXRequest: function(args) {
		this.charset = Simple.AJAXHandler.GetCharset(args['charset']);
		this.contentType = Simple.AJAXHandler.GetContentType(args['contentType']);
		this.http = new XMLHttpRequest();
		this.method = Simple.AJAXHandler.GetMethod(args['method']);
		this.onConnect = args['onConnect'];
		this.onError = args['onError'];
		this.onNotFound = args['onNotFound'];
		this.onProcess = args['onProcess'];
		this.onRequest = args['onRequest'];
		this.onSuccess = args['onSuccess'];
		this.onTimeout = args['onTimeout'];
		this.queryString = Simple.AJAXHandler.GetQueryString(args['data']);
		this.timeBegin = 0;
		this.timeDifference = 0;
		this.timeEnd = 0;
		this.timeout = null;
		this.url = Simple.AJAXHandler.GetUrl(args['url']);
		this.urlToOpen = Simple.AJAXHandler.GetUrlToOpen(this.url, this.queryString, this.method);
	},

	Cookie: {
		data: {},

		DoUpdateData: function() {
			this.data = {};

			var arr = document.cookie.split('; ');
			var buffer = null;
			var cookie = null;
			var regex = /([^=]+)=(.*)/;

			Simple.Each(arr, function(){
				cookie = regex.exec(this);
				Simple.Cookie.data[escape(cookie[1])] = escape(cookie[2]);
			});
		},

		Get: function(name) {
			if (this.data === null) {
				this.DoUpdateData();
			}
			return Simple.Cookie.data[name];
		},

		Set: function(name, value, expiration) {
			document.cookie = (name+'='+value+';') + (expiration ? ' expires=0;' : '');
			this.DoUpdateData();
		}
	},

	/*
	 * Each() returns Nothing
	 * Input: Array|Object, Function
	    *
	    * */
	Each: function (haystack, callback) {
		if (typeof haystack !== 'undefined' && haystack !== null) {
			var iterator = {
				i: null,
				parent: haystack,
				value: null
			};
			if (haystack.forEach !== undefined) {
				var end = haystack.length;
				for (var i = 0; i < end; i++) {
					iterator.value = haystack[i];
					if (callback.call(iterator.value, iterator) === false) {
						break;
					}
				}
			} else {
				for (iterator.i in haystack) {
					iterator.value = haystack[iterator.i];
					if (callback.call(iterator.value, iterator) === false) {
						break;
					}
				}
			}
		}
	},

	/*
	 * Equals() returns Boolean
	 * Input: Mixed, Mixed
	    * Compares each element of both passed objects, checking for strict equality.
	    * */
	Equals: function(first, second) {
		var result = true;

		Simple.Each(first, function(itr) {
			if (itr.value !== second[itr.index]) {
				return result = false;
			}
		});

		return result;
	},

	/*
	 * Exists() returns Mixed
	 * Input: Mixed, Mixed, Boolean
	    *
	    * */
	Exists: function(value, override, doReturnBoolean) {
		var output;

		if (typeof value !== 'undefined') {
			output = value;
		} else if (typeof doReturnBoolean !== 'undefined' && doReturnBoolean === true) {
			output = false;
		} else {
			output = override;
		}

		return output;
	},

	DOM: {
		callbacks: [], // The array of each callback function to be called when the DOM is ready.
		isReady: false, // This boolean is used to ensure that DOM.OnReady is only called once.

		/*
		 * OnDOMContentLoaded() returns Nothing
		 * Input: Nothing
		    * The function called by the event listeners.
		    * Because of the legacy event listener this may be called twice.
		    * */
		OnDOMContentLoaded: function() {
			if (typeof document.addEventListener !== 'undefined') {
				document.removeEventListener('DOMContentLoaded', Simple.DOM.OnDOMContentLoaded, false);
				Simple.DOM.OnReady();
			} else if (typeof document.attachEvent !== 'undefined' && document.readyState === 'complete' && document.body !== null) {
				document.detachEvent('onreadystatechange', Simple.DOM.OnDOMContentLoaded);
				Simple.DOM.OnReady();
			}
		},

		/*
		 * OnReady() returns Nothing
		 * Input: Nothing
		    * The function called when the DOM has finished loading/is ready.
		    * Uses a boolean to prevent multiple calls because it may be called twice by
		    * the event listener and legacy event listener.
		    * */
		OnReady: function() {
			if (Simple.DOM.isReady === false) {
				if (Simple.DOM.callbacks.length > 0) {
					Simple.Each(Simple.DOM.callbacks, function(){
						this.call(null);
					});
				}
				Simple.DOM.isReady = true;
			}
		},

		/*
		 * WhenReady() returns Nothing
		 * Input: Function
		    * Adds the passed callback to the array of callbacks that are called when
		    * the DOM is ready.
		    * */
		WhenReady: function(callback) {
			if (Simple.DOM.isReady === false) {
				Simple.DOM.callbacks.push(callback);
			}
		}
	},

	GET: document.location.search.decodeQueryString()
};

Simple.Cookie.DoUpdateData();

if (typeof document.addEventListener !== 'undefined') {
	document.addEventListener('DOMContentLoaded', Simple.DOM.OnDOMContentLoaded, false);
	window.addEventListener('load', Simple.DOM.OnReady, false);
} else if (typeof document.attachEvent !== 'undefined') {
	document.attachEvent('onreadystatechange', Simple.DOM.OnDOMContentLoaded);
	window.attachEvent('onload', Simple.DOM.OnReady, false);
} else {
	window.onload = Simple.DOM.OnReady;
}<|endoftext|>


<commit_before>/**@
* #Sprite
* @category Graphics
* Component for using tiles in a sprite map.
*/
Crafty.c("Sprite", {
	__image: '',
	__tile: 0,
	__tileh: 0,
	__padding: null,
	__trim: null,
	img: null,
	ready: false,

	init: function() {
		this.__trim = [0,0,0,0];

		var draw = function(e) {
			var co = e.co,
				pos = e.pos,
				context = e.ctx;

			if(e.type === "canvas") {
				//draw the image on the canvas element
				context.drawImage(this.img, //image element
								 co.x, //x position on sprite
								 co.y, //y position on sprite
								 co.w, //width on sprite
								 co.h, //height on sprite
								 pos._x, //x position on canvas
								 pos._y, //y position on canvas
								 pos._w, //width on canvas
								 pos._h //height on canvas
				);
			} else if(e.type === "DOM") {
				this._element.style.background = "url('" + this.__image + "') no-repeat -" + co.x + "px -" + co.y + "px";
			}
		};

		this.bind("Draw", draw).bind("RemoveComponent", function(id) {
			if(id === pos) this.unbind("Draw", draw);
		});
	},

	/**@
	* #.sprite
	* @comp Sprite
	* @sign public this .sprite(Number x, Number y, Number w, Number h)
	* @param x - X cell position
	* @param y - Y cell position
	* @param w - Width in cells
	* @param h - Height in cells
	* Uses a new location on the sprite map as its sprite.
	*
	* Values should be in tiles or cells (not pixels).
	*/
	sprite: function(x,y,w,h) {
		this.__coord = [x * this.__tile + this.__padding[0] + this.__trim[0],
						y * this.__tileh + this.__padding[1] + this.__trim[1],
						this.__trim[2] || w * this.__tile || this.__tile,
						this.__trim[3] || h * this.__tileh || this.__tileh];

		this.trigger("Change");
		return this;
	},

	/**@
	* #.crop
	* @comp Sprite
	* @sign public this .crop(Number x, Number y, Number w, Number h)
	* @param x - Offset x position
	* @param y - Offset y position
	* @param w - New width
	* @param h - New height
	* If the entity needs to be smaller than the tile size, use this method to crop it.
	*
	* The values should be in pixels rather than tiles.
	*/
	crop: function(x,y,w,h) {
		var old = this._mbr || this.pos();
		this.__trim = [];
		this.__trim[0] = x;
		this.__trim[1] = y;
		this.__trim[2] = w;
		this.__trim[3] = h;

		this.__coord[0] += x;
		this.__coord[1] += y;
		this.__coord[2] = w;
		this.__coord[3] = h;
		this._w = w;
		this._h = h;

		this.trigger("Change", old);
		return this;
	},
});<commit_msg>Internet Explorer throws an error on 'pos' not being defined. I guess that there should be "Sprite" instead "pos"<commit_after>/**@
* #Sprite
* @category Graphics
* Component for using tiles in a sprite map.
*/
Crafty.c("Sprite", {
	__image: '',
	__tile: 0,
	__tileh: 0,
	__padding: null,
	__trim: null,
	img: null,
	ready: false,

	init: function() {
		this.__trim = [0,0,0,0];

		var draw = function(e) {
			var co = e.co,
				pos = e.pos,
				context = e.ctx;

			if(e.type === "canvas") {
				//draw the image on the canvas element
				context.drawImage(this.img, //image element
								 co.x, //x position on sprite
								 co.y, //y position on sprite
								 co.w, //width on sprite
								 co.h, //height on sprite
								 pos._x, //x position on canvas
								 pos._y, //y position on canvas
								 pos._w, //width on canvas
								 pos._h //height on canvas
				);
			} else if(e.type === "DOM") {
				this._element.style.background = "url('" + this.__image + "') no-repeat -" + co.x + "px -" + co.y + "px";
			}
		};

		this.bind("Draw", draw).bind("RemoveComponent", function(id) {
			if(id === "Sprite") this.unbind("Draw", draw);
		});
	},

	/**@
	* #.sprite
	* @comp Sprite
	* @sign public this .sprite(Number x, Number y, Number w, Number h)
	* @param x - X cell position
	* @param y - Y cell position
	* @param w - Width in cells
	* @param h - Height in cells
	* Uses a new location on the sprite map as its sprite.
	*
	* Values should be in tiles or cells (not pixels).
	*/
	sprite: function(x,y,w,h) {
		this.__coord = [x * this.__tile + this.__padding[0] + this.__trim[0],
						y * this.__tileh + this.__padding[1] + this.__trim[1],
						this.__trim[2] || w * this.__tile || this.__tile,
						this.__trim[3] || h * this.__tileh || this.__tileh];

		this.trigger("Change");
		return this;
	},

	/**@
	* #.crop
	* @comp Sprite
	* @sign public this .crop(Number x, Number y, Number w, Number h)
	* @param x - Offset x position
	* @param y - Offset y position
	* @param w - New width
	* @param h - New height
	* If the entity needs to be smaller than the tile size, use this method to crop it.
	*
	* The values should be in pixels rather than tiles.
	*/
	crop: function(x,y,w,h) {
		var old = this._mbr || this.pos();
		this.__trim = [];
		this.__trim[0] = x;
		this.__trim[1] = y;
		this.__trim[2] = w;
		this.__trim[3] = h;

		this.__coord[0] += x;
		this.__coord[1] += y;
		this.__coord[2] = w;
		this.__coord[3] = h;
		this._w = w;
		this._h = h;

		this.trigger("Change", old);
		return this;
	},
});<|endoftext|>


<commit_before>
// Extends the Channel class with support
// for Node.js streams.

var Channel = require('./channel');
var stream = require('stream');

// Non-deterministic behaviour if you create multiple
// writable streams on a single channel.
Channel.prototype.asWritableStream = function () {
    var writable = new stream.Writable();
    var chan = this;
    writable._write = function (chunk, encoding, done) {
        chan.put(chunk, done);
    };
    return writable;
};

// Non-deterministic behaviour if you make multiple readable streams
// on the same channel. If you want to fan out a channel to multiple
// readable streams, then use Channel.prototype.tap() to tap a channel
// without disrupting its dataflow.
Channel.prototype.asReadableStream = function () {
    var readable = new stream.Readable();

    var chan = this;

    readable._read = function () {
        chan.take(receiver);
    };

    function receiver(err, value) {
        readable.push(value);
    }

    return readable;
};

module.exports = Channel;
<commit_msg>Added .read(readable) and .write(writable) methods to channel<commit_after>
// Extends the Channel class with support
// for Node.js streams.

var Channel = require('./channel');
var stream = require('stream');

// Non-deterministic behaviour if you create multiple
// writable streams on a single channel.
Channel.prototype.asWritableStream = function () {
    var writable = new stream.Writable();
    var chan = this;
    writable._write = function (chunk, encoding, done) {
        chan.put(chunk, done);
    };
    return writable;
};

// Non-deterministic behaviour if you make multiple readable streams
// on the same channel. If you want to fan out a channel to multiple
// readable streams, then use Channel.prototype.tap() to tap a channel
// without disrupting its dataflow.
Channel.prototype.asReadableStream = function () {
    var readable = new stream.Readable();

    var chan = this;

    readable._read = function () {
        chan.take(receiver);
    };

    function receiver(err, value) {
        readable.push(value);
    }

    return readable;
};

// Simple piping function for continuously reading from
// a readable stream.
Channel.prototype.read = function (readable) {
    readable.pipe(this.asWritableStream());
    return this;
};

// Simple piping function for continuously writing to
// a writable stream.
Channel.prototype.write = function (writable) {
    this.asReadableStream().pipe(writable);
    return this;
};

module.exports = Channel;
<|endoftext|>


<commit_before>import get from 'lodash-es/get';
import has from 'lodash-es/has';
import merge from 'lodash-es/merge';
import template from 'lodash-es/template';
import AbstractFormat from './abstract';

export default class StringFormat extends AbstractFormat {
  constructor(i18n) {
    super(i18n);
    this._data = {};
  }

  data(data) {
    merge(this._data, data);
  }

  format(value, values, locale) {
    value = this.get(value, locale) || value;
    values = values || {};

    value = typeof value === 'object' ?
      value[values.number] || value.d || null :
      value;

    return template(value, {
      interpolate: /{([\s\S]+?)}/g
    })(values);
  }

  get(value, locale) {
    locale = locale || this._i18n.locale();
    const [language] = locale.split('_');

    if (has(this._data, locale + '.' + value)) {
      return get(this._data, locale + '.' + value);
    } else if (has(this._data, language + '.' + value)) {
      return get(this._data, language + '.' + value);
    }

    return null;
  }
}
<commit_msg>Use index instead of number when formatting string<commit_after>import get from 'lodash-es/get';
import has from 'lodash-es/has';
import merge from 'lodash-es/merge';
import template from 'lodash-es/template';
import AbstractFormat from './abstract';

export default class StringFormat extends AbstractFormat {
  constructor(i18n) {
    super(i18n);
    this._data = {};
  }

  data(data) {
    merge(this._data, data);
    return this;
  }

  format(value, values, locale) {
    value = this.get(value, locale) || value;
    values = values || {};

    value = typeof value === 'object' ?
      value[values.index] || value.d || null :
      value;

    return template(value, {
      interpolate: /{([\s\S]+?)}/g
    })(values);
  }

  get(value, locale) {
    locale = locale || this._i18n.locale();
    const [language] = locale.split('_');

    if (has(this._data, locale + '.' + value)) {
      return get(this._data, locale + '.' + value);
    } else if (has(this._data, language + '.' + value)) {
      return get(this._data, language + '.' + value);
    }

    return null;
  }
}
<|endoftext|>


<commit_before>/**
 * SVGoban
 * styles.js
 *
 */

/**
 * Chosen constants for a top left radial gradient
 */
var SV_GRAD = {
    "cx" : "50%",
    "cy" : "45%",
    "r"  : "60%",
    "fx" : "10%",
    "fy" : "10%"
}

var SV_BW = {
    "black": {
	"start" : "rgb(75,75,75)",
	"stop"  : "rgb(0,0,0)"
    },
    "white": {
	"start" : "rgb(255,255,255)",
	"stop"  : "rgb(180,180,180)"
    }
};

exports.defineRadialColors = function(color) {
    var gradient =  {cx:SV_GRAD.cx, cy:SV_GRAD.cy, r:SV_GRAD.r, fx:SV_GRAD.fx, fy:SV_GRAD.fy};
    return {id:color+"grad", a:SV_BW[color]["start"], z:SV_BW[color]["stop"], gradient:gradient};
}

/**
 * Themes are just CSS rules
 */
exports.Themes = {
    "classic" : function() {
	return `
	    .wood {
		fill: #b4916c;
	    }
	    .placeholder {
		stroke: black;
		opacity: 0
	    }
    	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: url(#blackgrad);
	    }
	    .whitestone {
		fill: url(#whitegrad);
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: sans-serif;
	    font-size: 1.1em;
	}
	`;
    },
    "night" : function() {
	return `
	    .wood {
		fill: #425b5b;
	    }
	    .placeholder {
		fill: black;
		stroke: black;
		opacity: 0
	    }
	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: #222222;
	    }
	    .whitestone {
		fill: #888888;
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: sans-serif;
	    font-size: 1.1em;
	}
	`;
    },
    "paper" : function() {
	return `
	    .wood {
		fill: white;
	    }
	    .placeholder {
		fill: black;
		stroke: black;
		opacity: 0
	    }
	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: black;
		stroke: black;
	    }
	    .whitestone {
		fill: white;
		stroke: black;
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: sans-serif;
	    font-size: 1.1em;
	}
	`;
    }
}

<commit_msg>Add Ubuntu Light font<commit_after>/**
 * SVGoban
 * styles.js
 *
 */

/**
 * Chosen constants for a top left radial gradient
 */
var SV_GRAD = {
    "cx" : "50%",
    "cy" : "45%",
    "r"  : "60%",
    "fx" : "10%",
    "fy" : "10%"
}

var SV_BW = {
    "black": {
	"start" : "rgb(75,75,75)",
	"stop"  : "rgb(0,0,0)"
    },
    "white": {
	"start" : "rgb(255,255,255)",
	"stop"  : "rgb(180,180,180)"
    }
};

exports.defineRadialColors = function(color) {
    var gradient =  {cx:SV_GRAD.cx, cy:SV_GRAD.cy, r:SV_GRAD.r, fx:SV_GRAD.fx, fy:SV_GRAD.fy};
    return {id:color+"grad", a:SV_BW[color]["start"], z:SV_BW[color]["stop"], gradient:gradient};
}

/**
 * Themes are just CSS rules
 */
exports.Themes = {
    "classic" : function() {
	return `
	    .wood {
		fill: #b4916c;
	    }
	    .placeholder {
		stroke: black;
		opacity: 0
	    }
    	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: url(#blackgrad);
	    }
	    .whitestone {
		fill: url(#whitegrad);
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: "Ubuntu Light", sans-serif;
	    font-size: 1.1em;
	}
	`;
    },
    "night" : function() {
	return `
	    .wood {
		fill: #425b5b;
	    }
	    .placeholder {
		fill: black;
		stroke: black;
		opacity: 0
	    }
	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: #222222;
	    }
	    .whitestone {
		fill: #888888;
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: sans-serif;
	    font-size: 1.1em;
	}
	`;
    },
    "paper" : function() {
	return `
	    .wood {
		fill: white;
	    }
	    .placeholder {
		fill: black;
		stroke: black;
		opacity: 0
	    }
	    .black .placeholder:hover {
		fill: black;
		stroke: black;
		opacity: 0.2
	    }
	    .white .placeholder:hover {
		fill: white;
		stroke: white;
		opacity: 0.2
	    }
	    .blackstone {
		fill: black;
		stroke: black;
	    }
	    .whitestone {
		fill: white;
		stroke: black;
	    }
	line {
	    stroke: black;
	}
	text {
	    font-family: sans-serif;
	    font-size: 1.1em;
	}
	`;
    }
}

<|endoftext|>


<commit_before>import knex from 'knex';
import PromiseAsyncCache from 'promise-async-cache';
import * as knexTenantSupport from './knex-tenant-support';

const debug = require('./debug')('tenant');

/**
 * Defines whenever the tenant monkey patch on knex has been installed
 */
let isMultiTenantSupportInstalled = false;

/**
 * Keep knex tenants in memory and handle race conditions
 */
const cache = new PromiseAsyncCache({
  /**
   * Build knex tenant and load it to the cache
   * @param tenantId
   */
  async load (tenantId, baseKnex) {
    if (!isMultiTenantSupportInstalled) {
      try {
        debug('installing knextancy');
        knexTenantSupport.install();
        isMultiTenantSupportInstalled = true;
      } catch (err) {
        debug('Error installing knex multi tenant support', err.stack || err);
        throw err;
      }
    }

    debug('building knex for new tenant %d', tenantId);
    const proxyKnex = knex(knexTenantSupport.buildConfig(baseKnex.client.config, tenantId));

    Object.defineProperty(proxyKnex, 'tenantId', {
      get: function() {
        return this.client.tenantId;
      },
    });

    debug('initializing multi tenant database');
    debug('running migration tasks');
    await proxyKnex.migrate.latest();

    debug('running seed tasks');
    await proxyKnex.seed.run();

    return proxyKnex;
  },
});

export default async function (baseKnex, tenantId) {
  try {
    return cache.get(tenantId, baseKnex);
  } catch (err) {
    debug('Error on initializing the multi tenant database', err.stack || err);
    throw err;
  }
}
<commit_msg>Remove useless doc<commit_after>import knex from 'knex';
import PromiseAsyncCache from 'promise-async-cache';
import * as knexTenantSupport from './knex-tenant-support';

const debug = require('./debug')('tenant');

/**
 * Defines whenever the tenant monkey patch on knex has been installed
 */
let isMultiTenantSupportInstalled = false;

/**
 * Keep knex tenants in memory and handle race conditions
 */
const cache = new PromiseAsyncCache({
  /**
   * Build knex tenant and load it to the cache
   */
  async load (tenantId, baseKnex) {
    if (!isMultiTenantSupportInstalled) {
      try {
        debug('installing knextancy');
        knexTenantSupport.install();
        isMultiTenantSupportInstalled = true;
      } catch (err) {
        debug('Error installing knex multi tenant support', err.stack || err);
        throw err;
      }
    }

    debug('building knex for new tenant %d', tenantId);
    const proxyKnex = knex(knexTenantSupport.buildConfig(baseKnex.client.config, tenantId));

    Object.defineProperty(proxyKnex, 'tenantId', {
      get: function() {
        return this.client.tenantId;
      },
    });

    debug('initializing multi tenant database');
    debug('running migration tasks');
    await proxyKnex.migrate.latest();

    debug('running seed tasks');
    await proxyKnex.seed.run();

    return proxyKnex;
  },
});

export default async function (baseKnex, tenantId) {
  try {
    return cache.get(tenantId, baseKnex);
  } catch (err) {
    debug('Error on initializing the multi tenant database', err.stack || err);
    throw err;
  }
}
<|endoftext|>