<commit_before>var expect = require('chai').expect;
var util = require('./util');
var fs = require('fs');
var path = require('path');

var http2 = require('../lib/http');
var https = require('https');

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

var options = {
  key: fs.readFileSync(path.join(__dirname, '../example/localhost.key')),
  cert: fs.readFileSync(path.join(__dirname, '../example/localhost.crt')),
  log: util.log
};

http2.globalAgent = new http2.Agent({ log: util.log });

describe('http.js', function() {
  describe('Server', function() {
    describe('new Server(options)', function() {
      it('should throw if called without \'plain\' or TLS options', function() {
        expect(function() {
          new http2.Server();
        }).to.throw(Error);
      });
    });
    describe('property `timeout`', function() {
      it('should be a proxy for the backing HTTPS server\'s `timeout` property', function() {
        var server = new http2.Server(options);
        var backingServer = server._server;
        var newTimeout = 10;
        server.timeout = newTimeout;
        expect(server.timeout).to.be.equal(newTimeout);
        expect(backingServer.timeout).to.be.equal(newTimeout);
      });
    });
  });
  describe('Agent', function() {
    describe('property `maxSockets`', function() {
      it('should be a proxy for the backing HTTPS agent\'s `maxSockets` property', function() {
        var agent = new http2.Agent({ log: util.log });
        var backingAgent = agent._httpsAgent;
        var newMaxSockets = backingAgent.maxSockets + 1;
        agent.maxSockets = newMaxSockets;
        expect(agent.maxSockets).to.be.equal(newMaxSockets);
        expect(backingAgent.maxSockets).to.be.equal(newMaxSockets);
      });
    });
  });
  describe('test scenario', function() {
    describe('simple request', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1234, function() {
          http2.get('https://localhost:1234' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
        });
      });
    });
    describe('request with payload', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          request.once('readable', function() {
            expect(request.read().toString()).to.equal(message);
            response.end();
          });
        });

        server.listen(1240, function() {
          var request = http2.request({
            host: 'localhost',
            port: 1240,
            path: path
          });
          request.write(message);
          request.end();
          request.on('response', function() {
            server.close();
            done();
          });
        });
      });
    });
    describe('request with custom headers', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';
        var headerName = 'name';
        var headerValue = 'value';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          expect(request.headers[headerName]).to.equal(headerValue);
          response.setHeader(headerName, headerValue);
          expect(response.getHeader(headerName)).to.equal(headerValue);
          response.setHeader('nonexistent', 'x');
          response.removeHeader('nonexistent');
          expect(response.getHeader('nonexistent')).to.equal(undefined);
          response.end(message);
        });

        server.listen(1239, function() {
          var headers = {};
          headers[headerName] = headerValue;
          var request = http2.request({
            host: 'localhost',
            port: 1239,
            path: path,
            headers: headers
          });
          request.end();
          request.on('response', function(response) {
            expect(response.headers[headerName]).to.equal(headerValue);
            expect(response.headers['nonexistent']).to.equal(undefined);
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
        });
      });
    });
    describe('request over plain TCP', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer({
          plain: true,
          log: util.log
        }, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1237, function() {
          var request = http2.request({
            plain: true,
            host: 'localhost',
            port: 1237,
            path: path
          }, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
          request.end();
        });
      });
    });
    describe('request to an HTTPS/1 server', function() {
      it('should fall back to HTTPS/1 successfully', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = https.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(5678, function() {
          http2.get('https://localhost:5678' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('HTTPS/1 request to a HTTP/2 server', function() {
      it('should fall back to HTTPS/1 successfully', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1236, function() {
          https.get('https://localhost:1236' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('two parallel request', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1237, function() {
          done = util.callNTimes(2, done);
          // 1. request
          http2.get('https://localhost:1237' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
          // 2. request
          http2.get('https://localhost:1237' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('two subsequent request', function() {
      it('should use the same HTTP/2 connection', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1238, function() {
          // 1. request
          http2.get('https://localhost:1238' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);

              // 2. request
              http2.get('https://localhost:1238' + path, function(response) {
                response.on('readable', function() {
                  expect(response.read().toString()).to.equal(message);
                  done();
                });
              });
            });
          });
        });
      });
    });
    describe('server push', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';
        var pushedPath = '/y';
        var pushedMessage = 'Hello world 2';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          var push = response.push('/y');
          push.end(pushedMessage);
          response.end(message);
        });

        server.listen(1235, function() {
          var request = http2.get('https://localhost:1235' + path);
          done = util.callNTimes(4, done);

          request.on('response', function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
            response.on('end', done);
          });

          request.on('push', function(promise) {
            expect(promise.url).to.be.equal(pushedPath);
            promise.on('response', function(pushStream) {
              pushStream.on('readable', function() {
                expect(pushStream.read().toString()).to.equal(pushedMessage);
                done();
              });
              pushStream.on('end', done);
            });
          });
        });
      });
    });
  });
});
<commit_msg>HTTP tests: adding test for using agent for http: URIs<commit_after>var expect = require('chai').expect;
var util = require('./util');
var fs = require('fs');
var path = require('path');

var http2 = require('../lib/http');
var https = require('https');

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

var options = {
  key: fs.readFileSync(path.join(__dirname, '../example/localhost.key')),
  cert: fs.readFileSync(path.join(__dirname, '../example/localhost.crt')),
  log: util.log
};

http2.globalAgent = new http2.Agent({ log: util.log });

