<commit_before>/**
 * QClient.js
 * ==========
 * Main module exported from this library.
 */

/**
 * QClient
 * -------
 * The main function exposed to your code.
 * QClient will take your client ID and token
 * and set up subsequent API calls.
 *
 * `clientId` [String] - The Client ID you are given when signing up for Q
 * `secretToken` [String] - The secret token you are given when signin up for Q
 */
function QClient(clientId, secretToken) {
  // body...
}
<commit_msg>Add QClient function and object prototype.<commit_after>/**
 * QClient.js
 * ==========
 * Main module exported from this library.
 */

// Require our dependencies
var http    = require('http'),
    crypto  = require('crypto');

/**
 * QClient
 * -------
 * The main function exposed to your code.
 * QClient will take your client ID and token
 * and set up subsequent API calls.
 *
 * `clientId` [String] - The Client ID you are given when signing up for Q
 * `secretToken` [String] - The secret token you are given when signin up for Q
 */
function QClient(clientId, secretToken) {
  if (!(this instanceof QClient)) return new QClient(clientId, secretToken);

  this.setApiKey(clientId);
  this.setToken(secretToken);
}

QClient.prototype = {
  setApiKey: function(key) {
    if (key) this.clientId = key;
  },

  setToken: function(secret) {
    if (secret) this.secretToken = secret;
  },

  /**
   * Signature
   * ---------
   * Build a signature to send in the
   * request header.
   */
  signature: function(endpoint, reqBody) {
    var hmac = crypto.createHmac('sha1', this.secretToken).setEncoding('hex');
    hmac.write(endpoint + reqBody);
    hmac.end();
    return hmac.read();
  },

  getSubsidy: function(state, zip, demographics) {
    var endpoint      = ['/plans', state, zip].join('/'),
        demographics  = JSON.stringify(demographics);

    var request = http.request({
      host: 'localhost',
      path: endpoint,
      port: 9292,
      method: 'POST',
      headers: { 'Authorization': [this.clientId, this.signature(endpoint, demographics)].join(':') }
    }, function(response) {
      var reply = '';
      response.on('data', function(chunk) {
        reply += chunk;
      });

      response.on('end', function() {
        console.log(reply);

        return reply;
      });
    });

    request.write(demographics);

    console.log(endpoint, [this.clientId, this.signature(endpoint, demographics)].join(':'));

    return request.end();
  }
};

module.exports = QClient;
<|endoftext|>


<commit_before>/*
 * grunt
 * http://gruntjs.com/
 *
 * Copyright (c) 2012 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 */

'use strict';

// Nodejs libs.
var path = require('path');

// This allows grunt to require() .coffee files.
require('coffee-script');

// The module to be exported.
var grunt = module.exports = {};

// Expose internal grunt libs.
function gRequire(name) {
  return grunt[name] = require('./grunt/' + name);
}
var util = gRequire('util');
gRequire('template');
gRequire('event');
var fail = gRequire('fail');
var file = gRequire('file');
var option = gRequire('option');
var config = gRequire('config');
var task = gRequire('task');
var log = gRequire('log');
var help = gRequire('help');
gRequire('cli');
var verbose = grunt.verbose = log.verbose;

// Expose some grunt metadata.
grunt.package = file.readJSON(path.join(__dirname, '../package.json'));
grunt.version = grunt.package.version;

// Expose specific grunt lib methods on grunt.
function gExpose(obj, methodName, newMethodName) {
  grunt[newMethodName || methodName] = obj[methodName].bind(obj);
}
gExpose(task, 'registerTask');
gExpose(task, 'unregisterTasks');
gExpose(task, 'registerMultiTask');
gExpose(task, 'registerInitTask');
gExpose(task, 'renameTask');
gExpose(task, 'loadTasks');
gExpose(task, 'registerTask');
gExpose(task, 'loadNpmTasks');
gExpose(config, 'init', 'initConfig');
gExpose(fail, 'warn');
gExpose(fail, 'fatal');

// Handle otherwise unhandleable (probably asynchronous) exceptions.
process.on('uncaughtException', function (e) {
  fail.fatal(e, fail.code.TASK_FAILURE);
});

// Expose the task interface. I've never called this manually, and have no idea
// how it will work. But it might.
grunt.tasks = function(tasks, options, done) {
  // Update options with passed-in options.
  option.init(options);

  // Display the grunt version and quit if the user did --version.
  if (option('version')) {
    // Not --verbose.
    verbose.or.writeln('grunt v' + grunt.version);
    // --verbose
    verbose.writeln('Version: v' + grunt.version);
    verbose.writeln('Install path: ' + path.resolve(__dirname, '..'));
    return;
  }

  // Init colors.
  log.initColors();

  // Display help and quit if the user did --help.
  if (option('help')) {
    help.display();
    return;
  }

  // Display bash completion and quit if the user did --completion=bash.
  if (option('completion')) {
    require('./grunt/completion');
    return;
  }

  // A little header stuff.
  verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');

  // Determine and output which tasks will be run.
  var tasksSpecified = tasks && tasks.length > 0;
  tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);

  // Initialize tasks.
  task.init(tasks);

  verbose.writeln();
  if (!tasksSpecified) {
    verbose.writeln('No tasks specified, running default tasks.');
  }
  verbose.writeflags(tasks, 'Running tasks');

  // Report, etc when all tasks have completed.
  task.options({
    error: function(e) {
      fail.warn(e, fail.code.TASK_FAILURE);
    },
    done: function() {
      // Output a final fail / success report.
      fail.report();

      if (done) {
        // Execute "done" function when done (only if passed, of course).
        done();
      } else {
        // Otherwise, explicitly exit.
        util.exit(0);
      }
    }
  });

  // Execute all tasks, in order. Passing each task individually in a forEach
  // allows the error callback to execute multiple times.
  tasks.forEach(function(name) { task.run(name); });
  task.start();
};
<commit_msg>Minor tweaks to the way --version --verbose is displayed.<commit_after>/*
 * grunt
 * http://gruntjs.com/
 *
 * Copyright (c) 2012 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 */

'use strict';

// Nodejs libs.
var path = require('path');

// This allows grunt to require() .coffee files.
require('coffee-script');

// The module to be exported.
var grunt = module.exports = {};

// Expose internal grunt libs.
function gRequire(name) {
  return grunt[name] = require('./grunt/' + name);
}
var util = gRequire('util');
gRequire('template');
gRequire('event');
var fail = gRequire('fail');
var file = gRequire('file');
var option = gRequire('option');
var config = gRequire('config');
var task = gRequire('task');
var log = gRequire('log');
var help = gRequire('help');
gRequire('cli');
var verbose = grunt.verbose = log.verbose;

// Expose some grunt metadata.
grunt.package = file.readJSON(path.join(__dirname, '../package.json'));
grunt.version = grunt.package.version;

// Expose specific grunt lib methods on grunt.
function gExpose(obj, methodName, newMethodName) {
  grunt[newMethodName || methodName] = obj[methodName].bind(obj);
}
gExpose(task, 'registerTask');
gExpose(task, 'unregisterTasks');
gExpose(task, 'registerMultiTask');
gExpose(task, 'registerInitTask');
gExpose(task, 'renameTask');
gExpose(task, 'loadTasks');
gExpose(task, 'registerTask');
gExpose(task, 'loadNpmTasks');
gExpose(config, 'init', 'initConfig');
gExpose(fail, 'warn');
gExpose(fail, 'fatal');

// Handle otherwise unhandleable (probably asynchronous) exceptions.
process.on('uncaughtException', function (e) {
  fail.fatal(e, fail.code.TASK_FAILURE);
});

// Expose the task interface. I've never called this manually, and have no idea
// how it will work. But it might.
grunt.tasks = function(tasks, options, done) {
  // Update options with passed-in options.
  option.init(options);

  // Display the grunt version and quit if the user did --version.
  if (option('version')) {
    // Not --verbose.
    log.writeln('grunt v' + grunt.version);
    // --verbose
    verbose.writeln('Install path: ' + path.resolve(__dirname, '..'));
    return;
  }

  // Init colors.
  log.initColors();

  // Display help and quit if the user did --help.
  if (option('help')) {
    help.display();
    return;
  }

  // Display bash completion and quit if the user did --completion=bash.
  if (option('completion')) {
    require('./grunt/completion');
    return;
  }

  // A little header stuff.
  verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');

  // Determine and output which tasks will be run.
  var tasksSpecified = tasks && tasks.length > 0;
  tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);

  // Initialize tasks.
  task.init(tasks);

  verbose.writeln();
  if (!tasksSpecified) {
    verbose.writeln('No tasks specified, running default tasks.');
  }
  verbose.writeflags(tasks, 'Running tasks');

  // Report, etc when all tasks have completed.
  task.options({
    error: function(e) {
      fail.warn(e, fail.code.TASK_FAILURE);
    },
    done: function() {
      // Output a final fail / success report.
      fail.report();

      if (done) {
        // Execute "done" function when done (only if passed, of course).
        done();
      } else {
        // Otherwise, explicitly exit.
        util.exit(0);
      }
    }
  });

  // Execute all tasks, in order. Passing each task individually in a forEach
  // allows the error callback to execute multiple times.
  tasks.forEach(function(name) { task.run(name); });
  task.start();
};
<|endoftext|>


<commit_before>var events = require('events');
var util = require('util');
var http = require('http');
var ws = require('ws');
var websocket = require('websocket-stream');
var pkgcloud = require('pkgcloud');

var WebSocketServer = ws.Server;

module.exports = Hades;

util.inherits(Hades, events.EventEmitter);

function Hades(options) {
  if(!this instanceof Hades) {
    return new Hades(options);
  }
  events.EventEmitter.call(this);

  this.pkgcloudOpts = options.pkgcloud;

  if(!this.pkgcloudOpts) {
    this.emit('error', new Error('pkgcloud options are required'));
    return process.exit();
  }

  this.pkgcloud = pkgcloud.storage.createClient(this.pkgcloudOpts);

  this.pkgcloud.on('error', this.emit.bind('error'));

  this.server = http.createServer(this._requestHandler.bind(this));

  this.wss = new WebSocketServer({server: this.server});

  this.wss.on('connection', this._onSocketConnect.bind(this));

}

Hades.prototype.listen = function (port, callback) {
  this.server.listen(port, callback);
};

Hades.prototype._requestHandler = function (req, res) {
  res.writeHead(500);
  res.end('Not available right now\n');
};

Hades.prototype._onSocketConnect = function (socket) {
  var stream = websocket(socket);

  var upload = this.pkgcloud.upload();

  stream.pipe(upload);
};

<commit_msg>[minor fix] OCD<commit_after>var events = require('events');
var util = require('util');
var http = require('http');
var ws = require('ws');
var websocket = require('websocket-stream');
var pkgcloud = require('pkgcloud');

