<commit_before>"use strict";

var keys = Object.keys;
var every = Array.prototype.every;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var getClass = require("./get-class");
var identical = require("./identical");
var isArguments = require("./is-arguments");
var isDate = require("./is-date");
var isElement = require("./is-element");
var isNaN = require("./is-nan");
var isObject = require("./is-object");
var isSet = require("./is-set");
var isSubset = require("./is-subset");

var indexOf = Array.prototype.indexOf;

/**
 * @name samsam.deepEqual
 * @param Object first
 * @param Object second
 *
 * Deep equal comparison. Two values are "deep equal" if:
 *
 *   - They are equal, according to samsam.identical
 *   - They are both date objects representing the same time
 *   - They are both arrays containing elements that are all deepEqual
 *   - They are objects with the same set of properties, and each property
 *     in ``first`` is deepEqual to the corresponding property in ``second``
 *
 * Supports cyclic objects.
 */
function deepEqualCyclic(first, second) {
    // used for cyclic comparison
    // contain already visited objects
    var objects1 = [];
    var objects2 = [];
    // contain pathes (position in the object structure)
    // of the already visited objects
    // indexes same as in objects arrays
    var paths1 = [];
    var paths2 = [];
    // contains combinations of already compared objects
    // in the manner: { "$1['ref']$2['ref']": true }
    var compared = {};

    // does the recursion for the deep equal check
    return (function deepEqual(obj1, obj2, path1, path2) {
        var type1 = typeof obj1;
        var type2 = typeof obj2;

        // == null also matches undefined
        if (
            obj1 === obj2 ||
            isNaN(obj1) ||
            isNaN(obj2) ||
            obj1 == null ||
            obj2 == null ||
            type1 !== "object" ||
            type2 !== "object"
        ) {
            return identical(obj1, obj2);
        }

        // Elements are only equal if identical(expected, actual)
        if (isElement(obj1) || isElement(obj2)) {
            return false;
        }

        var isDate1 = isDate(obj1);
        var isDate2 = isDate(obj2);
        if (isDate1 || isDate2) {
            if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
                return false;
            }
        }

        if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
            if (obj1.toString() !== obj2.toString()) {
                return false;
            }
        }

        if (obj1 instanceof Error && obj2 instanceof Error) {
            if (obj1.stack !== obj2.stack) {
                return false;
            }
        }

        var class1 = getClass(obj1);
        var class2 = getClass(obj2);
        var keys1 = keys(obj1);
        var keys2 = keys(obj2);

        if (isArguments(obj1) || isArguments(obj2)) {
            if (obj1.length !== obj2.length) {
                return false;
            }
        } else {
            if (
                type1 !== type2 ||
                class1 !== class2 ||
                keys1.length !== keys2.length
            ) {
                return false;
            }
        }

        if (isSet(obj1) || isSet(obj2)) {
            if (!isSet(obj1) || !isSet(obj2) || obj1.size !== obj2.size) {
                return false;
            }

            return isSubset(obj1, obj2, deepEqual);
        }

        return every.call(keys1, function(key) {
            if (!hasOwnProperty.call(obj2, key)) {
                return false;
            }

            var value1 = obj1[key];
            var value2 = obj2[key];
            var isObject1 = isObject(value1);
            var isObject2 = isObject(value2);
            // determines, if the objects were already visited
            // (it's faster to check for isObject first, than to
            // get -1 from getIndex for non objects)
            var index1 = isObject1 ? indexOf.call(objects1, value1) : -1;
            var index2 = isObject2 ? indexOf.call(objects2, value2) : -1;
            // determines the new paths of the objects
            // - for non cyclic objects the current path will be extended
            //   by current property name
            // - for cyclic objects the stored path is taken
            var newPath1 =
                index1 !== -1
                    ? paths1[index1]
                    : path1 + "[" + JSON.stringify(key) + "]";
            var newPath2 =
                index2 !== -1
                    ? paths2[index2]
                    : path2 + "[" + JSON.stringify(key) + "]";
            var combinedPath = newPath1 + newPath2;

            // stop recursion if current objects are already compared
            if (compared[combinedPath]) {
                return true;
            }

            // remember the current objects and their paths
            if (index1 === -1 && isObject1) {
                objects1.push(value1);
                paths1.push(newPath1);
            }
            if (index2 === -1 && isObject2) {
                objects2.push(value2);
                paths2.push(newPath2);
            }

            // remember that the current objects are already compared
            if (isObject1 && isObject2) {
                compared[combinedPath] = true;
            }

            // End of cyclic logic

            // neither value1 nor value2 is a cycle
            // continue with next level
            return deepEqual(value1, value2, newPath1, newPath2);
        });
    })(first, second, "$1", "$2");
}

module.exports = deepEqualCyclic;
<commit_msg>Cache reference to Date.prototype.getTime<commit_after>"use strict";

var keys = Object.keys;
var every = Array.prototype.every;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var getClass = require("./get-class");
var identical = require("./identical");
var isArguments = require("./is-arguments");
var isDate = require("./is-date");
var isElement = require("./is-element");
var isNaN = require("./is-nan");
var isObject = require("./is-object");
var isSet = require("./is-set");
var isSubset = require("./is-subset");
var getTime = Date.prototype.getTime;
var indexOf = Array.prototype.indexOf;

/**
 * @name samsam.deepEqual
 * @param Object first
 * @param Object second
 *
 * Deep equal comparison. Two values are "deep equal" if:
 *
 *   - They are equal, according to samsam.identical
 *   - They are both date objects representing the same time
 *   - They are both arrays containing elements that are all deepEqual
 *   - They are objects with the same set of properties, and each property
 *     in ``first`` is deepEqual to the corresponding property in ``second``
 *
 * Supports cyclic objects.
 */
function deepEqualCyclic(first, second) {
    // used for cyclic comparison
    // contain already visited objects
    var objects1 = [];
    var objects2 = [];
    // contain pathes (position in the object structure)
    // of the already visited objects
    // indexes same as in objects arrays
    var paths1 = [];
    var paths2 = [];
    // contains combinations of already compared objects
    // in the manner: { "$1['ref']$2['ref']": true }
    var compared = {};

    // does the recursion for the deep equal check
    return (function deepEqual(obj1, obj2, path1, path2) {
        var type1 = typeof obj1;
        var type2 = typeof obj2;

        // == null also matches undefined
        if (
            obj1 === obj2 ||
            isNaN(obj1) ||
            isNaN(obj2) ||
            obj1 == null ||
            obj2 == null ||
            type1 !== "object" ||
            type2 !== "object"
        ) {
            return identical(obj1, obj2);
        }

        // Elements are only equal if identical(expected, actual)
        if (isElement(obj1) || isElement(obj2)) {
            return false;
        }

        var isDate1 = isDate(obj1);
        var isDate2 = isDate(obj2);
        if (isDate1 || isDate2) {
            if (
                !isDate1 ||
                !isDate2 ||
                getTime.call(obj1) !== getTime.call(obj2)
            ) {
                return false;
            }
        }

        if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
            if (obj1.toString() !== obj2.toString()) {
                return false;
            }
        }

        if (obj1 instanceof Error && obj2 instanceof Error) {
            if (obj1.stack !== obj2.stack) {
                return false;
            }
        }

        var class1 = getClass(obj1);
        var class2 = getClass(obj2);
        var keys1 = keys(obj1);
        var keys2 = keys(obj2);

        if (isArguments(obj1) || isArguments(obj2)) {
            if (obj1.length !== obj2.length) {
                return false;
            }
        } else {
            if (
                type1 !== type2 ||
                class1 !== class2 ||
                keys1.length !== keys2.length
            ) {
                return false;
            }
        }

        if (isSet(obj1) || isSet(obj2)) {
            if (!isSet(obj1) || !isSet(obj2) || obj1.size !== obj2.size) {
                return false;
            }

            return isSubset(obj1, obj2, deepEqual);
        }

        return every.call(keys1, function(key) {
            if (!hasOwnProperty.call(obj2, key)) {
                return false;
            }

            var value1 = obj1[key];
            var value2 = obj2[key];
            var isObject1 = isObject(value1);
            var isObject2 = isObject(value2);
            // determines, if the objects were already visited
            // (it's faster to check for isObject first, than to
            // get -1 from getIndex for non objects)
            var index1 = isObject1 ? indexOf.call(objects1, value1) : -1;
            var index2 = isObject2 ? indexOf.call(objects2, value2) : -1;
            // determines the new paths of the objects
            // - for non cyclic objects the current path will be extended
            //   by current property name
            // - for cyclic objects the stored path is taken
            var newPath1 =
                index1 !== -1
                    ? paths1[index1]
                    : path1 + "[" + JSON.stringify(key) + "]";
            var newPath2 =
                index2 !== -1
                    ? paths2[index2]
                    : path2 + "[" + JSON.stringify(key) + "]";
            var combinedPath = newPath1 + newPath2;

            // stop recursion if current objects are already compared
            if (compared[combinedPath]) {
                return true;
            }

            // remember the current objects and their paths
            if (index1 === -1 && isObject1) {
                objects1.push(value1);
                paths1.push(newPath1);
            }
            if (index2 === -1 && isObject2) {
                objects2.push(value2);
                paths2.push(newPath2);
            }

            // remember that the current objects are already compared
            if (isObject1 && isObject2) {
                compared[combinedPath] = true;
            }

            // End of cyclic logic

            // neither value1 nor value2 is a cycle
            // continue with next level
            return deepEqual(value1, value2, newPath1, newPath2);
        });
    })(first, second, "$1", "$2");
}

module.exports = deepEqualCyclic;
<|endoftext|>


<commit_before>var sys = require('sys'),
    exec = require('child_process').exec,
    config = require('./../config.json'),
    path = config.path,
    origin = config.remote_name,
    branch = config.branch;

var deployment = {
    execTaskList : [
        "cd " + path + ";git pull " + origin + " " + branch
    ],
    execTask : function(execArg){
        exec(execArg, function(error, stdout, stderr) {
            sys.print('stdout: ' + stdout);
            sys.print('stderr: ' + stderr);
            if (error !== null) {
                console.log('exec error: ' + error);
                return (stderr);
            } else {
                return(stdout);
            }
        });
    }
}

module.exports = deployment;<commit_msg>Replaced semi colon with && resolves issue 8<commit_after>var sys = require('sys'),
    exec = require('child_process').exec,
    config = require('./../config.json'),
    path = config.path,
    origin = config.remote_name,
    branch = config.branch;