describe('http.js', function() {
  describe('Server', function() {
    describe('new Server(options)', function() {
      it('should throw if called without \'plain\' or TLS options', function() {
        expect(function() {
          new http2.Server();
        }).to.throw(Error);
      });
    });
    describe('property `timeout`', function() {
      it('should be a proxy for the backing HTTPS server\'s `timeout` property', function() {
        var server = new http2.Server(options);
        var backingServer = server._server;
        var newTimeout = 10;
        server.timeout = newTimeout;
        expect(server.timeout).to.be.equal(newTimeout);
        expect(backingServer.timeout).to.be.equal(newTimeout);
      });
    });
  });
  describe('Agent', function() {
    describe('property `maxSockets`', function() {
      it('should be a proxy for the backing HTTPS agent\'s `maxSockets` property', function() {
        var agent = new http2.Agent({ log: util.log });
        var backingAgent = agent._httpsAgent;
        var newMaxSockets = backingAgent.maxSockets + 1;
        agent.maxSockets = newMaxSockets;
        expect(agent.maxSockets).to.be.equal(newMaxSockets);
        expect(backingAgent.maxSockets).to.be.equal(newMaxSockets);
      });
    });
    describe('method `request(options, [callback])`', function() {
      it('should throw when trying to use with \'http\' scheme', function() {
        expect(function() {
          var agent = new http2.Agent({ log: util.log });
          agent.request({ protocol: 'http:' });
        }).to.throw(Error);
      });
    });
  });
  describe('test scenario', function() {
    describe('simple request', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1234, function() {
          http2.get('https://localhost:1234' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
        });
      });
    });
    describe('request with payload', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          request.once('readable', function() {
            expect(request.read().toString()).to.equal(message);
            response.end();
          });
        });

        server.listen(1240, function() {
          var request = http2.request({
            host: 'localhost',
            port: 1240,
            path: path
          });
          request.write(message);
          request.end();
          request.on('response', function() {
            server.close();
            done();
          });
        });
      });
    });
    describe('request with custom headers', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';
        var headerName = 'name';
        var headerValue = 'value';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          expect(request.headers[headerName]).to.equal(headerValue);
          response.setHeader(headerName, headerValue);
          expect(response.getHeader(headerName)).to.equal(headerValue);
          response.setHeader('nonexistent', 'x');
          response.removeHeader('nonexistent');
          expect(response.getHeader('nonexistent')).to.equal(undefined);
          response.end(message);
        });

        server.listen(1239, function() {
          var headers = {};
          headers[headerName] = headerValue;
          var request = http2.request({
            host: 'localhost',
            port: 1239,
            path: path,
            headers: headers
          });
          request.end();
          request.on('response', function(response) {
            expect(response.headers[headerName]).to.equal(headerValue);
            expect(response.headers['nonexistent']).to.equal(undefined);
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
        });
      });
    });
    describe('request over plain TCP', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer({
          plain: true,
          log: util.log
        }, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1237, function() {
          var request = http2.request({
            plain: true,
            host: 'localhost',
            port: 1237,
            path: path
          }, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              server.close();
              done();
            });
          });
          request.end();
        });
      });
    });
    describe('request to an HTTPS/1 server', function() {
      it('should fall back to HTTPS/1 successfully', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = https.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(5678, function() {
          http2.get('https://localhost:5678' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('HTTPS/1 request to a HTTP/2 server', function() {
      it('should fall back to HTTPS/1 successfully', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1236, function() {
          https.get('https://localhost:1236' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('two parallel request', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1237, function() {
          done = util.callNTimes(2, done);
          // 1. request
          http2.get('https://localhost:1237' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
          // 2. request
          http2.get('https://localhost:1237' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
          });
        });
      });
    });
    describe('two subsequent request', function() {
      it('should use the same HTTP/2 connection', function(done) {
        var path = '/x';
        var message = 'Hello world';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          response.end(message);
        });

        server.listen(1238, function() {
          // 1. request
          http2.get('https://localhost:1238' + path, function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);

              // 2. request
              http2.get('https://localhost:1238' + path, function(response) {
                response.on('readable', function() {
                  expect(response.read().toString()).to.equal(message);
                  done();
                });
              });
            });
          });
        });
      });
    });
    describe('server push', function() {
      it('should work as expected', function(done) {
        var path = '/x';
        var message = 'Hello world';
        var pushedPath = '/y';
        var pushedMessage = 'Hello world 2';

        var server = http2.createServer(options, function(request, response) {
          expect(request.url).to.equal(path);
          var push = response.push('/y');
          push.end(pushedMessage);
          response.end(message);
        });

        server.listen(1235, function() {
          var request = http2.get('https://localhost:1235' + path);
          done = util.callNTimes(4, done);

          request.on('response', function(response) {
            response.on('readable', function() {
              expect(response.read().toString()).to.equal(message);
              done();
            });
            response.on('end', done);
          });

          request.on('push', function(promise) {
            expect(promise.url).to.be.equal(pushedPath);
            promise.on('response', function(pushStream) {
              pushStream.on('readable', function() {
                expect(pushStream.read().toString()).to.equal(pushedMessage);
                done();
              });
              pushStream.on('end', done);
            });
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>/**
 * Created by rulkens on 16/09/15.
 */
<commit_msg>test API<commit_after>/**
 front-end api for interacting with the actions
 **/

module.exports = Api;

function Api (){

}

Api.call = call;
Api.actions = actions;

function call (action, arguments){
    try {

    }
}

/**
 * get a list of actions
 */
function actions (){

}<|endoftext|>


<commit_before>'use strict';

require('../lib/bootstrap-local');

const validateCommitMessage = require('./validate-commit-message');
const execSync = require('child_process').execSync;
const chalk = require('chalk');
const Logger = require('@ngtools/logger').Logger;
require('rxjs/add/operator/filter');

// Configure logger
const logger = new Logger('test-commit-messages');

logger.subscribe((entry) => {
  let color = chalk.white;
  let output = process.stdout;
  switch (entry.level) {
    case 'info': color = chalk.white; break;
    case 'warn': color = chalk.yellow; break;
    case 'error': color = chalk.red; output = process.stderr; break;
    case 'fatal': color = (x) => chalk.bold(chalk.red(x)); output = process.stderr; break;
  }

  output.write(color(entry.message) + '\n');
});

logger
  .filter((entry) => entry.level === 'fatal')
  .subscribe(() => {
    process.stderr.write('A fatal error happened. See details above.');
    process.exit(1);
  });

// Note: This is based on the gulp task found in the angular/angular repository
execSync('git fetch origin');
// Travis doesn't have master when running jobs on other branches (minor/patch/etc).
execSync('git fetch origin master:master --force');

// Get PR target branch, default to master for running locally.
const currentBranch = process.env.TRAVIS_BRANCH
  || process.env.APPVEYOR_REPO_BRANCH
  || 'master';

const output = execSync('git log ' + currentBranch + '..HEAD --reverse --format="%H %s" --no-merges', {
  encoding: 'utf-8'
});

if (output.length === 0) {
  logger.warn('There are zero new commits between this HEAD and master');
  process.exit(0);
}
const commitsByLine = output.trim().split(/\n/).map(line => {
  return line.trim().split(' ').slice(1).join(' ');
});
logger.info(`Examining ${commitsByLine.length} commit(s) between HEAD and master`);

const someCommitsInvalid = !commitsByLine.every(message => validateCommitMessage(message));

if (someCommitsInvalid) {
  logger.error('Please fix the failing commit messages before continuing...');
  logger.fatal(
    'Commit message guidelines: https://github.com/angular/angular-cli/blob/master/CONTRIBUTING.md#commit');
} else {
  logger.info('All commit messages are valid.');
}
<commit_msg>ci: fix fetching master into master<commit_after>'use strict';

require('../lib/bootstrap-local');

const validateCommitMessage = require('./validate-commit-message');
const execSync = require('child_process').execSync;
const chalk = require('chalk');
const Logger = require('@ngtools/logger').Logger;
require('rxjs/add/operator/filter');

// Configure logger
const logger = new Logger('test-commit-messages');

logger.subscribe((entry) => {
  let color = chalk.white;
  let output = process.stdout;
  switch (entry.level) {
    case 'info': color = chalk.white; break;
    case 'warn': color = chalk.yellow; break;
    case 'error': color = chalk.red; output = process.stderr; break;
    case 'fatal': color = (x) => chalk.bold(chalk.red(x)); output = process.stderr; break;
  }

  output.write(color(entry.message) + '\n');
});

logger
  .filter((entry) => entry.level === 'fatal')
  .subscribe(() => {
    process.stderr.write('A fatal error happened. See details above.');
    process.exit(1);
  });

// Note: This is based on the gulp task found in the angular/angular repository
execSync('git fetch origin');

// Get PR target branch, default to master for running locally.
const currentBranch = process.env.TRAVIS_BRANCH
  || process.env.APPVEYOR_REPO_BRANCH
  || 'master';

if (currentBranch !== 'master') {
  // Travis doesn't have master when running jobs on other branches (minor/patch/etc).
  execSync('git fetch origin master:master --force');
}

const output = execSync('git log ' + currentBranch + '..HEAD --reverse --format="%H %s" --no-merges', {
  encoding: 'utf-8'
});

if (output.length === 0) {
  logger.warn('There are zero new commits between this HEAD and master');
  process.exit(0);
}
const commitsByLine = output.trim().split(/\n/).map(line => {
  return line.trim().split(' ').slice(1).join(' ');
});
logger.info(`Examining ${commitsByLine.length} commit(s) between HEAD and master`);

const someCommitsInvalid = !commitsByLine.every(message => validateCommitMessage(message));

if (someCommitsInvalid) {
  logger.error('Please fix the failing commit messages before continuing...');
  logger.fatal(
    'Commit message guidelines: https://github.com/angular/angular-cli/blob/master/CONTRIBUTING.md#commit');
} else {
  logger.info('All commit messages are valid.');
}
<|endoftext|>


<commit_before>
// Reference to the root of the Firebase database
var database = new Firebase("https://conquiz.firebaseio.com/");
// Reference to the google sheets of questions
var questionsLink = "https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK";
var questions;

$("#upload").click(function() { // If the user clicks on the input with the id="upload"
	var name = $("#nameInput").val();
	var text = $("#messageInput").val();
	if (name.length != 0 && text.length != 0) { // Don't upload if there's no information in the textboxes
		console.log(name.length);
		console.log(text.length);

		database.push({name: name, text: text}); // Push the data onto the database

	}else { // warns user of their empty textbox
		console.log("Please input values into the textbox");
	}
});

// Get an update once the database has new data
database.on('child_added', function(update) {
	questions = update.val();

	console.log("Successfully retrieve questions from database.");
});

// database.on("child_added", function(update) { // Get an update once the database has new data
// 			console.log("Callback function: New data has been added to the database");
// 			var message = update.val();
// 			displayUpdate(message.name, message.text);
// });

function displayUpdate(name, text) {
	$("<div/>").text(text).prepend($("<em/>").text(name+": ")).appendTo($("#messageDiv"));
	$("#messageDiv")[0].scrollTop = $("#messageDiv")[0].scrollHeight;
};

console.log('LOADED BACKEND');<commit_msg>trying to update database<commit_after>
// Reference to the root of the Firebase database
var database = new Firebase("https://conquiz.firebaseio.com/");
// Reference to the google sheets of questions
var questionsLink = "https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK";
var questions;

$("#upload").click(function() { // If the user clicks on the input with the id="upload"
	var name = $("#nameInput").val();
	var text = $("#messageInput").val();
	if (name.length != 0 && text.length != 0) { // Don't upload if there's no information in the textboxes
		console.log(name.length);
		console.log(text.length);

		database.push({name: name, text: text}); // Push the data onto the database

	}else { // warns user of their empty textbox
		console.log("Please input values into the textbox");
	}
});

// Get an update once the database has new data
// database.on('child_added', function(update) {
// 	questions = update.val();

// 	console.log("Successfully retrieve questions from database.");
// });

// database.on("child_added", function(update) { // Get an update once the database has new data
// 			console.log("Callback function: New data has been added to the database");
// 			var message = update.val();
// 			displayUpdate(message.name, message.text);
// });

function displayUpdate(name, text) {
	$("<div/>").text(text).prepend($("<em/>").text(name+": ")).appendTo($("#messageDiv"));
	$("#messageDiv")[0].scrollTop = $("#messageDiv")[0].scrollHeight;
};

// One time push to update the questions on firebase
function updateDatabase() {
	$.ajax({
		url: 'https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK',
		success: function(data) {
			console.log("success");
			questions = data;
			console.log(data);
		},
		onError: function() {
			console.log("Error");
		}
	});
	// $.getJSON('https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK', function(data) {
	// 	questions = data;
	// });
}

updateDatabase();

console.log('LOADED BACKEND');<|endoftext|>


<commit_before>/**
 * Created by gannonhuiting on 4/25/16.
 */
process.env.NODE_ENV = 'test';

var http = require('http'),
    assert = require('assert'),
    fs = require('fs'),
    url = require('url'),
    config = require('../config/test'),
    host = config.host;

before(function() {
    // also, store the app globally
    global.app = require('./../bin/www');
});

describe('app tests', function() {

    it('app should exist', function() {
        assert.ok(app);
    });

    it('should be listening at ' + host, function(done){
        http.get(host, function(res) {
            console.log(res.statusCode)
            assert.equal(res.statusCode, 200);
            done();
        });
    });

    function testCodeAndTitle(url, statusCode, title)
    {
        it('should have status code: '+statusCode, function(done) {
            http.get(host + url,function(res){
                assert.equal(res.statusCode,statusCode);
                var body = "";
                res.on('data', function(data) {body += data;});
                res.on('end', function() {
                    assert.equal(res.statusCode, statusCode);
                    var resTitle = body.split("<title>")[1].split("</title>")[0];
                    assert.equal(resTitle,title);
                    done();
                });
                res.on('err', function(err){done(err);});
            });

        });
    }

    //all the routs that need to be tested
    [
        ['/challenge',200,"Challenge Page"],
        ['/scoreboard',200,"Scoreboard page"],
        ['/login',200,"Login"],
        ['/logout',200,""],
        ['/register',200,"Register Here"],
        ['/foobar',404,""],
        ['/',200, "Home Page"]
    ].forEach(function(spec){
        testCodeAndTitle(spec[0],spec[1],spec[2]);
    });

});<commit_msg>cleaned up what little there was<commit_after>/**
 * Created by gannonhuiting on 4/25/16.
 */
process.env.NODE_ENV = 'test';

var http = require('http'),
    assert = require('assert'),
    fs = require('fs'),
    url = require('url'),
    config = require('../config/test'),
    host = config.host;

before(function() {
    // also, store the app globally
    global.app = require('./../bin/www');
});

describe('app tests', function() {

    it('app should exist', function() {
        assert.ok(app);
    });

    //test to be sure the server is running.
    it('should be listening at ' + host, function(done){
        http.get(host, function(res) {
            console.log(res.statusCode)
            assert.equal(res.statusCode, 200);
            done();
        });
    });

    //test the function with the given code and title
    function testCodeAndTitle(url, statusCode, title)
    {
        it('should have status code: '+statusCode, function(done) {
            http.get(host + url,function(res){
                assert.equal(res.statusCode,statusCode);
                var body = "";
                res.on('data', function(data) {body += data;});
                res.on('end', function() {
                    assert.equal(res.statusCode, statusCode);
                    var resTitle = body.split("<title>")[1].split("</title>")[0];
                    assert.equal(resTitle,title);
                    done();
                });
                res.on('err', function(err){done(err);});
            });

        });
    }

    //all the routs that need to be tested
    [
        ['/challenge',200,"Challenge Page"],
        ['/scoreboard',200,"Scoreboard page"],
        ['/login',200,"Login"],
        ['/logout',200,""],
        ['/register',200,"Register Here"],
        ['/foobar',404,""],
        ['/',200, "Home Page"]
    ].forEach(function(spec){
        testCodeAndTitle(spec[0],spec[1],spec[2]);
    });

});<|endoftext|>


<commit_before>/**
 * The pie chart module of Chartist that can be used to draw pie, donut or gauge charts
 *
 * @module Chartist.Pie
 */
/* global Chartist */
(function(window, document, Chartist) {
  'use strict';

  /**
   * Default options in line charts. Expand the code view to see a detailed list of options with comments.
   *
   * @memberof Chartist.Pie
   */
  var defaultOptions = {
    // Specify a fixed width for the chart as a string (i.e. '100px' or '50%')
    width: undefined,
    // Specify a fixed height for the chart as a string (i.e. '100px' or '50%')
    height: undefined,
    // Padding of the chart drawing area to the container element and labels as a number or padding object {top: 5, right: 5, bottom: 5, left: 5}
    chartPadding: 5,
    // Override the class names that are used to generate the SVG structure of the chart
    classNames: {
      chart: 'ct-chart-pie',
      series: 'ct-series',
      slice: 'ct-slice',
      donut: 'ct-donut',
      label: 'ct-label'
    },
    // The start angle of the pie chart in degrees where 0 points north. A higher value offsets the start angle clockwise.
    startAngle: 0,
    // An optional total you can specify. By specifying a total value, the sum of the values in the series must be this total in order to draw a full pie. You can use this parameter to draw only parts of a pie or gauge charts.
    total: undefined,
    // If specified the donut CSS classes will be used and strokes will be drawn instead of pie slices.
    donut: false,
    // Specify the donut stroke width, currently done in javascript for convenience. May move to CSS styles in the future.
    donutWidth: 60,
    // If a label should be shown or not
    showLabel: true,
    // Label position offset from the standard position which is half distance of the radius. This value can be either positive or negative. Positive values will position the label away from the center.
    labelOffset: 0,
    // An interpolation function for the label value
    labelInterpolationFnc: Chartist.noop,
    // Label direction can be 'neutral', 'explode' or 'implode'. The labels anchor will be positioned based on those settings as well as the fact if the labels are on the right or left side of the center of the chart. Usually explode is useful when labels are positioned far away from the center.
    labelDirection: 'neutral',
    // If true the whole data is reversed including labels, the series order as well as the whole series data arrays.
    reverseData: false
  };

  /**
   * Determines SVG anchor position based on direction and center parameter
   *
   * @param center
   * @param label
   * @param direction
   * @return {string}
   */
  function determineAnchorPosition(center, label, direction) {
    var toTheRight = label.x > center.x;

    if(toTheRight && direction === 'explode' ||
      !toTheRight && direction === 'implode') {
      return 'start';
    } else if(toTheRight && direction === 'implode' ||
      !toTheRight && direction === 'explode') {
      return 'end';
    } else {
      return 'middle';
    }
  }

  /**
   * Creates the pie chart
   *
   * @param options
   */
  function createChart(options) {
    var seriesGroups = [],
      chartRect,
      radius,
      labelRadius,
      totalDataSum,
      startAngle = options.startAngle,
      dataArray = Chartist.getDataArray(this.data, options.reverseData);

    // Create SVG.js draw
    this.svg = Chartist.createSvg(this.container, options.width, options.height, options.classNames.chart);
    // Calculate charting rect
    chartRect = Chartist.createChartRect(this.svg, options, defaultOptions.padding);
    // Get biggest circle radius possible within chartRect
    radius = Math.min(chartRect.width() / 2, chartRect.height() / 2);
    // Calculate total of all series to get reference value or use total reference from optional options
    totalDataSum = options.total || dataArray.reduce(function(previousValue, currentValue) {
      return previousValue + currentValue;
    }, 0);

    // If this is a donut chart we need to adjust our radius to enable strokes to be drawn inside
    // Unfortunately this is not possible with the current SVG Spec
    // See this proposal for more details: http://lists.w3.org/Archives/Public/www-svg/2003Oct/0000.html
    radius -= options.donut ? options.donutWidth / 2  : 0;

    // If a donut chart then the label position is at the radius, if regular pie chart it's half of the radius
    // see https://github.com/gionkunz/chartist-js/issues/21
    labelRadius = options.donut ? radius : radius / 2;
    // Add the offset to the labelRadius where a negative offset means closed to the center of the chart
    labelRadius += options.labelOffset;

    // Calculate end angle based on total sum and current data value and offset with padding
    var center = {
      x: chartRect.x1 + chartRect.width() / 2,
      y: chartRect.y2 + chartRect.height() / 2
    };

    // Check if there is only one non-zero value in the series array.
    var hasSingleValInSeries = this.data.series.filter(function(val) {
      return val.hasOwnProperty('value') ? val.value !== 0 : val !== 0;
    }).length === 1;

    // Draw the series
    // initialize series groups
    for (var i = 0; i < this.data.series.length; i++) {
      seriesGroups[i] = this.svg.elem('g', null, null, true);

      // If the series is an object and contains a name or meta data we add a custom attribute
      seriesGroups[i].attr({
        'series-name': this.data.series[i].name,
        'meta': Chartist.serialize(this.data.series[i].meta)
      }, Chartist.xmlNs.uri);

      // Use series class from series data or if not set generate one
      seriesGroups[i].addClass([
        options.classNames.series,
        (this.data.series[i].className || options.classNames.series + '-' + Chartist.alphaNumerate(i))
      ].join(' '));

      var endAngle = startAngle + dataArray[i] / totalDataSum * 360;
      // If we need to draw the arc for all 360 degrees we need to add a hack where we close the circle
      // with Z and use 359.99 degrees
      if(endAngle - startAngle === 360) {
        endAngle -= 0.01;
      }

      var start = Chartist.polarToCartesian(center.x, center.y, radius, startAngle - (i === 0 || hasSingleValInSeries ? 0 : 0.2)),
        end = Chartist.polarToCartesian(center.x, center.y, radius, endAngle);

      // Create a new path element for the pie chart. If this isn't a donut chart we should close the path for a correct stroke
      var path = new Chartist.Svg.Path(!options.donut)
        .move(end.x, end.y)
        .arc(radius, radius, 0, endAngle - startAngle > 180, 0, start.x, start.y);

      // If regular pie chart (no donut) we add a line to the center of the circle for completing the pie
      if(!options.donut) {
        path.line(center.x, center.y);
      }

      // Create the SVG path
      // If this is a donut chart we add the donut class, otherwise just a regular slice
      var pathElement = seriesGroups[i].elem('path', {
        d: path.stringify()
      }, options.classNames.slice + (options.donut ? ' ' + options.classNames.donut : ''));

      // Adding the pie series value to the path
      pathElement.attr({
        'value': dataArray[i]
      }, Chartist.xmlNs.uri);

      // If this is a donut, we add the stroke-width as style attribute
      if(options.donut) {
        pathElement.attr({
          'style': 'stroke-width: ' + (+options.donutWidth) + 'px'
        });
      }

      // Fire off draw event
      this.eventEmitter.emit('draw', {
        type: 'slice',
        value: dataArray[i],
        totalDataSum: totalDataSum,
        index: i,
        group: seriesGroups[i],
        element: pathElement,
        path: path.clone(),
        center: center,
        radius: radius,
        startAngle: startAngle,
        endAngle: endAngle
      });

      // If we need to show labels we need to add the label for this slice now
      if(options.showLabel) {
        // Position at the labelRadius distance from center and between start and end angle
        var labelPosition = Chartist.polarToCartesian(center.x, center.y, labelRadius, startAngle + (endAngle - startAngle) / 2),
          interpolatedValue = options.labelInterpolationFnc(this.data.labels ? this.data.labels[i] : dataArray[i], i);

        var labelElement = seriesGroups[i].elem('text', {
          dx: labelPosition.x,
          dy: labelPosition.y,
          'text-anchor': determineAnchorPosition(center, labelPosition, options.labelDirection)
        }, options.classNames.label).text('' + interpolatedValue);

        // Fire off draw event
        this.eventEmitter.emit('draw', {
          type: 'label',
          index: i,
          group: seriesGroups[i],
          element: labelElement,
          text: '' + interpolatedValue,
          x: labelPosition.x,
          y: labelPosition.y
        });
      }

      // Set next startAngle to current endAngle. Use slight offset so there are no transparent hairline issues
      // (except for last slice)
      startAngle = endAngle;
    }

    this.eventEmitter.emit('created', {
      chartRect: chartRect,
      svg: this.svg,
      options: options
    });
  }

  /**
   * This method creates a new pie chart and returns an object that can be used to redraw the chart.
   *
   * @memberof Chartist.Pie
   * @param {String|Node} query A selector query string or directly a DOM element
   * @param {Object} data The data object in the pie chart needs to have a series property with a one dimensional data array. The values will be normalized against each other and don't necessarily need to be in percentage. The series property can also be an array of value objects that contain a value property and a className property to override the CSS class name for the series group.
   * @param {Object} [options] The options object with options that override the default options. Check the examples for a detailed list.
   * @param {Array} [responsiveOptions] Specify an array of responsive option arrays which are a media query and options object pair => [[mediaQueryString, optionsObject],[more...]]
   * @return {Object} An object with a version and an update method to manually redraw the chart
   *
   * @example
   * // Simple pie chart example with four series
   * new Chartist.Pie('.ct-chart', {
   *   series: [10, 2, 4, 3]
   * });
   *
   * @example
   * // Drawing a donut chart
   * new Chartist.Pie('.ct-chart', {
   *   series: [10, 2, 4, 3]
   * }, {
   *   donut: true
   * });
   *
   * @example
   * // Using donut, startAngle and total to draw a gauge chart
   * new Chartist.Pie('.ct-chart', {
   *   series: [20, 10, 30, 40]
   * }, {
   *   donut: true,
   *   donutWidth: 20,
   *   startAngle: 270,
   *   total: 200
   * });
   *
   * @example
   * // Drawing a pie chart with padding and labels that are outside the pie
   * new Chartist.Pie('.ct-chart', {
   *   series: [20, 10, 30, 40]
   * }, {
   *   chartPadding: 30,
   *   labelOffset: 50,
   *   labelDirection: 'explode'
   * });
   *
   * @example
   * // Overriding the class names for individual series and include meta data
   * new Chartist.Pie('.ct-chart', {
   *   series: [{
   *     value: 20,
   *     className: 'my-custom-class-one',
   *     meta: 'Meta One'
   *   }, {
   *     value: 10,
   *     className: 'my-custom-class-two',
   *     meta: 'Meta Two'
   *   }, {
   *     value: 70,
   *     className: 'my-custom-class-three',
   *     meta: 'Meta Three'
   *   }]
   * });
   */
  function Pie(query, data, options, responsiveOptions) {
    Chartist.Pie.super.constructor.call(this,
      query,
      data,
      defaultOptions,
      Chartist.extend({}, defaultOptions, options),
      responsiveOptions);
  }

  // Creating pie chart type in Chartist namespace
  Chartist.Pie = Chartist.Base.extend({
    constructor: Pie,
    createChart: createChart,
    determineAnchorPosition: determineAnchorPosition
  });

}(window, document, Chartist));
<commit_msg>Added some more example documentation to Pie<commit_after>/**
 * The pie chart module of Chartist that can be used to draw pie, donut or gauge charts
 *
 * @module Chartist.Pie
 */
/* global Chartist */
(function(window, document, Chartist) {
  'use strict';

  /**
   * Default options in line charts. Expand the code view to see a detailed list of options with comments.
   *
   * @memberof Chartist.Pie
   */
  var defaultOptions = {
    // Specify a fixed width for the chart as a string (i.e. '100px' or '50%')
    width: undefined,
    // Specify a fixed height for the chart as a string (i.e. '100px' or '50%')
    height: undefined,
    // Padding of the chart drawing area to the container element and labels as a number or padding object {top: 5, right: 5, bottom: 5, left: 5}
    chartPadding: 5,
    // Override the class names that are used to generate the SVG structure of the chart
    classNames: {
      chart: 'ct-chart-pie',
      series: 'ct-series',
      slice: 'ct-slice',
      donut: 'ct-donut',
      label: 'ct-label'
    },
    // The start angle of the pie chart in degrees where 0 points north. A higher value offsets the start angle clockwise.
    startAngle: 0,
    // An optional total you can specify. By specifying a total value, the sum of the values in the series must be this total in order to draw a full pie. You can use this parameter to draw only parts of a pie or gauge charts.
    total: undefined,
    // If specified the donut CSS classes will be used and strokes will be drawn instead of pie slices.
    donut: false,
    // Specify the donut stroke width, currently done in javascript for convenience. May move to CSS styles in the future.
    donutWidth: 60,
    // If a label should be shown or not
    showLabel: true,
    // Label position offset from the standard position which is half distance of the radius. This value can be either positive or negative. Positive values will position the label away from the center.
    labelOffset: 0,
    // An interpolation function for the label value
    labelInterpolationFnc: Chartist.noop,
    // Label direction can be 'neutral', 'explode' or 'implode'. The labels anchor will be positioned based on those settings as well as the fact if the labels are on the right or left side of the center of the chart. Usually explode is useful when labels are positioned far away from the center.
    labelDirection: 'neutral',
    // If true the whole data is reversed including labels, the series order as well as the whole series data arrays.
    reverseData: false
  };

  /**
   * Determines SVG anchor position based on direction and center parameter
   *
   * @param center
   * @param label
   * @param direction
   * @return {string}
   */
  function determineAnchorPosition(center, label, direction) {
    var toTheRight = label.x > center.x;

    if(toTheRight && direction === 'explode' ||
      !toTheRight && direction === 'implode') {
      return 'start';
    } else if(toTheRight && direction === 'implode' ||
      !toTheRight && direction === 'explode') {
      return 'end';
    } else {
      return 'middle';
    }
  }

  /**
   * Creates the pie chart
   *
   * @param options
   */
  function createChart(options) {
    var seriesGroups = [],
      chartRect,
      radius,
      labelRadius,
      totalDataSum,
      startAngle = options.startAngle,
      dataArray = Chartist.getDataArray(this.data, options.reverseData);

    // Create SVG.js draw
    this.svg = Chartist.createSvg(this.container, options.width, options.height, options.classNames.chart);
    // Calculate charting rect
    chartRect = Chartist.createChartRect(this.svg, options, defaultOptions.padding);
    // Get biggest circle radius possible within chartRect
    radius = Math.min(chartRect.width() / 2, chartRect.height() / 2);
    // Calculate total of all series to get reference value or use total reference from optional options
    totalDataSum = options.total || dataArray.reduce(function(previousValue, currentValue) {
      return previousValue + currentValue;
    }, 0);

    // If this is a donut chart we need to adjust our radius to enable strokes to be drawn inside
    // Unfortunately this is not possible with the current SVG Spec
    // See this proposal for more details: http://lists.w3.org/Archives/Public/www-svg/2003Oct/0000.html
    radius -= options.donut ? options.donutWidth / 2  : 0;

    // If a donut chart then the label position is at the radius, if regular pie chart it's half of the radius
    // see https://github.com/gionkunz/chartist-js/issues/21
    labelRadius = options.donut ? radius : radius / 2;
    // Add the offset to the labelRadius where a negative offset means closed to the center of the chart
    labelRadius += options.labelOffset;

    // Calculate end angle based on total sum and current data value and offset with padding
    var center = {
      x: chartRect.x1 + chartRect.width() / 2,
      y: chartRect.y2 + chartRect.height() / 2
    };

    // Check if there is only one non-zero value in the series array.
    var hasSingleValInSeries = this.data.series.filter(function(val) {
      return val.hasOwnProperty('value') ? val.value !== 0 : val !== 0;
    }).length === 1;

    // Draw the series
    // initialize series groups
    for (var i = 0; i < this.data.series.length; i++) {
      seriesGroups[i] = this.svg.elem('g', null, null, true);

      // If the series is an object and contains a name or meta data we add a custom attribute
      seriesGroups[i].attr({
        'series-name': this.data.series[i].name,
        'meta': Chartist.serialize(this.data.series[i].meta)
      }, Chartist.xmlNs.uri);

      // Use series class from series data or if not set generate one
      seriesGroups[i].addClass([
        options.classNames.series,
        (this.data.series[i].className || options.classNames.series + '-' + Chartist.alphaNumerate(i))
      ].join(' '));

      var endAngle = startAngle + dataArray[i] / totalDataSum * 360;
      // If we need to draw the arc for all 360 degrees we need to add a hack where we close the circle
      // with Z and use 359.99 degrees
      if(endAngle - startAngle === 360) {
        endAngle -= 0.01;
      }

      var start = Chartist.polarToCartesian(center.x, center.y, radius, startAngle - (i === 0 || hasSingleValInSeries ? 0 : 0.2)),
        end = Chartist.polarToCartesian(center.x, center.y, radius, endAngle);

      // Create a new path element for the pie chart. If this isn't a donut chart we should close the path for a correct stroke
      var path = new Chartist.Svg.Path(!options.donut)
        .move(end.x, end.y)
        .arc(radius, radius, 0, endAngle - startAngle > 180, 0, start.x, start.y);

      // If regular pie chart (no donut) we add a line to the center of the circle for completing the pie
      if(!options.donut) {
        path.line(center.x, center.y);
      }

      // Create the SVG path
      // If this is a donut chart we add the donut class, otherwise just a regular slice
      var pathElement = seriesGroups[i].elem('path', {
        d: path.stringify()
      }, options.classNames.slice + (options.donut ? ' ' + options.classNames.donut : ''));

      // Adding the pie series value to the path
      pathElement.attr({
        'value': dataArray[i]
      }, Chartist.xmlNs.uri);

      // If this is a donut, we add the stroke-width as style attribute
      if(options.donut) {
        pathElement.attr({
          'style': 'stroke-width: ' + (+options.donutWidth) + 'px'
        });
      }

      // Fire off draw event
      this.eventEmitter.emit('draw', {
        type: 'slice',
        value: dataArray[i],
        totalDataSum: totalDataSum,
        index: i,
        group: seriesGroups[i],
        element: pathElement,
        path: path.clone(),
        center: center,
        radius: radius,
        startAngle: startAngle,
        endAngle: endAngle
      });

      // If we need to show labels we need to add the label for this slice now
      if(options.showLabel) {
        // Position at the labelRadius distance from center and between start and end angle
        var labelPosition = Chartist.polarToCartesian(center.x, center.y, labelRadius, startAngle + (endAngle - startAngle) / 2),
          interpolatedValue = options.labelInterpolationFnc(this.data.labels ? this.data.labels[i] : dataArray[i], i);

        var labelElement = seriesGroups[i].elem('text', {
          dx: labelPosition.x,
          dy: labelPosition.y,
          'text-anchor': determineAnchorPosition(center, labelPosition, options.labelDirection)
        }, options.classNames.label).text('' + interpolatedValue);

        // Fire off draw event
        this.eventEmitter.emit('draw', {
          type: 'label',
          index: i,
          group: seriesGroups[i],
          element: labelElement,
          text: '' + interpolatedValue,
          x: labelPosition.x,
          y: labelPosition.y
        });
      }

      // Set next startAngle to current endAngle. Use slight offset so there are no transparent hairline issues
      // (except for last slice)
      startAngle = endAngle;
    }

    this.eventEmitter.emit('created', {
      chartRect: chartRect,
      svg: this.svg,
      options: options
    });
  }

  /**
   * This method creates a new pie chart and returns an object that can be used to redraw the chart.
   *
   * @memberof Chartist.Pie
   * @param {String|Node} query A selector query string or directly a DOM element
   * @param {Object} data The data object in the pie chart needs to have a series property with a one dimensional data array. The values will be normalized against each other and don't necessarily need to be in percentage. The series property can also be an array of value objects that contain a value property and a className property to override the CSS class name for the series group.
   * @param {Object} [options] The options object with options that override the default options. Check the examples for a detailed list.
   * @param {Array} [responsiveOptions] Specify an array of responsive option arrays which are a media query and options object pair => [[mediaQueryString, optionsObject],[more...]]
   * @return {Object} An object with a version and an update method to manually redraw the chart
   *
   * @example
   * // Simple pie chart example with four series
   * new Chartist.Pie('.ct-chart', {
   *   series: [10, 2, 4, 3]
   * });
   *
   * @example
   * // Drawing a donut chart
   * new Chartist.Pie('.ct-chart', {
   *   series: [10, 2, 4, 3]
   * }, {
   *   donut: true
   * });
   *
   * @example
   * // Using donut, startAngle and total to draw a gauge chart
   * new Chartist.Pie('.ct-chart', {
   *   series: [20, 10, 30, 40]
   * }, {
   *   donut: true,
   *   donutWidth: 20,
   *   startAngle: 270,
   *   total: 200
   * });
   *
   * @example
   * // Drawing a pie chart with padding and labels that are outside the pie
   * new Chartist.Pie('.ct-chart', {
   *   series: [20, 10, 30, 40]
   * }, {
   *   chartPadding: 30,
   *   labelOffset: 50,
   *   labelDirection: 'explode'
   * });
   *
   * @example
   * // Overriding the class names for individual series as well as a name and meta data.
   * // The name will be written as ct:series-name attribute and the meta data will be serialized and written
   * // to a ct:meta attribute.
   * new Chartist.Pie('.ct-chart', {
   *   series: [{
   *     value: 20,
   *     name: 'Series 1',
   *     className: 'my-custom-class-one',
   *     meta: 'Meta One'
   *   }, {
   *     value: 10,
   *     name: 'Series 2',
   *     className: 'my-custom-class-two',
   *     meta: 'Meta Two'
   *   }, {
   *     value: 70,
   *     name: 'Series 3',
   *     className: 'my-custom-class-three',
   *     meta: 'Meta Three'
   *   }]
   * });
   */
  function Pie(query, data, options, responsiveOptions) {
    Chartist.Pie.super.constructor.call(this,
      query,
      data,
      defaultOptions,
      Chartist.extend({}, defaultOptions, options),
      responsiveOptions);
  }

  // Creating pie chart type in Chartist namespace
  Chartist.Pie = Chartist.Base.extend({
    constructor: Pie,
    createChart: createChart,
    determineAnchorPosition: determineAnchorPosition
  });

}(window, document, Chartist));
<|endoftext|>


<commit_before>/* Configuration, database and crypto */
var config = require("./config"),
  db = require("./database"),
  crypto = require('crypto');

/* OAuth stuff */
var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
	GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
	TwitterStrategy = require('passport-twitter').Strategy,
	FacebookStrategy = require('passport-facebook').Strategy,
  LinkedInStrategy = require('passport-linkedin').Strategy,
  GitHubStrategy = require('passport-github').Strategy;

/* Hashing function */
exports.calculateHash = function calculateHash(type, text) {
  var shasum = crypto.createHash(type);
  shasum.update(text);
  return shasum.digest("hex");
}

/* Simple route middleware to ensure user is authenticated. Otherwise send to login page. */
exports.ensureAuthenticated = function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect('/login');
}

/* Signup for a user */
var registerUser = function registerUser(name, email, provider_name, mugshot, link, done) {
  /* Find user by email */
  db.User.findOne({ email: email }).populate('profile.providers').exec(function (err, user) {
    if (err) return done(err);
    /* When the user with the email was found and the provider is registered */
    else if (user && user.profile.providers.map(function(elem) { return elem.name; }).join(",").indexOf(provider_name) > -1) return done(null, user);

    /* Register a new provider */
    var provider = new db.Provider({ name: provider_name, mugshot: mugshot, display_name: name, url: link });
    provider.save();
    /* When no user under this email was found */
    if (!user) {
      var user = new db.User({ name: name, email: email });
      user.profile.mugshot = mugshot;
      user.profile.website = link;
    }
    /* Register this provider for the user */
    user.profile.providers.push(provider);
    user.save(function(err) {
      if (err) console.log("ERROR", "error saving user:", err);
      else {
        console.log("INFO", "user saved:", user.email);
        /* Fetch the information again, for the new provider information */
        db.User.findOne({ email: email }).populate('profile.providers').exec(function (err, user) {
          return done(null, user);
        });
      }
    });
  });
};

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

passport.use(new LocalStrategy(
  function(username, password, done) {
    process.nextTick(function () {
      /* Escape some characters before using regular expression matching */
      db.User.findOne({ email: new RegExp("(^" + username.replace(/([+])/g, "\\$1") + "$)", "i") }).populate('profile.providers').exec(function (err, user) {
        if (err) return done(err);
        if (!user) return done(null, false, { message: "Wrong username or password" });
        if (user.password != exports.calculateHash("sha256", password + user.joined_date)) return done(null, false, { message: "Wrong username or password" });
        return done(null, user);
      });
    });
  }
));

passport.use(new GoogleStrategy({
    clientID: config.google.consumer_key,
    clientSecret: config.google.consumer_secret,
    callbackURL: config.google.callback
  },
  function(accessToken, refreshToken, profile, done) {
  	process.nextTick(function () {
      console.log("INFO", "google user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.picture, profile._json.link, done);
	  });
  }
));

passport.use(new TwitterStrategy({
    consumerKey: config.twitter.consumer_key,
    consumerSecret: config.twitter.consumer_secret,
    callbackURL: config.twitter.callback
  },
  function(token, tokenSecret, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "twitter user info:", profile);
      db.User.findOne({ name: new RegExp("^" + profile.displayName, "i") }).populate('profile.providers').exec(function (err, user) {
        if (err) done(err);
        /* No user with this display name was found */
        else if (!user) done(null, false, { message: "Twitter username must match your profiles: " + profile.displayName });
        /* The user was found */
        else registerUser(user.name, user.email, profile.provider, profile._json.profile_image_url, profile._json.url, done);
      });
	  });
  }
));

passport.use(new FacebookStrategy({
    clientID: config.facebook.consumer_key,
    clientSecret: config.facebook.consumer_secret,
    callbackURL: config.facebook.callback,
    profileFields: ['emails', 'displayName', 'photos', 'profileUrl']
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "facebook user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.picture.data.url, profile._json.link, done);
    });
  }
));

passport.use(new LinkedInStrategy({
    consumerKey: config.linkedin.consumer_key,
    consumerSecret: config.linkedin.consumer_secret,
    callbackURL: config.linkedin.callback,
    profileFields: ['id', 'first-name', 'last-name', 'email-address', 'picture-url', 'public-profile-url']
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "linkedin user info:", profile);
      registerUser(profile.displayName, profile._json.emailAddress, profile.provider, profile._json.pictureUrl, profile._json.publicProfileUrl, done);
    });
  }
));

passport.use(new GitHubStrategy({
    clientID: config.github.consumer_key,
    clientSecret: config.github.consumer_secret,
    callbackURL: config.github.callback
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "github user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.avatar_url, profile._json.html_url, done);
    });
  }
));<commit_msg>added guest generation<commit_after>/* Configuration, database and crypto */
var config = require("./config"),
  db = require("./database"),
  crypto = require('crypto');