var WebSocketServer = ws.Server;

module.exports = Hades;

util.inherits(Hades, events.EventEmitter);

function Hades(options) {
  if(!this instanceof Hades) { return new Hades(options) }
  events.EventEmitter.call(this);

  this.pkgcloudOpts = options.pkgcloud;

  if(!this.pkgcloudOpts) {
    this.emit('error', new Error('pkgcloud options are required'));
    return process.exit();
  }

  this.pkgcloud = pkgcloud.storage.createClient(this.pkgcloudOpts);

  this.pkgcloud.on('error', this.emit.bind('error'));

  this.server = http.createServer(this._requestHandler.bind(this));

  this.wss = new WebSocketServer({server: this.server});

  this.wss.on('connection', this._onSocketConnect.bind(this));

}

Hades.prototype.listen = function (port, callback) {
  this.server.listen(port, callback);
};

Hades.prototype._requestHandler = function (req, res) {
  res.writeHead(500);
  res.end('Not available right now\n');
};

Hades.prototype._onSocketConnect = function (socket) {
  var stream = websocket(socket);

  var upload = this.pkgcloud.upload();

  stream.pipe(upload);
};

<|endoftext|>


<commit_before>function getsnippet(code) {
  var js = "!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src=n,s.parentNode.insertBefore(o,s)}(window,document,\"script\",\"\/\/www.google-analytics.com\/analytics.js\",\"ga\"),ga(\"create\",\"" + code + "\",\"auto\"),ga(\"send\",\"pageview\");";
  var snippet = "<script>" + '\n' + js + '\n' + "</script>";

  return snippet;
}

function addsnippet(code) {
  var js = "!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src=n,s.parentNode.insertBefore(o,s)}(window,document,\"script\",\"\/\/www.google-analytics.com\/analytics.js\",\"ga\"),ga(\"create\",\"" + code + "\",\"auto\"),ga(\"send\",\"pageview\");";
  var snippet = '\n' + js + '\n';

  var script = document.createElement('script');
  script.innerHTML = snippet;

  document.getElementsByTagName('head')[0].appendChild(script);
}
<commit_msg>fix script<commit_after>function getsnippet(code) {
  var js = "(function(i,s,o,g,r,a,m){i[\'GoogleAnalyticsObject\']=r;i[r]=i[r]||function(){\r\n  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\r\n  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\r\n  })(window,document,\'script\',\'\/\/www.google-analytics.com\/analytics.js\',\'ga\');\r\n\r\n  ga(\'create\', \'" + code + "\', \'auto\');\r\n  ga(\'send\', \'pageview\');";
  var snippet = "<script>" + '\n' + js + '\n' + "</script>";

  return snippet;
}

function addsnippet(code) {
  var js = "(function(i,s,o,g,r,a,m){i[\'GoogleAnalyticsObject\']=r;i[r]=i[r]||function(){\r\n  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\r\n  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\r\n  })(window,document,\'script\',\'\/\/www.google-analytics.com\/analytics.js\',\'ga\');\r\n\r\n  ga(\'create\', \'" + code + "\', \'auto\');\r\n  ga(\'send\', \'pageview\');";
  var snippet = '\n' + js + '\n';

  var script = document.createElement('script');
  script.innerHTML = snippet;

  document.getElementsByTagName('head')[0].appendChild(script);
}
<|endoftext|>


<commit_before>'use strict';

var Utils = require('./utils')
  , Promise = require('./promise');

/**
 * Hooks are function that are called before and after  (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
 *
 * 1. By specifying them as options in `sequelize.define`
 * 2. By calling `hook()` with a string and your hook handler function
 * 3. By calling the function with the same name as the hook you want

 * ```js
 * // Method 1
 * sequelize.define(name, { attributes }, {
 *   hooks: {
 *     beforeBulkCreate: function () {
 *       // can be a single function
 *     },
 *     beforeValidate: [
 *       function () {},
 *       function() {} // Or an array of several
 *     ]
 *   }
 * })
 *
 * // Method 2
 * Model.hook('afterDestroy', function () {})
 *
 * // Method 3
 * Model.afterBulkUpdate(function () {})
 * ```
 *
 * @see {Sequelize#define}
 * @mixin Hooks
 */
var Hooks = module.exports = function() {};
var hookTypes = {
  beforeValidate: {params: 2},
  afterValidate: {params: 2},
  beforeCreate: {params: 2},
  afterCreate: {params: 2},
  beforeDestroy: {params: 2},
  afterDestroy: {params: 2},
  beforeUpdate: {params: 2},
  afterUpdate: {params: 2},
  beforeBulkCreate: {params: 2},
  afterBulkCreate: {params: 2},
  beforeBulkDestroy: {params: 1},
  afterBulkDestroy: {params: 1},
  beforeBulkUpdate: {params: 1},
  afterBulkUpdate: {params: 1},
  beforeFind: {params: 1},
  beforeFindAfterExpandIncludeAll: {params: 1},
  beforeFindAfterOptions: {params: 1},
  afterFind: {params: 2}
};
var hookAliases = {
  beforeDelete: 'beforeDestroy',
  afterDelete: 'afterDestroy',
  beforeBulkDelete: 'beforeBulkDestroy',
  afterBulkDelete: 'afterBulkDestroy'
};

Hooks.replaceHookAliases = function(hooks) {
  var realHookName;

  Utils._.each(hooks, function(hooksArray, name) {
    // Does an alias for this hook name exist?
    if (realHookName = hookAliases[name]) {
      // Add the hooks to the actual hook
      hooks[realHookName] = (hooks[realHookName] || []).concat(hooksArray);

      // Delete the alias
      delete hooks[name];
    }
  });

  return hooks;
};

Hooks.runHooks = function(hooks) {
  var self = this
    , fn
    , fnArgs = Array.prototype.slice.call(arguments, 1)
    , hookType;

  if (typeof fnArgs[fnArgs.length - 1] === 'function') {
    fn = fnArgs.pop();
  }

  if (typeof hooks === 'string') {
    hookType = hooks;
    hooks = this.options.hooks[hookType] || [];
	if (!Array.isArray(hooks)) hooks = hooks === undefined ? [] : [hooks];
	if (this.sequelize) hooks = hooks.concat(this.sequelize.options.hooks[hookType] || []);
  }

  if (!Array.isArray(hooks)) {
    hooks = hooks === undefined ? [] : [hooks];
  }

  var promise = Promise.each(hooks, function (hook) {
    if (typeof hook === 'object') {
      hook = hook.fn;
    }

    if (hookType && hook.length > hookTypes[hookType].params) {
      hook = Promise.promisify(hook, self);
    }

    return hook.apply(self, fnArgs);
  }).return();

  if (fn) {
    return promise.nodeify(fn);
  }

  return promise;
};

Hooks.hook = function() {
  return Hooks.addHook.apply(this, arguments);
};

/**
 * Add a hook to the model
 *
 * @param {String}    hooktype
 * @param {String}    [name]    Provide a name for the hook function. This serves no purpose, other than the ability to be able to order hooks based on some sort of priority system in the future.
 * @param {Function}  fn        The hook function
 *
 * @alias hook
 */
Hooks.addHook = function(hookType, name, fn) {
  if (typeof name === 'function') {
    fn = name;
    name = null;
  }

  // Aliases
  hookType = hookAliases[hookType] || hookType;

  // Just in case if we override the default DAOFactory.options
  this.options.hooks[hookType] = this.options.hooks[hookType] || [];
  this.options.hooks[hookType][this.options.hooks[hookType].length] = !!name ? {name: name, fn: fn} : fn;
  return this;
};

/**
 * A hook that is run before validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeValidate', name, fn);
};

/**
 * A hook that is run after validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterValidate', name, fn);
};

/**
 * A hook that is run before creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.beforeCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeCreate', name, fn);
};

/**
 * A hook that is run after creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.afterCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterCreate', name, fn);
};

/**
 * A hook that is run before destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias beforeDelete
 */
Hooks.beforeDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDestroy', name, fn);
};

Hooks.beforeDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDelete', name, fn);
};

/**
 * A hook that is run after destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias afterDelete
 */
Hooks.afterDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDestroy', name, fn);
};

Hooks.afterDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDelete', name, fn);
};

/**
 * A hook that is run before updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeUpdate', name, fn);
};

/**
 * A hook that is run after updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterUpdate', name, fn);
};

/**
 * A hook that is run before creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.beforeBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkCreate', name, fn);
};

/**
 * A hook that is run after creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.afterBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkCreate', name, fn);
};

/**
 * A hook that is run before destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias beforeBulkDelete
 */
Hooks.beforeBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDestroy', name, fn);
};

Hooks.beforeBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDelete', name, fn);
};

/**
 * A hook that is run after destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias afterBulkDelete
 */
Hooks.afterBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDestroy', name, fn);
};

Hooks.afterBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDelete', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkUpdate', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.afterBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkUpdate', name, fn);
};

/**
 * A hook that is run before a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFind = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFind', name, fn);
};

/**
 * A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterExpandIncludeAll = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterExpandIncludeAll', name, fn);
};

/**
 * A hook that is run before a find (select) query, after all option parsing is complete
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterOptions = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterOptions', name, fn);
};

/**
 * A hook that is run after a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance(s), options, callback(err)
 */
Hooks.afterFind = function(name, fn) {
  return Hooks.addHook.call(this, 'afterFind', name, fn);
};
<commit_msg>Hooks run sync in sync functions<commit_after>'use strict';

var Utils = require('./utils')
  , Promise = require('./promise');

/**
 * Hooks are function that are called before and after  (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
 *
 * 1. By specifying them as options in `sequelize.define`
 * 2. By calling `hook()` with a string and your hook handler function
 * 3. By calling the function with the same name as the hook you want

 * ```js
 * // Method 1
 * sequelize.define(name, { attributes }, {
 *   hooks: {
 *     beforeBulkCreate: function () {
 *       // can be a single function
 *     },
 *     beforeValidate: [
 *       function () {},
 *       function() {} // Or an array of several
 *     ]
 *   }
 * })
 *
 * // Method 2
 * Model.hook('afterDestroy', function () {})
 *
 * // Method 3
 * Model.afterBulkUpdate(function () {})
 * ```
 *
 * @see {Sequelize#define}
 * @mixin Hooks
 */