var deployment = {
    execTaskList : [
        "cd " + path + "&&git pull " + origin + " " + branch
    ],
    execTask : function(execArg){
        exec(execArg, function(error, stdout, stderr) {
            sys.print('stdout: ' + stdout);
            sys.print('stderr: ' + stderr);
            if (error !== null) {
                console.log('exec error: ' + error);
                return (stderr);
            } else {
                return(stdout);
            }
        });
    }
}

module.exports = deployment;<|endoftext|>


<commit_before>'use strict';

/**
 * Deploy a software package.
 * (C) 2013 Alex Fernández.
 */

// requires
var childProcess = require('child_process');
var util = require('util');
var async = require('async');
var testing = require('testing');
var Log = require('log');

// globals
var log = new Log('info');
var originalLog = log;

// constants
var DEFAULT_TIMEOUT_SECONDS = 60;

/**
 * A deployment of a software package, using the same options as exports.run().
 */
var Deployment = function(options, log)
{
	// self-reference
	var self = this;

	// init
	if (options.quiet)
	{
		log.level = 'notice';
	}
	if (!options.testDirectory && !options.directory)
	{
		log.warning('No directories given; no deployment done');
	}

	/**
	 * Run the deployment.
	 */
	self.run = function(callback)
	{
		var tasks = [];
		if (options.testDirectory)
		{
			tasks.push(self.updateTestDirectory);
			tasks.push(getRunnerIn('npm test', options.testDirectory));
		}
		if (options.directory)
		{
			tasks.push(self.updateDeploymentDirectory);
		}
		if (options.deploymentCommand)
		{
			var directory = options.directory || process.cwd();
			tasks.push(getRunnerIn(options.deploymentCommand, directory));
		}
		async.waterfall(tasks, callback);
	};

	/**
	 * Update the test directory.
	 */
	self.updateTestDirectory = function(callback)
	{
		update(options.testDirectory, callback);
	};

	/**
	 * Update the deployment directory.
	 */
	self.updateDeploymentDirectory = function(callback)
	{
		update(options.directory, callback);
	};

	/**
	 * Update the given directory.
	 */
	function update(directory, callback)
	{
		log.info('Updating %s', directory);
		var tasks = [];
		if (options.detail)
		{
			tasks.push(getRunnerIn('git fetch', directory));
			tasks.push(getRunnerIn('git log HEAD..@{u} --format=oneline', directory));
			tasks.push(getRunnerIn('git diff HEAD..@{u}', directory));
			tasks.push(getRunnerIn('git merge @{u}', directory));
		}
		else
		{
			tasks.push(getRunnerIn('git pull', directory));
		}
		tasks.push(getRunnerIn('npm install', directory));
		async.waterfall(tasks, callback);
	}

	/**
	 * Get a function to exec the command in the directory.
	 */
	function getRunnerIn(command, directory)
	{
		return function(callback)
		{
			var params = {
				cwd: directory,
				timeout: 1000 * (options.timeout || DEFAULT_TIMEOUT_SECONDS),
			};
			childProcess.exec(command, params, function(error, stdout, stderr)
			{
				if (error)
				{
					return callback(command + ': ' + stdout + '\n' + error + ', ' + stderr);
				}
				log.info(command + ': ' + stdout);
				if (stderr)
				{
					log.error(command + ': ' + stderr);
				}
				return callback(null);
			});
		};
	}
};

/**
 * Run a test deployment.
 */
function testDeployment(callback)
{
	var options = {
		directory: '.',
		deploymentCommand: 'ls .',
	};
	var deployment = new Deployment(options, new Log('error'));
	deployment.run(callback);
}

/**
 * Run a deployment. Options has these attributes:
 *	- directory: the directory where the package currently resides.
 *	- testDirectory: the directory where the test version of the package resides.
 *	- deploymentCommand: a command to run after a successful deployment,
 *	e.g. "sudo restart myService".
 *	- packageName: the name of the package to show in logs.
 *	- timeout: seconds to wait for all comands, default 60 seconds.
 *	- detail: show full log and diff of code to deploy.
 * An optional log object is used to send messages.
 * An optional callback will be called after the deployment finishes.
 */
exports.run = function(options, log, callback)
{
	if (typeof log == 'function')
	{
		callback = log;
		log = null;
	}
	if (!log)
	{
		log = originalLog;
	}
	var start = Date.now();
	if (options.packageName)
	{
		log.notice('Starting deployment for %s', options.packageName);
	}
	var deployment = new Deployment(options, log);
	deployment.run(function(error)
	{
		var message;
		var elapsed = Math.round((Date.now() - start) / 10) / 100;
		if (error)
		{
			log.error(error);
			message = util.format('Error running deployment after %s seconds; finishing', elapsed);
			if (callback)
			{
				return callback(message);
			}
			log.error(message);
			return;
		}
		message = util.format('Deployment success! in %s seconds', elapsed);
		if (callback)
		{
			return callback(null, message);
		}
		log.notice(message);
	});
};

/**
 * Run all tests.
 */
exports.test = function(callback)
{
	testing.run([
		testDeployment,
	], 10000, callback);
};

// start if invoked directly
if (__filename == process.argv[1])
{
	exports.test(testing.show);
}

<commit_msg>Show detail in tests.<commit_after>'use strict';

/**
 * Deploy a software package.
 * (C) 2013 Alex Fernández.
 */

// requires
var childProcess = require('child_process');
var util = require('util');
var async = require('async');
var testing = require('testing');
var Log = require('log');

// globals
var log = new Log('info');
var originalLog = log;

// constants
var DEFAULT_TIMEOUT_SECONDS = 60;

/**
 * A deployment of a software package, using the same options as exports.run().
 */
var Deployment = function(options, log)
{
	// self-reference
	var self = this;

	// init
	if (options.quiet)
	{
		log.level = 'notice';
	}
	if (!options.testDirectory && !options.directory)
	{
		log.warning('No directories given; no deployment done');
	}

	/**
	 * Run the deployment.
	 */
	self.run = function(callback)
	{
		var tasks = [];
		if (options.testDirectory)
		{
			tasks.push(self.updateTestDirectory);
			tasks.push(getRunnerIn('npm test', options.testDirectory));
		}
		if (options.directory)
		{
			tasks.push(self.updateDeploymentDirectory);
		}
		if (options.deploymentCommand)
		{
			var directory = options.directory || process.cwd();
			tasks.push(getRunnerIn(options.deploymentCommand, directory));
		}
		async.waterfall(tasks, callback);
	};

	/**
	 * Update the test directory.
	 */
	self.updateTestDirectory = function(callback)
	{
		update(options.testDirectory, callback);
	};

	/**
	 * Update the deployment directory.
	 */
	self.updateDeploymentDirectory = function(callback)
	{
		update(options.directory, callback);
	};

	/**
	 * Update the given directory.
	 */
	function update(directory, callback)
	{
		log.info('Updating %s', directory);
		var tasks = [];
		if (options.detail)
		{
			tasks.push(getRunnerIn('git fetch', directory));
			tasks.push(getRunnerIn('git log HEAD..@{u} --format=oneline', directory));
			tasks.push(getRunnerIn('git diff HEAD..@{u}', directory));
			tasks.push(getRunnerIn('git merge @{u}', directory));
		}
		else
		{
			tasks.push(getRunnerIn('git pull', directory));
		}
		tasks.push(getRunnerIn('npm install', directory));
		async.waterfall(tasks, callback);
	}

	/**
	 * Get a function to exec the command in the directory.
	 */
	function getRunnerIn(command, directory)
	{
		return function(callback)
		{
			var params = {
				cwd: directory,
				timeout: 1000 * (options.timeout || DEFAULT_TIMEOUT_SECONDS),
			};
			childProcess.exec(command, params, function(error, stdout, stderr)
			{
				if (error)
				{
					return callback(command + ': ' + stdout + '\n' + error + ', ' + stderr);
				}
				log.info(command + ': ' + stdout);
				if (stderr)
				{
					log.error(command + ': ' + stderr);
				}
				return callback(null);
			});
		};
	}
};

/**
 * Run a test deployment.
 */
function testDeployment(callback)
{
	var options = {
		directory: '.',
		deploymentCommand: 'ls .',
		detail: true,
	};
	var deployment = new Deployment(options, new Log('error'));
	deployment.run(callback);
}

/**
 * Run a deployment. Options has these attributes:
 *	- directory: the directory where the package currently resides.
 *	- testDirectory: the directory where the test version of the package resides.
 *	- deploymentCommand: a command to run after a successful deployment,
 *	e.g. "sudo restart myService".
 *	- packageName: the name of the package to show in logs.
 *	- timeout: seconds to wait for all comands, default 60 seconds.
 *	- detail: show full log and diff of code to deploy.
 * An optional log object is used to send messages.
 * An optional callback will be called after the deployment finishes.
 */
exports.run = function(options, log, callback)
{
	if (typeof log == 'function')
	{
		callback = log;
		log = null;
	}
	if (!log)
	{
		log = originalLog;
	}
	var start = Date.now();
	if (options.packageName)
	{
		log.notice('Starting deployment for %s', options.packageName);
	}
	var deployment = new Deployment(options, log);
	deployment.run(function(error)
	{
		var message;
		var elapsed = Math.round((Date.now() - start) / 10) / 100;
		if (error)
		{
			log.error(error);
			message = util.format('Error running deployment after %s seconds; finishing', elapsed);
			if (callback)
			{
				return callback(message);
			}
			log.error(message);
			return;
		}
		message = util.format('Deployment success! in %s seconds', elapsed);
		if (callback)
		{
			return callback(null, message);
		}
		log.notice(message);
	});
};

/**
 * Run all tests.
 */
exports.test = function(callback)
{
	testing.run([
		testDeployment,
	], 10000, callback);
};

// start if invoked directly
if (__filename == process.argv[1])
{
	exports.test(testing.show);
}

<|endoftext|>


<commit_before>'use strict';

const RiveScript = require('rivescript');
const logger = require('./logger');
const config = require('../config/lib/rivescript');

let brain;
let additionalRivescripts;
let hasSortedReplies = false;

function handleError(error) {
  logger.error('rivescript.handleError', { error });
}

