<commit_before>
// import dependencies
import {EventEmitter} from 'events';
import qs             from 'querystring';
import fetch,
       {Response}     from 'node-fetch';
import WebSocket      from 'ws';
import WEB_METHODS    from './web-methods';
import singleLine     from './tags/singleline';

const VALID_TOKEN = /^([a-z]*)\-([0-9]*)\-([0-9a-zA-Z]*)/;
const VALID_URL   = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;

/**
 * @class BaseAPI
 * @classdesc provides a promise-based async API for working with Slack
 */
export default class BaseAPI extends EventEmitter {

  baseURL        = 'https://slack.com/api/';
  connection     = null;
  socketMsgId    = 0;
  callbacks      = {};
  events         = ['open', 'close', 'message', 'error'];

  /**
   * @constructs BaseAPI
   * @param {String|Object} opts - pass in a Slack API token,
   * incoming webhook URL, a slackbot URL, or an
   * object containing Slack options. Any option keys will be used
   * as the default for the key of the same name in any Slack method
   * options. The keys are named the same as they are on the Slack docs.
   */
  constructor(opts) {
    super();

    if (opts == null || !opts) {
      // bail if no options supplied. can't connect to an API without
      // access, now can we?
      throw new Error(
        singleLine`
          [fatal] missing options. please provide a token, webhook,
          slackbot url or settings object.
        `
      );
    } else if (typeof opts === 'string') {
      if (VALID_TOKEN.test(opts)) {
        // set default token if only string was supplied
        this.defaults = { token: opts };
      } else if (opts.includes('hooks.slack')) {
        // set default webhook
        this.defaults = { webhook: opts };
      } else if (opts.includes('slackbot?')) {
        this.defaults = { slackbot: opts };
      } else {
        throw new Error(
          singleLine`
            [fatal] unrecognized option "${opts}". please specify
            a valid API token, slackbot URL, webhook URL
            or an object containing these properties.
          `
        );
      }
    } else if (typeof opts === 'object') {
      this.defaults = opts;
    } else {
      throw new Error(
        singleLine`
          [fatal] expected options to be of type "string" or
          "object", but instead got "${typeof opts}".
        `
      );
    }
    validateOptions(this.defaults, 'fatal');
  }

  /**
   * sends a socket event with a payload to Slack's RTM API.
   * Slack requires that each event contain an ID, any responses
   * from the Slack API will contain a `reply_to` key that identifies
   * which sent message ID the response is replying to.
   * This API abstracts away the need to maintain that ID,
   * but it is returned if you need it. Overriden IDs are allowed
   * and are also returned.
   * @param  {Object} opts={} - the payload you wish to send
   * @param  {Function} callback - optional, is passed to the socket send method
   * @return {Number} - the ID of the message
   */
  send(opts, callback) {
    // increment the maintained id
    let id = opts.id || this.socketMsgId++;
    // encode the payload as a JSON string
    let encode = JSON.stringify({ ...opts, id });
    // slack will bail on us if the message is > 16kb.
    if (encode.length > 4000) {
      throw new Error(
        `message needs to be under 16kb. try chunking your ".send" calls.`
      );
    }
    this.ws.send(encode, callback);
    return id;
  }

  /**
   * shorthand method that calls rtm.start and initiates
   * websocket listeners for events sent from Slack's RTM API
   * @param  {Object} opts={} options to be passed to rtm.start
   * @param  {Object} WebSocket=WebSocket used to override socket in mock testing
   * @return {Promise} - a promise for the parsed reply from rtm.start
   */
  async connect(opts, WebSocket=WebSocket) {
    if (opts && opts.dontExecute) return;
    // call the rtm.start method
    let connection = await this.method('rtm.start', opts);

    this.ws         = new WebSocket(connection.url);
    this.connection = connection;

    // bind websocket events to base class
    // and emit events of the same name
    this.events.forEach(event => {
      this.ws.on(event, data => {
        // if the event is a message event, parse the
        // JSON payload before emitting from base class
        if (event === 'message' && data != null) data = JSON.parse(data);
        this.emit(event, data);
      });
    });

    // only resolve once the connection has been opened
    return new Promise(resolve => {
      this.on('open', () => resolve(this.connection));
    });
  }

  /**
   * asynchronously sends a querystring payload to the endpoint for the given
   * Slack Web API method
   * @param  {String} method - the name of the method https://api.slack.com/methods
   * @param  {Object} opts={} - the payload to send to the method
   * @return {Promise} - a promise for the parsed JSON response
   */
  async method(method, opts) {
    // merge given opts with defaults
    opts = { ...this.defaults, ...opts };
    cleanOptProps(opts, 'webhook', 'slackbot');
    if (method === 'api.test') {
      cleanOptProps(opts, 'token');
    }
    validateOptions(opts, 'error');
    for (let option of Object.keys(opts)) {
      // if the option is an array, stringify it,
      // as slack uses a weird query string syntax
      // that mixes JSON strings
      if (Array.isArray(opts[option])) {
        opts[option] = JSON.stringify(opts[option]);
      }
    }
    let response = await this.api(
      `${this.baseURL + method}?${qs.stringify(opts)}`
    );
    if (!response.ok) {
      let errors = WEB_METHODS.find(web => web.name === method).errors;
      throw new Error(
        singleLine`
          [${method} error] the response returned with error "${response.error}"
          - ${errors[response.error] || 'No description.'}
        `
      );
    }
    return response;
  }

  /**
   * sends a JSON payload to an incoming webhook URL (set as opts.webhook)
   * https://api.slack.com/incoming-webhooks
   * @param  {Object} opts={} object to be sent as the JSON payload
   * @return {Promise} the parsed JSON response
   */
  async submit(opts) {
    opts = { ...this.defaults, ...opts };
    validateOptions(opts, 'error');
    let webhook = opts.webhook;
    // delete the webhook key as Slack doesn't know WTF that is
    cleanOptProps(opts, 'webhook', 'slackbot', 'token');
    let response = await this.api(webhook, {
      method: 'post',
      body: JSON.stringify(opts)
    }, 'text');
    if (response !== 'ok') {
      throw new Error(
        singleLine`
          [error] the response returned with error "${response}"
        `
      );
    }
    return response;
  }

  /**
   * posts a message to slack as slackbot
   * @param  {Object} opts={} an object containing a channel
   *                          text you wish to send
   * @return {Promise} the parsed JSON response
   */
  async slackbot(opts) {
    opts.channel = opts.channel || '#general';
    let channel = qs.stringify({ channel: opts.channel });
    let url     = `${this.defaults.slackbot}&${channel}`;
    let response = await this.api(url, {
      method: 'post',
      body: opts.text
    }, 'text');
    if (response !== 'ok') {
      throw new Error(
        singleLine`
          [error] the response returned with error "${response}"
        `
      );
    }
    return response;
  }

  /**
   * sends an HTTP request and resolves to the parsed JSON
   * response
   * @param  {String} endpoint - the URL to send the request to
   * @param  {Object} opts - request options
   * @return {Promise} - the resolved & parsed JSON response
   */
  async api(endpoint, opts, type='json') {
    let response = await fetch(endpoint, opts);
    return await response[type]();
  }

}

function cleanOptProps(opts, ...props) {
  props.forEach(prop => delete opts[prop]);
}

function validateOptions(opts, level) {
  const invalid_token    = opts.token != null &&
                           !VALID_TOKEN.test(opts.token);
  const invalid_webhook  = opts.webhook != null &&
                           !VALID_URL.test(opts.webhook);
  const invalid_slackbot = opts.slackbot != null &&
                           !VALID_URL.test(opts.slackbot);
  if (invalid_webhook) {
    throw new Error(
      singleLine`
        [${level}] "${opts.webhook}" is not a valid webhook URL.
      `
    );
  }
  if (invalid_token) {
    throw new Error(
      singleLine`
        [${level}] "${opts.token}" is not a valid Slack API token.
      `
    );
  }
  if (invalid_slackbot) {
    throw new Error(
      singleLine`
        [${level}] "${opts.slackbot}" is not a valid slackbot URL.
      `
    );
  }
}
<commit_msg>add case for file upload method<commit_after>
// import dependencies
import {EventEmitter} from 'events';
import qs             from 'querystring';
import fetch,
       {Response}     from 'node-fetch';
import WebSocket      from 'ws';
import WEB_METHODS    from './web-methods';
import singleLine     from './tags/singleline';

const VALID_TOKEN = /^([a-z]*)\-([0-9]*)\-([0-9a-zA-Z]*)/;
const VALID_URL   = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;

/**
 * @class BaseAPI
 * @classdesc provides a promise-based async API for working with Slack
 */
export default class BaseAPI extends EventEmitter {