/* OAuth stuff */
var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
	GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
	TwitterStrategy = require('passport-twitter').Strategy,
	FacebookStrategy = require('passport-facebook').Strategy,
  LinkedInStrategy = require('passport-linkedin').Strategy,
  GitHubStrategy = require('passport-github').Strategy;

/* Hashing function */
exports.calculateHash = function calculateHash(type, text) {
  var shasum = crypto.createHash(type);
  shasum.update(text);
  return shasum.digest("hex");
}

/* Random function */
exports.generateRandom = function generateRandom() {
  var current_date = (new Date()).valueOf().toString();
  var random = Math.random().toString();
  return crypto.createHash('sha1').update(current_date + random).digest('hex');
}

/* Generate a random guest account */
exports.generateGuest = function generateGuest() {
  var randomEmail = exports.generateRandom() + "@email.com";
  var user = {
    name: "Guest", email: randomEmail,
    profile: {
      mugshot: "http://www.gravatar.com/avatar/" + randomEmail + "?d=identicon",
      website: "http://www.google.com/",
      description: ""
    }
  };
  return user;
}

/* Simple route middleware to ensure user is authenticated. Otherwise send to login page. */
exports.ensureAuthenticated = function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect('/login');
}

/* Signup for a user */
var registerUser = function registerUser(name, email, provider_name, mugshot, link, done) {
  /* Find user by email */
  db.User.findOne({ email: email }).populate('profile.providers').exec(function (err, user) {
    if (err) return done(err);
    /* When the user with the email was found and the provider is registered */
    else if (user && user.profile.providers.map(function(elem) { return elem.name; }).join(",").indexOf(provider_name) > -1) return done(null, user);

    /* Register a new provider */
    var provider = new db.Provider({ name: provider_name, mugshot: mugshot, display_name: name, url: link });
    provider.save();
    /* When no user under this email was found */
    if (!user) {
      var user = new db.User({ name: name, email: email });
      user.profile.mugshot = mugshot;
      user.profile.website = link;
    }
    /* Register this provider for the user */
    user.profile.providers.push(provider);
    user.save(function(err) {
      if (err) console.log("ERROR", "error saving user:", err);
      else {
        console.log("INFO", "user saved:", user.email);
        /* Fetch the information again, for the new provider information */
        db.User.findOne({ email: email }).populate('profile.providers').exec(function (err, user) {
          return done(null, user);
        });
      }
    });
  });
};

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