function loadingDone() {
  logger.info('rivescript.brain.loadDirectory success');
  // Loads our saved additionalRivescript into the brain.
  // @see https://github.com/aichaos/rivescript-js/blob/v1.17.2/docs/rivescript.md#bool-stream-string-code-func-onerror
  additionalRivescripts.forEach(item => brain.stream(item, handleError));
  logger.info('rivescript.brain.stream success');
  brain.sortReplies();
  logger.info('rivescript.brain.sortReplies success');
  hasSortedReplies = true;
}

/**
 * Creates a Rivescript bot and loads it with our hardcoded rivescript as well as rivescripts passed
 * in a rivescripts array property.
 *
 * @param {Array} rivescripts
 */
function loadBotWithRivescripts(rivescripts = []) {
  logger.debug('loadBotWithRivescripts');
  additionalRivescripts = rivescripts;
  try {
    if (!brain) {
      brain = new RiveScript({ debug: config.debug, concat: config.concat });
    }
    brain.loadDirectory(config.directory, loadingDone, handleError);
  } catch (err) {
    logger.error('bot.createNewBot', err);
  }
}

/**
 * @param {String} userId
 * @param {String} topicId
 * @param {String} messageText
 * @return {Promise}
 */
function getBotReply(userId, topicId, messageText) {
  if (!brain) {
    return Promise.reject(Error('Bot is not loaded, please retry your message.'));
  }
  // Set the Conversation's current topic in bot.uservars.
  // @see https://github.com/aichaos/rivescript-js/wiki/Asynchronous-Support#user-variable-session-adapters
  brain.setUservars(userId, { topic: topicId });

  return brain.replyAsync(userId, messageText)
    .then((rivescriptReplyText) => {
      if (!hasSortedReplies) {
        throw new Error('Still sorting bot replies, please retry your message.');
      }
      // The inbound message may have triggered a topic change, check bot.uservars to return topic.
      const updatedUservars = brain.getUservars(userId);
      return {
        text: rivescriptReplyText,
        topicId: updatedUservars.topic,
        match: updatedUservars.__initialmatch__, // eslint-disable-line no-underscore-dangle
      };
    });
}

module.exports = {
  loadBotWithRivescripts,
  getBotReply,
};
<commit_msg>Set hasSortedReplies to false when reloading per https://github.com/DoSomething/gambit-conversations/pull/390#pullrequestreview-150584626<commit_after>'use strict';

const RiveScript = require('rivescript');
const logger = require('./logger');
const config = require('../config/lib/rivescript');

let brain;
let additionalRivescripts;
let hasSortedReplies = false;

function handleError(error) {
  logger.error('rivescript.handleError', { error });
}

function loadingDone() {
  logger.info('rivescript.brain.loadDirectory success');
  // Loads our saved additionalRivescript into the brain.
  // @see https://github.com/aichaos/rivescript-js/blob/v1.17.2/docs/rivescript.md#bool-stream-string-code-func-onerror
  additionalRivescripts.forEach(item => brain.stream(item, handleError));
  logger.info('rivescript.brain.stream success');
  brain.sortReplies();
  logger.info('rivescript.brain.sortReplies success');
  hasSortedReplies = true;
}

/**
 * Creates a Rivescript bot and loads it with our hardcoded rivescript as well as rivescripts passed
 * in a rivescripts array property.
 *
 * @param {Array} rivescripts
 */
function loadBotWithRivescripts(rivescripts = []) {
  logger.debug('loadBotWithRivescripts');
  additionalRivescripts = rivescripts;
  hasSortedReplies = false;
  try {
    if (!brain) {
      brain = new RiveScript({ debug: config.debug, concat: config.concat });
    }
    brain.loadDirectory(config.directory, loadingDone, handleError);
  } catch (err) {
    logger.error('bot.createNewBot', err);
  }
}

/**
 * @param {String} userId
 * @param {String} topicId
 * @param {String} messageText
 * @return {Promise}
 */
function getBotReply(userId, topicId, messageText) {
  if (!brain) {
    return Promise.reject(Error('Bot is not loaded, please retry your message.'));
  }
  // Set the Conversation's current topic in bot.uservars.
  // @see https://github.com/aichaos/rivescript-js/wiki/Asynchronous-Support#user-variable-session-adapters
  brain.setUservars(userId, { topic: topicId });

  return brain.replyAsync(userId, messageText)
    .then((rivescriptReplyText) => {
      if (!hasSortedReplies) {
        throw new Error('Still sorting bot replies, please retry your message.');
      }
      // The inbound message may have triggered a topic change, check bot.uservars to return topic.
      const updatedUservars = brain.getUservars(userId);
      return {
        text: rivescriptReplyText,
        topicId: updatedUservars.topic,
        match: updatedUservars.__initialmatch__, // eslint-disable-line no-underscore-dangle
      };
    });
}