var Hooks = module.exports = function() {};
var hookTypes = {
  beforeValidate: {params: 2},
  afterValidate: {params: 2},
  beforeCreate: {params: 2},
  afterCreate: {params: 2},
  beforeDestroy: {params: 2},
  afterDestroy: {params: 2},
  beforeUpdate: {params: 2},
  afterUpdate: {params: 2},
  beforeBulkCreate: {params: 2},
  afterBulkCreate: {params: 2},
  beforeBulkDestroy: {params: 1},
  afterBulkDestroy: {params: 1},
  beforeBulkUpdate: {params: 1},
  afterBulkUpdate: {params: 1},
  beforeFind: {params: 1},
  beforeFindAfterExpandIncludeAll: {params: 1},
  beforeFindAfterOptions: {params: 1},
  afterFind: {params: 2}
};
var hookAliases = {
  beforeDelete: 'beforeDestroy',
  afterDelete: 'afterDestroy',
  beforeBulkDelete: 'beforeBulkDestroy',
  afterBulkDelete: 'afterBulkDestroy'
};

Hooks.replaceHookAliases = function(hooks) {
  var realHookName;

  Utils._.each(hooks, function(hooksArray, name) {
    // Does an alias for this hook name exist?
    if (realHookName = hookAliases[name]) {
      // Add the hooks to the actual hook
      hooks[realHookName] = (hooks[realHookName] || []).concat(hooksArray);

      // Delete the alias
      delete hooks[name];
    }
  });

  return hooks;
};

Hooks.runHooks = function(hooks) {
  var self = this
    , fn
    , fnArgs = Array.prototype.slice.call(arguments, 1)
    , hookType;

  if (typeof fnArgs[fnArgs.length - 1] === 'function') {
    fn = fnArgs.pop();
  }

  if (typeof hooks === 'string') {
    hookType = hooks;
    hooks = this.options.hooks[hookType] || [];
	if (!Array.isArray(hooks)) hooks = hooks === undefined ? [] : [hooks];
	if (this.sequelize) hooks = hooks.concat(this.sequelize.options.hooks[hookType] || []);
  }

  if (!Array.isArray(hooks)) {
    hooks = hooks === undefined ? [] : [hooks];
  }

  // run hooks as sync functions if flagged as sync
  if (hookTypes[hookType] && hookTypes[hookType].sync) {
    hooks.forEach(function(hook) {
      if (typeof hook === 'object') hook = hook.fn;
      return hook.apply(self, fnArgs);
    });
    return;
  }

  // run hooks async
  var promise = Promise.each(hooks, function (hook) {
    if (typeof hook === 'object') {
      hook = hook.fn;
    }

    if (hookType && hook.length > hookTypes[hookType].params) {
      hook = Promise.promisify(hook, self);
    }

    return hook.apply(self, fnArgs);
  }).return();

  if (fn) {
    return promise.nodeify(fn);
  }

  return promise;
};

Hooks.hook = function() {
  return Hooks.addHook.apply(this, arguments);
};

/**
 * Add a hook to the model
 *
 * @param {String}    hooktype
 * @param {String}    [name]    Provide a name for the hook function. This serves no purpose, other than the ability to be able to order hooks based on some sort of priority system in the future.
 * @param {Function}  fn        The hook function
 *
 * @alias hook
 */
Hooks.addHook = function(hookType, name, fn) {
  if (typeof name === 'function') {
    fn = name;
    name = null;
  }

  // Aliases
  hookType = hookAliases[hookType] || hookType;

  // Just in case if we override the default DAOFactory.options
  this.options.hooks[hookType] = this.options.hooks[hookType] || [];
  this.options.hooks[hookType][this.options.hooks[hookType].length] = !!name ? {name: name, fn: fn} : fn;
  return this;
};

/**
 * A hook that is run before validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeValidate', name, fn);
};

/**
 * A hook that is run after validation
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterValidate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterValidate', name, fn);
};

/**
 * A hook that is run before creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.beforeCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeCreate', name, fn);
};

/**
 * A hook that is run after creating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with attributes, options, callback(err)
 */
Hooks.afterCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterCreate', name, fn);
};

/**
 * A hook that is run before destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias beforeDelete
 */
Hooks.beforeDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDestroy', name, fn);
};

Hooks.beforeDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeDelete', name, fn);
};

/**
 * A hook that is run after destroying a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 *
 * @alias afterDelete
 */
Hooks.afterDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDestroy', name, fn);
};

Hooks.afterDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterDelete', name, fn);
};

/**
 * A hook that is run before updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.beforeUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeUpdate', name, fn);
};

/**
 * A hook that is run after updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options, callback(err)
 */
Hooks.afterUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterUpdate', name, fn);
};

/**
 * A hook that is run before creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.beforeBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkCreate', name, fn);
};

/**
 * A hook that is run after creating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instances, options, callback(err)
 */
Hooks.afterBulkCreate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkCreate', name, fn);
};

/**
 * A hook that is run before destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias beforeBulkDelete
 */
Hooks.beforeBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDestroy', name, fn);
};

Hooks.beforeBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkDelete', name, fn);
};

/**
 * A hook that is run after destroying instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 *
 * @alias afterBulkDelete
 */
Hooks.afterBulkDestroy = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDestroy', name, fn);
};

Hooks.afterBulkDelete = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkDelete', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeBulkUpdate', name, fn);
};

/**
 * A hook that is run after updating instances in bulk
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.afterBulkUpdate = function(name, fn) {
  return Hooks.addHook.call(this, 'afterBulkUpdate', name, fn);
};

/**
 * A hook that is run before a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFind = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFind', name, fn);
};

/**
 * A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterExpandIncludeAll = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterExpandIncludeAll', name, fn);
};

/**
 * A hook that is run before a find (select) query, after all option parsing is complete
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with options, callback(err)
 */
Hooks.beforeFindAfterOptions = function(name, fn) {
  return Hooks.addHook.call(this, 'beforeFindAfterOptions', name, fn);
};

/**
 * A hook that is run after a find (select) query
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance(s), options, callback(err)
 */
Hooks.afterFind = function(name, fn) {
  return Hooks.addHook.call(this, 'afterFind', name, fn);
};
<|endoftext|>


<commit_before>define(['utils', 'color', './context'], function(utils, color, context) {
    // reference http://el.media.mit.edu/logo-foundation/logo/turtle.html
    var rgba = color.rgba;

    var turtle = function(ctx) {
        if(!ctx) {
            return null;
        }

        // make sure ctx contains all appropriate methods
        var containsMethods = utils.contains(utils.keys(ctx), utils.keys(context.normal()));

        if(!containsMethods) {
            return null;
        }

        var penDown = true;

        var isRecording = false;
        var currentRecording = [];
        var recordingName = '';
        var penWasDown = false;
        var col = rgba();

        var repeating = false;

        ctx.color(col);
        ctx.lineWidth(1);
        var width = 1;

        var commands = {
            forward: function(distance) {
                if(penDown) {
                    ctx.line(distance);
                }

                ctx.translate(0, distance);
            },
            backward: function(distance) {
                if(penDown) {
                    ctx.line(distance);
                }

                ctx.translate(0, -distance);
            },
            rotate: function(degrees) {
                ctx.rotate(degrees);
            },
            penDown: function() {
                penDown = true;
            },
            penUp: function() {
                penDown = false;
            },
            reset: function() {
                ctx.center();
                ctx.rotate(180);

                penDown = true;
            },
            repeat: function() {
                var times = arguments[0];

                // this disables recording of repeated commands. we need to record just repeat call
                repeating = true;

                for(var i = 0; i < times; i++) {
                    for(var j = 1; j < arguments.length; j += 2) {
                        var name = arguments[j];
                        var arg = arguments[j + 1];

                        commands[name].call({}, arg);
                    }
                }

                var repeating = false;
            }
        };

        // these won't get recorded
        var recordCommands = {
            record: function(name) {
                isRecording = true;
                recordingName = name;
                penWasDown = penDown;

                penDown = false;
            },
            stop: function() {
                var recording = currentRecording.slice(0); // clone

                commands[recordingName] = wrapCommand(recordingName,
                    function() {
                        var fillArgs;

                        if(arguments.length == 1 && arguments[0]) {
                            fillArgs = arguments[0];
                        }

                        var constructArgs = function(args) {
                            var ret = utils.clone(utils.argumentsToArray(args));

                            if(fillArgs) {
                                for(var i = 0; i < args.length; i++) {
                                    var arg = args[i];

                                    if(!arg) {
                                        ret[i] = fillArgs;
                                    }
                                    else if(typeof(arg) == 'string' && arg.match('^<[a-zA-Z]*>$')) {
                                        var argName = arg.substring(1, arg.length - 1);

                                        ret[i] = fillArgs[argName];
                                    }
                                }
                            }

                            return ret;
                        };

                        utils.each(function(part, i) {
                            var args = constructArgs(part.args) || [];

                            commands[part.name].apply({}, args);
                        }, recording);
                    }
                    );

                isRecording = false;
                currentRecording = [];

                penDown = penWasDown;
            },
            penState: function() {
                return penDown? 'down': 'up';
            },
            color: function(c) {
                if(c) {
                    col = rgba(c);

                    ctx.color(col);
                }
                else {
                    return col;
                }
            },
            lineWidth: function(w) {
                if(w) {
                    width = w;

                    ctx.lineWidth(w);
                }
                else {
                    return width;
                }
            }
        };

        var wrapCommand = function(name, command) {
            return function() {
                if(isRecording && !repeating) {
                    currentRecording.push({
                        name: name,
                        args: arguments
                    });
                }
                else {
                    command.apply({}, arguments);
                }
            };
        };

        utils.each(function(k, v) {
            commands[k] = wrapCommand(k, v);
        }, commands);

        commands = utils.extend(commands, recordCommands);

        commands.reset();

        return commands;
    };

    return turtle;
});<commit_msg>Fix IDE warnings<commit_after>define(['utils', 'color', './context'], function(utils, color, context) {
    // reference http://el.media.mit.edu/logo-foundation/logo/turtle.html
    var rgba = color.rgba;

    var turtle = function(ctx) {
        if(!ctx) {
            return null;
        }

        // make sure ctx contains all appropriate methods
        var containsMethods = utils.contains(utils.keys(ctx), utils.keys(context.normal()));

        if(!containsMethods) {
            return null;
        }

        var penDown = true;

        var isRecording = false;
        var currentRecording = [];
        var recordingName = '';
        var penWasDown = false;
        var col = rgba();

        var repeating = false;

        ctx.color(col);
        ctx.lineWidth(1);
        var width = 1;

        var commands = {
            forward: function(distance) {
                if(penDown) {
                    ctx.line(distance);
                }

                ctx.translate(0, distance);
            },
            backward: function(distance) {
                if(penDown) {
                    ctx.line(distance);
                }

                ctx.translate(0, -distance);
            },
            rotate: function(degrees) {
                ctx.rotate(degrees);
            },
            penDown: function() {
                penDown = true;
            },
            penUp: function() {
                penDown = false;
            },
            reset: function() {
                ctx.center();
                ctx.rotate(180);

                penDown = true;
            },
            repeat: function() {
                var times = arguments[0];

                // this disables recording of repeated commands. we need to record just repeat call
                repeating = true;

                for(var i = 0; i < times; i++) {
                    for(var j = 1; j < arguments.length; j += 2) {
                        var name = arguments[j];
                        var arg = arguments[j + 1];

                        commands[name].call({}, arg);
                    }
                }

                var repeating = false;
            }
        };

        // these won't get recorded
        var recordCommands = {
            record: function(name) {
                isRecording = true;
                recordingName = name;
                penWasDown = penDown;

                penDown = false;
            },
            stop: function() {
                var recording = currentRecording.slice(0); // clone

                commands[recordingName] = wrapCommand(recordingName,
                    function() {
                        var fillArgs;

                        if(arguments.length == 1 && arguments[0]) {
                            fillArgs = arguments[0];
                        }

                        var constructArgs = function(args) {
                            var ret = utils.clone(utils.argumentsToArray(args));

                            if(fillArgs) {
                                for(var i = 0; i < args.length; i++) {
                                    var arg = args[i];

                                    if(!arg) {
                                        ret[i] = fillArgs;
                                    }
                                    else if(typeof(arg) == 'string' && arg.match('^<[a-zA-Z]*>$')) {
                                        var argName = arg.substring(1, arg.length - 1);

                                        ret[i] = fillArgs[argName];
                                    }
                                }
                            }

                            return ret;
                        };

                        utils.each(function(part, i) {
                            var args = constructArgs(part.args) || [];

                            commands[part.name].apply({}, args);
                        }, recording);
                    }
                    );

                isRecording = false;
                currentRecording = [];

                penDown = penWasDown;
            },
            penState: function() {
                return penDown? 'down': 'up';
            },
            color: function(c) {
                if(c) {
                    col = rgba(c);

                    ctx.color(col);
                }
                else {
                    return col;
                }

                return null;
            },
            lineWidth: function(w) {
                if(w) {
                    width = w;

                    ctx.lineWidth(w);
                }
                else {
                    return width;
                }

                return null;
            }
        };

        var wrapCommand = function(name, command) {
            return function() {
                if(isRecording && !repeating) {
                    currentRecording.push({
                        name: name,
                        args: arguments
                    });
                }
                else {
                    command.apply({}, arguments);
                }
            };
        };

        utils.each(function(k, v) {
            commands[k] = wrapCommand(k, v);
        }, commands);

        commands = utils.extend(commands, recordCommands);

        commands.reset();

        return commands;
    };

    return turtle;
});<|endoftext|>