passport.use(new LocalStrategy(
  function(username, password, done) {
    process.nextTick(function () {
      /* Escape some characters before using regular expression matching */
      db.User.findOne({ email: new RegExp("(^" + username.replace(/([+])/g, "\\$1") + "$)", "i") }).populate('profile.providers').exec(function (err, user) {
        if (err) return done(err);
        if (!user) return done(null, false, { message: "Wrong username or password" });
        if (user.password != exports.calculateHash("sha256", password + user.joined_date)) return done(null, false, { message: "Wrong username or password" });
        return done(null, user);
      });
    });
  }
));

passport.use(new GoogleStrategy({
    clientID: config.google.consumer_key,
    clientSecret: config.google.consumer_secret,
    callbackURL: config.google.callback
  },
  function(accessToken, refreshToken, profile, done) {
  	process.nextTick(function () {
      console.log("INFO", "google user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.picture, profile._json.link, done);
	  });
  }
));

passport.use(new TwitterStrategy({
    consumerKey: config.twitter.consumer_key,
    consumerSecret: config.twitter.consumer_secret,
    callbackURL: config.twitter.callback
  },
  function(token, tokenSecret, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "twitter user info:", profile);
      db.User.findOne({ name: new RegExp("^" + profile.displayName, "i") }).populate('profile.providers').exec(function (err, user) {
        if (err) done(err);
        /* No user with this display name was found */
        else if (!user) done(null, false, { message: "Twitter username must match your profiles: " + profile.displayName });
        /* The user was found */
        else registerUser(user.name, user.email, profile.provider, profile._json.profile_image_url, profile._json.url, done);
      });
	  });
  }
));