module.exports = {
  loadBotWithRivescripts,
  getBotReply,
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var h = require('highland');

var _filters = require('./filters');

module.exports = function(recipe, toVinyl, wrapper) {
  var filters = _filters(wrapper);

  return function(err, file, push, next) {
    var dropRecord = false;

    /*
     * Forward any errors:
     */

    if (err) {
      push(err);
      next();
      return;
    }

    /**
     * Check to see if we're finished:
     */

    if (file === h.nil) {
      push(null, file);
      return;
    }

    if (recipe.filter) {
      var data = file.data;

      data['@meta'] = {};
      data['@meta'].params = recipe.input.params;

      recipe.filter.forEach(function(filter) {
        if (filter.csv) {
          data = filters.csv(filter.csv, data);
        }

        if (filter.geoip) {
          data = filters.geoip(filter.geoip, data);
        }

        if (filter.javascript) {
          data = filters.javascript(filter.javascript, data);
        }

        if (filter.json) {
          data = filters.json(filter.json, data);
        }

        if (filter.mutate) {
          data = filters.mutate(filter.mutate, data);
        }

        if (filter.paginate) {
          data = filters.paginate(filter.paginate, data);
        }

        if (filter.select) {
          data = filters.select(filter.select, data);
        }

        if (filter.sum) {
          data = filters.sum(filter.sum, data);
        }

        if (filter.split) {
          var split = filter.split;
          var field = split.field;

          /**
           * Even if there is only one item we pass it through the split
           * pipeline and drop the current record:
           */

          var toSplit = data[field];

          if (!Array.isArray(toSplit)) {
            toSplit = [toSplit];
          }

          toSplit
            .forEach(function(entry) {
              var dataNew = _.clone(data);

              dataNew[field] = entry;
              if (split.filter) {
                split.filter.forEach(function(filterDash) {
                  if (filterDash.mutate) {
                    dataNew = filters.mutate(filterDash.mutate, dataNew);
                  }
                });
              }
              push(null, toVinyl(dataNew));
            });
          dropRecord = true;
        }
      });

      delete data['@meta'];
      file.data = data;
    }
    if (!dropRecord) {
      push(null, file);
    }
    next();
    return;
  };
};
<commit_msg>ensure non-JSON incoming data goes in a property ready for processing<commit_after>var _ = require('lodash');
var h = require('highland');

var _filters = require('./filters');

module.exports = function(recipe, toVinyl, wrapper) {
  var filters = _filters(wrapper);

  return function(err, file, push, next) {
    var dropRecord = false;

    /*
     * Forward any errors:
     */

    if (err) {
      push(err);
      next();
      return;
    }

    /**
     * Check to see if we're finished:
     */

    if (file === h.nil) {
      push(null, file);
      return;
    }

    if (recipe.filter) {
      var data = file.data || {message: String(file.contents)};

      data['@meta'] = {};
      data['@meta'].params = recipe.input.params;

      recipe.filter.forEach(function(filter) {
        if (filter.csv) {
          data = filters.csv(filter.csv, data);
        }

        if (filter.geoip) {
          data = filters.geoip(filter.geoip, data);
        }

        if (filter.javascript) {
          data = filters.javascript(filter.javascript, data);
        }

        if (filter.json) {
          data = filters.json(filter.json, data);
        }

        if (filter.mutate) {
          data = filters.mutate(filter.mutate, data);
        }

        if (filter.paginate) {
          data = filters.paginate(filter.paginate, data);
        }

        if (filter.select) {
          data = filters.select(filter.select, data);
        }

        if (filter.sum) {
          data = filters.sum(filter.sum, data);
        }

        if (filter.split) {
          var split = filter.split;
          var field = split.field;

          /**
           * Even if there is only one item we pass it through the split
           * pipeline and drop the current record:
           */

          var toSplit = data[field];

          if (!Array.isArray(toSplit)) {
            toSplit = [toSplit];
          }

          toSplit
            .forEach(function(entry) {
              var dataNew = _.clone(data);

              dataNew[field] = entry;
              if (split.filter) {
                split.filter.forEach(function(filterDash) {
                  if (filterDash.mutate) {
                    dataNew = filters.mutate(filterDash.mutate, dataNew);
                  }
                });
              }
              push(null, toVinyl(dataNew));
            });
          dropRecord = true;
        }
      });

      delete data['@meta'];
      file.data = data;
    }
    if (!dropRecord) {
      push(null, file);
    }
    next();
    return;
  };
};
<|endoftext|>


<commit_before>// const random = require('random-js')(); // uses the nativeMath engine
const Cron = require('cron').CronJob; // cron works
const { INPUT, OUTPUT, DB } = require('./word');
const SlackBot = require('./helper/slackBot');

class Dumbledore {
  constructor(settings) {
    const token = settings.token || 'your-token';
    const name = settings.name || 'your-bot-name';

    this.slackBot = new SlackBot({ token, name });

    this.user = null;
    this.githubChannel = settings.githubChannel || 'null';
    this.name = this.slackBot.getName();
    this.awardPoints = require('./controller/awardPoints').bind(this);
    this.deductPoints = require('./controller/deductPoints').bind(this);
    this.replyWithDumbledore = require('./controller/replyWithDumbledore').bind(this);
    this.getUser = require('./controller/getUser').bind(this);
    this.replyWithGithub = require('./controller/replyWithGithub').bind(this);
    this.helpMessage = require('./controller/helpMessage').bind(this);
  }

  run() {
    return new Promise((resolve, reject) => {
      this.slackBot.on('start', () => {
        this.onStart().then(() => {
          resolve();
        });
      });

      this.slackBot.on('error', (error) => {
        console.error('error on dumbledore', error);
      });

      this.slackBot.on('message', (message) => {
        this.onMessage(message);
      });
    });
  }

  async onStart() {
    await this.loadBotUser();
    await this.firstRunCheck();
    await this.getUser();
    this.onCron();
  }

  onCron() {
    const doRegular = new Cron({
      cronTime: '00 00 00 * * 1',
      onTick: () => this.welcomeMessage(), // set function to run something regularly
      start: false,
      timeZone: 'Asia/Seoul'
    });

    doRegular.start();
  }

  async loadBotUser() {
    this.user = await this.slackBot.getUser(this.name);
  }

  async firstRunCheck() {
    try {
      const query = new Parse.Query(DB.INFO.CALL);
      query.equalTo('name', DB.INFO.LASTRUN);
      const doc = await query.first();
      const currentTime = (new Date()).toJSON();

      // this is a first run
      if (!doc) {
        this.welcomeMessage();
        const _doc = new Parse.Object(DB.INFO.CALL);
        return _doc.save({ name: DB.INFO.LASTRUN, val: currentTime });
      }

      // updates with new last running time
      return doc.save({ val: currentTime });
    } catch (e) {
      console.error(e);
      throw e;
    }
  }

  async welcomeMessage() {
    const { channels } = await this.slackBot.getChannels();
    this.channels = channels.filter(channel => channel.is_member);
    if (!this.channels.length) return;
    return this.slackBot.postTo(this.channels[0].name, OUTPUT.SAY_HELLO, { as_user: true });
  }

  onMessage(message) {
    if (this.isChatMessageEvent(message)) {
      this.parseMessage(message);
    } else if (this.isReplayEvent(message)) {
      const { user } = message.message.replies[message.message.reply_count - 1];
      const point = 5;
      this.awardPoints(this.name, user, point);
    } else if (this.isReactionEvent(message)) {
      const user = message.item_user;
      const point = 10;
      if (message.type === 'reaction_added') {
        this.awardPoints(this.name, user, point);
      } else {
        this.awardPoints(this.name, user, -point);
      }
    }
  }

  isChatMessageEvent(message) {
    const isChatMessage = message.type === 'message' && (Boolean(message.text) || Boolean(message.attachments));
    const isChannelConversation = (typeof message.channel === 'string' && message.channel[0] === 'C');
    const isFromDumbledore = message.user === this.user.id;
    const isFromSlackbot = message.user === 'USLACKBOT';

    return isChatMessage && isChannelConversation && !isFromDumbledore && !isFromSlackbot;
  }

  isReplayEvent(message) {
    if (typeof message.subtype === 'undefined') return false;
    const isReplayMessage = message.type === 'message' && message.subtype === 'message_replied';
    const isChannelConversation = (typeof message.channel === 'string' && message.channel[0] === 'C');
    const isSameUser = message.message.user === message.message.replies[message.message.reply_count - 1].user;
    const isFromSlackbot = message.message.user === this.user.id;

    return isReplayMessage && isChannelConversation && !isSameUser && !isFromSlackbot;
  }

  isReactionEvent(message) {
    if (typeof message.item === 'undefined') return false;
    const isReactionMessage = message.type === 'reaction_added' || message.type === 'reaction_removed';
    const isScoreReaction = message.reaction === '100';
    const isChannelConversation = (typeof message.item.channel === 'string' && message.item.channel[0] === 'C');
    const isSameUser = message.user === message.item_user;
    const isFromSlackbot = message.item_user === this.user.id;

    return isReactionMessage && isScoreReaction && isChannelConversation && !isSameUser && !isFromSlackbot;
  }

  parseMessage(message) {
    /* todo: determine what if handle multiple messages? */
    const text = message.text.toLowerCase();

    if (text.includes(INPUT.POINTS_TO.CALL)) {
      this.awardPoints(message);
    } else if (text.includes(INPUT.POINTS_FROM.CALL)) {
      this.deductPoints(message);
    } else if (text.includes(INPUT.PROFESSOR.CALL) || text.includes(this.name)) {
      this.replyWithDumbledore(message);
    } else if (text.includes(INPUT.HELP.CALL)) {
      this.helpMessage(message);
    } else if (message.channel != null && message.channel === this.githubChannel) {
      this.replyWithGithub(message);
    }
  }

  static async convertToUserID(key) {
    const users = await this.slackBot.getUsers();

    if (key in users) {
      return key;
    }
    return users.find((userid) => {
      if (userid.name === key) {
        return userid.id;
      }
      return false;
    });
  }
}

module.exports = Dumbledore;
<commit_msg>add error handler on dumbledore<commit_after>// const random = require('random-js')(); // uses the nativeMath engine
const Cron = require('cron').CronJob; // cron works
const { INPUT, OUTPUT, DB } = require('./word');
const SlackBot = require('./helper/slackBot');

class Dumbledore {
  constructor(settings) {
    const token = settings.token || 'your-token';
    const name = settings.name || 'your-bot-name';

    this.slackBot = new SlackBot({ token, name });

    this.user = null;
    this.githubChannel = settings.githubChannel || 'null';
    this.name = this.slackBot.getName();
    this.awardPoints = require('./controller/awardPoints').bind(this);
    this.deductPoints = require('./controller/deductPoints').bind(this);
    this.replyWithDumbledore = require('./controller/replyWithDumbledore').bind(this);
    this.getUser = require('./controller/getUser').bind(this);
    this.replyWithGithub = require('./controller/replyWithGithub').bind(this);
    this.helpMessage = require('./controller/helpMessage').bind(this);
  }

  run() {
    return new Promise((resolve, reject) => {
      this.slackBot.on('start', () => {
        this.onStart().then(() => {
          resolve();
        }, (error) => {
          console.error('error on dumbledore', error);
          reject(error);
        });
      });

      this.slackBot.on('error', (error) => {
        console.error('error on dumbledore', error);
      });

      this.slackBot.on('message', (message) => {
        this.onMessage(message);
      });
    });
  }

  async onStart() {
    try {
      await this.loadBotUser();
      await this.firstRunCheck();
      await this.getUser();
      this.onCron();
    } catch (error) {
      return new Error(error);
    }
  }

  onCron() {
    const doRegular = new Cron({
      cronTime: '00 00 00 * * 1',
      onTick: () => this.welcomeMessage(), // set function to run something regularly
      start: false,
      timeZone: 'Asia/Seoul'
    });

    doRegular.start();
  }

  async loadBotUser() {
    this.user = await this.slackBot.getUser(this.name);
  }

  async firstRunCheck() {
    try {
      const query = new Parse.Query(DB.INFO.CALL);
      query.equalTo('name', DB.INFO.LASTRUN);
      const doc = await query.first();
      const currentTime = (new Date()).toJSON();

      // this is a first run
      if (!doc) {
        this.welcomeMessage();
        const _doc = new Parse.Object(DB.INFO.CALL);
        return _doc.save({ name: DB.INFO.LASTRUN, val: currentTime });
      }

      // updates with new last running time
      return doc.save({ val: currentTime });
    } catch (e) {
      console.error(e);
      throw e;
    }
  }

  async welcomeMessage() {
    const { channels } = await this.slackBot.getChannels();
    this.channels = channels.filter(channel => channel.is_member);
    if (!this.channels.length) return;
    return this.slackBot.postTo(this.channels[0].name, OUTPUT.SAY_HELLO, { as_user: true });
  }

  onMessage(message) {
    if (this.isChatMessageEvent(message)) {
      this.parseMessage(message);
    } else if (this.isReplayEvent(message)) {
      const { user } = message.message.replies[message.message.reply_count - 1];
      const point = 5;
      this.awardPoints(this.name, user, point);
    } else if (this.isReactionEvent(message)) {
      const user = message.item_user;
      const point = 10;
      if (message.type === 'reaction_added') {
        this.awardPoints(this.name, user, point);
      } else {
        this.awardPoints(this.name, user, -point);
      }
    }
  }

  isChatMessageEvent(message) {
    const isChatMessage = message.type === 'message' && (Boolean(message.text) || Boolean(message.attachments));
    const isChannelConversation = (typeof message.channel === 'string' && message.channel[0] === 'C');
    const isFromDumbledore = message.user === this.user.id;
    const isFromSlackbot = message.user === 'USLACKBOT';

    return isChatMessage && isChannelConversation && !isFromDumbledore && !isFromSlackbot;
  }

  isReplayEvent(message) {
    if (typeof message.subtype === 'undefined') return false;
    const isReplayMessage = message.type === 'message' && message.subtype === 'message_replied';
    const isChannelConversation = (typeof message.channel === 'string' && message.channel[0] === 'C');
    const isSameUser = message.message.user === message.message.replies[message.message.reply_count - 1].user;
    const isFromSlackbot = message.message.user === this.user.id;

    return isReplayMessage && isChannelConversation && !isSameUser && !isFromSlackbot;
  }

  isReactionEvent(message) {
    if (typeof message.item === 'undefined') return false;
    const isReactionMessage = message.type === 'reaction_added' || message.type === 'reaction_removed';
    const isScoreReaction = message.reaction === '100';
    const isChannelConversation = (typeof message.item.channel === 'string' && message.item.channel[0] === 'C');
    const isSameUser = message.user === message.item_user;
    const isFromSlackbot = message.item_user === this.user.id;

    return isReactionMessage && isScoreReaction && isChannelConversation && !isSameUser && !isFromSlackbot;
  }

  parseMessage(message) {
    /* todo: determine what if handle multiple messages? */
    const text = message.text.toLowerCase();

    if (text.includes(INPUT.POINTS_TO.CALL)) {
      this.awardPoints(message);
    } else if (text.includes(INPUT.POINTS_FROM.CALL)) {
      this.deductPoints(message);
    } else if (text.includes(INPUT.PROFESSOR.CALL) || text.includes(this.name)) {
      this.replyWithDumbledore(message);
    } else if (text.includes(INPUT.HELP.CALL)) {
      this.helpMessage(message);
    } else if (message.channel != null && message.channel === this.githubChannel) {
      this.replyWithGithub(message);
    }
  }

  static async convertToUserID(key) {
    const users = await this.slackBot.getUsers();

    if (key in users) {
      return key;
    }
    return users.find((userid) => {
      if (userid.name === key) {
        return userid.id;
      }
      return false;
    });
  }
}

module.exports = Dumbledore;
<|endoftext|>


<commit_before>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  angular.module('Satellizer', [])
    .service('Utils', utils)
    .factory('OAuth2', oauth2)
    .factory('OAuth1', oauth1)
    .factory('Popup', popup)
    .provider('$auth', $auth)
    .config(httpInterceptor)
    .run(onRun);

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    loginRoute: '/login',
    signupRoute: '/signup',
    user: 'currentUser'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'oauth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'oauth1'
    }
  };

  function $auth() {

    this.config = config;

    this.setProvider = function(params) {
      angular.extend(providers[params.name], params);
    };

    this.addProvider = function(params) {
      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function(OAuth1, OAuth2, $http, $location, $rootScope, $q, $window) {

      var $auth = {};

      $auth.authenticate = function(providerName) {
        var deferred = $q.defer();

        var provider = (providers[providerName].type === 'oauth1') ?
          (new OAuth1(providers[providerName])) :
          (new OAuth2(providers[providerName]));

        provider.open().then(function(token) {
          var payload = JSON.parse($window.atob(token.split('.')[1]));
          $window.localStorage.jwtToken = token;
          $rootScope[config.user] = payload.user;
          $location.path(config.loginRedirect);
          deferred.resolve();
        });

        return deferred.promise;
      };

      $auth.login = function(user) {
        if (!user) {
          throw new Error('You must provide a user object.');
        }

        var deferred = $q.defer();

        $http.post(config.loginUrl, user)
          .success(function(data) {
            var payload = JSON.parse($window.atob(data.token.split('.')[1]));
            $rootScope[config.user] = payload.user;
            $location.path(config.loginRedirect);
            $window.localStorage.jwtToken = data.token;
            deferred.resolve(payload.user);
          })
          .error(function(error) {
            deferred.reject(error);
          });

        return deferred.promise;
      };

      $auth.signup = function(user) {
        $http.post(config.signupUrl, user).then(function() {
          $location.path(config.signupRedirect);
        });
      };

      $auth.logout = function() {
        delete $rootScope[config.user];
        delete $window.localStorage.jwtToken;
        $location.path(config.logoutRedirect);
      };

      $auth.isAuthenticated = function() {
        return Boolean($rootScope.currentUser);
      };

      return $auth;
    };

  }

  function popup($q, $interval, $window) {
    // **Popup** constructor. The *popup* property refers to the `window`
    // object of the browser popup and the *polling* property is an interval
    // object assigned by the `Popup.prototype.pollPopup` method.
    var Popup = function() {
      this.popup = null;
      this.polling = null;
    };

    // Opens the popup with the optional `options` object to specify width and
    // height of a popup. An event listener is then added to the parent window
    // to wait for the `message` event from the popup. Meanwhile popup is
    // polled to detect when popup is abruptly closed by the user. Returns
    // promise that is either **rejected** in the `pollPopup` or **resolved**
    // in the `postMessageHandler`.
    Popup.prototype.open = function(url, options) {
      var deferred = $q.defer();
      var optionsString = stringifyOptions(prepareOptions(options || { }));

      this.popup = $window.open(url, 'ngAuth', optionsString);
      this.popup.focus();

      this.postMessageHandler(deferred);
      this.pollPopup(deferred);

      return deferred.promise;
    };

    // Polls the popup every 35 milliseconds. If popup is closed by the user
    // intervall polling is cancelled and promise is rejected.
    Popup.prototype.pollPopup = function(deferred) {
      this.polling = $interval(function() {
        if (this.popup.closed) {
          $interval.cancel(this.polling);
          deferred.reject('Popup was closed by the user.');
        }
      }.bind(this), 35);
    };

    // Listens for the *message* event that contains an `authorization_code`
    // string.
    Popup.prototype.postMessageHandler = function(deferred) {
      $window.addEventListener('message', function(event) {
        if (event.origin === $window.location.origin) {
          deferred.resolve(event.data);
        }
      }, false);
    };

    function prepareOptions(options) {
      var width = options.width || 500;
      var height = options.height || 500;
      return angular.extend({
        left: ((window.screen.width / 2) - (width / 2)),
        top: ((window.screen.height / 2) - (height / 2)),
        width: width,
        height: height
      }, options);
    }

    function stringifyOptions(options) {
      var optionsStrings = [];
      for (var key in options) {
        if (options.hasOwnProperty(key)) {
          var value;
          switch (options[key]) {
            case true:
              value = '1';
              break;
            case false:
              value = '0';
              break;
            default:
              value = options[key];
          }
          optionsStrings.push(
              key + '=' + value
          );
        }
      }
      return optionsStrings.join(',');
    }
  }

  function oauth1($q, $http, Popup) {
    var OAuth1 = function(config) {
      angular.extend(this, config);
      this.name = config.name;
      this.url = config.url;
      this.authorizationEndpoint = config.authorizationEndpoint;
      this.popupOptions = config.popupOptions;
    };

    OAuth1.prototype.tokenRequest = function() {
      return $http.post(this.url);
    };

    OAuth1.prototype.open = function() {
      var deferred = $q.defer();

      var popup = new Popup();
      popup.open(this.url).then(function(oauthData) {
        this.exchangeForToken(oauthData).then(function(response) {
          deferred.resolve(response.data);
        });
      }.bind(this));

      return deferred.promise;
    };

    OAuth1.prototype.exchangeForToken = function(oauthData) {
      return $http.get(this.url, { params: oauthData });
    };
  }

  function oauth2($q, $http, Utils, Popup) {
    var OAuth2 = function(config) {
      angular.extend(this, config);
      this.name = config.name;
      this.clientId = config.clientId;
      this.scope = config.scope;
      this.authorizationEndpoint = config.authorizationEndpoint;
      this.redirectUri = config.redirectUri;
      this.responseType = 'code';
      this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
      this.requiredUrlParams = config.requiredUrlParams;
      this.optionalUrlParams = config.optionalUrlParams;
      this.popupOptions = config.popupOptions;
    };

    OAuth2.prototype.open = function() {
      var deferred = $q.defer();
      var url = this.buildUrl();
      var popup = new Popup();

      popup.open(url, this.popupOptions).then(function(oauthData) {
        this.exchangeForToken(oauthData).then(function(response) {
          deferred.resolve(response.data);
        });
      }.bind(this));

      return deferred.promise;
    };

    OAuth2.prototype.exchangeForToken = function(oauthData) {
      return $http.post(this.url, {
        code: oauthData.code,
        clientId: this.clientId,
        redirectUri: this.redirectUri
      });
    };

    OAuth2.prototype.buildUrl = function() {
      var baseUrl = this.authorizationEndpoint;
      var qs = this.buildQueryString();
      return [baseUrl, qs].join('?');
    };

    OAuth2.prototype.buildQueryString = function() {
      var obj = this;
      var keyValuePairs = [];

      angular.forEach(this.defaultUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      angular.forEach(this.requiredUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      angular.forEach(this.optionalUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      return keyValuePairs.map(function(pair) {
        return pair.join('=');
      }).join('&');
    };
  }

  function httpInterceptor($httpProvider) {
    $httpProvider.interceptors.push(function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.jwtToken) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.jwtToken;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      };
    });
  }

  function onRun($rootScope, $window, $location, Utils) {
    var token = $window.localStorage.jwtToken;
    if (token) {
      var payload = JSON.parse($window.atob(token.split('.')[1]));
      $rootScope.currentUser = payload.user;
    }

    var params = $window.location.search.substring(1);
    var qs = Utils.parseQueryString(params);
    if ($window.opener && $window.opener.location.origin === $window.location.origin) {
      if (qs.oauth_token && qs.oauth_verifier) {
        $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
      } else if (qs.code) {
        $window.opener.postMessage({ code: qs.code }, '*');
      }
      $window.close();
    }

    $rootScope.$on('$routeChangeStart', function(event, current) {
      if ($rootScope[config.user] &&
        (current.originalPath === '/login' || current.originalPath === '/signup')) {
        $location.path('/');
      }
      if (current.authenticated && !$rootScope[config.user]) {
        $location.path('/login');
      }
    });
  }

  function utils() {
    this.camelCase = function(name) {
      return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
        return offset ? letter.toUpperCase() : letter;
      });
    };
    this.parseQueryString = function(keyValue) {
      var obj = { }, key, value;
      angular.forEach((keyValue || '').split('&'), function(keyValue) {
        if (keyValue) {
          value = keyValue.split('=');
          key = decodeURIComponent(value[0]);
          obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
        }
      });
      return obj;
    };
  }

})(window, window.angular);