<commit_before>"use strict";

// For the mapping.coffee template
require('coffee-script')

var request = require('request')
  , Buffers = require('buffers')
  , im = require('imagemagick')
  , url = require('url')
  , async = require('async')
  , crypto = require('crypto')
  , mapping = require('../mapping')
  , util = require('./util')
  , cache = util.cache

var mashapeHash = crypto.createHmac('sha1', process.env.MASHAPE_API_SECRET)
    .update(process.env.MASHAPE_API_KEY)
    .digest('hex')

var mashapeAuth = Buffer(process.env.MASHAPE_API_KEY + ':' + mashapeHash).toString('base64')

var faceApis = {
  lambda: function(image, callback) {
    var uri = url.parse('https://lambda-face-detection-and-recognition.p.mashape.com/detect', true)
    uri.query = {
      images: image,
    }
    var options = {
        uri: url.format(uri),
        headers: {"X-Mashape-Authorization": mashapeAuth},
        json: true
    }
    request(options, function(err, response, data) {
      if (err) return callback(err)
      // console.log(JSON.stringify(data))
      if (data && data.photos && data.photos[0]) {
        // Convert the data to look like the face.com API
        data.photos[0].tags.forEach(function(face) {
          // Eyes are switched
          var eye_right = face.eye_right
          face.eye_right = face.eye_left
          face.eye_left = eye_right

          // Calculate the roll
          if (face.roll == null) {
            if (face.eye_right && face.eye_left) {
              face.roll = util.angle(face.eye_left, face.eye_right)
            } else {
              face.roll = 0
            }
          }
        })
      }
      callback(null, data)
    })
  }
}

function faceDetect(image, method, callback) {
  cache('face:' + method + ':' + image, function(i, callback) {
    if (!faceApis[method]) {
      return callback(Error('No such face api: ' + method))
    }
    faceApis[method](image, callback)
  }, callback)
}

function fetchImage(image, callback) {
  cache('image:' + image, function(i, callback) {
    request({uri: image, onResponse: true}, function(err, res) {
      if (err) return callback(err)
      var data = Buffers()
      res.on('data', function(chunk) {
        data.push(chunk)
      })
      res.on('end', function() {
        callback(null, data.toBuffer())
      })
    })
  }, callback)
}

function applyOverlay(image, options, callback) {
  var args = [
    '-',
    '-virtual-pixel',
    'transparent',
  ]

  var photo = options.face.photos[0]
  var overlays = options.overlay.split(',')

  if (!photo.tags) {
    return callback(null, null)
  }

  var w,h
  if (options.method == 'face') {
    var w = function(x) { return x * photo.width * 0.01 }
    var h = function(y) { return y * photo.height * 0.01 }
  } else {
    var w = function(x) { return x }
    var h = function(y) { return y }
  }

  photo.tags.forEach(function(face) {
    overlays.forEach(function(overlay) {
      // TODO move this conversion to a better spot
      if (!face.converted) {
        face.width = w(face.width)
        face.height = h(face.height)
        Object.keys(face).forEach(function(k) {
          var v = face[k]
          if (v && v.x) v.x = w(v.x)
          if (v && v.y) v.y = h(v.y)
        })
        face.converted = true
      }

      try {
        var transform = mapping[overlay].call(util, face, photo)
      } catch (err) {
        // TODO Probably just missing the feature (like face.nose, etc)
        // console.log(err.stack)
        return
      }

      args = args.concat([
        '(',
        'overlays/'+overlay+'.png',
        '+distort'
      ])
      args = args.concat(transform)
      args.push(')')
    })
  })

  args.push('-flatten')
  args.push('jpg:-')

  // console.log(args.join(' '))

  var proc = im.convert(args, function(err, stdout, stdin) {
    if (err) return callback(err)

    // THIS IS STUPID, IMAGEMAGICK Y U NO OUTPUT A BUFFER?!
    stdout = Buffer(stdout, 'binary')

    callback(err, stdout)
  })
  proc.stdin.end(image)
}

exports.mash = function(data, callback){
  cache(data, function(data, callback) {
    console.log('overlay:', data.overlay, 'image:', data.image)
    async.parallel(
      {
        face: async.apply(faceDetect, data.image, data.method),
        image: async.apply(fetchImage, data.image),
      },
      function(err, results) {
        if (err) return callback(err)

        if (results.face.photos == null || results.face.photos[0] == null) return callback(null, null)

        var options = {
          face: results.face,
          overlay: data.overlay,
          method: data.method
        }
        applyOverlay(results.image, options, callback)
      }
    )
  }, callback)
};
<commit_msg>face isn't a method anymore<commit_after>"use strict";

// For the mapping.coffee template
require('coffee-script')

var request = require('request')
  , Buffers = require('buffers')
  , im = require('imagemagick')
  , url = require('url')
  , async = require('async')
  , crypto = require('crypto')
  , mapping = require('../mapping')
  , util = require('./util')
  , cache = util.cache

var mashapeHash = crypto.createHmac('sha1', process.env.MASHAPE_API_SECRET)
    .update(process.env.MASHAPE_API_KEY)
    .digest('hex')

var mashapeAuth = Buffer(process.env.MASHAPE_API_KEY + ':' + mashapeHash).toString('base64')

var faceApis = {
  lambda: function(image, callback) {
    var uri = url.parse('https://lambda-face-detection-and-recognition.p.mashape.com/detect', true)
    uri.query = {
      images: image,
    }
    var options = {
        uri: url.format(uri),
        headers: {"X-Mashape-Authorization": mashapeAuth},
        json: true
    }
    request(options, function(err, response, data) {
      if (err) return callback(err)
      // console.log(JSON.stringify(data))
      if (data && data.photos && data.photos[0]) {
        // Convert the data to look like the face.com API
        data.photos[0].tags.forEach(function(face) {
          // Eyes are switched
          var eye_right = face.eye_right
          face.eye_right = face.eye_left
          face.eye_left = eye_right

          // Calculate the roll
          if (face.roll == null) {
            if (face.eye_right && face.eye_left) {
              face.roll = util.angle(face.eye_left, face.eye_right)
            } else {
              face.roll = 0
            }
          }
        })
      }
      callback(null, data)
    })
  }
}

function faceDetect(image, method, callback) {
  cache('face:' + method + ':' + image, function(i, callback) {
    if (!faceApis[method]) {
      return callback(Error('No such face api: ' + method))
    }
    faceApis[method](image, callback)
  }, callback)
}

function fetchImage(image, callback) {
  cache('image:' + image, function(i, callback) {
    request({uri: image, onResponse: true}, function(err, res) {
      if (err) return callback(err)
      var data = Buffers()
      res.on('data', function(chunk) {
        data.push(chunk)
      })
      res.on('end', function() {
        callback(null, data.toBuffer())
      })
    })
  }, callback)
}

function applyOverlay(image, options, callback) {
  var args = [
    '-',
    '-virtual-pixel',
    'transparent',
  ]

  var photo = options.face.photos[0]
  var overlays = options.overlay.split(',')

  if (!photo.tags) {
    return callback(null, null)
  }

  var w = function(x) { return x }
  var h = function(y) { return y }

  photo.tags.forEach(function(face) {
    overlays.forEach(function(overlay) {
      // TODO move this conversion to a better spot
      if (!face.converted) {
        face.width = w(face.width)
        face.height = h(face.height)
        Object.keys(face).forEach(function(k) {
          var v = face[k]
          if (v && v.x) v.x = w(v.x)
          if (v && v.y) v.y = h(v.y)
        })
        face.converted = true
      }

      try {
        var transform = mapping[overlay].call(util, face, photo)
      } catch (err) {
        // TODO Probably just missing the feature (like face.nose, etc)
        // console.log(err.stack)
        return
      }

      args = args.concat([
        '(',
        'overlays/'+overlay+'.png',
        '+distort'
      ])
      args = args.concat(transform)
      args.push(')')
    })
  })

  args.push('-flatten')
  args.push('jpg:-')

  // console.log(args.join(' '))

  var proc = im.convert(args, function(err, stdout, stdin) {
    if (err) return callback(err)

    // THIS IS STUPID, IMAGEMAGICK Y U NO OUTPUT A BUFFER?!
    stdout = Buffer(stdout, 'binary')

    callback(err, stdout)
  })
  proc.stdin.end(image)
}