  baseURL        = 'https://slack.com/api/';
  connection     = null;
  socketMsgId    = 0;
  callbacks      = {};
  events         = ['open', 'close', 'message', 'error'];

  /**
   * @constructs BaseAPI
   * @param {String|Object} opts - pass in a Slack API token,
   * incoming webhook URL, a slackbot URL, or an
   * object containing Slack options. Any option keys will be used
   * as the default for the key of the same name in any Slack method
   * options. The keys are named the same as they are on the Slack docs.
   */
  constructor(opts) {
    super();

    if (opts == null || !opts) {
      // bail if no options supplied. can't connect to an API without
      // access, now can we?
      throw new Error(
        singleLine`
          [fatal] missing options. please provide a token, webhook,
          slackbot url or settings object.
        `
      );
    } else if (typeof opts === 'string') {
      if (VALID_TOKEN.test(opts)) {
        // set default token if only string was supplied
        this.defaults = { token: opts };
      } else if (opts.includes('hooks.slack')) {
        // set default webhook
        this.defaults = { webhook: opts };
      } else if (opts.includes('slackbot?')) {
        this.defaults = { slackbot: opts };
      } else {
        throw new Error(
          singleLine`
            [fatal] unrecognized option "${opts}". please specify
            a valid API token, slackbot URL, webhook URL
            or an object containing these properties.
          `
        );
      }
    } else if (typeof opts === 'object') {
      this.defaults = opts;
    } else {
      throw new Error(
        singleLine`
          [fatal] expected options to be of type "string" or
          "object", but instead got "${typeof opts}".
        `
      );
    }
    validateOptions(this.defaults, 'fatal');
  }

  /**
   * sends a socket event with a payload to Slack's RTM API.
   * Slack requires that each event contain an ID, any responses
   * from the Slack API will contain a `reply_to` key that identifies
   * which sent message ID the response is replying to.
   * This API abstracts away the need to maintain that ID,
   * but it is returned if you need it. Overriden IDs are allowed
   * and are also returned.
   * @param  {Object} opts={} - the payload you wish to send
   * @param  {Function} callback - optional, is passed to the socket send method
   * @return {Number} - the ID of the message
   */
  send(opts, callback) {
    // increment the maintained id
    let id = opts.id || this.socketMsgId++;
    // encode the payload as a JSON string
    let encode = JSON.stringify({ ...opts, id });
    // slack will bail on us if the message is > 16kb.
    if (encode.length > 4000) {
      throw new Error(
        `message needs to be under 16kb. try chunking your ".send" calls.`
      );
    }
    this.ws.send(encode, callback);
    return id;
  }

  /**
   * shorthand method that calls rtm.start and initiates
   * websocket listeners for events sent from Slack's RTM API
   * @param  {Object} opts={} options to be passed to rtm.start
   * @param  {Object} WebSocket=WebSocket used to override socket in mock testing
   * @return {Promise} - a promise for the parsed reply from rtm.start
   */
  async connect(opts, WebSocket=WebSocket) {
    if (opts && opts.dontExecute) return;
    // call the rtm.start method
    let connection = await this.method('rtm.start', opts);

    this.ws         = new WebSocket(connection.url);
    this.connection = connection;

    // bind websocket events to base class
    // and emit events of the same name
    this.events.forEach(event => {
      this.ws.on(event, data => {
        // if the event is a message event, parse the
        // JSON payload before emitting from base class
        if (event === 'message' && data != null) data = JSON.parse(data);
        this.emit(event, data);
      });
    });

    // only resolve once the connection has been opened
    return new Promise(resolve => {
      this.on('open', () => resolve(this.connection));
    });
  }

  /**
   * asynchronously sends a querystring payload to the endpoint for the given
   * Slack Web API method
   * @param  {String} method - the name of the method https://api.slack.com/methods
   * @param  {Object} opts={} - the payload to send to the method
   * @return {Promise} - a promise for the parsed JSON response
   */
  async method(method, opts) {
    let response;
    // merge given opts with defaults
    opts = { ...this.defaults, ...opts };
    cleanOptProps(opts, 'webhook', 'slackbot');
    if (method === 'api.test') {
      cleanOptProps(opts, 'token');
    }
    validateOptions(opts, 'error');
    for (let option of Object.keys(opts)) {
      // if the option is an array, stringify it,
      // as slack uses a weird query string syntax
      // that mixes JSON strings
      if (Array.isArray(opts[option])) {
        opts[option] = JSON.stringify(opts[option]);
      }
    }
    if (method === 'files.upload') {
      response = await this.api(`${this.baseURL + method}`, {
        method: 'post',
        body: JSON.stringify(opts)
      });
    } else {
      response = await this.api(
        `${this.baseURL + method}?${qs.stringify(opts)}`
      );
    }
    if (!response.ok) {
      let errors = WEB_METHODS.find(web => web.name === method).errors;
      throw new Error(
        singleLine`
          [${method} error] the response returned with error "${response.error}"
          - ${errors[response.error] || 'No description.'}
        `
      );
    }
    return response;
  }

  /**
   * sends a JSON payload to an incoming webhook URL (set as opts.webhook)
   * https://api.slack.com/incoming-webhooks
   * @param  {Object} opts={} object to be sent as the JSON payload
   * @return {Promise} the parsed JSON response
   */
  async submit(opts) {
    opts = { ...this.defaults, ...opts };
    validateOptions(opts, 'error');
    let webhook = opts.webhook;
    // delete the webhook key as Slack doesn't know WTF that is
    cleanOptProps(opts, 'webhook', 'slackbot', 'token');
    let response = await this.api(webhook, {
      method: 'post',
      body: JSON.stringify(opts)
    }, 'text');
    if (response !== 'ok') {
      throw new Error(
        singleLine`
          [error] the response returned with error "${response}"
        `
      );
    }
    return response;
  }

  /**
   * posts a message to slack as slackbot
   * @param  {Object} opts={} an object containing a channel
   *                          text you wish to send
   * @return {Promise} the parsed JSON response
   */
  async slackbot(opts) {
    opts.channel = opts.channel || '#general';
    let channel = qs.stringify({ channel: opts.channel });
    let url     = `${this.defaults.slackbot}&${channel}`;
    let response = await this.api(url, {
      method: 'post',
      body: opts.text
    }, 'text');
    if (response !== 'ok') {
      throw new Error(
        singleLine`
          [error] the response returned with error "${response}"
        `
      );
    }
    return response;
  }

  /**
   * sends an HTTP request and resolves to the parsed JSON
   * response
   * @param  {String} endpoint - the URL to send the request to
   * @param  {Object} opts - request options
   * @return {Promise} - the resolved & parsed JSON response
   */
  async api(endpoint, opts, type='json') {
    let response = await fetch(endpoint, opts);
    return await response[type]();
  }

}

function cleanOptProps(opts, ...props) {
  props.forEach(prop => delete opts[prop]);
}

function validateOptions(opts, level) {
  const invalid_token    = opts.token != null &&
                           !VALID_TOKEN.test(opts.token);
  const invalid_webhook  = opts.webhook != null &&
                           !VALID_URL.test(opts.webhook);
  const invalid_slackbot = opts.slackbot != null &&
                           !VALID_URL.test(opts.slackbot);
  if (invalid_webhook) {
    throw new Error(
      singleLine`
        [${level}] "${opts.webhook}" is not a valid webhook URL.
      `
    );
  }
  if (invalid_token) {
    throw new Error(
      singleLine`
        [${level}] "${opts.token}" is not a valid Slack API token.
      `
    );
  }
  if (invalid_slackbot) {
    throw new Error(
      singleLine`
        [${level}] "${opts.slackbot}" is not a valid slackbot URL.
      `
    );
  }
}
<|endoftext|>


<commit_before>'use strict';

// List of supported http methods.
var HTTP_METHODS = ['get', 'post', 'put', 'delete'];
var router = {};
var routes = {};

/**
 * Parse path to regexp.
 * @param  {String} path URL path.
 * @return {Object} Object with new RegExp and keys.
 */