<commit_msg>refactored oauth2 factory and authenticate method<commit_after>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  angular.module('Satellizer', [])
    .service('Utils', Utils)
    .factory('OAuth2', Oauth2)
    .factory('OAuth1', oauth1)
    .factory('Popup', popup)
    .provider('$auth', $auth)
    .config(httpInterceptor)
    .run(onRun);

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    loginRoute: '/login',
    signupRoute: '/signup',
    user: 'currentUser'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'oauth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'oauth1'
    }
  };

  function $auth() {

    this.config = config;

    this.setProvider = function(params) {
      angular.extend(providers[params.name], params);
    };

    this.addProvider = function(params) {
      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function(OAuth1, OAuth2, $http, $location, $rootScope, $q, $window) {

      var $auth = {};

      $auth.authenticate = function(providerName) {
        var deferred = $q.defer();

        var provider = (providers[providerName].type === 'oauth1') ? OAuth1 : OAuth2;

        provider.open().then(function(token) {
          var payload = JSON.parse($window.atob(token.split('.')[1]));
          $window.localStorage.jwtToken = token;
          $rootScope[config.user] = payload.user;
          $location.path(config.loginRedirect);
          deferred.resolve();
        });

        return deferred.promise;
      };

      $auth.login = function(user) {
        if (!user) {
          throw new Error('You must provide a user object.');
        }

        var deferred = $q.defer();

        $http.post(config.loginUrl, user)
          .success(function(data) {
            var payload = JSON.parse($window.atob(data.token.split('.')[1]));
            $rootScope[config.user] = payload.user;
            $location.path(config.loginRedirect);
            $window.localStorage.jwtToken = data.token;
            deferred.resolve(payload.user);
          })
          .error(function(error) {
            deferred.reject(error);
          });

        return deferred.promise;
      };

      $auth.signup = function(user) {
        $http.post(config.signupUrl, user).then(function() {
          $location.path(config.signupRedirect);
        });
      };

      $auth.logout = function() {
        delete $rootScope[config.user];
        delete $window.localStorage.jwtToken;
        $location.path(config.logoutRedirect);
      };

      $auth.isAuthenticated = function() {
        return Boolean($rootScope.currentUser);
      };

      return $auth;
    };

  }

  function popup($q, $interval, $window) {
    // **Popup** constructor. The *popup* property refers to the `window`
    // object of the browser popup and the *polling* property is an interval
    // object assigned by the `Popup.prototype.pollPopup` method.
    var Popup = function() {
      this.popup = null;
      this.polling = null;
    };

    // Opens the popup with the optional `options` object to specify width and
    // height of a popup. An event listener is then added to the parent window
    // to wait for the `message` event from the popup. Meanwhile popup is
    // polled to detect when popup is abruptly closed by the user. Returns
    // promise that is either **rejected** in the `pollPopup` or **resolved**
    // in the `postMessageHandler`.
    Popup.prototype.open = function(url, options) {
      var deferred = $q.defer();
      var optionsString = stringifyOptions(prepareOptions(options || { }));

      this.popup = $window.open(url, 'ngAuth', optionsString);
      this.popup.focus();

      this.postMessageHandler(deferred);
      this.pollPopup(deferred);

      return deferred.promise;
    };

    // Polls the popup every 35 milliseconds. If popup is closed by the user
    // intervall polling is cancelled and promise is rejected.
    Popup.prototype.pollPopup = function(deferred) {
      this.polling = $interval(function() {
        if (this.popup.closed) {
          $interval.cancel(this.polling);
          deferred.reject('Popup was closed by the user.');
        }
      }.bind(this), 35);
    };

    // Listens for the *message* event that contains an `authorization_code`
    // string.
    Popup.prototype.postMessageHandler = function(deferred) {
      $window.addEventListener('message', function(event) {
        if (event.origin === $window.location.origin) {
          deferred.resolve(event.data);
        }
      }, false);
    };

    function prepareOptions(options) {
      var width = options.width || 500;
      var height = options.height || 500;
      return angular.extend({
        left: ((window.screen.width / 2) - (width / 2)),
        top: ((window.screen.height / 2) - (height / 2)),
        width: width,
        height: height
      }, options);
    }

    function stringifyOptions(options) {
      var optionsStrings = [];
      for (var key in options) {
        if (options.hasOwnProperty(key)) {
          var value;
          switch (options[key]) {
            case true:
              value = '1';
              break;
            case false:
              value = '0';
              break;
            default:
              value = options[key];
          }
          optionsStrings.push(
              key + '=' + value
          );
        }
      }
      return optionsStrings.join(',');
    }
  }

  function oauth1($q, $http, Popup) {
    var OAuth1 = function(config) {
      angular.extend(this, config);
      this.name = config.name;
      this.url = config.url;
      this.authorizationEndpoint = config.authorizationEndpoint;
      this.popupOptions = config.popupOptions;
    };

    OAuth1.prototype.tokenRequest = function() {
      return $http.post(this.url);
    };

    OAuth1.prototype.open = function() {
      var deferred = $q.defer();

      var popup = new Popup();
      popup.open(this.url).then(function(oauthData) {
        this.exchangeForToken(oauthData).then(function(response) {
          deferred.resolve(response.data);
        });
      }.bind(this));

      return deferred.promise;
    };

    OAuth1.prototype.exchangeForToken = function(oauthData) {
      return $http.get(this.url, { params: oauthData });
    };
  }

  function Oauth2($q, $http, Utils, Popup) {
    var name = config.name;
    var url = config.url;
    var clientId = config.clientId;
    var scope = config.scope;
    var authorizationEndpoint = config.authorizationEndpoint;
    var redirectUri = config.redirectUri;
    var responseType = 'code';
    var defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
    var requiredUrlParams = config.requiredUrlParams;
    var optionalUrlParams = config.optionalUrlParams;
    var popupOptions = config.popupOptions;

    var oauth2 = {};

    oauth2.open = function() {
      var deferred = $q.defer();
      var url = this.buildUrl();
      var popup = new Popup();

      popup.open(url, popupOptions).then(function(oauthData) {
        oauth2.exchangeForToken(oauthData).then(function(response) {
          deferred.resolve(response.data);
        });
      });

      return deferred.promise;
    };

    oauth2.exchangeForToken = function(oauthData) {
      return $http.post(url, {
        code: oauthData.code,
        clientId: clientId,
        redirectUri: redirectUri
      });
    };

    oauth2.buildUrl = function() {
      var baseUrl = authorizationEndpoint;
      var qs = oauth2.buildQueryString();
      return [baseUrl, qs].join('?');
    };

    oauth2.buildQueryString = function() {
      var obj = this;
      var keyValuePairs = [];

      angular.forEach(this.defaultUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      angular.forEach(this.requiredUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      angular.forEach(this.optionalUrlParams, function(paramName) {
        var camelizedName = Utils.camelCase(paramName);
        var paramValue = obj[camelizedName];
        keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
      });

      return keyValuePairs.map(function(pair) {
        return pair.join('=');
      }).join('&');
    };

    return oauth2;
  }

  function httpInterceptor($httpProvider) {
    $httpProvider.interceptors.push(function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.jwtToken) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.jwtToken;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      };
    });
  }

  function onRun($rootScope, $window, $location, Utils) {
    var token = $window.localStorage.jwtToken;
    if (token) {
      var payload = JSON.parse($window.atob(token.split('.')[1]));
      $rootScope.currentUser = payload.user;
    }

    var params = $window.location.search.substring(1);
    var qs = Utils.parseQueryString(params);
    if ($window.opener && $window.opener.location.origin === $window.location.origin) {
      if (qs.oauth_token && qs.oauth_verifier) {
        $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
      } else if (qs.code) {
        $window.opener.postMessage({ code: qs.code }, '*');
      }
      $window.close();
    }

    $rootScope.$on('$routeChangeStart', function(event, current) {
      if ($rootScope[config.user] &&
        (current.originalPath === '/login' || current.originalPath === '/signup')) {
        $location.path('/');
      }
      if (current.authenticated && !$rootScope[config.user]) {
        $location.path('/login');
      }
    });
  }

  function Utils() {
    this.camelCase = function(name) {
      return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
        return offset ? letter.toUpperCase() : letter;
      });
    };
    this.parseQueryString = function(keyValue) {
      var obj = { }, key, value;
      angular.forEach((keyValue || '').split('&'), function(keyValue) {
        if (keyValue) {
          value = keyValue.split('=');
          key = decodeURIComponent(value[0]);
          obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
        }
      });
      return obj;
    };
  }

})(window, window.angular);