exports.mash = function(data, callback){
  cache(data, function(data, callback) {
    console.log('overlay:', data.overlay, 'image:', data.image)
    async.parallel(
      {
        face: async.apply(faceDetect, data.image, data.method),
        image: async.apply(fetchImage, data.image),
      },
      function(err, results) {
        if (err) return callback(err)

        if (results.face.photos == null || results.face.photos[0] == null) return callback(null, null)

        var options = {
          face: results.face,
          overlay: data.overlay,
          method: data.method
        }
        applyOverlay(results.image, options, callback)
      }
    )
  }, callback)
};
<|endoftext|>


<commit_before>// We have to remove node_modules/react to avoid having multiple copies loaded.
// eslint-disable-next-line import/no-unresolved
import React, { Component, PropTypes } from 'react';

import _ from 'lodash';

import Paneset from '@folio/stripes-components/lib/Paneset';
import Pane from '@folio/stripes-components/lib/Pane';
import PaneMenu from '@folio/stripes-components/lib/PaneMenu';
import Icon from '@folio/stripes-components/lib/Icon';
import NavList from '@folio/stripes-components/lib/NavList';
import NavListSection from '@folio/stripes-components/lib/NavListSection';
import IfPermission from '@folio/stripes-components/lib/IfPermission';
import PermissionSetDetails from './PermissionSetDetails';

class PermissionSets extends Component {
  static propTypes = {
    stripes: PropTypes.shape({
      hasPerm: PropTypes.func.isRequired,
    }).isRequired,
    data: PropTypes.shape({
      permissionSets: PropTypes.arrayOf(PropTypes.object),
    }).isRequired,
    mutator: PropTypes.shape({
      permissionSets: PropTypes.shape({
        POST: PropTypes.func,
        DELETE: PropTypes.func,
        GET: PropTypes.func,
      }),
    }).isRequired,
  };

  static manifest = Object.freeze({
    permissionSets: {
      type: 'okapi',
      records: 'permissions',
      DELETE: {
        path: 'perms/permissions',
      },
      POST: {
        path: 'perms/permissions',
      },
      GET: {
        path: 'perms/permissions?length=100&query=(mutable=true)',
      },
      path: 'perms/permissions',
    },
  });

  constructor(props) {
    super(props);

    // 'Manager' just for example...

    this.state = {
      selectedSet: null,
    };

    this.navList = null;

    this.onSelectSet = this.onSelectSet.bind(this);
    this.createNewPermissionSet = this.createNewPermissionSet.bind(this);
    this.clearSelection = this.clearSelection.bind(this);
  }

  componentDidUpdate(prevProps) {
    const permSetsDiffs = _.differenceBy(this.props.data.permissionSets, prevProps.data.permissionSets, 'id');
    const newPermSet = permSetsDiffs[0];

    if (newPermSet && !newPermSet.pendingCreate) {
      // At this point in the lifecycle the CID is still on the object, and
      // this messes up the saveing of the Permission Set. It should not be needed any longer
      // and will be removed.
      delete newPermSet._cid; // eslint-disable-line no-underscore-dangle

      // Jeremy has investigated that and confirmed that it is harmless.
      // eslint-disable-next-line react/no-did-update-set-state
      this.setState({
        selectedSet: newPermSet,
      });
    }
  }

  onSelectSet(e) {
    e.preventDefault();
    const permissionId = e.target.dataset.id;
    _.forEach(this.props.data.permissionSets, (set) => {
      if (set.id === permissionId) {
        this.setSelectedSet(set);
      }
    });
  }

  setSelectedSet(set) {
    this.setState({
      selectedSet: set,
    });
  }

  clearSelection() {
    this.setSelectedSet(null);
  }

  createNewPermissionSet() {
    this.props.mutator.permissionSets.POST({
      mutable: true,
    });
  }

  render() {
    const RenderedPermissionSets = this.props.data.permissionSets ? this.props.data.permissionSets.map(
      set => <a data-id={set.id} key={set.id} href={`#${set.permissionName}`} onClick={this.onSelectSet}>{set.displayName ? set.displayName : 'Untitled Permission Set'},
    ) : [];

    const PermissionsSetsLastMenu = (
      <IfPermission perm="perms.permissions.item.post">
        {/* In practice, there is point letting someone create a set if they can't set its name */}
        <IfPermission perm="perms.permissions.item.put">
          <PaneMenu>
            <button title="Add Permission Set" onClick={this.createNewPermissionSet}>
              <Icon icon="plus-sign" />
            </button>
          </PaneMenu>
        </IfPermission>
      </IfPermission>
    );

    return (
      <Paneset nested>
        <Pane defaultWidth="20%" lastMenu={PermissionsSetsLastMenu}>
          <NavList>
            <NavListSection activeLink={this.state.selectedSet ? `#${this.state.selectedSet.id}` : ''}>
              {RenderedPermissionSets}
            </NavListSection>
          </NavList>
        </Pane>
        {this.state.selectedSet && <PermissionSetDetails parentMutator={this.props.mutator} clearSelection={this.clearSelection} stripes={this.props.stripes} initialValues={this.state.selectedSet} selectedSet={this.state.selectedSet} />}
      </Paneset>
    );
  }
}

export default PermissionSets;
<commit_msg>Fetch up to 1000 permissions, not just 100.<commit_after>// We have to remove node_modules/react to avoid having multiple copies loaded.
// eslint-disable-next-line import/no-unresolved
import React, { Component, PropTypes } from 'react';

import _ from 'lodash';

import Paneset from '@folio/stripes-components/lib/Paneset';
import Pane from '@folio/stripes-components/lib/Pane';
import PaneMenu from '@folio/stripes-components/lib/PaneMenu';
import Icon from '@folio/stripes-components/lib/Icon';
import NavList from '@folio/stripes-components/lib/NavList';
import NavListSection from '@folio/stripes-components/lib/NavListSection';
import IfPermission from '@folio/stripes-components/lib/IfPermission';
import PermissionSetDetails from './PermissionSetDetails';

class PermissionSets extends Component {
  static propTypes = {
    stripes: PropTypes.shape({
      hasPerm: PropTypes.func.isRequired,
    }).isRequired,
    data: PropTypes.shape({
      permissionSets: PropTypes.arrayOf(PropTypes.object),
    }).isRequired,
    mutator: PropTypes.shape({
      permissionSets: PropTypes.shape({
        POST: PropTypes.func,
        DELETE: PropTypes.func,
        GET: PropTypes.func,
      }),
    }).isRequired,
  };

  static manifest = Object.freeze({
    permissionSets: {
      type: 'okapi',
      records: 'permissions',
      DELETE: {
        path: 'perms/permissions',
      },
      POST: {
        path: 'perms/permissions',
      },
      GET: {
        path: 'perms/permissions?length=1000&query=(mutable=true)',
      },
      path: 'perms/permissions',
    },
  });

  constructor(props) {
    super(props);

    // 'Manager' just for example...

    this.state = {
      selectedSet: null,
    };

    this.navList = null;

    this.onSelectSet = this.onSelectSet.bind(this);
    this.createNewPermissionSet = this.createNewPermissionSet.bind(this);
    this.clearSelection = this.clearSelection.bind(this);
  }

  componentDidUpdate(prevProps) {
    const permSetsDiffs = _.differenceBy(this.props.data.permissionSets, prevProps.data.permissionSets, 'id');
    const newPermSet = permSetsDiffs[0];

    if (newPermSet && !newPermSet.pendingCreate) {
      // At this point in the lifecycle the CID is still on the object, and
      // this messes up the saveing of the Permission Set. It should not be needed any longer
      // and will be removed.
      delete newPermSet._cid; // eslint-disable-line no-underscore-dangle

      // Jeremy has investigated that and confirmed that it is harmless.
      // eslint-disable-next-line react/no-did-update-set-state
      this.setState({
        selectedSet: newPermSet,
      });
    }
  }

  onSelectSet(e) {
    e.preventDefault();
    const permissionId = e.target.dataset.id;
    _.forEach(this.props.data.permissionSets, (set) => {
      if (set.id === permissionId) {
        this.setSelectedSet(set);
      }
    });
  }

  setSelectedSet(set) {
    this.setState({
      selectedSet: set,
    });
  }

  clearSelection() {
    this.setSelectedSet(null);
  }

  createNewPermissionSet() {
    this.props.mutator.permissionSets.POST({
      mutable: true,
    });
  }

  render() {
    const RenderedPermissionSets = this.props.data.permissionSets ? this.props.data.permissionSets.map(
      set => <a data-id={set.id} key={set.id} href={`#${set.permissionName}`} onClick={this.onSelectSet}>{set.displayName ? set.displayName : 'Untitled Permission Set'},
    ) : [];

    const PermissionsSetsLastMenu = (
      <IfPermission perm="perms.permissions.item.post">
        {/* In practice, there is point letting someone create a set if they can't set its name */}
        <IfPermission perm="perms.permissions.item.put">
          <PaneMenu>
            <button title="Add Permission Set" onClick={this.createNewPermissionSet}>
              <Icon icon="plus-sign" />
            </button>
          </PaneMenu>
        </IfPermission>
      </IfPermission>
    );

    return (
      <Paneset nested>
        <Pane defaultWidth="20%" lastMenu={PermissionsSetsLastMenu}>
          <NavList>
            <NavListSection activeLink={this.state.selectedSet ? `#${this.state.selectedSet.id}` : ''}>
              {RenderedPermissionSets}
            </NavListSection>
          </NavList>
        </Pane>
        {this.state.selectedSet && <PermissionSetDetails parentMutator={this.props.mutator} clearSelection={this.clearSelection} stripes={this.props.stripes} initialValues={this.state.selectedSet} selectedSet={this.state.selectedSet} />}
      </Paneset>
    );
  }
}

export default PermissionSets;
<|endoftext|>


<commit_before>'use strict'

const Github = require('github')
    , pkg = require('../package')

module.exports = GetReviewers