passport.use(new FacebookStrategy({
    clientID: config.facebook.consumer_key,
    clientSecret: config.facebook.consumer_secret,
    callbackURL: config.facebook.callback,
    profileFields: ['emails', 'displayName', 'photos', 'profileUrl']
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "facebook user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.picture.data.url, profile._json.link, done);
    });
  }
));

passport.use(new LinkedInStrategy({
    consumerKey: config.linkedin.consumer_key,
    consumerSecret: config.linkedin.consumer_secret,
    callbackURL: config.linkedin.callback,
    profileFields: ['id', 'first-name', 'last-name', 'email-address', 'picture-url', 'public-profile-url']
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "linkedin user info:", profile);
      registerUser(profile.displayName, profile._json.emailAddress, profile.provider, profile._json.pictureUrl, profile._json.publicProfileUrl, done);
    });
  }
));

passport.use(new GitHubStrategy({
    clientID: config.github.consumer_key,
    clientSecret: config.github.consumer_secret,
    callbackURL: config.github.callback
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
      console.log("INFO", "github user info:", profile);
      registerUser(profile._json.name, profile._json.email, profile.provider, profile._json.avatar_url, profile._json.html_url, done);
    });
  }
));<|endoftext|>


<commit_before>var exec   = require('child_process').exec
  , assert = require('assert')
  , fs     = require('fs')
  , rimraf = require('rimraf')
  , path   = require('path')
  , Hogan  = require('../lib/hogan.js');