<|endoftext|>


<commit_before>'use strict';

exports.run = function (options, cb) {
  var page = require('webpage').create();
  var port = options.port || 3000;
  var id = options.id;
  var size = options.size || '800x600';
  var quality = options.quality || 100;
  var format = options.format || 'jpeg';
  var url = 'http://localhost:' + port + '/' + id;
  var validFormats = ['jpeg', 'png', 'gif', 'pdf'];

  if (validFormats.indexOf(format) === -1) {
    return cb('Invalid format type, valid options include: ' + validFormats.join(', '));
  }

  page.viewportSize = { width: 600, height: 600 };

  if (size) {
    size = size.split('x');
    page.viewportSize = { width: size[0], height: size[1] };
  }

  if (format === 'pdf') {
    if (size) {
      page.paperSize = { width: size[0], height: size[1], margin: '0px' };
    }

    page.paperSize = { format: 'A4', orientation: 'landscape', margin: '1cm' };
    page.viewportSize = undefined;
  }

  page.open(url, function () {
    var filePath = '.tmp/' + id + '.' + format;

    setTimeout(function () {
      page.render(filePath, { format: format, quality: quality });

      cb(undefined, filePath);

      page.close();
      phantom.exit();
    }, 200);
  });
};
<commit_msg>Fix accidental overwrite of paperSize<commit_after>'use strict';

exports.run = function (options, cb) {
  var page = require('webpage').create();
  var port = options.port || 3000;
  var id = options.id;
  var size = options.size || '800x600';
  var quality = options.quality || 100;
  var format = options.format || 'jpeg';
  var url = 'http://localhost:' + port + '/' + id;
  var validFormats = ['jpeg', 'png', 'gif', 'pdf'];

  if (validFormats.indexOf(format) === -1) {
    return cb('Invalid format type, valid options include: ' + validFormats.join(', '));
  }

  page.viewportSize = { width: 600, height: 600 };

  if (size) {
    size = size.split('x');
    page.viewportSize = { width: size[0], height: size[1] };
  }

  if (format === 'pdf') {
    if (size) {
      page.paperSize = { width: size[0], height: size[1], margin: '0px' };
    }
    else {
      page.paperSize = { format: 'A4', orientation: 'landscape', margin: '1cm' };
    }

    page.viewportSize = undefined;
  }

  page.open(url, function () {
    var filePath = '.tmp/' + id + '.' + format;

    setTimeout(function () {
      page.render(filePath, { format: format, quality: quality });

      cb(undefined, filePath);

      page.close();
      phantom.exit();
    }, 200);
  });
};
<|endoftext|>


<commit_before>var esl = require('../esl'),
utile = require('utile'),
events = require('events'),
xml2js = require('xml2js');

//liberal inspiration from: http://shimaore.github.com/esl/esl.html

var Parser = exports.Parser = function(socket) {
    events.EventEmitter.call(this);

    this.buffer = '';
    this.bodyLen = 0;
    this.encoding = 'utf8';

    this.socket = socket;
    this.socket.setEncoding(this.encoding);

    this.event = null;

    socket.on('data', this._onData.bind(this));
    socket.on('end', this._onEnd.bind(this));
};

utile.inherits(Parser, events.EventEmitter);

Parser.prototype._onData = function(data) {
    this.buffer += data;

    //if we have found a Content-Length header, parse as body
    if(this.bodyLen > 0)
        return this._parseBody();
    //otherwise this is more headers
    else
        return this._parseHeaders();
};

Parser.prototype._onEnd = function() {
};

Parser.prototype._parseHeaders = function() {
    //get end of header marker
    var headEnd = this.buffer.indexOf('\n\n'),
    headText;

    //if the headers haven't ended yet, keep buffering
    if(headEnd < 0)
        return;

    //if the headers have ended pull out the header text
    headText = this.buffer.substring(0, headEnd);

    //remove header text from buffer
    this.buffer = this.buffer.substring(headEnd + 2);

    //parse text into object
    this.headers = this._parseHeaderText(headText);

    if(this.headers['Content-Length']) {
        //set bodyLen so next data event with process as body
        this.bodyLen = this.headers['Content-Length'];

        //continue processing the buffer as body
        if(this.buffer.length) this._parseBody();
    }
    else {
        //an event is complete, emit it
        this._parseEvent(this.headers);

        //continue parsing the buffer
        if(this.buffer.length) this._parseHeaders();
    }
};