const users = {
  // TSC
  'bnoordhuis': 'Ben Noordhuis <info@bnoordhuis.nl>'
, 'chrisdickinson': 'Chris Dickinson <christopher.s.dickinson@gmail.com>'
, 'cjihrig': 'Colin Ihrig <cjihrig@gmail.com>'
, 'Fishrock123': 'Jeremiah Senkpiel <fishrock123@rocketmail.com>'
, 'indutny': 'Fedor Indutny <fedor.indutny@gmail.com>'
, 'jasnell': 'James M Snell <jasnell@gmail.com>'
, 'misterdjules': 'Julien Gilli <jgilli@nodejs.org>'
, 'mscdex': 'Brian White <mscdex@mscdex.net>'
, 'orangemocha': 'Alexis Campailla <orangemocha@nodejs.org>'
, 'piscisaureus': 'Bert Belder <bertbelder@gmail.com>'
, 'rvagg': 'Rod Vagg <rod@vagg.org>'
, 'shigeki': 'Shigeki Ohtsu <ohtsu@iij.ad.jp>'
, 'trevnorris': 'Trevor Norris <trev.norris@gmail.com>'
  // Collaborators
, 'addaleax': 'Anna Henningsen <anna@addaleax.net>'
, 'andrasq': 'Andras <andras@kinvey.com>'
, 'bengl': 'Bryan English <bryan@bryanenglish.com>'
, 'bmeck': 'Bradley Farias <bradley.meck@gmail.com>'
, 'AndreasMadsen': 'Andreas Madsen <amwebdk@gmail.com>'
, 'benjamingr': 'Benjamin Gruenbaum <benjamingr@gmail.com>'
, 'brendanashworth': 'Brendan Ashworth <brendan.ashworth@me.com>'
, 'bzoz': 'Bartosz Sosnowski <bartosz@janeasystems.com>'
, 'calvinmetcalf': 'Calvin Metcalf <calvin.metcalf@gmail.com>'
, 'ChALkeR': 'Сковорода Никита Андреевич <chalkerx@gmail.com>'
, 'claudiorodriguez': 'Claudio Rodriguez <cjrodr@yahoo.com>'
, 'danbev': 'Daniel Bevenius <daniel.bevenius@gmail.com>'
, 'domenic': 'Domenic Denicola <d@domenic.me>'
, 'eljefedelrodeodeljefe': 'Robert Lindstaedt <robert.lindstaedt@gmail.com>'
, 'estliberitas': 'Alexander Makarenko <estliberitas@gmail.com>'
, 'evanlucas': 'Evan Lucas <evanlucas@me.com>'
, 'fhinkel': 'Franziska Hinkelmann <franziska.hinkelmann@gmail.com>'
, 'firedfox': 'Daniel Wang <wangyang0123@gmail.com>'
, 'geek': 'Wyatt Preul <wpreul@gmail.com>'
, 'iarna': 'Rebecca Turner <me@re-becca.org>'
, 'isaacs': 'Isaac Z. Schlueter <i@izs.me>'
, 'iWuzHere': 'Imran Iqbal <imran@imraniqbal.org>'
, 'JacksonTian': 'Jackson Tian <shvyo1987@gmail.com>'
, 'jbergstroem': 'Johan Bergström <bugs@bergstroem.nu>'
, 'jhamhader': 'Yuval Brik <yuval@brik.org.il>'
, 'joaocgreis': 'João Reis <reis@janeasystems.com>'
, 'joshgav': 'Josh Gavant <josh.gavant@outlook.com>'
, 'julianduque': 'Julian Duque <julianduquej@gmail.com>'
, 'JungMinu': 'Minwoo Jung <jmwsoft@gmail.com>'
, 'lance': 'Lance Ball <lball@redhat.com>'
, 'lpinca': 'Luigi Pinca <luigipinca@gmail.com>'
, 'lxe': 'Aleksey Smolenchuk <lxe@lxe.co>'
, 'matthewloring': 'Matthew Loring <mattloring@google.com>'
, 'mcollina': 'Matteo Collina <matteo.collina@gmail.com>'
, 'mhdawson': 'Michael Dawson <michael_dawson@ca.ibm.com>'
, 'micnic': 'Nicu Micleușanu <micnic90@gmail.com>'
, 'mikeal': 'Mikeal Rogers <mikeal.rogers@gmail.com>'
, 'monsanto': 'Christopher Monsanto <chris@monsan.to>'
, 'ofrobots': 'Ali Ijaz Sheikh <ofrobots@google.com>'
, 'Olegas': 'Oleg Elifantiev <oleg@elifantiev.ru>'
, 'othiym23': 'Forrest L Norvell <ogd@aoaioxxysz.net>'
, 'petkaantonov': 'Petka Antonov <petka_antonov@hotmail.com>'
, 'phillipj': 'Phillip Johnsen <johphi@gmail.com>'
, 'pmq20': 'Minqi Pan <pmq2001@gmail.com>'
, 'princejwesley': 'Prince John Wesley <princejohnwesley@gmail.com>'
, 'Qard': 'Stephen Belanger <admin@stephenbelanger.com>'
, 'rlidwka': 'Alex Kocharin <alex@kocharin.ru>'
, 'rmg': 'Ryan Graham <r.m.graham@gmail.com>'
, 'robertkowalski': 'Robert Kowalski <rok@kowalski.gd>'
, 'romankl': 'Roman Klauke <romaaan.git@gmail.com>'
, 'ronkorving': 'Ron Korving <ron@ronkorving.nl>'
, 'RReverser': 'Ingvar Stepanyan <me@rreverser.com>'
, 'saghul': 'Saúl Ibarra Corretgé <saghul@gmail.com>'
, 'sam-github': 'Sam Roberts <vieuxtech@gmail.com>'
, 'santigimeno': 'Santiago Gimeno <santiago.gimeno@gmail.com>'
, 'seishun': 'Nikolai Vavilov <vvnicholas@gmail.com>'
, 'silverwind': 'Roman Reiss <me@silverwind.io>'
, 'srl295': 'Steven R Loomis <srloomis@us.ibm.com>'
, 'stefanmb': 'Stefan Budeanu <stefan@budeanu.com>'
, 'targos': 'Michaël Zasso <mic.besace@gmail.com>'
, 'tellnes': 'Christian Tellnes <christian@tellnes.no>'
, 'TheAlphaNerd': 'Myles Borins <myles.borins@gmail.com>'
, 'thefourtheye': 'Sakthipriyan Vairamani <thechargingvolcano@gmail.com>'
, 'thekemkid': 'Glen Keane <glenkeane.94@gmail.com>'
, 'thlorenz': 'Thorsten Lorenz <thlorenz@gmx.de>'
, 'Trott': 'Rich Trott <rtrott@gmail.com>'
, 'tunniclm': 'Mike Tunnicliffe <m.j.tunnicliffe@gmail.com>'
, 'vkurchatkin': 'Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>'
, 'whitlockjc': 'Jeremy Whitlock <jwhitlock@apache.org>'
, 'yorkie': 'Yorkie Liu <yorkiefixer@gmail.com>'
, 'yosuke-furukawa': 'Yosuke Furukawa <yosuke.furukawa@gmail.com>'
, 'zkat': 'Kat Marchán <kzm@sykosomatic.org>'
}

function GetReviewers(opts) {
  if (!(this instanceof GetReviewers))
    return new GetReviewers(opts)

  this.version = pkg.version
  this.opts = opts
  this.github = new Github({
    version: '3.0.0'
  , headers: {
      'User-Agent': `core-get-reviewers v${pkg.version}`
    }
  })

  this.github.authenticate({
    type: 'oauth'
  , token: opts.token
  })
}

GetReviewers.users = users

// the Collaborators team is id 1202829
GetReviewers.prototype.fetchCollabs = function fetchCollabs(cb) {
  this.fetchTeams((err, team) => {
    if (err) return cb(err)
    const id = team.id
    this.github.orgs.getTeamMembers({
      id: team.id
    , page: 0
    , per_page: 100
    }, (err, members) => {
      if (err) return cb(err)
      const out = members.map((item) => {
        return item.login
      })
      cb(null, out)
    })
  })
}

GetReviewers.prototype.fetchTeams = function fetchTeams(cb) {
  this.github.orgs.getTeams({
    org: 'nodejs'
  , page: 0
  , per_page: 50
  }, (err, teams) => {
    if (err) return cb(err)
    for (let i = 0; i < teams.length; i++) {
      const team = teams[i]
      if (team.name === 'Collaborators') {
        return cb(null, team)
      }
    }
    cb(new Error('Unable to find collaborators team'))
  })
}

GetReviewers.prototype.getReviewer = function getReviewer(username) {
  return users[username]
}

GetReviewers.prototype.fetchPR = function fetchPR(number, cb) {
  var self = this
  if (!number) {
    setImmediate(function() {
      cb(new Error('PR number is required'))
    })
    return
  }
  // TODO(evanlucas) handle situations where there are > 100 comments
  self.github.issues.getComments({
    user: 'nodejs'
  , repo: this.opts.nodePrivate ? 'node-private' : 'node'
  , number: number
  , page: 0
  , per_page: 100
  }, function(err, comments) {
    if (err) return cb(err)
    comments = comments.filter(function(comment) {
      return /LGTM/i.test(comment.body)
        && users.hasOwnProperty(comment.user.login)
    }).reduce(function(set, comment) {
      if (!set.hasOwnProperty(comment.user.login)) {
        set[comment.user.login] = {
          username: comment.user.login
        , userId: comment.user.id
        , body: comment.body
        }
      }

      return set
    }, {})

    const keys = Object.keys(comments)
        , len = keys.length
        , out = new Array(len)

    for (var i = 0; i < len; i++) {
      out[i] = comments[keys[i]]
    }
    cb(null, out)
  })
}

GetReviewers.prototype.generate = function generate(pr, reviewers) {
  var str = `\nPR-URL: https://github.com/nodejs/${this.opts.nodePrivate ? 'node-private' : 'node'}/pull/${pr}`
  var len = reviewers.length
  for (var i = 0; i < len; i++) {
    var reviewer = reviewers[i].username
    var email = users[reviewer]
    if (!email) {
      throw new Error(`Cannot find email for reviewer ${reviewer}`)
    }
    str += `\nReviewed-By: ${email}`
  }

  return str
}
<commit_msg>index: add new collaborators<commit_after>'use strict'

const Github = require('github')
    , pkg = require('../package')

module.exports = GetReviewers