// help text
exec('node bin/hulk', function (error, stdout, stderr) {
  if (error) throw error;
  assert(typeof stdout == 'string', 'it should have help text.');
  assert(/USAGE/.test(stdout), 'has USAGE text');
  assert(/NOTE/.test(stdout), 'has NOTE text about wildcard');
});

// wrapper options: --wrapper amd
exec('node bin/hulk --wrapper amd test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  var define = function (name, dep, template) {
    template = template(Hogan);
    assert(/list$/.test(name), 'name path ends in list');
    assert(dep[0] === 'hogan.js', 'Make sure the "hogan" dependency is passed');
    assert(typeof template   == 'object', 'defined a templates.list object');
    assert(typeof template.r == 'function', 'defined a templates.list.r function');
  };
  eval(stdout);
});

// wrapper options: --outputdir
exec('node bin/hulk --outputdir dist/foo test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  assert(path.existsSync('dist/foo'), 'dist/foo directory created');
  assert(path.existsSync('dist/foo/list.js'), 'dist/foo/list.js file created');
  rimraf.sync('dist');
});

// templates wildcard
exec('node bin/hulk test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});

// templates wildcard w/ extension
exec('node bin/hulk test/templates/*.mustache', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});

// templates single file
exec('node bin/hulk test/templates/list.mustache', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});<commit_msg>[fix] path.existsSync was moved to fs.existsSync<commit_after>var exec   = require('child_process').exec
  , assert = require('assert')
  , fs     = require('fs')
  , rimraf = require('rimraf')
  , path   = require('path')
  , Hogan  = require('../lib/hogan.js');