Parser.prototype._parseBody = function() {
    //haven't buffered the entire body yet
    if(Buffer.byteLength(this.buffer, this.encoding) < this.bodyLen)
        return;

    //create a real buffer with the data, and pull out the body
    //using byte lengths
    var buf = new Buffer(this.buffer),
        body = buf.slice(0, this.bodyLen).toString(this.encoding);

    this.buffer = buf.slice(this.bodyLen).toString(this.encoding);
    this.bodyLen = 0;

    //create the event
    this._parseEvent(this.headers, body);

    //continue procesing the buffer body has been pulled out
    this._parseHeaders();
};

Parser.prototype._parseHeaderText = function(txt) {
    var lines = txt.split('\n'),
    headers = {};

    lines.forEach(function(line, i) {
        var data = line.split(/: /, 2);
        headers[data[0]] = decodeURIComponent(data[1]);

        if(data[0] == 'Content-Length')
            headers[data[0]] = parseInt(headers[data[0]], 10);
    });

    return headers;
};

Parser.prototype._parseXmlBody = function(txt, cb) {
    //in the form:
    //<event>
    //  <headers>...</headers>
    //  <Content-Length>4</Content-Length> [optional]
    //  ... [optional]
    //</event>
    var parser = new xml2js.Parser({ explicitArray: false, explicitRoot: false }),
    self = this, headers = {};

    //parsing the xml is synchronous, despite the callback
    parser.parseString(txt, function(err, data) {
        if(err) {
            self.emit('error', err);
        }
        //do a little bit of massaging to get it into the same format
        //as what a JSON message looks like
        headers = data.headers;

        if(data.headers['Content-Length']) {
            headers['Content-Length'] = parseInt(data.headers['Content-Length'], 10);
            headers._body = data.body;
        }
    });

    return headers;
};

Parser.prototype._parsePlainBody = function(txt) {
    //if the body is event-plain then it is just a bunch of key/value pairs
    var headerEnd = txt.indexOf('\n\n'),
        headers = this._parseHeaderText(txt.substring(0, headerEnd));

    if(headers['Content-Length']) {
        var len = parseInt(headers['Content-Length'], 10),
            start = headerEnd + 2,
            end = start + len;

        //extract body with byte length
        headers._body = (new Buffer(txt)).slice(start, end).toString(this.encoding);
    }

    return headers;
};

Parser.prototype._parseEvent = function(headers, body) {
    var event, data;

    switch(headers['Content-Type']) {
        //parse body as JSON event data
    case 'text/event-json':
        try {
            data = JSON.parse(body);
            if(data['Content-Length'])
                data['Content-Length'] = parseInt(data['Content-Length'], 10);
        }
        catch(e) { this.emit('error', e); }
        break;

        //parse body as PLAIN event data
    case 'text/event-plain':
        data = this._parsePlainBody(body);
        break;

        //parse body as XML event data
    case 'text/event-xml':
        data = this._parseXmlBody(body);
        break;
    }

    if(data)
        event = new esl.Event(data);
    else
        event = new esl.Event(headers, body);

    //try and massage an OK/Error message
    var reply = event.getHeader('Reply-Text');
    if(reply) {
        if(reply.indexOf('-ERR') === 0) {
            event.addHeader('Modesl-Reply-ERR', reply.substring(5));
        } else if(reply.indexOf('+OK') === 0) {
            event.addHeader('Modesl-Reply-OK', reply.substring(4));
        }
    }

    this.emit('esl::event', event, headers, body);
};<commit_msg>use Buffer until last moment to avoid byte-length issues for garbage data<commit_after>var esl = require('../esl'),
utile = require('utile'),
events = require('events'),
xml2js = require('xml2js');

//liberal inspiration from: http://shimaore.github.com/esl/esl.html

var Parser = exports.Parser = function(socket) {
    events.EventEmitter.call(this);

    this.buffer = new Buffer([]);
    this.bodyLen = 0;
    this.encoding = 'utf8';

    this.socket = socket;

    this.event = null;

    socket.on('data', this._onData.bind(this));
    socket.on('end', this._onEnd.bind(this));
};

utile.inherits(Parser, events.EventEmitter);

Parser.prototype._onData = function(data) {
    this.buffer = Buffer.concat([this.buffer, data], this.buffer.length + data.length);

    //if we have found a Content-Length header, parse as body
    if(this.bodyLen > 0)
        return this._parseBody();
    //otherwise this is more headers
    else
        return this._parseHeaders();
};

Parser.prototype._onEnd = function() {
};

function findNewlineInBuffer(buffer, start, double) {
    for (var i = start || 0; i < buffer.length; i++) {
        if (buffer[i] == 0x0a) {
            if (double) {
                // Need to find a '\n\n'
                if (buffer[i + 1] == 0x0a) {
                    return i;
                }
            }
            else {
                return i;
            }
        }
    }
    return null;
}

Parser.prototype._parseHeaders = function() {
    //get end of header marker
    var headEnd = findNewlineInBuffer(this.buffer, 0, true),
    headText;

    //if the headers haven't ended yet, keep buffering
    if(headEnd === null) {
        return;
    }

    //if the headers have ended pull out the header text
    headText = this.buffer.toString(this.encoding, 0, headEnd);

    //remove header text from buffer
    this.buffer = this.buffer.slice(headEnd + 2);

    //parse text into object
    this.headers = this._parseHeaderText(headText);

    if(this.headers['Content-Length']) {
        //set bodyLen so next data event with process as body
        this.bodyLen = this.headers['Content-Length'];

        //continue processing the buffer as body
        if(this.buffer.length) this._parseBody();
    }
    else {
        //an event is complete, emit it
        this._parseEvent(this.headers);

        //continue parsing the buffer
        if(this.buffer.length) this._parseHeaders();
    }
};

Parser.prototype._parseBody = function() {
    //haven't buffered the entire body yet
    if(this.buffer.length < this.bodyLen)
        return;

    //pull out the body
    var body = this.buffer.slice(0, this.bodyLen).toString(this.encoding);

    this.buffer = this.buffer.slice(this.bodyLen);
    this.bodyLen = 0;

    //create the event
    this._parseEvent(this.headers, body);

    //continue procesing the buffer body has been pulled out
    this._parseHeaders();
};

Parser.prototype._parseHeaderText = function(txt) {
    var lines = txt.split('\n'),
    headers = {};

    lines.forEach(function(line, i) {
        var data = line.split(/: /, 2);
        headers[data[0]] = decodeURIComponent(data[1]);

        if(data[0] == 'Content-Length')
            headers[data[0]] = parseInt(headers[data[0]], 10);
    });

    return headers;
};

Parser.prototype._parseXmlBody = function(txt, cb) {
    //in the form:
    //<event>
    //  <headers>...</headers>
    //  <Content-Length>4</Content-Length> [optional]
    //  ... [optional]
    //</event>
    var parser = new xml2js.Parser({ explicitArray: false, explicitRoot: false }),
    self = this, headers = {};

    //parsing the xml is synchronous, despite the callback
    parser.parseString(txt, function(err, data) {
        if(err) {
            self.emit('error', err);
        }
        //do a little bit of massaging to get it into the same format
        //as what a JSON message looks like
        headers = data.headers;

        if(data.headers['Content-Length']) {
            headers['Content-Length'] = parseInt(data.headers['Content-Length'], 10);
            headers._body = data.body;
        }
    });

    return headers;
};

Parser.prototype._parsePlainBody = function(txt) {
    //if the body is event-plain then it is just a bunch of key/value pairs
    var headerEnd = txt.indexOf('\n\n'),
        headers = this._parseHeaderText(txt.substring(0, headerEnd));

    if(headers['Content-Length']) {
        var len = parseInt(headers['Content-Length'], 10),
            start = headerEnd + 2,
            end = start + len;

        //extract body with byte length
        headers._body = (new Buffer(txt)).slice(start, end).toString(this.encoding);
    }

    return headers;
};

Parser.prototype._parseEvent = function(headers, body) {
    var event, data;

    switch(headers['Content-Type']) {
        //parse body as JSON event data
    case 'text/event-json':
        try {
            data = JSON.parse(body);
            if(data['Content-Length'])
                data['Content-Length'] = parseInt(data['Content-Length'], 10);
        }
        catch(e) { this.emit('error', e); }
        break;

        //parse body as PLAIN event data
    case 'text/event-plain':
        data = this._parsePlainBody(body);
        break;

        //parse body as XML event data
    case 'text/event-xml':
        data = this._parseXmlBody(body);
        break;
    }

    if(data)
        event = new esl.Event(data);
    else
        event = new esl.Event(headers, body);

    //try and massage an OK/Error message
    var reply = event.getHeader('Reply-Text');
    if(reply) {
        if(reply.indexOf('-ERR') === 0) {
            event.addHeader('Modesl-Reply-ERR', reply.substring(5));
        } else if(reply.indexOf('+OK') === 0) {
            event.addHeader('Modesl-Reply-OK', reply.substring(4));
        }
    }

    this.emit('esl::event', event, headers, body);
};<|endoftext|>


<commit_before>var stream = require("stream");

var amf = require("amf"),
    compost = require("compost");

var FLVSerialiser = module.exports = function FLVSerialiser(options, config) {
  options = options || {};

  options.objectMode = true;

  stream.Transform.call(this, options);

  this._writtenHeader = false;

  config = config || {};

  this.version = config.version || 1;
  this.flags = config.flags || {};
};
FLVSerialiser.prototype = Object.create(stream.Transform.prototype);