const users = {
  // TSC
  'bnoordhuis': 'Ben Noordhuis <info@bnoordhuis.nl>'
, 'chrisdickinson': 'Chris Dickinson <christopher.s.dickinson@gmail.com>'
, 'cjihrig': 'Colin Ihrig <cjihrig@gmail.com>'
, 'Fishrock123': 'Jeremiah Senkpiel <fishrock123@rocketmail.com>'
, 'indutny': 'Fedor Indutny <fedor.indutny@gmail.com>'
, 'jasnell': 'James M Snell <jasnell@gmail.com>'
, 'misterdjules': 'Julien Gilli <jgilli@nodejs.org>'
, 'mscdex': 'Brian White <mscdex@mscdex.net>'
, 'orangemocha': 'Alexis Campailla <orangemocha@nodejs.org>'
, 'piscisaureus': 'Bert Belder <bertbelder@gmail.com>'
, 'rvagg': 'Rod Vagg <rod@vagg.org>'
, 'shigeki': 'Shigeki Ohtsu <ohtsu@iij.ad.jp>'
, 'trevnorris': 'Trevor Norris <trev.norris@gmail.com>'
  // Collaborators
, 'addaleax': 'Anna Henningsen <anna@addaleax.net>'
, 'andrasq': 'Andras <andras@kinvey.com>'
, 'bengl': 'Bryan English <bryan@bryanenglish.com>'
, 'bmeck': 'Bradley Farias <bradley.meck@gmail.com>'
, 'AndreasMadsen': 'Andreas Madsen <amwebdk@gmail.com>'
, 'benjamingr': 'Benjamin Gruenbaum <benjamingr@gmail.com>'
, 'brendanashworth': 'Brendan Ashworth <brendan.ashworth@me.com>'
, 'bzoz': 'Bartosz Sosnowski <bartosz@janeasystems.com>'
, 'calvinmetcalf': 'Calvin Metcalf <calvin.metcalf@gmail.com>'
, 'ChALkeR': 'Сковорода Никита Андреевич <chalkerx@gmail.com>'
, 'claudiorodriguez': 'Claudio Rodriguez <cjrodr@yahoo.com>'
, 'danbev': 'Daniel Bevenius <daniel.bevenius@gmail.com>'
, 'domenic': 'Domenic Denicola <d@domenic.me>'
, 'eljefedelrodeodeljefe': 'Robert Lindstaedt <robert.lindstaedt@gmail.com>'
, 'estliberitas': 'Alexander Makarenko <estliberitas@gmail.com>'
, 'evanlucas': 'Evan Lucas <evanlucas@me.com>'
, 'fhinkel': 'Franziska Hinkelmann <franziska.hinkelmann@gmail.com>'
, 'firedfox': 'Daniel Wang <wangyang0123@gmail.com>'
, 'geek': 'Wyatt Preul <wpreul@gmail.com>'
, 'gibfahn': 'Gibson Fahnestock <gibfahn@gmail.com>'
, 'iarna': 'Rebecca Turner <me@re-becca.org>'
, 'imyller': 'Ilkka Myller <ilkka.myller@nodefield.com>'
, 'isaacs': 'Isaac Z. Schlueter <i@izs.me>'
, 'iWuzHere': 'Imran Iqbal <imran@imraniqbal.org>'
, 'JacksonTian': 'Jackson Tian <shvyo1987@gmail.com>'
, 'jbergstroem': 'Johan Bergström <bugs@bergstroem.nu>'
, 'jhamhader': 'Yuval Brik <yuval@brik.org.il>'
, 'joaocgreis': 'João Reis <reis@janeasystems.com>'
, 'joshgav': 'Josh Gavant <josh.gavant@outlook.com>'
, 'julianduque': 'Julian Duque <julianduquej@gmail.com>'
, 'JungMinu': 'Minwoo Jung <jmwsoft@gmail.com>'
, 'lance': 'Lance Ball <lball@redhat.com>'
, 'lpinca': 'Luigi Pinca <luigipinca@gmail.com>'
, 'lxe': 'Aleksey Smolenchuk <lxe@lxe.co>'
, 'matthewloring': 'Matthew Loring <mattloring@google.com>'
, 'mcollina': 'Matteo Collina <matteo.collina@gmail.com>'
, 'mhdawson': 'Michael Dawson <michael_dawson@ca.ibm.com>'
, 'micnic': 'Nicu Micleușanu <micnic90@gmail.com>'
, 'mikeal': 'Mikeal Rogers <mikeal.rogers@gmail.com>'
, 'monsanto': 'Christopher Monsanto <chris@monsan.to>'
, 'not-an-aardvark': 'Teddy Katz <teddy.katz@gmail.com>'
, 'ofrobots': 'Ali Ijaz Sheikh <ofrobots@google.com>'
, 'Olegas': 'Oleg Elifantiev <oleg@elifantiev.ru>'
, 'othiym23': 'Forrest L Norvell <ogd@aoaioxxysz.net>'
, 'petkaantonov': 'Petka Antonov <petka_antonov@hotmail.com>'
, 'phillipj': 'Phillip Johnsen <johphi@gmail.com>'
, 'pmq20': 'Minqi Pan <pmq2001@gmail.com>'
, 'princejwesley': 'Prince John Wesley <princejohnwesley@gmail.com>'
, 'Qard': 'Stephen Belanger <admin@stephenbelanger.com>'
, 'rlidwka': 'Alex Kocharin <alex@kocharin.ru>'
, 'rmg': 'Ryan Graham <r.m.graham@gmail.com>'
, 'robertkowalski': 'Robert Kowalski <rok@kowalski.gd>'
, 'romankl': 'Roman Klauke <romaaan.git@gmail.com>'
, 'ronkorving': 'Ron Korving <ron@ronkorving.nl>'
, 'RReverser': 'Ingvar Stepanyan <me@rreverser.com>'
, 'saghul': 'Saúl Ibarra Corretgé <saghul@gmail.com>'
, 'sam-github': 'Sam Roberts <vieuxtech@gmail.com>'
, 'santigimeno': 'Santiago Gimeno <santiago.gimeno@gmail.com>'
, 'seishun': 'Nikolai Vavilov <vvnicholas@gmail.com>'
, 'silverwind': 'Roman Reiss <me@silverwind.io>'
, 'srl295': 'Steven R Loomis <srloomis@us.ibm.com>'
, 'stefanmb': 'Stefan Budeanu <stefan@budeanu.com>'
, 'targos': 'Michaël Zasso <mic.besace@gmail.com>'
, 'tellnes': 'Christian Tellnes <christian@tellnes.no>'
, 'TheAlphaNerd': 'Myles Borins <myles.borins@gmail.com>'
, 'thefourtheye': 'Sakthipriyan Vairamani <thechargingvolcano@gmail.com>'
, 'thekemkid': 'Glen Keane <glenkeane.94@gmail.com>'
, 'thlorenz': 'Thorsten Lorenz <thlorenz@gmx.de>'
, 'Trott': 'Rich Trott <rtrott@gmail.com>'
, 'tunniclm': 'Mike Tunnicliffe <m.j.tunnicliffe@gmail.com>'
, 'vkurchatkin': 'Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>'
, 'whitlockjc': 'Jeremy Whitlock <jwhitlock@apache.org>'
, 'yorkie': 'Yorkie Liu <yorkiefixer@gmail.com>'
, 'yosuke-furukawa': 'Yosuke Furukawa <yosuke.furukawa@gmail.com>'
, 'zkat': 'Kat Marchán <kzm@sykosomatic.org>'
}

function GetReviewers(opts) {
  if (!(this instanceof GetReviewers))
    return new GetReviewers(opts)

  this.version = pkg.version
  this.opts = opts
  this.github = new Github({
    version: '3.0.0'
  , headers: {
      'User-Agent': `core-get-reviewers v${pkg.version}`
    }
  })

  this.github.authenticate({
    type: 'oauth'
  , token: opts.token
  })
}

GetReviewers.users = users

// the Collaborators team is id 1202829
GetReviewers.prototype.fetchCollabs = function fetchCollabs(cb) {
  this.fetchTeams((err, team) => {
    if (err) return cb(err)
    const id = team.id
    this.github.orgs.getTeamMembers({
      id: team.id
    , page: 0
    , per_page: 100
    }, (err, members) => {
      if (err) return cb(err)
      const out = members.map((item) => {
        return item.login
      })
      cb(null, out)
    })
  })
}

GetReviewers.prototype.fetchTeams = function fetchTeams(cb) {
  this.github.orgs.getTeams({
    org: 'nodejs'
  , page: 0
  , per_page: 50
  }, (err, teams) => {
    if (err) return cb(err)
    for (let i = 0; i < teams.length; i++) {
      const team = teams[i]
      if (team.name === 'Collaborators') {
        return cb(null, team)
      }
    }
    cb(new Error('Unable to find collaborators team'))
  })
}

GetReviewers.prototype.getReviewer = function getReviewer(username) {
  return users[username]
}

GetReviewers.prototype.fetchPR = function fetchPR(number, cb) {
  var self = this
  if (!number) {
    setImmediate(function() {
      cb(new Error('PR number is required'))
    })
    return
  }
  // TODO(evanlucas) handle situations where there are > 100 comments
  self.github.issues.getComments({
    user: 'nodejs'
  , repo: this.opts.nodePrivate ? 'node-private' : 'node'
  , number: number
  , page: 0
  , per_page: 100
  }, function(err, comments) {
    if (err) return cb(err)
    comments = comments.filter(function(comment) {
      return /LGTM/i.test(comment.body)
        && users.hasOwnProperty(comment.user.login)
    }).reduce(function(set, comment) {
      if (!set.hasOwnProperty(comment.user.login)) {
        set[comment.user.login] = {
          username: comment.user.login
        , userId: comment.user.id
        , body: comment.body
        }
      }

      return set
    }, {})

    const keys = Object.keys(comments)
        , len = keys.length
        , out = new Array(len)

    for (var i = 0; i < len; i++) {
      out[i] = comments[keys[i]]
    }
    cb(null, out)
  })
}

GetReviewers.prototype.generate = function generate(pr, reviewers) {
  var str = `\nPR-URL: https://github.com/nodejs/${this.opts.nodePrivate ? 'node-private' : 'node'}/pull/${pr}`
  var len = reviewers.length
  for (var i = 0; i < len; i++) {
    var reviewer = reviewers[i].username
    var email = users[reviewer]
    if (!email) {
      throw new Error(`Cannot find email for reviewer ${reviewer}`)
    }
    str += `\nReviewed-By: ${email}`
  }

  return str
}
<|endoftext|>


<commit_before>'use strict';

const Objection = require('objection');
const Model = Objection.Model;
const Knex = require('knex');

const Path = require('path');
const Hoek = require('hoek');
const Joi = require('joi');
const Schema = require('./schema');
const Package = require('../package.json');

const SchwiftyMigration = require('schwifty-migration');

const internals = {};

exports.register = function (server, options, next) {

    const rootState = internals.state(server.root);

    internals.state(server).dir = options.dir;
    const knexFile = options.knexFile;

    internals.state(server).knex = Knex(knexFile[process.env.NODE_ENV]);

    if (!rootState.setup) {

        rootState.collector = {
            models: {},
            teardownOnStop: null // Not set, effectively defaults true
        };

        // Here's the ORM!

        server.decorate('server', 'schwifty', internals.schwifty);
        server.decorate('server', 'models', internals.models((ctx) => ctx, 'realm'));
        server.decorate('request', 'models', internals.models((ctx) => ctx.server, 'route.realm'));
        server.decorate('server', 'knex', internals.knex((ctx) => ctx, 'realm'));
        server.decorate('request', 'knex', internals.knex((ctx) => ctx.server, 'route.realm'));
        server.ext('onPreStart', internals.initialize);
        server.ext('onPostStop', internals.stop);

        rootState.setup = true;
    };

    // Decide whether server stop should teardown

    const collector = rootState.collector;

    if (typeof knexFile.teardownOnStop !== 'undefined') {
        Hoek.assert(collector.teardownOnStop === null, 'Schwifty\'s teardownOnStop option can only be specified once.');
        collector.teardownOnStop = knexFile.teardownOnStop;
    }

    const config = internals.registrationConfig(knexFile);
    server.root.schwifty(config);

    next();
};