// help text
exec('node bin/hulk', function (error, stdout, stderr) {
  if (error) throw error;
  assert(typeof stdout == 'string', 'it should have help text.');
  assert(/USAGE/.test(stdout), 'has USAGE text');
  assert(/NOTE/.test(stdout), 'has NOTE text about wildcard');
});

// wrapper options: --wrapper amd
exec('node bin/hulk --wrapper amd test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  var define = function (name, dep, template) {
    template = template(Hogan);
    assert(/list$/.test(name), 'name path ends in list');
    assert(dep[0] === 'hogan.js', 'Make sure the "hogan" dependency is passed');
    assert(typeof template   == 'object', 'defined a templates.list object');
    assert(typeof template.r == 'function', 'defined a templates.list.r function');
  };
  eval(stdout);
});

// wrapper options: --outputdir
exec('node bin/hulk --outputdir dist/foo test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  assert(fs.existsSync('dist/foo'), 'dist/foo directory created');
  assert(fs.existsSync('dist/foo/list.js'), 'dist/foo/list.js file created');
  rimraf.sync('dist');
});

// templates wildcard
exec('node bin/hulk test/templates/*', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});

// templates wildcard w/ extension
exec('node bin/hulk test/templates/*.mustache', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});

// templates single file
exec('node bin/hulk test/templates/list.mustache', function (error, stdout, stderr) {
  if (error) throw error;
  eval(stdout);
  assert(typeof templates        == 'object', 'defineed a templates object');
  assert(typeof templates.list   == 'object', 'defined a templates.list object');
  assert(typeof templates.list.r == 'function', 'defined a templates.list.r function');
  assert(templates.list.r() == '
\n

\n

\n

\n

\n

\n

\n
');
});<|endoftext|>


<commit_before>(function(Mobify, $) {
    var console = Mobify.console = window.console;
    if (!console.group) {
        console.group = console.log;
        console.groupEnd = function(){};
    }
    $.extend(console, {
        die : function() {
            var args = [].slice.call(arguments);
            console.group('(T_T) Fatal error (T_T)')
            console.error.apply(console, args);
            console.groupEnd();

            if (!Mobify.config.isDebug) {
                Mobify.unmobify();
            }

            throw args;
        },
        logGroup : function(fn, title, obj) {
            var noneWritten = true;

            if (obj) {
                $.each(obj, function(key, value) {
                    noneWritten && console.group(title);
                    if (typeof key == "number") {
                        console[fn].apply(window, value);
                    } else {
                        console[fn](key, value);
                    }

                    noneWritten = false;
                });
            }

            noneWritten || console.groupEnd();
        }
    });
})(Mobify, Mobify.$);<commit_msg>Call toString on Error objects when logging to console.<commit_after>(function(Mobify, $) {
    var console = Mobify.console = window.console;
    if (!console.group) {
        console.group = console.log;
        console.groupEnd = function(){};
    }
    $.extend(console, {
        die : function() {
            var args = [].slice.call(arguments);
            console.group('(T_T) Fatal error (T_T)')
            console.error.apply(console, args);
            console.groupEnd();

            if (!Mobify.config.isDebug) {
                Mobify.unmobify();
            }

            throw args;
        },
        logGroup : function(fn, title, obj) {
            var noneWritten = true;

            if (obj) {
                $.each(obj, function(key, value) {
                    noneWritten && console.group(title);

                    if (typeof key == "number") {
                        console[fn].apply(window, value);
                    } else if (value instanceof Error) {
                        console.error(key, value.toString());
                    } else {
                        console[fn](key, value);
                    }

                    noneWritten = false;
                });
            }

            noneWritten || console.groupEnd();
        }
    });
})(Mobify, Mobify.$);<|endoftext|>


<commit_before>/**
 * JS supplement to the Sked PHP calendar library.
 *
 * @see https://github.com/CampusUnion/Sked
 */
(function($) {

    $(document).ready(function(){

        // Pluralize intervals (days, weeks, etc.) based on frequency
        $('.sked-form select[name="frequency"]').change(function(){
            var bPlural = $(this).val() !== '1';
            var fnPluralString = function(){
                var strText = $(this).text();
                if (bPlural && strText !== '-' && !strText.match('s$'))
                    $(this).text(strText + 's');
                else if (!bPlural && strText.match('s$'))
                    $(this).text(strText.slice(0, -1));
            };
            $('.sked-form select[name="interval"] option').each(fnPluralString);
        }).change();

        // Only show weekdays for weekly & monthly intervals
        $('.sked-form select[name="interval"]').change(function(){
            var bHide = ($(this).val() === '1' || $(this).val() === '');
            $('[name="weekdays[]"]').prop('disabled', bHide)
                .parent(':not(form)')[bHide ? 'hide' : 'show']();
        }).change();

    });

})(jQuery);
<commit_msg>pluralize lead time field too<commit_after>/**
 * JS supplement to the Sked PHP calendar library.
 *
 * @see https://github.com/CampusUnion/Sked
 */
(function($) {

    $(document).ready(function(){

        // Pluralize intervals (days, weeks, etc.) based on frequency
        $('.sked-form select[name="frequency"], .sked-form select[name="lead_time_num"]').change(function(){
            var bPlural = $(this).val() !== '1';
            var fnPluralString = function(){
                var strText = $(this).text();
                if (bPlural && strText !== '-' && !strText.match('s$'))
                    $(this).text(strText + 's');
                else if (!bPlural && strText.match('s$'))
                    $(this).text(strText.slice(0, -1));
            };
            $(this).siblings('select').children('option').each(fnPluralString);
        }).change();

        // Only show weekdays for weekly & monthly intervals
        $('.sked-form select[name="interval"]').change(function(){
            var bHide = ($(this).val() === '1' || $(this).val() === '');
            $('[name="weekdays[]"]').prop('disabled', bHide)
                .parent(':not(form)')[bHide ? 'hide' : 'show']();
        }).change();

    });

})(jQuery);
<|endoftext|>


<commit_before>import cheerio from 'cheerio';
import commander from 'commander';
import fs from 'fs';
import path from 'path';
import process from 'process';
import request from 'superagent';
import Table from 'cli-table';

const packageJson = require('../../package.json');

export default class App {
  listModules() {
    const table = new Table({
      head: ['Name', 'URL']
    });

    Object.keys(this.modules).forEach((moduleName) => {
      const info = this.modules[moduleName].info;
      table.push([
        info.name,
        info.url
      ]);
    });

    console.log(table.toString());
  }

  loadModules() {
    return new Promise((resolve, reject) => {
      const dir = path.resolve(__dirname, '..', 'modules');

      fs.readdir(dir, (err, data) => {
        if (err) {
          return reject(err);
        }

        const res = {};
        data.forEach((file) => {
          const fullPath = path.join(dir, file);

          const isFile = fs.lstatSync(fullPath).isFile();
          const moduleName = isFile ? file.replace('.js', '') : file;

          const module = require(fullPath);
          res[moduleName] = module;
        });

        resolve(res);
      });
    });
  }

  processResults(results) {
    console.log(JSON.stringify(results, null, 4));
  }

  run() {
    commander
      .version(packageJson.version)
      .option('-l, --list-modules', 'List supported crawlers/modules')
      .option('-t, --type [type]', 'Type of crawler to use')
      .parse(process.argv);

    this.loadModules().then((modules) => {
      this.modules = modules;

      if (commander.listModules) {
        return this.listModules();
      }

      if (!commander.args.length) {
        return commander.help();
      }

      // Check if crawler type/module name was specified
      if (!commander.type) {
        console.log('Type of crawlwer to use not specified!');
        return commander.help();
      }

      const module = modules[commander.type];
      if (!module) {
        console.log(`Invalid crawler type '${commander.type}' specified.`);
        return false;
      }

      // Process arguments
      commander.args.forEach((uri) => {
        request
          .get(uri)
          .end((err, data) => {
            if (err) {
              console.log(err);
              return;
            }

            const doc = cheerio.load(data.text);
            const res = module.listing(doc, {
              url: uri
            });

            this.processResults(res);
          });
      });
    }, (err) => {
      console.log(err);
    });
  }
};
<commit_msg>Improve modules listing - use table<commit_after>import cheerio from 'cheerio';
import commander from 'commander';
import fs from 'fs';
import path from 'path';
import process from 'process';
import request from 'superagent';
import Table from 'cli-table';

const packageJson = require('../../package.json');

export default class App {
  static listModules(modules) {
    const table = new Table({
      head: ['Name', 'URL']
    });

    Object.keys(modules).forEach((moduleName) => {
      const info = modules[moduleName].info;
      table.push([
        info.name,
        info.url
      ]);
    });

    console.log(table.toString());
  }

  listModules() {
    App.listModules(this.modules);
  }

  loadModules() {
    return new Promise((resolve, reject) => {
      const dir = path.resolve(__dirname, '..', 'modules');

      fs.readdir(dir, (err, data) => {
        if (err) {
          return reject(err);
        }

        const res = {};
        data.forEach((file) => {
          const fullPath = path.join(dir, file);

          const isFile = fs.lstatSync(fullPath).isFile();
          const moduleName = isFile ? file.replace('.js', '') : file;

          const module = require(fullPath);
          res[moduleName] = module;
        });

        resolve(res);
      });
    });
  }

  processResults(results) {
    console.log(JSON.stringify(results, null, 4));
  }

  run() {
    commander
      .version(packageJson.version)
      .option('-l, --list-modules', 'List supported crawlers/modules')
      .option('-t, --type [type]', 'Type of crawler to use')
      .parse(process.argv);

    this.loadModules().then((modules) => {
      this.modules = modules;

      if (commander.listModules) {
        return this.listModules();
      }

      if (!commander.args.length) {
        return commander.help();
      }

      // Check if crawler type/module name was specified
      if (!commander.type) {
        console.log('Type of crawlwer to use not specified!');
        return commander.help();
      }

      const module = modules[commander.type];
      if (!module) {
        console.log(`Invalid crawler type '${commander.type}' specified.`);
        return false;
      }

      // Process arguments
      commander.args.forEach((uri) => {
        request
          .get(uri)
          .end((err, data) => {
            if (err) {
              console.log(err);
              return;
            }

            const doc = cheerio.load(data.text);
            const res = module.listing(doc, {
              url: uri
            });

            this.processResults(res);
          });
      });
    }, (err) => {
      console.log(err);
    });
  }
};
<|endoftext|>