FLVSerialiser.prototype._transform = function _transform(input, encoding, done) {
  if (input.header && !this._writtenHeader) {
    this.version = input.header.version;
    this.flags = input.header.flags;
  }

  if (!input.packet) {
    return done();
  }

  if (!this._writtenHeader) {
    this.push(Buffer([
      0x46, 0x4c, 0x56,
      this.version,
      compost.compose(this.flags),
      0, 0, 0, 9,
      0, 0, 0, 0,
    ]));

    this._writtenHeader = true;
  }

  var packet = Buffer(input.packet.length + 11 + 4);

  packet[0]  = (input.packet.type     & 255);
  packet[1]  = (input.packet.length   & 16711680) / 65536;
  packet[2]  = (input.packet.length   & 65280) / 256;
  packet[3]  = (input.packet.length   & 255);
  packet[4]  = (input.packet.time     & 16711680) / 65536;
  packet[5]  = (input.packet.time     & 65280) / 256;
  packet[6]  = (input.packet.time     & 255);
  packet[7]  = (input.packet.time     & 4278190080) / 16777216;
  packet[8]  = (input.packet.streamId & 16711680) / 65536;
  packet[9]  = (input.packet.streamId & 65280) / 256;
  packet[10] = (input.packet.streamId & 255);

  input.packet.data.copy(packet, 11);

  packet.writeUInt32BE(input.packet.length + 11, input.packet.length + 11);

  this.push(packet);

  return done();
};
<commit_msg>rename config to headerFields<commit_after>var stream = require("stream");

var amf = require("amf"),
    compost = require("compost");

var FLVSerialiser = module.exports = function FLVSerialiser(options, headerFields) {
  options = options || {};

  options.objectMode = true;

  stream.Transform.call(this, options);

  this._writtenHeader = false;

  headerFields = headerFields || {};

  this.version = headerFields.version || 1;
  this.flags = headerFields.flags || {};
};
FLVSerialiser.prototype = Object.create(stream.Transform.prototype);

FLVSerialiser.prototype._transform = function _transform(input, encoding, done) {
  if (input.header && !this._writtenHeader) {
    this.version = input.header.version;
    this.flags = input.header.flags;
  }

  if (!input.packet) {
    return done();
  }

  if (!this._writtenHeader) {
    this.push(Buffer([
      0x46, 0x4c, 0x56,
      this.version,
      compost.compose(this.flags),
      0, 0, 0, 9,
      0, 0, 0, 0,
    ]));

    this._writtenHeader = true;
  }

  var packet = Buffer(input.packet.length + 11 + 4);

  packet[0]  = (input.packet.type     & 255);
  packet[1]  = (input.packet.length   & 16711680) / 65536;
  packet[2]  = (input.packet.length   & 65280) / 256;
  packet[3]  = (input.packet.length   & 255);
  packet[4]  = (input.packet.time     & 16711680) / 65536;
  packet[5]  = (input.packet.time     & 65280) / 256;
  packet[6]  = (input.packet.time     & 255);
  packet[7]  = (input.packet.time     & 4278190080) / 16777216;
  packet[8]  = (input.packet.streamId & 16711680) / 65536;
  packet[9]  = (input.packet.streamId & 65280) / 256;
  packet[10] = (input.packet.streamId & 255);

  input.packet.data.copy(packet, 11);

  packet.writeUInt32BE(input.packet.length + 11, input.packet.length + 11);

  this.push(packet);

  return done();
};
<|endoftext|>


<commit_before>/**
 * Module that is a function that will get a list of handlers for a named event.
 * Then call each of the handlers with the passed in payload.
 *
 * @param name - Name of the event
 * @param filter - Event filter (node, type, contentid)
 * @param payload - Custom object that will get passed to the event handler
 */
module.exports = function ( name, filter, payload ) {
    'use strict';

    var async = require('async'),
        q = require('q'),
        listeners = require('./listeners'),
        handlers = listeners.filter(name, filter),
        deferred = q.defer();

    async.applyEachSeries(handlers, payload, function(err){
        if(err){
            deferred.reject(err);
        }
        else {
            deferred.resolve();
        }
    });

    return deferred.promise;
};<commit_msg>Changed up the event deferred to resolve with the payload.<commit_after>/**
 * Module that is a function that will get a list of handlers for a named event.
 * Then call each of the handlers with the passed in payload.
 *
 * @param name - Name of the event
 * @param filter - Event filter (node, type, contentid)
 * @param payload - Custom object that will get passed to the event handler
 */
module.exports = function ( name, filter, payload ) {
    'use strict';

    var async = require('async'),
        q = require('q'),
        listeners = require('./listeners'),
        handlers = listeners.filter(name, filter),
        deferred = q.defer();

    async.applyEachSeries(handlers, payload, function(err){
        if(err){
            deferred.reject(err);
        }
        else {
            deferred.resolve(payload);
        }
    });

    return deferred.promise;
};<|endoftext|>


<commit_before>var _ = require('underscore'),
    fs = require('fs'),
    printf = require('printf'),
    sourceMap = require('./source-map');

const CONTEXT = 4;

module.exports = {
  debug: false,
  exec: exec,
  processError: processError,
  rewriteStack: rewriteStack
};

function exec(exec) {
  try {
    exec();
  } catch (err) {
    processError(err);
    throw err;
  }
}

function processError(err) {
  if (err.clientProcessed) {
    return;
  }

  err.clientProcessed = true;

  var stack = err.stack,
      map = mapReference(stack),
      fileLines = '';

  if (map) {
    try {
      fileLines = fileContext(map.source, map.line) + '\n';
    } catch (err) {
      /* NOP */
    }

    stack = stack.split(/\n/);
    var msg = stack.shift() + '\n' + fileLines;

    err.message = msg;
    err.stack = msg + rewriteStack(stack);
  }
}

/*
 * Rewrites all matching source references for the given input.
 */
function rewriteStack(stack) {
  if (!_.isArray(stack)) {
    stack = stack.split(/\n/g);
  }

  var msg = '',
      seenClient = true;
  for (var i = 0; i < stack.length; i++) {
    var frame = stack[i];
    if (!module.exports.debug && (frame.indexOf('fruit-loops/lib') >= 0 || frame.indexOf('fruit-loops/node_modules') >= 0)) {
      // Don't include anything more than the code we called
      if (seenClient) {
        msg += '  at (native)\n';
        seenClient = false;
      }
    } else {
      seenClient = true;

      var lookup = mapReference(frame);
      if (lookup) {
        msg += '  at' + (lookup.name ? ' ' + lookup.name : '') + ' (' + lookup.source + (lookup.line ? ':' + lookup.line : '') + (lookup.column ? ':' + lookup.column : '') + ')\n';
      } else if (frame || i + 1 < stack.length) {
        msg += frame + '\n';
      }
    }
  }
  return msg;
}

/*
 * Uses source map to map an execption from source maped output to input.
 */
function mapReference(pathRef) {
  try {
    var match = /^\s+at (?:(.*?) \((.*?)\)|(.*?))$/m.exec(pathRef),
        location = match && (match[2] || match[3]),
        components = location.split(/:/g);

    var map = sourceMap.map(components[0], parseInt(components[1], 10), parseInt(components[2], 10));
    map.name = match[1];
    return map;
  } catch (err) {
    /* NOP */
  }
}

/*
 * Pulls the file content around the point that failed.
 */
function fileContext(file, line) {
  // Input is 1 indexed, the array is 0 indexed.
  line--;

  var content = fs.readFileSync(file),
      lines = content.toString().split(/\n/g),

      start = Math.max(0, line - CONTEXT),
      end = Math.min(line + CONTEXT, lines.length),

      msg = '';

  for (var i = start; i < end; i++) {
    msg += printf('\t% 6d:%s %s\n', i+1, i === line ? '>' : ' ', lines[i]);
  }
  return msg;
}
<commit_msg>Do not emit unnecessary newlines in rewrite<commit_after>var _ = require('underscore'),
    fs = require('fs'),
    printf = require('printf'),
    sourceMap = require('./source-map');

const CONTEXT = 4;

module.exports = {
  debug: false,
  exec: exec,
  processError: processError,
  rewriteStack: rewriteStack
};

function exec(exec) {
  try {
    exec();
  } catch (err) {
    processError(err);
    throw err;
  }
}

function processError(err) {
  if (err.clientProcessed) {
    return;
  }

  err.clientProcessed = true;

  var stack = err.stack,
      map = mapReference(stack),
      fileLines = '';

  if (map) {
    try {
      fileLines = fileContext(map.source, map.line) + '\n';
    } catch (err) {
      /* NOP */
    }

    stack = stack.split(/\n/);
    var msg = stack.shift() + '\n' + fileLines;

    err.message = msg;
    err.stack = msg + rewriteStack(stack);
  }
}

/*
 * Rewrites all matching source references for the given input.
 */
function rewriteStack(stack) {
  if (!_.isArray(stack)) {
    stack = stack.split(/\n/g);
  }

  var msg = '',
      seenClient = true;
  for (var i = 0; i < stack.length; i++) {
    var frame = stack[i];
    if (!module.exports.debug && (frame.indexOf('fruit-loops/lib') >= 0 || frame.indexOf('fruit-loops/node_modules') >= 0)) {
      // Don't include anything more than the code we called
      if (seenClient) {
        msg += '  at (native)\n';
        seenClient = false;
      }
    } else {
      seenClient = true;

      var lookup = mapReference(frame);
      if (lookup) {
        msg += '  at' + (lookup.name ? ' ' + lookup.name : '') + ' (' + lookup.source + (lookup.line ? ':' + lookup.line : '') + (lookup.column ? ':' + lookup.column : '') + ')\n';
      } else {
        msg += (frame || '') + (i + 1 < stack.length ? '\n' : '');
      }
    }
  }
  return msg;
}

/*
 * Uses source map to map an execption from source maped output to input.
 */
function mapReference(pathRef) {
  try {
    var match = /^\s+at (?:(.*?) \((.*?)\)|(.*?))$/m.exec(pathRef),
        location = match && (match[2] || match[3]),
        components = location.split(/:/g);

    var map = sourceMap.map(components[0], parseInt(components[1], 10), parseInt(components[2], 10));
    map.name = match[1];
    return map;
  } catch (err) {
    /* NOP */
  }
}

/*
 * Pulls the file content around the point that failed.
 */
function fileContext(file, line) {
  // Input is 1 indexed, the array is 0 indexed.
  line--;

  var content = fs.readFileSync(file),
      lines = content.toString().split(/\n/g),

      start = Math.max(0, line - CONTEXT),
      end = Math.min(line + CONTEXT, lines.length),

      msg = '';

  for (var i = start; i < end; i++) {
    msg += printf('\t% 6d:%s %s\n', i+1, i === line ? '>' : ' ', lines[i]);
  }
  return msg;
}
<|endoftext|>