exports.register.attributes = {
    pkg: Package,
    multiple: true
};

// Massage registration config for use with rejoice
internals.registrationConfig = (options) => {

    const config = Hoek.shallow(options);

    delete config.teardownOnStop;

    // Resolve models

    if (typeof config.models === 'string') {
        if (Path.isAbsolute(config.models)) {
            config.models = require(config.models);
        }
        else {
            config.models = require(Path.resolve(process.cwd(), config.models));
        }
    }

    return config;
};

exports.Model = class SchwiftyModel extends Model {

    constructor(...args) {
        super(...args);
    }

    // $beforeInsert() {
    //   this.createdAt = new Date().toISOString();
    // };

    // $beforeUpdate() {
    //   this.updatedAt = new Date().toISOString();
    // };

    tryValidate(schema, json) {

        return Joi.validate(json, schema);
    }

    parseValidationError(err) {

        return err;
    }

    $validate(json = this, options = {}) {

        const ModelClass = this.constructor;

        let joiSchema = ModelClass.schema;

        if (!joiSchema || options.skipValidation) {
          return json;
        }

        let validationError = null;

        let validation = this.tryValidate(joiSchema, json);

        if(validation.error) {
            throw new Objection.ValidationError(this.parseValidationError(validation.error.message));
        } else {
            validation = validation.value;
            this.$afterValidate(validation, options);
        }

        return validation;
    }
}

internals.initialize = function (server, next) {

    const collector = internals.state(server.root).collector;

    const modelsAsArray = [];

    Object.keys(collector.models).forEach((id) => {

        let model = collector.models[id];
        model = model.bindKnex(internals.state(server).knex);
        collector.models[id] = model;
        modelsAsArray.push(model);
    });

    SchwiftyMigration.initModels(modelsAsArray, internals.state(server).knex, internals.state(server).dir, server, (err, res) => {

        if(err) {
            throw new Error(err);
        }

        next();
    });
};

internals.stop = function (server, next) {

    const collector = internals.state(server.root).collector;

    // Do not teardown if specifically asked not to
    if (collector.teardownOnStop === false) {
        return next();
    }

    return Knex.destroy(next);
};

internals.schwifty = function (config) {

    let isModels = false;

    // Array of models, coerce to config
    if (Array.isArray(config)) {
        config = Joi.validate(config, Schema.schwifty);
        isModels = true;
    } else {

        // Sim a Joi validation
        config = {
            error: null,
            value: config
        }
    }

    if(config.error) {
        throw new Objection.ValidationError(this.parseValidationError(config.error.message));
    } else {
        config = config.value;
    }

    if(isModels === true) {
        config = { models: config };
    }

    // Apply empty defaults
    config.models = config.models || [];

    // Collect adapters, connections, models, ensuring no dupes
    const collector = internals.state(this.root).collector;
    const modelIds = config.models.map((model) => new model().constructor.name);

    modelIds.forEach((id, index) => {

        // Classnames are often first-capital
        id = String(id).toLowerCase();
        Hoek.assert(!collector.models[id], `Model definition with identity "${id}" has already been registered.`);
        collector.models[id] = config.models[index];

        Hoek.assert(collector.models[id].tableName, `Model definition must have "static get tableName(){ return 'myTableName' }"`);
    });

    // If all went well, track which models belong to which realms
    const state = internals.state(this);
    state.models = (state.models || []).concat(modelIds);
};

internals.models = (serverFrom, realmPath) => {

    return function (all) {

        const rootCollector = internals.state(serverFrom.root).collector;

        if(!rootCollector.models) {
            return {};
        }

        if (all) {
            return rootCollector.models;
        }

        const models = Hoek.reach(this, `${realmPath}.plugins.schwifty.models`) || [];

        for (let i = 0; i < models.length; ++i) {
            const modelName = models[i].toLowerCase();
            models[modelName] = rootCollector.models[modelName];
        }

        return models;
    };
};

internals.knex = (serverFrom, realmPath) => {

    return function () {

        return Hoek.reach(this, `${realmPath}.plugins.schwifty.knex`);
    };
};

internals.state = (srv) => {

    const state = srv.realm.plugins.schwifty = srv.realm.plugins.schwifty || {};

    return state;
};
<commit_msg>Fix lint<commit_after>'use strict';

const Objection = require('objection');
const Model = Objection.Model;
const Knex = require('knex');

const Path = require('path');
const Hoek = require('hoek');
const Joi = require('joi');
const Schema = require('./schema');
const Package = require('../package.json');

// const SchwiftyMigration = require('schwifty-migration');

const internals = {};

exports.register = function (server, options, next) {

    const rootState = internals.state(server.root);

    internals.state(server).dir = options.dir;
    const knexFile = options.knexFile;

    internals.state(server).knex = Knex(knexFile[process.env.NODE_ENV]);

    if (!rootState.setup) {

        rootState.collector = {
            models: {},
            teardownOnStop: null // Not set, effectively defaults true
        };

        // Here's the ORM!

        server.decorate('server', 'schwifty', internals.schwifty);
        server.decorate('server', 'models', internals.models((ctx) => ctx, 'realm'));
        server.decorate('request', 'models', internals.models((ctx) => ctx.server, 'route.realm'));
        server.decorate('server', 'knex', internals.knex((ctx) => ctx, 'realm'));
        server.decorate('request', 'knex', internals.knex((ctx) => ctx.server, 'route.realm'));
        server.ext('onPreStart', internals.initialize);
        server.ext('onPostStop', internals.stop);

        rootState.setup = true;
    };

    // Decide whether server stop should teardown

    const collector = rootState.collector;

    if (typeof knexFile.teardownOnStop !== 'undefined') {
        Hoek.assert(collector.teardownOnStop === null, 'Schwifty\'s teardownOnStop option can only be specified once.');
        collector.teardownOnStop = knexFile.teardownOnStop;
    }

    const config = internals.registrationConfig(knexFile);
    server.root.schwifty(config);

    next();
};

exports.register.attributes = {
    pkg: Package,
    multiple: true
};

// Massage registration config for use with rejoice
internals.registrationConfig = (options) => {

    const config = Hoek.shallow(options);

    delete config.teardownOnStop;

    // Resolve models

    if (typeof config.models === 'string') {
        if (Path.isAbsolute(config.models)) {
            config.models = require(config.models);
        }
        else {
            config.models = require(Path.resolve(process.cwd(), config.models));
        }
    }

    return config;
};

exports.Model = class SchwiftyModel extends Model {

    constructor(...args) {

        super(...args);
    }

    // $beforeInsert() {
    //   this.createdAt = new Date().toISOString();
    // };

    // $beforeUpdate() {
    //   this.updatedAt = new Date().toISOString();
    // };

    tryValidate(schema, json) {

        return Joi.validate(json, schema);
    }

    parseValidationError(err) {

        return err;
    }

    $validate(json = this, options = {}) {

        const ModelClass = this.constructor;

        const joiSchema = ModelClass.schema;

        if (!joiSchema || options.skipValidation) {
            return json;
        }

        let validation = this.tryValidate(joiSchema, json);

        if (validation.error) {
            throw new Objection.ValidationError(this.parseValidationError(validation.error.message));
        }
        else {
            validation = validation.value;
            this.$afterValidate(validation, options);
        }

        return validation;
    }
};

internals.initialize = function (server, next) {

    const collector = internals.state(server.root).collector;

    const modelsAsArray = [];

    Object.keys(collector.models).forEach((id) => {

        let model = collector.models[id];
        model = model.bindKnex(internals.state(server).knex);
        collector.models[id] = model;
        modelsAsArray.push(model);
    });

    next();

    // SchwiftyMigration.initModels(modelsAsArray, internals.state(server).knex, internals.state(server).dir, server, (err, res) => {

    //     if(err) {
    //         throw new Error(err);
    //     }

        // next();
    // });
};

internals.stop = function (server, next) {

    const collector = internals.state(server.root).collector;

    // Do not teardown if specifically asked not to
    if (collector.teardownOnStop === false) {
        return next();
    }

    return Knex.destroy(next);
};

internals.schwifty = function (config) {

    let isModels = false;

    // Array of models, coerce to config
    if (Array.isArray(config)) {
        config = Joi.validate(config, Schema.schwifty);
        isModels = true;
    }
    else {

        // Sim a Joi validation
        config = {
            error: null,
            value: config
        };
    }

    if (config.error) {
        throw new Objection.ValidationError(this.parseValidationError(config.error.message));
    }
    else {
        config = config.value;
    }

    if (isModels === true) {
        config = { models: config };
    }

    // Apply empty defaults
    config.models = config.models || [];

    // Collect adapters, connections, models, ensuring no dupes
    const collector = internals.state(this.root).collector;
    const modelIds = config.models.map((model) => new model().constructor.name);

    modelIds.forEach((id, index) => {

        // Classnames are often first-capital
        id = String(id).toLowerCase();
        Hoek.assert(!collector.models[id], `Model definition with identity "${id}" has already been registered.`);
        collector.models[id] = config.models[index];

        Hoek.assert(collector.models[id].tableName, `Model definition must have "static get tableName(){ return 'myTableName' }"`);
    });

    // If all went well, track which models belong to which realms
    const state = internals.state(this);
    state.models = (state.models || []).concat(modelIds);
};

internals.models = (serverFrom, realmPath) => {

    return function (all) {

        const rootCollector = internals.state(serverFrom.root).collector;

        if (!rootCollector.models) {
            return {};
        }

        if (all) {
            return rootCollector.models;
        }

        const models = Hoek.reach(this, `${realmPath}.plugins.schwifty.models`) || [];

        for (let i = 0; i < models.length; ++i) {
            const modelName = models[i].toLowerCase();
            models[modelName] = rootCollector.models[modelName];
        }

        return models;
    };
};

internals.knex = (serverFrom, realmPath) => {

    return function () {

        return Hoek.reach(this, `${realmPath}.plugins.schwifty.knex`);
    };
};

internals.state = (srv) => {

    const state = srv.realm.plugins.schwifty = srv.realm.plugins.schwifty || {};

    return state;
};
<|endoftext|>