function pathRegexp(path) {
    var keys = [];

    if (Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    path = path.toLowerCase().replace(/(:[\w\-]+)/g, function() {
        keys.push(arguments[0].slice(1));
        return '(?:([^\/]+?))';
    }).replace(/([\/.])/g, '\\$1');

    return {
        path: new RegExp('^' + path + '$'),
        keys: keys
    };
}

/**
 * Find route.
 * @param  {String} method HTTP method.
 * @param  {String} path URL path.
 * @return {OBject|Boolean} Found route object or false.
 */
function matchRoute(method, path) {
    var route;

    method = method.toLowerCase();

    // TODO: Use handler to response Error.
    if (!method && HTTP_METHODS.indexOf(method) < 0) {
        throw new Error('Not supported HTTP method: ' + method);
    }

    if (!path && Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    for (var i in routes[method]) {
        route = routes[method][i];

        // TODO: call get Params.
        if (route.path.test(path)) {
            return route;
        }
    }

    return false;
}

/**
 * Get params from URL.
 * @param  {String} url URL path.
 * @param  {Object} route Route object.
 * @return {Object} params Object with parsed params.
 */
function getParams(url, route) {
    // TODO: Add query params.
    var params = {};

    url.match(route.path).slice(1).forEach(function(value, index) {
        params[route.keys[index]] = value;
    });

    return params;
}

HTTP_METHODS.forEach(function(method) {
    routes[method] = [];

    // TODO: Extract method.
    // TODO: Should to be uniq.
    router[method] = function(route, callback) {
        route = pathRegexp(route);
        route.callback = callback;
        routes[method].push(route);
    };
});

router.listener = function(request, response) {
    var args = Array.prototype.slice.call(arguments);
    var url = request.url;
    var route = matchRoute(request.method, url);

    if (route) {
        if (typeof route.callback === 'function') {
            route.callback(request, response, getParams(url, route));
        }

    // TODO: Add default 404 handler.
    } else {
        response.writeHead(404, { 'Content-Type': 'text/html' });
        response.end();
    }
};

module.exports = router;
<commit_msg>Removed extra handler parameter.<commit_after>'use strict';

// List of supported http methods.
var HTTP_METHODS = ['get', 'post', 'put', 'delete'];
var router = {};
var routes = {};

/**
 * Parse path to regexp.
 * @param  {String} path URL path.
 * @return {Object} Object with new RegExp and keys.
 */
function pathRegexp(path) {
    var keys = [];

    if (Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    path = path.toLowerCase().replace(/(:[\w\-]+)/g, function() {
        keys.push(arguments[0].slice(1));
        return '(?:([^\/]+?))';
    }).replace(/([\/.])/g, '\\$1');

    return {
        path: new RegExp('^' + path + '$'),
        keys: keys
    };
}

/**
 * Find route.
 * @param  {String} method HTTP method.
 * @param  {String} path URL path.
 * @return {OBject|Boolean} Found route object or false.
 */
function matchRoute(method, path) {
    var route;

    method = method.toLowerCase();

    // TODO: Use handler to response Error.
    if (!method && HTTP_METHODS.indexOf(method) < 0) {
        throw new Error('Not supported HTTP method: ' + method);
    }

    if (!path && Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    for (var i in routes[method]) {
        route = routes[method][i];

        // TODO: call get Params.
        if (route.path.test(path)) {
            return route;
        }
    }

    return false;
}

/**
 * Get params from URL.
 * @param  {String} url URL path.
 * @param  {Object} route Route object.
 * @return {Object} params Object with parsed params.
 */
function getParams(url, route) {
    // TODO: Add query params.
    var params = {};

    url.match(route.path).slice(1).forEach(function(value, index) {
        params[route.keys[index]] = value;
    });

    return params;
}

HTTP_METHODS.forEach(function(method) {
    routes[method] = [];

    // TODO: Extract method.
    // TODO: Should to be uniq.
    router[method] = function(route, callback) {
        route = pathRegexp(route);
        route.callback = callback;
        routes[method].push(route);
    };
});

router.listener = function(request, response) {
    var url = request.url;
    var route = matchRoute(request.method, url);

    request.params = getParams(url, route);

    if (route) {
        if (typeof route.callback === 'function') {
            route.callback(request, response);
        }

    // TODO: Add default 404 handler.
    } else {
        response.writeHead(404, { 'Content-Type': 'text/html' });
        response.end();
    }
};

module.exports = router;
<|endoftext|>


<commit_before>//Parse the text from stdin
module.exports = function(cb)
{
  //Body content
  var body = '';

  //Resume the event
  process.stdin.resume();

  //Set the default encoding
  process.stdin.setEncoding('utf8');

  //New data from stdin
  process.stdin.on('data', function(data){ body = body + data; });

  //End event
  process.stdin.on('end', function(){ return cb(body); });
};
<commit_msg>lib/body.js: check if is tty<commit_after>//Parse the text from stdin
module.exports = function(cb)
{
  //Check if is being run inside a text terminal ("TTY") context
  //https://nodejs.org/api/tty.html
  if(process.stdin.isTTY){ return cb(''); }

  //Body content
  var body = '';

  //Resume the event
  process.stdin.resume();

  //Set the default encoding
  process.stdin.setEncoding('utf8');

  //New data from stdin
  process.stdin.on('data', function(data){ body = body + data; });

  //End event
  process.stdin.on('end', function(){ return cb(body); });
};
<|endoftext|>


<commit_before>var bomb = {
    /**
     * Checks whether string has BOM
     * @param {String} str
     *
     * @returns {Number}
     */
    hasBOM: function (str) {
        if (typeof str !== 'string') {
            return 0;
        }

        // remove UTF-16 and UTF-32 BOM (https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8)
        if (str.charCodeAt(0) === 0xFEFF) {
            return 1;
        }

        // big endian UTF-16 BOM
        if ((str.charCodeAt(0) === 0xFE) && (str.charCodeAt(1) === 0xFF)) {
            return 2;
        }

        // little endian UTF-16 BOM
        if ((str.charCodeAt(0) === 0xFF) && (str.charCodeAt(1) === 0xFE)) {
            return 2;
        }

        // UTF-8 BOM
        if ((str.charCodeAt(0) === 0xEF) && (str.charCodeAt(1) === 0xBB) &&
            (str.charCodeAt(2) === 0xBF)) {
            return 3;
        }

        return 0;
    },

    /**
     * Trim BOM from a string
     *
     * @param {String} str
     * @returns {String}
     */
    trim: function (str) {
        var pos = bomb.hasBOM(str);
        return pos ? str.splice(post) : str;
    }
};

module.exports = bomb;
<commit_msg>Using the hex codes as constant<commit_after>var bomb = {
    /**
     * @private
     * @type {Object}
     */
    code: {
        FEFF: 0xFEFF,
        BBBF: 0xBBBF,
        FE: 0xFE,
        FF: 0xFF,
        EF: 0xEF,
        BB: 0xBB,
        BF: 0xBF
    },

    /**
     * Checks whether string has BOM
     * @param {String} str
     *
     * @returns {Number}
     */
    hasBOM: function (str) {
        if (typeof str !== 'string') {
            return 0;
        }

        // remove UTF-16 and UTF-32 BOM (https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8)
        if ((str.charCodeAt(0) === bomb.code.FEFF) || (str.charCodeAt(0) === bomb.code.BBBF)) {
            return 1;
        }

        // big endian UTF-16 BOM
        if ((str.charCodeAt(0) === bomb.code.FE) && (str.charCodeAt(1) === bomb.code.FF)) {
            return 2;
        }

        // little endian UTF-16 BOM
        if ((str.charCodeAt(0) === bomb.code.FF) && (str.charCodeAt(1) === bomb.code.FE)) {
            return 2;
        }

        // UTF-8 BOM
        if ((str.charCodeAt(0) === bomb.code.EF) && (str.charCodeAt(1) === bomb.code.BB) &&
            (str.charCodeAt(2) === bomb.code.BF)) {
            return 3;
        }

        return 0;
    },

    /**
     * Trim BOM from a string
     *
     * @param {String} str
     * @returns {String}
     */
    trim: function (str) {
        var pos = bomb.hasBOM(str);
        return pos ? str.splice(post) : str;
    }
};

module.exports = bomb;
<|endoftext|>


<commit_before>function loadCyvasseJs() {
    Module.canvas = document.getElementById("canvas");
    emscriptenHeader.show();
    $.getScript("/cyvasse.js");
}

function CyvasseWSClient(websockConn, loadNewPage) {
    if(websockConn instanceof WebSocket === false) {
        throw new TypeError("websockConn has to be a WebSocket instance");
    }
    if(typeof(loadNewPage) !== "function") {
        throw new TypeError("loadNewPage has to be a function");
    }

    this.conn = websockConn;
    this.loadNewPage = loadNewPage;
    this.nextMessageID = 1;
    this.awaitingReply = [];
    this.cachedIngameRequests = [];
    this.gameData = {};

    var self = this;

	this.conn.onmessage = function(msg) {
        if(self.debug === true) {
            console.log("[onmessage]");
            console.log(msg.data);
        }
		self.handleMessage(msg.data);
	};

    this.conn.onclose = function() {
		console.log("The connection to the server was closed.");
	};
}

CyvasseWSClient.prototype.handleMessage = function(msgData) {
    var msgObj = JSON.parse(msgData);

    if(msgObj.messageType === "request") {
        console.log("Got a request from the server; can't handle that yet.");
    }
    else if(msgObj.messageType === "reply") {
        var answeredRequest;

        for(var request in this.awaitingReply) {
            if(this.awaitingReply[request].messageID == msgObj.messageID) {
                // remove the request from this.awaitingReply
                // and save it to answeredRequests
                answeredRequest = this.awaitingReply.splice(request, 1)[0];
            }
        }
        if(answeredRequest === undefined) {
            throw new Error("Got a reply to an unknown server request!");
        }

        if(msgObj.success === false) {
            throw new Error("Got an error message from the server: " + msgObj.error + "\n" +
                "as response to:\n\n" + JSON.stringify(answeredRequest));
        }

        switch(answeredRequest.action) {
            case "create game":
                this.gameData.playerID = msgObj.data.playerID;
                this.loadNewPage("/match/" + msgObj.data.matchID, function() {
                    loadCyvasseJs();
                });
                break;
            case "join game":
                this.gameData.playerID = msgObj.data.playerID;
                this.gameData.color = msgObj.data.color;
                loadCyvasseJs();
                break;
            default:
                if(this.handleMessageIngame === undefined) {
                    console.log("Got a message for the game before it was loaded, caching.");
                    this.cachedIngameRequests.push(msgData);
                }
                else {
                    if(typeof(this.handleMessageIngame) !== "function") {
                        throw new TypeError("handleMessageIngame has to be a function");
                    }

                    handleMessageIngame(msgData);
                }
        }
    }
    else {
        throw new Error("Got malformed or incomplete message");
    }
};

CyvasseWSClient.prototype.send = function(msgObj) {
    var msgData = JSON.stringify(msgObj);
    if(this.debug === true) {
        console.log("[send]");
        console.log(msgData);
    }
    this.conn.send(msgData);
    this.awaitingReply.push(msgObj);
};

CyvasseWSClient.prototype.sendRequest = function(msgObj) {
    msgObj.messageType = "request";
    msgObj.messageID = this.nextMessageID++;

    this.send(msgObj);
};

CyvasseWSClient.prototype.sendReply = function(request, msgObj) {
    msgObj.messageType = "reply";
    msgObj.messageID = request.messageID;

    this.send(msgObj);
};

CyvasseWSClient.prototype.createGame = function(ruleSet, color) {
    this.sendRequest({
        "action": "create game",
        "param": {
            "ruleSet": ruleSet,
            "color": color
        }
    });
};

CyvasseWSClient.prototype.joinGame = function(matchID) {
    this.sendRequest({
        "action": "join game",
        "param": {
            "matchID": matchID
        }
    });
};
<commit_msg>Bytesize bug fix<commit_after>function loadCyvasseJs() {
    Module.canvas = document.getElementById("canvas");
    emscriptenHeader.show();
    $.getScript("/cyvasse.js");
}

function CyvasseWSClient(websockConn, loadNewPage) {
    if(websockConn instanceof WebSocket === false) {
        throw new TypeError("websockConn has to be a WebSocket instance");
    }
    if(typeof(loadNewPage) !== "function") {
        throw new TypeError("loadNewPage has to be a function");
    }

    this.conn = websockConn;
    this.loadNewPage = loadNewPage;
    this.nextMessageID = 1;
    this.awaitingReply = [];
    this.cachedIngameRequests = [];
    this.gameData = {};

    var self = this;

	this.conn.onmessage = function(msg) {
        if(self.debug === true) {
            console.log("[onmessage]");
            console.log(msg.data);
        }
		self.handleMessage(msg.data);
	};

    this.conn.onclose = function() {
		console.log("The connection to the server was closed.");
	};
}

CyvasseWSClient.prototype.handleMessage = function(msgData) {
    var msgObj = JSON.parse(msgData);

    if(msgObj.messageType === "request") {
        console.log("Got a request from the server; can't handle that yet.");
    }
    else if(msgObj.messageType === "reply") {
        var answeredRequest;

        for(var request in this.awaitingReply) {
            if(this.awaitingReply[request].messageID == msgObj.messageID) {
                // remove the request from this.awaitingReply
                // and save it to answeredRequests
                answeredRequest = this.awaitingReply.splice(request, 1)[0];
            }
        }
        if(answeredRequest === undefined) {
            throw new Error("Got a reply to an unknown server request!");
        }

        if(msgObj.success === false) {
            throw new Error("Got an error message from the server: " + msgObj.error + "\n" +
                "as response to:\n\n" + JSON.stringify(answeredRequest));
        }

        switch(answeredRequest.action) {
            case "create game":
                this.gameData.playerID = msgObj.data.playerID;
                this.loadNewPage("/match/" + msgObj.data.matchID, function() {
                    loadCyvasseJs();
                });
                break;
            case "join game":
                this.gameData.playerID = msgObj.data.playerID;
                this.gameData.color = msgObj.data.color;
                loadCyvasseJs();
                break;
            default:
                if(this.handleMessageIngame === undefined) {
                    console.log("Got a message for the game before it was loaded, caching.");
                    this.cachedIngameRequests.push(msgData);
                }
                else {
                    if(typeof(this.handleMessageIngame) !== "function") {
                        throw new TypeError("handleMessageIngame has to be a function");
                    }

                    handleMessageIngame(msgData);
                }
        }
    }
    else {
        throw new Error("Got malformed or incomplete message");
    }
};

CyvasseWSClient.prototype.send = function(msgObj) {
    var msgData = JSON.stringify(msgObj);
    if(this.debug === true) {
        console.log("[send]");
        console.log(msgData);
    }
    this.conn.send(msgData);
};

CyvasseWSClient.prototype.sendRequest = function(msgObj) {
    msgObj.messageType = "request";
    msgObj.messageID = this.nextMessageID++;

    this.send(msgObj);
    this.awaitingReply.push(msgObj);
};

CyvasseWSClient.prototype.sendReply = function(request, msgObj) {
    msgObj.messageType = "reply";
    msgObj.messageID = request.messageID;

    this.send(msgObj);
};

CyvasseWSClient.prototype.createGame = function(ruleSet, color) {
    this.sendRequest({
        "action": "create game",
        "param": {
            "ruleSet": ruleSet,
            "color": color
        }
    });
};

CyvasseWSClient.prototype.joinGame = function(matchID) {
    this.sendRequest({
        "action": "join game",
        "param": {
            "matchID": matchID
        }
    });
};
<|endoftext|>


<commit_before>'use strict';

module.exports = createCart;

var extend = require('extend');
var emitter = require('./util/emitter');
var toNumber = require('./util/to-number');
var options = require('./util/options');
var value = require('./util/value');
var createItem = require('./item');

var resolve = Promise.resolve.bind(Promise);
var reject = Promise.reject.bind(Promise);

var _defaultOptions = {
    storage: null,
    currency: 'USD',
    shipping: null,
    tax: null
};

function createCart(opts) {
    var _options = extend({}, _defaultOptions, opts);
    var _items = [];
    var _ready = load();

    function cart() {
        return _items.slice(0);
    }

    var emit = emitter(cart);

    cart.ready = function(onReady) {
        ready(onReady);

        return cart;
    };

    cart.error = function(onError) {
        error(onError);

        return cart;
    };

    cart.options = options.bind(cart, _options);

    cart.size = function() {
        return _items.length;
    };

    cart.has = function(item) {
        return !!has(item);
    };

    cart.get = function(item) {
        var found = has(item);

        return !found ? null : found.item;
    };

    cart.add = function(item) {
        ready(add.bind(cart, item));

        return cart;
    };

    cart.update = function(item) {
        ready(update.bind(cart, item));

        return cart;
    };

    cart.remove = function(item) {
        ready(remove.bind(cart, item));

        return cart;
    };

    cart.clear = function() {
        ready(clear);

        return cart;
    };

    cart.each = function(callback, context) {
        _items.every(function(item, index) {
            return false !== callback.call(context, item, index, cart);
        });

        return cart;
    };

    cart.quantity = function() {
        return cart().reduce(function(previous, item) {
            return previous + item.quantity();
        }, 0);
    };

    cart.subtotal = function() {
        return cart().reduce(function(previous, item) {
            return previous + (item.price() * item.quantity());
        }, 0);
    };

    cart.shipping = function() {
        if (!cart.size()) {
            return 0;
        }

        return toNumber(value(_options.shipping, undefined, [cart]), _options);
    };

    cart.tax = function() {
        if (!cart.size()) {
            return 0;
        }

        return toNumber(value(_options.tax, undefined, [cart]), _options);
    };

    cart.total = function() {
        return cart.subtotal() + cart.tax() + cart.shipping();
    };

    function ready(onReady) {
        _ready['catch'](function(e) {
            setTimeout(function() { throw e; });
        });

        _ready = _ready.then(function() {
            return onReady(cart);
        });
    }

    function error(onError) {
        _ready = _ready['catch'](function(e) {
            return onError(e, cart);
        });
    }

    function load() {
        return resolve(
            _options.storage && _options.storage.load()
        ).then(function(items) {
            if (Array.isArray(items)) {
                _items = items.map(function(attr) {
                    return createItem(attr);
                });
            }
        });
    }

    function has(attr) {
        var checkItem;
        var found = false;

        try {
            checkItem = createItem(attr);
        } catch (e) {
            return false;
        }

        _items.every(function(item, index) {
            if (checkItem.equals(item)) {
                found = {item: item, index: index};
            }

            return !found;
        });

        return found;
    }

    function update(attr) {
        var item = createItem(attr);

        if (!emit('update', item)) {
            return;
        }

        var existing = has(item);

        if (!existing) {
            return;
        }

        item = createItem(extend({}, existing.item(), item()));

        if (item.quantity() < 1) {
            return remove(item);
        }

        _items[existing.index] = item;

        return resolve(
            _options.storage && _options.storage.update(item, cart)
        ).then(emit.bind(cart, 'updated', item), function(e) {
            emit('updatefailed', e, item);
            return reject(e);
        });
    }

    function add(attr) {
        var item = createItem(attr);

        if (!emit('add', item)) {
            return;
        }

        var existing = has(item);

        if (existing) {
            item = createItem(extend({}, existing.item(), item(), {
                quantity: existing.item.quantity() + item.quantity()
            }));
        }

        if (item.quantity() < 1) {
            return remove(item);
        }

        if (existing) {
            _items[existing.index] = item;
        } else {
            _items.push(item);
        }

        return resolve(
            _options.storage && _options.storage.add(item, cart)
        ).then(emit.bind(cart, 'added', item), function(e) {
            emit('addfailed', e, item);
            return reject(e);
        });
    }

    function remove(attr) {
        var existing = has(attr);

        if (!existing || !emit('remove', existing.item)) {
            return;
        }

        _items.splice(existing.index, 1);

        return resolve(
            _options.storage && _options.storage.remove(existing.item, cart)
        ).then(emit.bind(cart, 'removed', existing.item), function(e) {
            emit('removefailed', e, existing.item);
            return reject(e);
        });
    }

    function clear() {
        if (!emit('clear')) {
            return;
        }

        _items.length = 0;

        return resolve(
            _options.storage && _options.storage.clear()
        ).then(emit.bind(cart, 'cleared'), function(e) {
            emit('clearfailed', e);
            return reject(e);
        });
    }

    return cart;
}

createCart.options = options.bind(createCart, _defaultOptions);
<commit_msg>Remove unused currency option<commit_after>'use strict';

module.exports = createCart;

var extend = require('extend');
var emitter = require('./util/emitter');
var toNumber = require('./util/to-number');
var options = require('./util/options');
var value = require('./util/value');
var createItem = require('./item');

var resolve = Promise.resolve.bind(Promise);
var reject = Promise.reject.bind(Promise);

var _defaultOptions = {
    storage: null,
    shipping: null,
    tax: null
};

function createCart(opts) {
    var _options = extend({}, _defaultOptions, opts);
    var _items = [];
    var _ready = load();

    function cart() {
        return _items.slice(0);
    }

    var emit = emitter(cart);

    cart.ready = function(onReady) {
        ready(onReady);

        return cart;
    };

    cart.error = function(onError) {
        error(onError);

        return cart;
    };

    cart.options = options.bind(cart, _options);

    cart.size = function() {
        return _items.length;
    };

    cart.has = function(item) {
        return !!has(item);
    };

    cart.get = function(item) {
        var found = has(item);

        return !found ? null : found.item;
    };

    cart.add = function(item) {
        ready(add.bind(cart, item));

        return cart;
    };

    cart.update = function(item) {
        ready(update.bind(cart, item));

        return cart;
    };

    cart.remove = function(item) {
        ready(remove.bind(cart, item));

        return cart;
    };

    cart.clear = function() {
        ready(clear);

        return cart;
    };

    cart.each = function(callback, context) {
        _items.every(function(item, index) {
            return false !== callback.call(context, item, index, cart);
        });

        return cart;
    };

    cart.quantity = function() {
        return cart().reduce(function(previous, item) {
            return previous + item.quantity();
        }, 0);
    };

    cart.subtotal = function() {
        return cart().reduce(function(previous, item) {
            return previous + (item.price() * item.quantity());
        }, 0);
    };

    cart.shipping = function() {
        if (!cart.size()) {
            return 0;
        }

        return toNumber(value(_options.shipping, undefined, [cart]), _options);
    };

    cart.tax = function() {
        if (!cart.size()) {
            return 0;
        }

        return toNumber(value(_options.tax, undefined, [cart]), _options);
    };

    cart.total = function() {
        return cart.subtotal() + cart.tax() + cart.shipping();
    };

    function ready(onReady) {
        _ready['catch'](function(e) {
            setTimeout(function() { throw e; });
        });

        _ready = _ready.then(function() {
            return onReady(cart);
        });
    }

    function error(onError) {
        _ready = _ready['catch'](function(e) {
            return onError(e, cart);
        });
    }

    function load() {
        return resolve(
            _options.storage && _options.storage.load()
        ).then(function(items) {
            if (Array.isArray(items)) {
                _items = items.map(function(attr) {
                    return createItem(attr);
                });
            }
        });
    }

    function has(attr) {
        var checkItem;
        var found = false;

        try {
            checkItem = createItem(attr);
        } catch (e) {
            return false;
        }

        _items.every(function(item, index) {
            if (checkItem.equals(item)) {
                found = {item: item, index: index};
            }

            return !found;
        });

        return found;
    }

    function update(attr) {
        var item = createItem(attr);

        if (!emit('update', item)) {
            return;
        }

        var existing = has(item);

        if (!existing) {
            return;
        }

        item = createItem(extend({}, existing.item(), item()));

        if (item.quantity() < 1) {
            return remove(item);
        }

        _items[existing.index] = item;

        return resolve(
            _options.storage && _options.storage.update(item, cart)
        ).then(emit.bind(cart, 'updated', item), function(e) {
            emit('updatefailed', e, item);
            return reject(e);
        });
    }

    function add(attr) {
        var item = createItem(attr);

        if (!emit('add', item)) {
            return;
        }

        var existing = has(item);

        if (existing) {
            item = createItem(extend({}, existing.item(), item(), {
                quantity: existing.item.quantity() + item.quantity()
            }));
        }

        if (item.quantity() < 1) {
            return remove(item);
        }

        if (existing) {
            _items[existing.index] = item;
        } else {
            _items.push(item);
        }

        return resolve(
            _options.storage && _options.storage.add(item, cart)
        ).then(emit.bind(cart, 'added', item), function(e) {
            emit('addfailed', e, item);
            return reject(e);
        });
    }

    function remove(attr) {
        var existing = has(attr);

        if (!existing || !emit('remove', existing.item)) {
            return;
        }

        _items.splice(existing.index, 1);

        return resolve(
            _options.storage && _options.storage.remove(existing.item, cart)
        ).then(emit.bind(cart, 'removed', existing.item), function(e) {
            emit('removefailed', e, existing.item);
            return reject(e);
        });
    }

    function clear() {
        if (!emit('clear')) {
            return;
        }

        _items.length = 0;

        return resolve(
            _options.storage && _options.storage.clear()
        ).then(emit.bind(cart, 'cleared'), function(e) {
            emit('clearfailed', e);
            return reject(e);
        });
    }

    return cart;
}

createCart.options = options.bind(createCart, _defaultOptions);
<|endoftext|>


<commit_before>"use strict";

var http, https, url, get, toJSON, CGDS;

http = require("http");
https = require("https");
url = require("url");

get = function (uri, proxy, callback) {
    var options, responseHandler, req;
    if (typeof proxy === "function") {
        callback = proxy;
        proxy = undefined;
    }
    if (proxy !== undefined) {
        options = url.parse(proxy + encodeURIComponent(uri));
    } else {
        options = url.parse(uri);
    }
    responseHandler = function (res) {
        var body;
     // Browserify does not seem to work well with buffers ("no method copy"),
     // therefore fall back to strings.
        body = "";
        res.on("data", function (chunk) {
            body += chunk;
        });
        res.on("end", function () {
            callback(null, body);
        });
    };
    // Don't use http.get until https://github.com/substack/https-browserify/pull/1
    // is fixed.
    options.method = "GET";
    if (options.protocol === "https:") {
        options.port = 443;
        req = https.request(options, responseHandler);
    } else {
        options.port = 80;
        req = http.request(options, responseHandler);
    }
    req.end();
};

toJSON = function (data, callback) {
    var lines, errorTerms, errorOccured, columns;
 // Split lines.
    lines = data.split(/\r?\n/);
 // Drop comments and empty lines.
    lines = lines.filter(function (line) {
        if (line.charAt(0) === "#" || line === "") {
            return false;
        } else {
            return true;
        }
    });
 // If the first line starts with "Error: " or in some buggy cases with the whole
 // error string after dropping the comments, then it is likely to be an error.
    errorTerms = ["Error: ", "No genetic profile available for genetic_profile_id: "];
    errorOccured = errorTerms.some(function (errorTerm) {
        if (lines[0].lastIndexOf(errorTerm, 0) === 0) {
            return true;
        } else {
            return false;
        }
    });
    if (errorOccured === true) {
        callback({
            message: lines[0]
        }, null);
    } else {
     // Convert to JSON.
        columns = lines.shift().split(/\t/);
        lines = lines.map(function (line) {
            var obj;
            obj = {};
            line.split(/\t/).forEach(function (column, idx) {
                obj[columns[idx]] = column;
            });
            return obj;
        });
        callback(null, lines);
    }
};

CGDS = function (url) {
    if (typeof url === "string") {
        this.url = url;
    } else if (url !== null && typeof url === "object" && url.hasOwnProperty("url") === true) {
        this.url = url.url;
        if (url.hasOwnProperty("proxy") === true) {
            this.proxy = url.proxy;
        }
    } else {
        throw new Error("Please provide a URL parameter.");
    }
};

CGDS.prototype.getTypesOfCancer = function (callback) {
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getTypesOfCancer", this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getCancerStudies = function (callback) {
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getCancerStudies", this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getGeneticProfiles = function (cancerStudyId, callback) {
    if (cancerStudyId === undefined) {
        throw new Error("Please provide a cancer_study_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getGeneticProfiles&cancer_study_id=" + cancerStudyId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getCaseLists = function (cancerStudyId, callback) {
    if (cancerStudyId === undefined) {
        throw new Error("Please provide a cancer_study_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getCaseLists&cancer_study_id=" + cancerStudyId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getProfileData = function (caseSetId, geneticProfileId, geneList, callback) {
    if (caseSetId === undefined) {
        throw new Error("Please provide a case_set_id parameter.");
    }
    if (geneticProfileId === undefined) {
        throw new Error("Please provide a genetic_profile_id parameter.");
    }
    if (geneList === undefined) {
        throw new Error("Please provide a gene_list parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    if (Array.isArray(geneticProfileId) && Array.isArray(geneList)) {
        throw new Error("You can specify multiple genes or multiple genetic profiles, but not both at once!");
    }
 // Convert geneticProfileId to string.
    if (Array.isArray(geneticProfileId) === true) {
        geneticProfileId = geneticProfileId.join("+");
    }
 // Convert geneList to string.
    if (Array.isArray(geneList) === true) {
        geneList = geneList.join("+");
    }
    get(this.url + "?cmd=getProfileData&case_set_id=" + caseSetId + "&genetic_profile_id=" + geneticProfileId + "&gene_list=" + geneList, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getMutationData = function (geneticProfileId, geneList, caseSetId, callback) {
    var url;
    if (geneticProfileId === undefined) {
        throw new Error("Please provide a genetic_profile_id parameter.");
    }
    if (geneList === undefined) {
        throw new Error("Please provide a gene_list parameter.");
    }
    if (typeof caseSetId === "function") {
        callback = caseSetId;
        caseSetId = undefined;
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
 // Convert geneticProfileId to string.
    if (Array.isArray(geneticProfileId) === true) {
        geneticProfileId = geneticProfileId.join("+");
    }
 // Convert geneList to string.
    if (Array.isArray(geneList) === true) {
        geneList = geneList.join("+");
    }
    url = this.url + "?cmd=getMutationData&genetic_profile_id=" + geneticProfileId + "&gene_list=" + geneList;
    if (caseSetId !== undefined) {
        url = url + "&case_set_id=" + caseSetId;
    }
    get(url, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getClinicalData = function (caseSetId, callback) {
    if (caseSetId === undefined) {
        throw new Error("Please provide a case_set_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getClinicalData&case_set_id=" + caseSetId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

module.exports = CGDS;
<commit_msg>Add workaround for http-browserify's withCredentials issue.<commit_after>"use strict";

var http, https, url, get, toJSON, CGDS;

http = require("http");
https = require("https");
url = require("url");

get = function (uri, proxy, callback) {
    var options, responseHandler, req;
    if (typeof proxy === "function") {
        callback = proxy;
        proxy = undefined;
    }
    if (proxy !== undefined) {
        options = url.parse(proxy + encodeURIComponent(uri));
    } else {
        options = url.parse(uri);
    }
    responseHandler = function (res) {
        var body;
     // Browserify does not seem to work well with buffers ("no method copy"),
     // therefore fall back to strings.
        body = "";
        res.on("data", function (chunk) {
            body += chunk;
        });
        res.on("end", function () {
            callback(null, body);
        });
    };
    // Don't use http.get until https://github.com/substack/https-browserify/pull/1
    // is fixed.
    options.method = "GET";
    // Setting withCredentials to false is required until
    // https://github.com/substack/http-browserify/pull/47 is fixed.
    options.withCredentials = false;
    if (options.protocol === "https:") {
        options.port = 443;
        req = https.request(options, responseHandler);
    } else {
        options.port = 80;
        req = http.request(options, responseHandler);
    }
    req.end();
};

toJSON = function (data, callback) {
    var lines, errorTerms, errorOccured, columns;
 // Split lines.
    lines = data.split(/\r?\n/);
 // Drop comments and empty lines.
    lines = lines.filter(function (line) {
        if (line.charAt(0) === "#" || line === "") {
            return false;
        } else {
            return true;
        }
    });
 // If the first line starts with "Error: " or in some buggy cases with the whole
 // error string after dropping the comments, then it is likely to be an error.
    errorTerms = ["Error: ", "No genetic profile available for genetic_profile_id: "];
    errorOccured = errorTerms.some(function (errorTerm) {
        if (lines[0].lastIndexOf(errorTerm, 0) === 0) {
            return true;
        } else {
            return false;
        }
    });
    if (errorOccured === true) {
        callback({
            message: lines[0]
        }, null);
    } else {
     // Convert to JSON.
        columns = lines.shift().split(/\t/);
        lines = lines.map(function (line) {
            var obj;
            obj = {};
            line.split(/\t/).forEach(function (column, idx) {
                obj[columns[idx]] = column;
            });
            return obj;
        });
        callback(null, lines);
    }
};

CGDS = function (url) {
    if (typeof url === "string") {
        this.url = url;
    } else if (url !== null && typeof url === "object" && url.hasOwnProperty("url") === true) {
        this.url = url.url;
        if (url.hasOwnProperty("proxy") === true) {
            this.proxy = url.proxy;
        }
    } else {
        throw new Error("Please provide a URL parameter.");
    }
};

CGDS.prototype.getTypesOfCancer = function (callback) {
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getTypesOfCancer", this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getCancerStudies = function (callback) {
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getCancerStudies", this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getGeneticProfiles = function (cancerStudyId, callback) {
    if (cancerStudyId === undefined) {
        throw new Error("Please provide a cancer_study_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getGeneticProfiles&cancer_study_id=" + cancerStudyId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getCaseLists = function (cancerStudyId, callback) {
    if (cancerStudyId === undefined) {
        throw new Error("Please provide a cancer_study_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getCaseLists&cancer_study_id=" + cancerStudyId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getProfileData = function (caseSetId, geneticProfileId, geneList, callback) {
    if (caseSetId === undefined) {
        throw new Error("Please provide a case_set_id parameter.");
    }
    if (geneticProfileId === undefined) {
        throw new Error("Please provide a genetic_profile_id parameter.");
    }
    if (geneList === undefined) {
        throw new Error("Please provide a gene_list parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    if (Array.isArray(geneticProfileId) && Array.isArray(geneList)) {
        throw new Error("You can specify multiple genes or multiple genetic profiles, but not both at once!");
    }
 // Convert geneticProfileId to string.
    if (Array.isArray(geneticProfileId) === true) {
        geneticProfileId = geneticProfileId.join("+");
    }
 // Convert geneList to string.
    if (Array.isArray(geneList) === true) {
        geneList = geneList.join("+");
    }
    get(this.url + "?cmd=getProfileData&case_set_id=" + caseSetId + "&genetic_profile_id=" + geneticProfileId + "&gene_list=" + geneList, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getMutationData = function (geneticProfileId, geneList, caseSetId, callback) {
    var url;
    if (geneticProfileId === undefined) {
        throw new Error("Please provide a genetic_profile_id parameter.");
    }
    if (geneList === undefined) {
        throw new Error("Please provide a gene_list parameter.");
    }
    if (typeof caseSetId === "function") {
        callback = caseSetId;
        caseSetId = undefined;
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
 // Convert geneticProfileId to string.
    if (Array.isArray(geneticProfileId) === true) {
        geneticProfileId = geneticProfileId.join("+");
    }
 // Convert geneList to string.
    if (Array.isArray(geneList) === true) {
        geneList = geneList.join("+");
    }
    url = this.url + "?cmd=getMutationData&genetic_profile_id=" + geneticProfileId + "&gene_list=" + geneList;
    if (caseSetId !== undefined) {
        url = url + "&case_set_id=" + caseSetId;
    }
    get(url, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

CGDS.prototype.getClinicalData = function (caseSetId, callback) {
    if (caseSetId === undefined) {
        throw new Error("Please provide a case_set_id parameter.");
    }
    if (callback === undefined) {
        throw new Error("Please provide a callback parameter.");
    }
    get(this.url + "?cmd=getClinicalData&case_set_id=" + caseSetId, this.proxy, function (err, res) {
        toJSON(res, callback);
    });
};

module.exports = CGDS;
<|endoftext|>


<commit_before>var $ = require('jquery');
var _ = require('underscore');
var cdb = require('cartodb.js');
var UserSettingsView = require('../public_common/user_settings_view');
var FavMapView = require('../public_dashboard/fav_map_view');
var Explore = require('../common/views/explore/view');

/**
 * Entry point for the user feed, bootstraps all dependency models and application.
 */
$(function() {
  cdb.init(function() {

    cdb.templates.namespace = 'cartodb/';
    cdb.config.set('url_prefix', window.base_url);

    var authenticatedUser = new cdb.open.AuthenticatedUser();

    $(document.body).bind('click', function() {
      cdb.god.trigger('closeDialogs');
    });

    authenticatedUser.bind('change', function() {
      if (authenticatedUser.get('username')) {
        var user = new cdb.admin.User(authenticatedUser.attributes);
        var userSettingsView = new UserSettingsView({
          el: $('.js-user-settings'),
          model: user
        });
        userSettingsView.render();

        var userDashboardUrl = user.viewUrl().dashboard();
        $('.js-user-info .UserAvatar-img').wrap($('<a>', {
          href: userDashboardUrl
        }));

        $('.js-login').hide();
        $('.js-learn').show();
      }
    });

    var feed = new Explore({
      el: $('.js-explore'),
      authenticatedUser: authenticatedUser
    });

    feed.render();
    authenticatedUser.fetch();
  });
});
<commit_msg>Adds dropdowns<commit_after>var $ = require('jquery');
var cdb = require('cartodb.js');
var UserSettingsView = require('../public_common/user_settings_view');
var UserTourView = require('../public_common/user_tour_view');
var UserIndustriesView = require('../public_common/user_industries_view');
var UserResourcesView = require('../public_common/user_resources_view');
var FavMapView = require('../public_dashboard/fav_map_view');
var Explore = require('../common/views/explore/view');

var F = Backbone.Collection.extend({
  url: 'http://common-data.cartodb.com/api/v2/sql'
});

/**
 * Entry point for the user feed, bootstraps all dependency models and application.
 */
$(function() {
  cdb.init(function() {

    cdb.templates.namespace = 'cartodb/';
    cdb.config.set('url_prefix', window.base_url);

    var userTourView = new UserTourView({
      el: $('.js-user-tour')
    });

    var userIndustriesView = new UserIndustriesView({
      el: $('.js-user-industries')
    });

    var userResourcesView = new UserResourcesView({
      el: $('.js-user-resources')
    });

    $(document.body).bind('click', function() {
      cdb.god.trigger('closeDialogs');
    });

    this.f = new F();
    this.f.bind('reset', function() {
      var r = this.f.models[0].attributes.rows[0]

      var url = '//' + r.username + '.cartodb.com/api/v2/viz/' + r.id + '/viz.json';
     this.$('.js-mapTitle').text(r.name);
      var favMapView = new FavMapView({
        el: '#fav-map-container',
        createVis: {
          url: url,
          opts: {
            no_cdn: true
          }
        }
      });

      favMapView.render();
     this.$('.js-favMapTitle').removeClass('is-hidden');

    }, this);

    var fields = [
      'visualization_mapviews::numeric/(1.0 + (now()::date - visualization_created_at::date)::numeric)^2 As r',
      'visualization_name AS name',
      'user_username AS username',
      'visualization_id AS id',
      'visualization_likes AS likes',
      'visualization_title AS title'
    ].join(',');

    var q = 'SELECT ' + fields + ' FROM visualizations ORDER BY r DESC LIMIT 1';
    var data = _.extend({ q: q });
    this.f.fetch({
      data: data
    });

    var authenticatedUser = new cdb.open.AuthenticatedUser();

    authenticatedUser.bind('change', function() {
      if (authenticatedUser.get('username')) {
        var user = new cdb.admin.User(authenticatedUser.attributes);
        var userSettingsView = new UserSettingsView({
          el: $('.js-user-settings'),
          model: user
        });
        userSettingsView.render();

        var userDashboardUrl = user.viewUrl().dashboard();
        $('.js-user-info .UserAvatar-img').wrap($('<a>', {
          href: userDashboardUrl
        }));

        $('.js-login').hide();
        $('.js-learn').show();
      }
    });

    var feed = new Explore({
      el: $('.js-explore'),
      authenticatedUser: authenticatedUser
    });

    feed.render();
    authenticatedUser.fetch();
  });
});
<|endoftext|>


<commit_before>(function() {
    'use strict';

    var copymitter  = require('copymitter'),
        mellow      = require('mellow');

    module.exports = function(socket, options) {
        if (!options)
            options = {};

        listen(socket, options);
    };

    function getRoot(root) {
        var value;

        if (typeof root === 'function')
            value = root();
        else
            value = root;

        return value;
    }

    function listen(socket, options) {
        var prefix  = options.prefix || 'spero',
            root    = options.root   || '/';

        socket.of(prefix)
            .on('connection', function(socket) {
                socket.on('copy', function(from, to, files) {
                    var value   = getRoot(root);

                    from        = mellow.pathFromWin(from, value);
                    to          = mellow.pathFromWin(to, value);
                    copy(socket, from, to, files);
                });

                socket.on('error', function(error) {
                    console.error('spero', error);
                });

                socket.on('disconnect', function() {
                    console.log('spero', 'disconnect');
                });
            })
            .on('error', function(error) {
                console.error(error);
            });
    }

    function copy(socket, from, to, files) {
        var cp = copymitter(from, to, files);

        socket.on('pause', cp.pause);

        cp.on('file', function(name) {
            socket.emit('file', name);
        });

        cp.on('progress', function(percent) {
            socket.emit('progress', percent);
        });

        cp.on('error', function(error, name, i, percent) {
            var msg         = error.code + ' :' + error.path,
                rm          = function() {
                    socket.removeListener('continue', onContinue);
                    socket.removeListener('abort', onAbort);
                },

                onAbort     = function() {
                    cp.abort();
                    rm();
                },

                onContinue  = function() {
                    cp.continue();
                    rm();
                };

            console.error(percent, ' -> ', name, ':', error.message);

            socket.emit('err', msg, name);
            socket.on('continue', onContinue);
            socket.on('abort',  onAbort);
        });

        cp.on('end', function() {
            socket.emit('end');
            socket.removeListener('pause', cp.pause);
        });
    }

})();
<commit_msg>fix(copy) pathFromWin -> pathToWin<commit_after>(function() {
    'use strict';

    var copymitter  = require('copymitter'),
        mellow      = require('mellow');

    module.exports = function(socket, options) {
        if (!options)
            options = {};

        listen(socket, options);
    };

    function getRoot(root) {
        var value;

        if (typeof root === 'function')
            value = root();
        else
            value = root;

        return value;
    }

    function listen(socket, options) {
        var prefix  = options.prefix || 'spero',
            root    = options.root   || '/';

        socket.of(prefix)
            .on('connection', function(socket) {
                socket.on('copy', function(from, to, files) {
                    var value   = getRoot(root);

                    from        = mellow.pathToWin(from, value);
                    to          = mellow.pathToWin(to, value);
                    copy(socket, from, to, files);
                });

                socket.on('error', function(error) {
                    console.error('spero', error);
                });

                socket.on('disconnect', function() {
                    console.log('spero', 'disconnect');
                });
            })
            .on('error', function(error) {
                console.error(error);
            });
    }

    function copy(socket, from, to, files) {
        var cp = copymitter(from, to, files);

        socket.on('pause', cp.pause);

        cp.on('file', function(name) {
            socket.emit('file', name);
        });

        cp.on('progress', function(percent) {
            socket.emit('progress', percent);
        });

        cp.on('error', function(error, name, i, percent) {
            var msg         = error.code + ' :' + error.path,
                rm          = function() {
                    socket.removeListener('continue', onContinue);
                    socket.removeListener('abort', onAbort);
                },

                onAbort     = function() {
                    cp.abort();
                    rm();
                },

                onContinue  = function() {
                    cp.continue();
                    rm();
                };

            console.error(percent, ' -> ', name, ':', error.message);

            socket.emit('err', msg, name);
            socket.on('continue', onContinue);
            socket.on('abort',  onAbort);
        });

        cp.on('end', function() {
            socket.emit('end');
            socket.removeListener('pause', cp.pause);
        });
    }

})();
<|endoftext|>


<commit_before>let moment = require("moment");
let sprintf = require("sprintf-js").sprintf;
let chalk = require("chalk");
let emoji = require("node-emoji");
let winston = require("winston");
let util = require("./utility.js");

let getLogger = (path) => {
  let settings = {
    transports: [
      new winston.transports.File({ filename: path, json: true})
    ],
    exceptionHandlers: [
      new winston.transports.File({ filename: path, json: true})
    ]
  };

  return new (winston.Logger)(settings);
};

let core = {};

core.start = (commander) => {
  let logger;

  if (commander.debug) {
    logger = getLogger(commander.debug);
  }

  let token = commander.token;
  let slack = require("@slack/client");
  let RtmClient = slack.RtmClient;

  let RTM_EVENTS = slack.RTM_EVENTS;
  let CLIENT_EVENTS = slack.CLIENT_EVENTS;

  let rtm = new RtmClient(token);

  util.channels = {};
  util.users = {};
  util.bots = {};

  let colors = ["red", "green", "yellow", "blue", "magenta", "cyan", "white"];

  rtm.start();

  rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
    console.log(
      `Logged in as ${chalk.bold(rtmStartData.self.name)} of team ${chalk.green.bold(rtmStartData.team.name)}, but not yet connected to a channel`
    );

    rtmStartData.users.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.users[v.id] = v;
    });
    console.log(`Update ${rtmStartData.users.length} users information...`);

    rtmStartData.channels.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.channels[v.id] = v;
    });
    console.log(`Update ${rtmStartData.channels.length} channels information...`);

    rtmStartData.bots.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.bots[v.id] = v;
    });
    console.log(`Update ${rtmStartData.bots.length} bots information...`);
  });

  rtm.on(RTM_EVENTS.MESSAGE, (message) => {
    let name = (util.users[message.user]) ? chalk[util.users[message.user].color](util.users[message.user].name) : chalk.white("-");
    let channel = (util.channels[message.channel]) ? "#" + chalk[util.channels[message.channel].color](util.channels[message.channel].name) : chalk.white("-");
    let time = moment(message.ts * 1000);
    let text = util.parseText(message);

    if (message.subtype) {
      switch(message.subtype) {
      case "message_deleted":
      case "message_changed":
        return;
      case "file_share":
        break;
      case "message_replied":
        return;
      case "channel_join":
        break;
      case "channel_leave":
        break;
      case "reply_broadcast":
        return;
      case "file_comment":
        break;
      case "bot_message":
        name = (util.bots[message.bot_id]) ? chalk[util.bots[message.bot_id].color](util.bots[message.bot_id].name) : "[BOT]";
        break;
      case "pinned_item":
        break;
      case "slackbot_response":
        break;
      default:
        if (commander.debug) {
          logger.error(message);
        }
        return;
      }
    }

    if (text == "") {
      text = message.attachments[0].text;
    }

    let lines;

    if (typeof(text) == "string") {
      lines = text.split(/\r\n|\r|\n/);
    } else {
      lines = [""];

      if (commander.debug) {
        logger.error(message);
      }
    }

    if (lines.length > 8) {
      lines = lines.slice(0, 5);
      lines.push("--- snip ---");
    }

    lines.forEach((line) => {
      let l;
      l = emoji.emojify(line);
      l = util.replaceSlackId(l);
      l = util.decolateText(l);

      console.log(
        "%s | %s | %s | %s",
        time.format("YYYY-MM-DD HH:mm:ss"),
        sprintf("%30s", channel),
        sprintf("%28s", name),
        l
      );

      name = chalk.white("|>");
    });
  });
};

module.exports = core;
<commit_msg>Add file_mention type.<commit_after>let moment = require("moment");
let sprintf = require("sprintf-js").sprintf;
let chalk = require("chalk");
let emoji = require("node-emoji");
let winston = require("winston");
let util = require("./utility.js");

let getLogger = (path) => {
  let settings = {
    transports: [
      new winston.transports.File({ filename: path, json: true})
    ],
    exceptionHandlers: [
      new winston.transports.File({ filename: path, json: true})
    ]
  };

  return new (winston.Logger)(settings);
};

let core = {};

core.start = (commander) => {
  let logger;

  if (commander.debug) {
    logger = getLogger(commander.debug);
  }

  let token = commander.token;
  let slack = require("@slack/client");
  let RtmClient = slack.RtmClient;

  let RTM_EVENTS = slack.RTM_EVENTS;
  let CLIENT_EVENTS = slack.CLIENT_EVENTS;

  let rtm = new RtmClient(token);

  util.channels = {};
  util.users = {};
  util.bots = {};

  let colors = ["red", "green", "yellow", "blue", "magenta", "cyan", "white"];

  rtm.start();

  rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
    console.log(
      `Logged in as ${chalk.bold(rtmStartData.self.name)} of team ${chalk.green.bold(rtmStartData.team.name)}, but not yet connected to a channel`
    );

    rtmStartData.users.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.users[v.id] = v;
    });
    console.log(`Update ${rtmStartData.users.length} users information...`);

    rtmStartData.channels.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.channels[v.id] = v;
    });
    console.log(`Update ${rtmStartData.channels.length} channels information...`);

    rtmStartData.bots.forEach((v, i) => {
      v.color = colors[i % colors.length];
      util.bots[v.id] = v;
    });
    console.log(`Update ${rtmStartData.bots.length} bots information...`);
  });

  rtm.on(RTM_EVENTS.MESSAGE, (message) => {
    let name = (util.users[message.user]) ? chalk[util.users[message.user].color](util.users[message.user].name) : chalk.white("-");
    let channel = (util.channels[message.channel]) ? "#" + chalk[util.channels[message.channel].color](util.channels[message.channel].name) : chalk.white("-");
    let time = moment(message.ts * 1000);
    let text = util.parseText(message);

    if (message.subtype) {
      switch(message.subtype) {
      case "message_deleted":
      case "message_changed":
        return;
      case "file_share":
        break;
      case "message_replied":
        return;
      case "channel_join":
        break;
      case "channel_leave":
        break;
      case "reply_broadcast":
        return;
      case "file_comment":
        break;
      case "bot_message":
        name = (util.bots[message.bot_id]) ? chalk[util.bots[message.bot_id].color](util.bots[message.bot_id].name) : "[BOT]";
        break;
      case "pinned_item":
        break;
      case "slackbot_response":
        break;
      case "file_mention":
        break;
      default:
        if (commander.debug) {
          logger.error(message);
        }
        return;
      }
    }

    if (text == "") {
      text = message.attachments[0].text;
    }

    let lines;

    if (typeof(text) == "string") {
      lines = text.split(/\r\n|\r|\n/);
    } else {
      lines = [""];

      if (commander.debug) {
        logger.error(message);
      }
    }

    if (lines.length > 8) {
      lines = lines.slice(0, 5);
      lines.push("--- snip ---");
    }

    lines.forEach((line) => {
      let l;
      l = emoji.emojify(line);
      l = util.replaceSlackId(l);
      l = util.decolateText(l);

      console.log(
        "%s | %s | %s | %s",
        time.format("YYYY-MM-DD HH:mm:ss"),
        sprintf("%30s", channel),
        sprintf("%28s", name),
        l
      );

      name = chalk.white("|>");
    });
  });
};

module.exports = core;
<|endoftext|>


<commit_before>/**
 * Global namespace for WeShare.Love (WSL)
 * @namespace WSL
 * @type {Object}
 */

WSL = {};

/**
 * WSL App Version
 * @type {string}
 */
WSL.VERSION = '0.0.1';

/**
 * WSL App Name
 * @type {string}
 */

WSL.appname = 'We share Love';
<commit_msg>WSL.publicRoutes<commit_after>/**
 * Global namespace for WeShare.Love (WSL)
 * @namespace WSL
 * @type {Object}
 */

WSL = {};

/**
 * App Version
 * @type {string}
 */

WSL.VERSION = '0.0.1',

/**
 * App Name
 * @type {string}
 */

WSL.appname = 'We share Love';

/**
 * Public routes
 * @type {array}
 */

WSL.publicRoutes= ['home'];
<|endoftext|>