<commit_before>/*!
 * reviews-to-slack
 * Copyright(c) 2015 Niklas Wahlén
 * MIT Licensed
 */

var request = require('request');
var Watcher = require('rss-watcher');

var WATCHER_EVENTS = {
  "NEW_ARTICLE": "new article",
  "ERROR": "error"
};

(function() {
  exports.start = function start(config) {
    var watcher;
    watcher = new Watcher(config.feed);
    watcher.set({
      feed: config.feed,
		  interval: config.interval != null ? config.interval : 300
    });

    watcher.on(WATCHER_EVENTS.NEW_ARTICLE, function onNewArticle(review) {
      if (isAppInformationEntry(review)) {
		    if (config.debug) console.log("Received app information");
      } else {
		    if (config.debug) console.log("Received new review: " + review);
		    message = slackMessage(review, config);
		    return postToSlack(message, config);
	    }
    });

    watcher.on(WATCHER_EVENTS.ERROR, function onError(error) {
      return console.error("ERROR: for new review: " + error);
    });

    return watcher.run(function run(error, reviews) {
      if (error != null) {
        return console.error("ERROR: Could not parse feed " + config.feed + ", " + error);
      }

      if (reviews == null) {
        return console.log("WARNING: Currently no reviews available for " + config.feed);
      }

      // Parse existing reviews for app information
      for (var i = 0; i < reviews.length; i++) {
        var review = reviews[i];

        // App information is available in an entry with some special fields
        if (isAppInformationEntry(review)) {
          if (config.appName == null && review['im:name'] != null) {
            config.appName = review['im:name']['#'];
            if (config.debug) console.log("Found app name: " + config.appName);
          }

          if (config.appIcon== null && review['im:image'] && review['im:image'].length > 0) {
            config.appIcon = review['im:image'][0]['#'];
            if (config.debug) console.log("Found app icon: " + config.appIcon);
          }

          if (config.appLink == null && review['link']) {
            config.appLink = review['link'];
            if (config.debug) console.log("Found app link: " + config.appLink);
          }
        }
      }

      if (config.debug) {
        console.log("Started watching app: " + config.appName);
        var welcomeMessage = {
          "username": config.botUsername,
          "icon_url": config.botIcon,
          "channel": config.channel,
          "attachments": [
            {
              "mrkdwn_in": ["pretext", "author_name"],
              "fallback": "This channel will now receive App Store reviews for " + config.appName,
              "pretext": "This channel will now receive App Store reviews for ",
              "author_name": config.appName,
              "author_icon": config.appIcon
            }
          ]
        }
        postToSlack(welcomeMessage, config);
      }
    });
  }
}).call(this);

var isAppInformationEntry = function(review) {
    return review != null && review['im:name'] != null;
}

var slackMessage = function(review, config) {
  if (config.debug) console.log("Creating message for review " + review.title);

  var title = review.title;
  var rating = review['im:rating'] != null && !isNaN(review['im:rating']['#']) ? parseInt(review['im:rating']['#']) : -1;
  var date = review.date.toISOString().replace("T", " ").substr(0, 16)

  var stars = "";
  for (var i = 0; i < 5; i++) {
    stars += i < rating ? "★" : "☆";
  }

  var pretext = "New review";
  if (config.appName != null) {
    pretext += " for " + config.appName;
  }
  pretext += "!";

  var color = rating >= 4 ? "good" : (rating >= 2 ? "warning" : "danger");

  var text = "";
  text += review.description + "\n";
  text += "_by " + review.author + ", " + date + "_";

  message = {
    "username": config.botUsername,
    "icon_url": config.botIcon,
    "channel": config.channel,
    "attachments": [
      {
        "mrkdwn_in": ["text", "pretext", "title"],
        "fallback": pretext + ": " + title + "(" + stars + "): " + review.author,

        "pretext": pretext,
        "color": color,

        "author_name": stars,
        "author_icon": config.appIcon,

        "title": title,
        "title_link": config.appLink,

        "text": text
      }
    ]
  }

  return message;
}

var postToSlack = function(message, config) {
  messageJSON = JSON.stringify(message);
  if (config.debug) console.log("Posting new message to Slack: " + messageJSON);
  return result = request.post({
    url: config.slackHook,
    headers: {
      "Content-Type": "application/json"
    },
    body: messageJSON
  });
}<commit_msg>always update local app information when new is received<commit_after>/*!
 * reviews-to-slack
 * Copyright(c) 2015 Niklas Wahlén
 * MIT Licensed
 */

var request = require('request');
var Watcher = require('rss-watcher');

var WATCHER_EVENTS = {
  "NEW_ARTICLE": "new article",
  "ERROR": "error"
};

(function() {
  exports.start = function start(config) {
    var appInformation = {};

    var watcher;
    watcher = new Watcher(config.feed);
    watcher.set({
      feed: config.feed,
		  interval: config.interval != null ? config.interval : 300
    });

    watcher.on(WATCHER_EVENTS.NEW_ARTICLE, function onNewArticle(review) {
      if (isAppInformationEntry(review)) {
        if (config.debug) console.log("INFO: Received new app information");
        updateAppInformation(config, review, appInformation);
      } else {
		    if (config.debug) console.log("INFO: Received new review: " + review);
		    message = slackMessage(review, config, appInformation);
		    return postToSlack(message, config);
	    }
    });

    watcher.on(WATCHER_EVENTS.ERROR, function onError(error) {
      return console.error("ERROR: for new review: " + error);
    });

    return watcher.run(function run(error, entries) {
      if (error != null) return console.error("ERROR: Could not parse feed " + config.feed + ", " + error);

      if (entries == null) return console.log("WARNING: Currently no reviews available for " + config.feed);

      // Parse existing entries for app information
      for (var i = 0; i < entries.length; i++) {
        var entry = entries[i];

        if (isAppInformationEntry(entry)) {
          updateAppInformation(config, entry, appInformation);
        }

        if (i == 1) {
          message = slackMessage(entry, config, appInformation);
          postToSlack(message, config);
        }
      }

      if (config.debug) {
        console.log("INFO: Started watching app: " + (config.appName ? config.appName : appInformation.appName));
        var welcomeMessage = {
          "username": config.botUsername,
          "icon_url": config.botIcon,
          "channel": config.channel,
          "attachments": [
            {
              "mrkdwn_in": ["pretext", "author_name"],
              "fallback": "This channel will now receive App Store reviews for " + (config.appName ? config.appName : appInformation.appName),
              "pretext": "This channel will now receive App Store reviews for ",
              "author_name": config.appName ? config.appName : appInformation.appName,
              "author_icon": config.appIcon ? config.appIcon : appInformation.appIcon
            }
          ]
        }
        postToSlack(welcomeMessage, config);
      }
    });
  }
}).call(this);

var isAppInformationEntry = function(entry) {
  // App information is available in an entry with some special fields
  return entry != null && entry['im:name'] != null;
}

var updateAppInformation = function(config, info, appInformation) {
  if (config.appName == null && info['im:name'] != null) {
    appInformation.appName = info['im:name']['#'];
    if (config.debug) console.log("INFO: Found app name: " + appInformation.appName);
  }

  if (config.appIcon == null && info['im:image'] && info['im:image'].length > 0) {
    appInformation.appIcon = info['im:image'][0]['#'];
    if (config.debug) console.log("INFO: Found app icon: " + appInformation.appIcon);
  }

  if (config.appLink == null && info['link']) {
    appInformation.appLink = info['link'];
    if (config.debug) console.log("INFO: Found app link: " + appInformation.appLink);
  }
}

var slackMessage = function(review, config, appInformation) {
  if (config.debug) console.log("INFO: Creating message for review " + review.title);

  var title = review.title;
  var rating = review['im:rating'] != null && !isNaN(review['im:rating']['#']) ? parseInt(review['im:rating']['#']) : -1;
  var date = review.date.toISOString().replace("T", " ").substr(0, 16)

  var stars = "";
  for (var i = 0; i < 5; i++) {
    stars += i < rating ? "★" : "☆";
  }

  var pretext = "New review";
  if (config.appName != null || appInformation.appName != null) {
    pretext += " for " + (config.appName ? config.appName : appInformation.appName);
  }
  pretext += "!";

  var color = rating >= 4 ? "good" : (rating >= 2 ? "warning" : "danger");

  var text = "";
  text += review.description + "\n";
  text += "_by " + review.author + ", " + date + "_";

  message = {
    "username": config.botUsername,
    "icon_url": config.botIcon,
    "channel": config.channel,
    "attachments": [
      {
        "mrkdwn_in": ["text", "pretext", "title"],
        "fallback": pretext + ": " + title + "(" + stars + "): " + review.author,

        "pretext": pretext,
        "color": color,

        "author_name": stars,
        "author_icon": config.appIcon ? config.appIcon : appInformation.appIcon,

        "title": title,
        "title_link": config.appLink ? config.appLink : appInformation.appLink,

        "text": text
      }
    ]
  }

  return message;
}

var postToSlack = function(message, config) {
  messageJSON = JSON.stringify(message);
  if (config.debug) console.log("INFO: Posting new message to Slack: " + messageJSON);
  return result = request.post({
    url: config.slackHook,
    headers: {
      "Content-Type": "application/json"
    },
    body: messageJSON
  });
}<|endoftext|>


<commit_before>'use strict';

var browserify = require('browserify')
  , boxview = require('box-view')
  , request = require('request')
  , envify = require('envify/custom')
  , send = require('send')
  , http = require('http')
  , path = require('path')
  , url = require('url')
  , fs = require('fs')

var BUNDLE_NAME = 'box-view-browser-bundle.js'

var uploadsURL = process.env.BOX_VIEW_DOCUMENTS_UPLOAD_URL || boxview.DOCUMENTS_UPLOAD_URL
  , documentsURL = process.env.BOX_VIEW_DOCUMENTS_URL || boxview.DOCUMENTS_URL
  , sessionsURL = process.env.BOX_VIEW_SESSIONS_URL || boxview.SESSIONS_URL

module.exports = function (opt, callback) {
  opt = opt || {}
  opt.cwd = path.resolve(opt.cwd || process.cwd())
  opt.serveStatic = ('serveStatic' in opt) ? opt.serveStatic : true
  if (!opt.port) {
    require('portfinder').getPort(function (err, port) {
      if (err) {
        throw err
      }
      opt.port = port
      init(opt, callback)
    })
  } else {
    init(opt, callback)
  }
}

function init(opt, callback) {
  var b = browserify()
    , output = fs.createWriteStream(path.resolve(opt.cwd, BUNDLE_NAME))
    , baseURL = 'http://localhost:' + opt.port
    , env = {
        UPLOAD_URL: baseURL + '/upload'
      , DOCUMENTS_URL: baseURL + '/documents'
      , SESSIONS_URL: baseURL + '/sessions'
    }

  b.transform(envify(env))
  b.require(require.resolve('browser-request'), { expose: 'request' })
  b.require(require.resolve('box-view'), { expose: 'node-box-view' })
  b.require(require.resolve('./browser-box-view'), { expose: 'box-view' })
  b.bundle().pipe(output)

  output.on('finish', createServer)

  function handle(req, res) {
    var path = url.parse(req.url).path

    if (req.method === 'OPTIONS') {
      return proxy(null, req, res)
    }

    if (opt.token) {
      req.headers.Authorization = 'Token ' + opt.token
    }

    if (path.indexOf('/upload') === 0) {
      proxy(uploadsURL + path.replace('/upload', ''), req, res)
    } else if (path.indexOf('/documents') === 0) {
      proxy(documentsURL + path.replace('/documents', ''), req, res)
    } else if (path.indexOf('/sessions') === 0) {
      proxy(sessionsURL + path.replace('/sessions', ''), req, res)
    } else {
      // serve up static file
      if (opt.serveStatic) {
        send(req, req.url, { root: opt.cwd }).pipe(res)
      } else {
        res.writeHead(404, { 'content-type': 'text/plain' })
        res.write('not found :(\n')
        res.end()
      }
    }
  }

  function createServer() {
    var server = http.createServer(handle).listen(opt.port, function () {
      if (typeof callback === 'function') {
        callback(opt.port, server)
      }
    })
  }
}

function proxy(uri, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Headers', 'origin,authorization,accept,content-type')
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
  if (!uri) {
    return res.end()
  }
  var r = request(uri, {
      method: req.method
    , headers: req.headers
  })
  req.pipe(r).pipe(res)
  r.on('error', function (err) {
    console.error(err)
  })
}

<commit_msg>Fix issue with non-matching host header against production env<commit_after>'use strict';

var browserify = require('browserify')
  , boxview = require('box-view')
  , request = require('request')
  , envify = require('envify/custom')
  , send = require('send')
  , http = require('http')
  , path = require('path')
  , url = require('url')
  , fs = require('fs')

var BUNDLE_NAME = 'box-view-browser-bundle.js'

var uploadsURL = process.env.BOX_VIEW_DOCUMENTS_UPLOAD_URL || boxview.DOCUMENTS_UPLOAD_URL
  , documentsURL = process.env.BOX_VIEW_DOCUMENTS_URL || boxview.DOCUMENTS_URL
  , sessionsURL = process.env.BOX_VIEW_SESSIONS_URL || boxview.SESSIONS_URL

module.exports = function (opt, callback) {
  opt = opt || {}
  opt.cwd = path.resolve(opt.cwd || process.cwd())
  opt.serveStatic = ('serveStatic' in opt) ? opt.serveStatic : true
  if (!opt.port) {
    require('portfinder').getPort(function (err, port) {
      if (err) {
        throw err
      }
      opt.port = port
      init(opt, callback)
    })
  } else {
    init(opt, callback)
  }
}

function init(opt, callback) {
  var b = browserify()
    , output = fs.createWriteStream(path.resolve(opt.cwd, BUNDLE_NAME))
    , baseURL = 'http://localhost:' + opt.port
    , env = {
        UPLOAD_URL: baseURL + '/upload'
      , DOCUMENTS_URL: baseURL + '/documents'
      , SESSIONS_URL: baseURL + '/sessions'
    }

  b.transform(envify(env))
  b.require(require.resolve('browser-request'), { expose: 'request' })
  b.require(require.resolve('box-view'), { expose: 'node-box-view' })
  b.require(require.resolve('./browser-box-view'), { expose: 'box-view' })
  b.bundle().pipe(output)

  output.on('finish', createServer)

  function handle(req, res) {
    var path = url.parse(req.url).path

    if (req.method === 'OPTIONS') {
      return proxy(null, req, res)
    }

    if (opt.token) {
      req.headers.Authorization = 'Token ' + opt.token
    }

    delete req.headers.host
    delete req.headers.origin
    delete req.headers.referer
    delete req.headers['user-agent']

    if (path.indexOf('/upload') === 0) {
      proxy(uploadsURL + path.replace('/upload', ''), req, res)
    } else if (path.indexOf('/documents') === 0) {
      proxy(documentsURL + path.replace('/documents', ''), req, res)
    } else if (path.indexOf('/sessions') === 0) {
      proxy(sessionsURL + path.replace('/sessions', ''), req, res)
    } else {
      // serve up static file
      if (opt.serveStatic) {
        send(req, req.url, { root: opt.cwd }).pipe(res)
      } else {
        res.writeHead(404, { 'content-type': 'text/plain' })
        res.write('not found :(\n')
        res.end()
      }
    }
  }

  function createServer() {
    var server = http.createServer(handle).listen(opt.port, function () {
      if (typeof callback === 'function') {
        callback(opt.port, server)
      }
    })
  }
}

function proxy(uri, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Headers', 'origin,authorization,accept,content-type')
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
  if (!uri) {
    return res.end()
  }
  var r = request(uri, {
      method: req.method
    , headers: req.headers
  })
  req.pipe(r).pipe(res)
  r.on('error', function (err) {
    console.error(err)
  })
}

<|endoftext|>


<commit_before>var fs = require('fs');

module.exports = function requireAll(options) {
  var files = fs.readdirSync(options.dirname);
  var modules = {};

  function excludeDirectory(dirname) {
    return options.excludeDirs && dirname.match(options.excludeDirs);
  }

  files.forEach(function (file) {
    var filepath = options.dirname + '/' + file;
    if (fs.statSync(filepath).isDirectory()) {

      if (excludeDirectory(file)) return;

      modules[file] = requireAll({
        dirname: filepath,
        filter: options.filter,
        excludeDirs: options.excludeDirs
      });

    } else {
      var match = file.match(options.filter);
      if (!match) return;

      modules[match[1]] = require(filepath);
    }
  });

  return modules;
};
<commit_msg>Adds defaults to index.js<commit_after>var fs = require('fs');

module.exports = function requireAll(options) {
  if (typeof options === 'string') {
    options = {
      dirname: options,
      filter: /(.+)\.js(on)?$/,
      excludeDirs: /^\.(git|svn)$/
    };
  }

  var files = fs.readdirSync(options.dirname);
  var modules = {};

  function excludeDirectory(dirname) {
    return options.excludeDirs && dirname.match(options.excludeDirs);
  }

  files.forEach(function (file) {
    var filepath = options.dirname + '/' + file;
    if (fs.statSync(filepath).isDirectory()) {

      if (excludeDirectory(file)) return;

      modules[file] = requireAll({
        dirname: filepath,
        filter: options.filter,
        excludeDirs: options.excludeDirs
      });

    } else {
      var match = file.match(options.filter);
      if (!match) return;

      modules[match[1]] = require(filepath);
    }
  });

  return modules;
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict"
const {existsSync} = require('fs')
const execSync = require('child_process').execSync
const {compose, converge, contains} = require('ramda')
const {red} = require('chalk')
const keysEqual = require('./lib/keysEqual')
const exec = require('./lib/getOutput')(execSync)
const {listChangedFiles, getFileAtSource} = require('./lib/gitUtil')(exec)
const LOCKFILE = 'yarn.lock'
const PACKAGE_JSON = 'package.json'
const deps = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']

const getStagedJSON = compose(JSON.parse, getFileAtSource(''))
const getJsonAtHEAD = compose(JSON.parse, getFileAtSource('HEAD'))
const depsUnchanged = converge(keysEqual(deps), [getStagedJSON, getJsonAtHEAD])

const files = listChangedFiles()
if (contains(PACKAGE_JSON, files) &&
  !contains(LOCKFILE, files) &&
  existsSync(LOCKFILE) &&
  !depsUnchanged(PACKAGE_JSON)) {
  console.error(`${red('Error!')}   Do not commit package.json changed without yarn.lock changes`)
  process.exitCode = 1
}<commit_msg>fix typo in error message<commit_after>#!/usr/bin/env node
"use strict"
const {existsSync} = require('fs')
const execSync = require('child_process').execSync
const {compose, converge, contains} = require('ramda')
const {red} = require('chalk')
const keysEqual = require('./lib/keysEqual')
const exec = require('./lib/getOutput')(execSync)
const {listChangedFiles, getFileAtSource} = require('./lib/gitUtil')(exec)
const LOCKFILE = 'yarn.lock'
const PACKAGE_JSON = 'package.json'
const deps = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']

const getStagedJSON = compose(JSON.parse, getFileAtSource(''))
const getJsonAtHEAD = compose(JSON.parse, getFileAtSource('HEAD'))
const depsUnchanged = converge(keysEqual(deps), [getStagedJSON, getJsonAtHEAD])

const files = listChangedFiles()
if (contains(PACKAGE_JSON, files) &&
  !contains(LOCKFILE, files) &&
  existsSync(LOCKFILE) &&
  !depsUnchanged(PACKAGE_JSON)) {
  console.error(`${red('Error!')}   Do not commit package.json changes without yarn.lock changes`)
  process.exitCode = 1
}<|endoftext|>


<commit_before>'use strict';

var debug = require('diagnostics')('fittings')
  , destroy = require('demolish')
  , Ultron = require('ultron')
  , path = require('path');

/**
 * Small helper function to generate warnings on all the things.
 *
 * @param {String} reason
 * @returns {Function} Configured warning function
 * @api private
 */
function warn(reason) {
  return function warning() {
    debug(reason);
    return '';
  };
}

/**
 * Fittings is the default framework provider for BigPipe.
 *
 * @constructor
 * @param {BigPipe} bigpipe
 * @api public
 */
function Fittings(bigpipe) {
  this.ultron = new Ultron(bigpipe);
  this.bigpipe = bigpipe;

  this.setup();
}

/**
 * The directory in which our properties or assets live.
 *
 * @type {String}
 * @private
 */
Fittings.prototype.directory = '';

/**
 * Assign all our custom hooks in to the BigPipe framework.
 *
 * @api private
 */
Fittings.prototype.setup = function setup() {
  var middleware = this.get('middleware')
    , plugins = this.get('use')
    , events = this.get('on');

  //
  // Introduce the middleware layers that we've added.
  //
  Object.keys(middleware).forEach(function each(name) {
    this.middleware.use(name, middleware[name]);
  }, this.bigpipe);

  //
  // Adding all the plugins.
  //
  Object.keys(plugins).forEach(function each(name) {
    this.use(name, plugins[name]);
  }, this.bigpipe);

  //
  // And listen to all the events.
  //
  Object.keys(events).forEach(function each(name) {
    this.on(name, events[event]);
  }, this.ulron);
};

/**
 * Get one of the properties.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @param {Object} data Data that can be introduced.
 * @return {String}
 * @api public
 */
Fittings.prototype.get = function get(what, data) {
  if (what === 'library') return this.resolve(what);
  return this.evaluate(what, data);
};

/**
 * Attempt to locate the location of a library.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @returns {Array}
 * @api private
 */
Fittings.prototype.resolve = function resolve(what) {
  what = this[what];

  /**
   * As the libraries as run through browserify it makes sense to give them
   * a custom export name. When it's an object we assume that they already
   * follow our required structure. If this is not the case we use the filename
   * as the name it should be exposed under.
   *
   * @param {String|Object} where Either the location of a file or object.
   * @returns {Object}
   * @api private
   */
  function makeitso(where) {
    if ('string' === typeof where) {
      where = {
        expose: path.basename(where).replace(new RegExp(path.extname(where).replace('.', '\\.') +'$'), ''),
        path: where
      };
    }

    return where;
  }

  var type = typeof what;

  if (Array.isArray(what)) return what.map(makeitso);
  if ('function' === type) return what.call(this).map(makeitso);
  if ('string' === type && what.charAt(0) === path.sep) return [what].map(makeitso);
  if ('object'=== type) return [what].map(makeitso);

  return [require.resolve(what)].map(makeitso);
};

/**
 * Either evaluate a function or template a string.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @param {Object} data Data that can be introduced.
 * @return {String|Object}
 * @api private
 */
Fittings.prototype.evaluate = function evaluate(what, data) {
  var type = typeof this[what];
  data = data || {};

  if ('function' === type) return this[what].call(this, data);
  if ('object' === type) return this[what];

  what = this[what].replace(/\$/, '\$');

  Object.keys(data).forEach(function each(key) {
    what = what.replace('{fittings:'+ key +'}', function hack() {
      return data[key];
    });
  });

  return what;
};

/**
 * Generate the wrapper around the template.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.template = warn('Missing override for the `.template` property, build is ignoring them.');

/**
 * Generate the wrapper around the plugins.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.plugin = warn('Missing override for the `.plugin` property, build is ignoring them.');

/**
 * The bootstrapper.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.bootstrap = warn('Missing override for the `.bootstrap` property, no startup code included.');

/**
 * The actual chunk of the response that is written for each Pagelet. The
 * current template is compatible with our `bigpipe.js` client code but if you
 * want to use the pagelets as a stand alone template/view you might want to
 * change this to a simple string.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.fragment = warn('Missing override for the `.fragment` property, html can\'t be rendered.');

/**
 * The location of the client side libraries that should be included. Can either
 * be a string, array or a function which returns an array or string.
 *
 * @type {String|Array}
 * @public
 */
Fittings.prototype.library = [];

/**
 * The various of middleware layers that need to be loaded in to the server.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.middleware = {};

/**
 * The plugins that need to be executed on the server/client.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.use = {};

/**
 * EventEmitters.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.on = {};

/**
 * Completely destroy the fittings instance and remove all of it's added
 * resources from the server (where possible).
 *
 * @api public
 */
Fittings.prototype.destroy = destroy('ultron', {
  before: function before() {
    var middleware = this.get('middleware');

    //
    // Manually remove the middleware, we cannot remove plugins as there is no
    // API for it and no way to "un-evaluate" the server side executed parts of
    // it.
    //
    Object.keys(middleware).forEach(function (name) {
      this.middleware.remove(name);
    }, this.bigpipe);

    //
    // Also manually nuke the `bigpipe` property or `demolish` with call the
    // destroy method on `bigpipe` causing you to also completely destroy the
    // server when you switch frameworks.
    //
    this.bigpipe = null;
  }
});

/**
 * Extend the library, if needed.
 *
 * @type {Function}
 * @api public
 */
Fittings.extend = require('extendible');

/**
 * Expose the Fittings on the exports and parse our the directory. This ensures
 * that we can properly resolve all relative properties:
 *
 * ```js
 * Fittings.extend({
 *   ..
 * }).on(module);
 * ```
 *
 * The use of this function is for convenience and optional. Developers can
 * choose to provide absolute paths to files.
 *
 * @param {Module} module The reference to the module object.
 * @returns {Pagelet}
 * @api public
 */
Fittings.on = function on(module) {
  this.prototype.directory = path.dirname(module.filename);
  return module.exports = this;
};

//
// Expose our default fittings.
//
module.exports = Fittings;
<commit_msg>[doc] Document the hack.<commit_after>'use strict';

var debug = require('diagnostics')('fittings')
  , destroy = require('demolish')
  , Ultron = require('ultron')
  , path = require('path');

/**
 * Small helper function to generate warnings on all the things.
 *
 * @param {String} reason
 * @returns {Function} Configured warning function
 * @api private
 */
function warn(reason) {
  return function warning() {
    debug(reason);
    return '';
  };
}

/**
 * Fittings is the default framework provider for BigPipe.
 *
 * @constructor
 * @param {BigPipe} bigpipe
 * @api public
 */
function Fittings(bigpipe) {
  this.ultron = new Ultron(bigpipe);
  this.bigpipe = bigpipe;

  this.setup();
}

/**
 * The directory in which our properties or assets live.
 *
 * @type {String}
 * @private
 */
Fittings.prototype.directory = '';

/**
 * Assign all our custom hooks in to the BigPipe framework.
 *
 * @api private
 */
Fittings.prototype.setup = function setup() {
  var middleware = this.get('middleware')
    , plugins = this.get('use')
    , events = this.get('on');

  //
  // Introduce the middleware layers that we've added.
  //
  Object.keys(middleware).forEach(function each(name) {
    this.middleware.use(name, middleware[name]);
  }, this.bigpipe);

  //
  // Adding all the plugins.
  //
  Object.keys(plugins).forEach(function each(name) {
    this.use(name, plugins[name]);
  }, this.bigpipe);

  //
  // And listen to all the events.
  //
  Object.keys(events).forEach(function each(name) {
    this.on(name, events[event]);
  }, this.ulron);
};

/**
 * Get one of the properties.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @param {Object} data Data that can be introduced.
 * @return {String}
 * @api public
 */
Fittings.prototype.get = function get(what, data) {
  if (what === 'library') return this.resolve(what);
  return this.evaluate(what, data);
};

/**
 * Attempt to locate the location of a library.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @returns {Array}
 * @api private
 */
Fittings.prototype.resolve = function resolve(what) {
  what = this[what];

  /**
   * As the libraries as run through browserify it makes sense to give them
   * a custom export name. When it's an object we assume that they already
   * follow our required structure. If this is not the case we use the filename
   * as the name it should be exposed under.
   *
   * @param {String|Object} where Either the location of a file or object.
   * @returns {Object}
   * @api private
   */
  function makeitso(where) {
    if ('string' === typeof where) {
      where = {
        expose: path.basename(where).replace(new RegExp(path.extname(where).replace('.', '\\.') +'$'), ''),
        path: where
      };
    }

    return where;
  }

  var type = typeof what;

  if (Array.isArray(what)) return what.map(makeitso);
  if ('function' === type) return what.call(this).map(makeitso);
  if ('string' === type && what.charAt(0) === path.sep) return [what].map(makeitso);
  if ('object'=== type) return [what].map(makeitso);

  return [require.resolve(what)].map(makeitso);
};

/**
 * Either evaluate a function or template a string.
 *
 * @param {String} what Property name that should either be a fn or string.
 * @param {Object} data Data that can be introduced.
 * @return {String|Object}
 * @api private
 */
Fittings.prototype.evaluate = function evaluate(what, data) {
  var type = typeof this[what];
  data = data || {};

  if ('function' === type) return this[what].call(this, data);
  if ('object' === type) return this[what];

  what = this[what].replace(/\$/, '\$');

  Object.keys(data).forEach(function each(key) {
    //
    // The reason that we're doing a function based replace is that to replacing
    // value can contain $' which is actually telling the regular expression
    // engine to copy and paste all the things to the back of string instead of
    // replacing it. All it needs a simple `if ('$' in global)` to completely
    // mess up the replacement.
    //
    what = what.replace('{fittings:'+ key +'}', function hack() {
      return data[key];
    });
  });

  return what;
};

/**
 * Generate the wrapper around the template.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.template = warn('Missing override for the `.template` property, build is ignoring them.');

/**
 * Generate the wrapper around the plugins.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.plugin = warn('Missing override for the `.plugin` property, build is ignoring them.');

/**
 * The bootstrapper.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.bootstrap = warn('Missing override for the `.bootstrap` property, no startup code included.');

/**
 * The actual chunk of the response that is written for each Pagelet. The
 * current template is compatible with our `bigpipe.js` client code but if you
 * want to use the pagelets as a stand alone template/view you might want to
 * change this to a simple string.
 *
 * @type {String|Function}
 * @public
 */
Fittings.prototype.fragment = warn('Missing override for the `.fragment` property, html can\'t be rendered.');

/**
 * The location of the client side libraries that should be included. Can either
 * be a string, array or a function which returns an array or string.
 *
 * @type {String|Array}
 * @public
 */
Fittings.prototype.library = [];

/**
 * The various of middleware layers that need to be loaded in to the server.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.middleware = {};

/**
 * The plugins that need to be executed on the server/client.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.use = {};

/**
 * EventEmitters.
 *
 * @type {Object}
 * @public
 */
Fittings.prototype.on = {};

/**
 * Completely destroy the fittings instance and remove all of it's added
 * resources from the server (where possible).
 *
 * @api public
 */
Fittings.prototype.destroy = destroy('ultron', {
  before: function before() {
    var middleware = this.get('middleware');

    //
    // Manually remove the middleware, we cannot remove plugins as there is no
    // API for it and no way to "un-evaluate" the server side executed parts of
    // it.
    //
    Object.keys(middleware).forEach(function (name) {
      this.middleware.remove(name);
    }, this.bigpipe);

    //
    // Also manually nuke the `bigpipe` property or `demolish` with call the
    // destroy method on `bigpipe` causing you to also completely destroy the
    // server when you switch frameworks.
    //
    this.bigpipe = null;
  }
});

/**
 * Extend the library, if needed.
 *
 * @type {Function}
 * @api public
 */
Fittings.extend = require('extendible');

/**
 * Expose the Fittings on the exports and parse our the directory. This ensures
 * that we can properly resolve all relative properties:
 *
 * ```js
 * Fittings.extend({
 *   ..
 * }).on(module);
 * ```
 *
 * The use of this function is for convenience and optional. Developers can
 * choose to provide absolute paths to files.
 *
 * @param {Module} module The reference to the module object.
 * @returns {Pagelet}
 * @api public
 */
Fittings.on = function on(module) {
  this.prototype.directory = path.dirname(module.filename);
  return module.exports = this;
};

//
// Expose our default fittings.
//
module.exports = Fittings;
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var fs = require('fs');
var path = require('path');

module.exports = {
  name: 'ember-get-config',

  included(app) {
    this._super.included.apply(this, arguments);

    var appConfig = app.project.config(process.env.EMBER_ENV) || {};

    fs.writeFileSync(
      path.join(__dirname, 'addon', 'index.js'),
      `export default ${JSON.stringify(appConfig, null, 2)};`,
      'utf-8'
    );
  }
};
<commit_msg>further es6 removal<commit_after>/* jshint node: true */
'use strict';

var fs = require('fs');
var path = require('path');

module.exports = {
  name: 'ember-get-config',

  included: function(app) {
    this._super.included.apply(this, arguments);

    var appConfig = app.project.config(process.env.EMBER_ENV) || {};

    fs.writeFileSync(
      path.join(__dirname, 'addon', 'index.js'),
      'export default ' + JSON.stringify(appConfig, null, 2) + ';',
      'utf-8'
    );
  }
};
<|endoftext|>


<commit_before>var mongo = require('mongodb').MongoClient;
var reg = new RegExp(/[Mm]ongo[Dd][Bb]/);

module.exports = function indexes(sails) {
  return {
    defaults: {
      indexes: {
        host: 'localhost',
        port: 27017,
        database: 'test'
      }
    },
    configure: function () {
      var name = this.configKey;
      if(sails.config['connections']){
        var keys = Object.keys(sails.config['connections']);
        keys.forEach(function(item) {
          if(reg.test(item)){
            sails.config[name] = sails.config['connections'].item;
          }
        }, this);
      }
    },
    initialize: function (cb) {
      if(sails.models){
        cb();
      }else cb();
    }
    //routes: {}
  }
}<commit_msg>no se si deba quedarse asi  o instalarlo<commit_after>var mongo = require('mongodb').MongoClient;
var reg = new RegExp(/[Mm]ongo[Dd][Bb]/);

module.exports = function indexes(sails) {
  return {
    defaults: {
      indexes: {
        host: 'localhost',
        port: 27017,
        database: 'test'
      }
    },
    configure: function () {
      var name = this.configKey;
      sails.config.globals.async = true;
      if(sails.config['connections']){
        var keys = Object.keys(sails.config['connections']);
        keys.forEach(function(item) {
          if(reg.test(item)){
            sails.config[name] = sails.config['connections'].item;
          }
        }, this);
      }
    },
    initialize: function (cb) {
      if(sails.models){
        cb();
      }else cb();
    }
    //routes: {}
  }
}<|endoftext|>


<commit_before>/*!
 * diff-buf - index.js
 * Copyright(c) 2014 dead_horse <dead_horse@qq.com>
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 */

var color = require('colors');
var jsdiff = require('diff');

var defaultOptions = {
  length: 1000,
  base: 16,
  string: true
};

function merge(dis, src) {
  for (var key in src) {
    if (dis[key] === undefined) {
      dis[key] = src[key];
    }
  }
}

function parseDiff(diffs, base) {
  var result = [];
  diffs.forEach(function (diff) {
    var added = diff.added;
    var removed =diff.removed;
    var values = diff.value.split(' ').filter(function (v) {
      return v !== '';
    }).map(function (v) {
      return {
        value: parseInt(v, 10),
        added: added,
        removed: removed
      };
    });
    result = result.concat(values);
  });

  return result;
}

function padding(s, base) {
  if (base === 16 && s.length === 1) {
    return '0' + s;
  }
  if (base === 10 && s.length === 1) {
    return '00' + s;
  }
  if (base === 10 && s.length === 2) {
    return '0' + s;
  }
  return s;
}

function inspect(diffs, base) {
  var strs = diffs.map(function (diff) {
    var s = diff.value.toString(base);
    s = padding(s, base);
    if (diff.added) {
      s = s.green;
    } else if (diff.removed) {
      s = s.red;
    }
    return s;
  });

  return '<Buffer ' + strs.join(' ') + '>';
}

module.exports = function (src, cmp, options) {
  options = options || {};
  merge(options, defaultOptions);
  var base = options.base === 10 ? 10 : 16; // only support 10 or 16
  var length = Math.max(src.length, cmp.length, options.length);

  src.slice(0, length);
  cmp.slice(0, length);

  // change on 0.11+ @see http://nodejs.org/docs/v0.11.12/api/buffer.html#buffer_buf_tojson
  var srcJSON = src.toJSON();
  var cmpJSON = cmp.toJSON();

  var srcStr = (srcJSON.data || srcJSON).join(' ');
  var cmpStr = (cmpJSON.data || cmpJSON).join(' ');

  var diffs = jsdiff.diffWords(srcStr, cmpStr);
  diffs = parseDiff(diffs);
  if (!options.string) {
    return diffs;
  }
  return inspect(diffs, base);
};
<commit_msg>fix length slice bug<commit_after>/*!
 * diff-buf - index.js
 * Copyright(c) 2014 dead_horse <dead_horse@qq.com>
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 */

var color = require('colors');
var jsdiff = require('diff');

var defaultOptions = {
  length: 1000,
  base: 16,
  string: true
};

function merge(dis, src) {
  for (var key in src) {
    if (dis[key] === undefined) {
      dis[key] = src[key];
    }
  }
}

function parseDiff(diffs, base) {
  var result = [];
  diffs.forEach(function (diff) {
    var added = diff.added;
    var removed =diff.removed;
    var values = diff.value.split(' ').filter(function (v) {
      return v !== '';
    }).map(function (v) {
      return {
        value: parseInt(v, 10),
        added: added,
        removed: removed
      };
    });
    result = result.concat(values);
  });

  return result;
}

function padding(s, base) {
  if (base === 16 && s.length === 1) {
    return '0' + s;
  }
  if (base === 10 && s.length === 1) {
    return '00' + s;
  }
  if (base === 10 && s.length === 2) {
    return '0' + s;
  }
  return s;
}

function inspect(diffs, base) {
  var strs = diffs.map(function (diff) {
    var s = diff.value.toString(base);
    s = padding(s, base);
    if (diff.added) {
      s = s.green;
    } else if (diff.removed) {
      s = s.red;
    }
    return s;
  });

  return '<Buffer ' + strs.join(' ') + '>';
}

module.exports = function (src, cmp, options) {
  options = options || {};
  merge(options, defaultOptions);
  var base = options.base === 10 ? 10 : 16; // only support 10 or 16

  src = src.slice(0, options.length);
  cmp = cmp.slice(0, options.length);

  // change on 0.11+ @see http://nodejs.org/docs/v0.11.12/api/buffer.html#buffer_buf_tojson
  var srcJSON = src.toJSON();
  var cmpJSON = cmp.toJSON();

  var srcStr = (srcJSON.data || srcJSON).join(' ');
  var cmpStr = (cmpJSON.data || cmpJSON).join(' ');

  var diffs = jsdiff.diffWords(srcStr, cmpStr);
  diffs = parseDiff(diffs);
  if (!options.string) {
    return diffs;
  }
  return inspect(diffs, base);
};
<|endoftext|>


<commit_before>/**
 * @fileOverview Implementation of a graph data structure
 * @author Jason S. Jones
 * @version 0.1.3
 * @license MIT
 */
(function() {
    'use strict';

    // pull in a few other data structurs to help build the graph
    // and to implement the two search algorithms: BFS and DFS.
    var Dictionary = require('simple-data-cache');
    var Queue = require('queue-fifo');
    var Stack = require('stack-lifo');

    /**
     * Creates a new Graph instance using the first parameter to provide the
     * labels for the intitial vertices of the graph.  If no parameter is
     * provided to this function, an empty graph will be instantiated and all
     * vertices will need to be added by using a call the 'addVertex' method.
     *
     * @constructor
     * @param {array} theVerts an array of labels to initialize as the vertices
     *                of the graph
     *
     */
    function Graph(theVerts) {
        this.adjacentList = new Dictionary();

        if (theVerts && theVerts.constructor === Array) {
            this.vertices = theVerts;

            for (var i = 0; i < this.vertices.length; i++) {
                this.adjacentList.set(this.vertices[i], []);
            }

        } else {
            this.vertices = [];
        }

    }

    /**
     *
     */
    Graph.prototype.addVertex = function (label) {
        this.vertices.push(label);
        this.adjacentList.set(label, []);
    };

    /**
     *
     */
    Graph.prototype.addEdge = function (v1, v2, w) {
        if (this.adjacentList.has(v1) && this.adjacentList.has(v2)) {
            var edgeWeight = w || 1;
            this.adjacentList.get(v1).push({label: v2, weight: edgeWeight});
            this.adjacentList.get(v2).push({label: v1, weight: edgeWeight});
        } else {
            throw new Error('Vertex does not exist: Cannot add edge.');
        }
    };

    /**
     * Breadth first search
     *
     */
    Graph.prototype.BFS = function(vertex) {
        var q = new Queue();
        var result = [];
        var visited = [];

        // mark the starting vertex as visited and add it the queue
        visited.push(vertex);
        q.enqueue(vertex);

        while (!q.isEmpty()) {

            // dequeue the front vertex from the queue
            var focusVertex = q.dequeue();

            // add it to the results list
            result.push(focusVertex);

            //get all of its connected vertices
            var neighbors = this.adjacentList.get(focusVertex);

            for (var i = 0; i < neighbors.length; i++) {

                // if neighbor[i] has not been visited, mark it as visited
                // and add it to the queue
                if (visited.indexOf(neighbors[i].label) === -1) {
                    visited.push(neighbors[i].label);
                    q.enqueue(neighbors[i].label);
                }
            }
        }

        return result;
    };

    /**
     * Depth first search
     *
     */
    Graph.prototype.DFS = function(vertex) {
        var stack = new Stack();
        var result = [];
        var visited = [];

        // mark the starting vertex as visited and push it on the stack
        visited.push(vertex);
        stack.push(vertex);

        while (!stack.isEmpty()) {

            // pop a vertex from the top of the stack
            var focusVertex = stack.pop();

            // add it to the results list
            result.push(focusVertex);

            //get all of its connected vertices
            var neighbors = this.adjacentList.get(focusVertex);

            for (var i = 0; i < neighbors.length; i++) {

                // if neighbor[i] has not been visited, mark it as visited
                // and push it on the stack
                if (visited.indexOf(neighbors[i].label) === -1) {
                    visited.push(neighbors[i].label);
                    stack.push(neighbors[i].label);
                }
            }
        }

        return result;
    };

    /**
     * Returns the string representation of the graph.  It will return the
     * list of vertices with their adjacency list, which is a list describing
     * the connected vertices to that particular vertex.
     *
     * @returns {string} the string representation of the graph
     */
    Graph.prototype.toString = function () {
        var str = '';
        for (var i = 0; i < this.vertices.length; i++) {
            str  += this.vertices[i] + ':';
            var connectedVerts = this.adjacentList.get(this.vertices[i]);
            for (var j = 0; j < connectedVerts.length; j++) {
                str += ' ' + connectedVerts[j].label;
            }
            str += '\n';
        }
        return str;
    };

    // expose the graph
    module.exports = Graph;

}());
<commit_msg>Refactor constructor to use forEach & edit comment<commit_after>/**
 * @fileOverview Implementation of a graph data structure
 * @author Jason S. Jones
 * @version 0.1.0
 * @license MIT
 */
(function() {
    'use strict';

    // pull in a few other data structurs to help build the graph
    // and to implement the two search algorithms: BFS and DFS.
    var Dictionary = require('simple-data-cache');
    var Queue = require('queue-fifo');
    var Stack = require('stack-lifo');

    /**
     * Creates a new Graph instance using the theVerts to provide the
     * labels for the intitial vertices of the graph.  If no parameter is
     * provided, an empty graph will be instantiated and all vertices will
     * need to be added by calling the 'addVertex' method.
     *
     * @constructor
     * @param {Array} theVerts an array of labels to initialize as the vertices
     *                of the graph
     *
     */
    function Graph(theVerts) {
        var self = this;
        this.adjacentList = new Dictionary();

        if (theVerts && theVerts.constructor === Array) {
            this.vertices = theVerts;

            this.vertices.forEach(function (v) {
                self.adjacentList.set(v, []);
            });

        } else {
            this.vertices = [];
        }

    }

    /**
     *
     */
    Graph.prototype.addVertex = function (label) {
        this.vertices.push(label);
        this.adjacentList.set(label, []);
    };

    /**
     *
     */
    Graph.prototype.addEdge = function (v1, v2, w) {
        if (this.adjacentList.has(v1) && this.adjacentList.has(v2)) {
            var edgeWeight = w || 1;
            this.adjacentList.get(v1).push({label: v2, weight: edgeWeight});
            this.adjacentList.get(v2).push({label: v1, weight: edgeWeight});
        } else {
            throw new Error('Vertex does not exist: Cannot add edge.');
        }
    };

    /**
     * Breadth first search
     *
     */
    Graph.prototype.BFS = function(vertex) {
        var q = new Queue();
        var result = [];
        var visited = [];

        // mark the starting vertex as visited and add it the queue
        visited.push(vertex);
        q.enqueue(vertex);

        while (!q.isEmpty()) {

            // dequeue the front vertex from the queue
            var focusVertex = q.dequeue();

            // add it to the results list
            result.push(focusVertex);

            //get all of its connected vertices
            var neighbors = this.adjacentList.get(focusVertex);

            for (var i = 0; i < neighbors.length; i++) {

                // if neighbor[i] has not been visited, mark it as visited
                // and add it to the queue
                if (visited.indexOf(neighbors[i].label) === -1) {
                    visited.push(neighbors[i].label);
                    q.enqueue(neighbors[i].label);
                }
            }
        }

        return result;
    };

    /**
     * Depth first search
     *
     */
    Graph.prototype.DFS = function(vertex) {
        var stack = new Stack();
        var result = [];
        var visited = [];

        // mark the starting vertex as visited and push it on the stack
        visited.push(vertex);
        stack.push(vertex);

        while (!stack.isEmpty()) {

            // pop a vertex from the top of the stack
            var focusVertex = stack.pop();

            // add it to the results list
            result.push(focusVertex);

            //get all of its connected vertices
            var neighbors = this.adjacentList.get(focusVertex);

            for (var i = 0; i < neighbors.length; i++) {

                // if neighbor[i] has not been visited, mark it as visited
                // and push it on the stack
                if (visited.indexOf(neighbors[i].label) === -1) {
                    visited.push(neighbors[i].label);
                    stack.push(neighbors[i].label);
                }
            }
        }

        return result;
    };

    /**
     * Returns the string representation of the graph.  It will return the
     * list of vertices with their adjacency list, which is a list describing
     * the connected vertices to that particular vertex.
     *
     * @returns {string} the string representation of the graph
     */
    Graph.prototype.toString = function () {
        var str = '';
        for (var i = 0; i < this.vertices.length; i++) {
            str  += this.vertices[i] + ':';
            var connectedVerts = this.adjacentList.get(this.vertices[i]);
            for (var j = 0; j < connectedVerts.length; j++) {
                str += ' ' + connectedVerts[j].label;
            }
            str += '\n';
        }
        return str;
    };

    // expose the graph
    module.exports = Graph;

}());
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose');

module.exports = function(app, config) {

  mongoose.connect(config.mongodb.uri, {
    db: {
      safe: true
    }
  });

  app.use(function(res, req, next) {
    // サーバー側でSessionを見て管理者判定する
    if (req.session && req.session.admin) {
      app.locals.admin = true;
    }
    next();
  });

}
<commit_msg>Change DB設定クラスをmongoldbからpostgresqlに変更した<commit_after>var fs = require('fs');
var path = require('path');

var config = require('config');
var Sequelize = require('sequelize');
var modelPath = path.join(__dirname, '../app/models');
var db = {};

var sequelize = new Sequelize(config.postgres.uri, {
  dialect: 'postgres',
  omitNull: true
});

// Import models
fs.readdirSync(modelPath)
  .forEach(function(file) {
    var model = sequelize.import(path.join(modelPath, file));
    db[model.name] = model;
  });

Object.keys(db).forEach((modelName) => {
  if ('associate' in db[modelName]) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;
<|endoftext|>


<commit_before>var config = require('rc')('upmon', {tray: {limit: 250}})
var menubar = require('menubar')
var upmon = require('upmon')
var ndjson = require('ndjson')
var ipcMain = require('electron').ipcMain
var debounce = require('debounce')
var Icons = require('./icons')

var data = {}

upmon().pipe(ndjson.parse()).on('data', d => {
  data[d.url] = data[d.url] || []
  data[d.url].unshift(d)
  data[d.url] = data[d.url].slice(0, config.tray.limit)
  send()
  updateIcon()
})

var mb = menubar({icon: Icons.default, height: 50})

mb.on('ready', () => {
  mb.tray.setPressedImage(Icons.pressed)

  updateIcon()

  mb.on('after-create-window', () => {
    // mb.window.webContents.openDevTools()
    mb.window.webContents.on('did-finish-load', send)
  })

  mb.on('after-show', send)
})

function send () {
  if (!mb.window) return
  if (!mb.window.isVisible()) return
  mb.window.webContents.send('render', data)
}

function updateIcon () {
  if (!mb.tray) return

  var isError = Object.keys(data).some(url => {
    return data[url][0].status < 200 || data[url][0].status >= 300
  })

  mb.tray.setImage(isError ? Icons.error : Icons.default)
}

ipcMain.on('height', (event, height) => setWindowSize(400, height))

var setWindowSize = debounce((w, h) => mb.window.setSize(w, h, true), 500)
<commit_msg>Set minimum height<commit_after>var config = require('rc')('upmon', {tray: {limit: 250}})
var menubar = require('menubar')
var upmon = require('upmon')
var ndjson = require('ndjson')
var ipcMain = require('electron').ipcMain
var debounce = require('debounce')
var Icons = require('./icons')

var data = {}

upmon().pipe(ndjson.parse()).on('data', d => {
  data[d.url] = data[d.url] || []
  data[d.url].unshift(d)
  data[d.url] = data[d.url].slice(0, config.tray.limit)
  send()
  updateIcon()
})

var mb = menubar({icon: Icons.default, height: 50})

mb.on('ready', () => {
  mb.tray.setPressedImage(Icons.pressed)

  updateIcon()

  mb.on('after-create-window', () => {
    // mb.window.webContents.openDevTools()
    mb.window.webContents.on('did-finish-load', send)
  })

  mb.on('after-show', send)
})

function send () {
  if (!mb.window) return
  if (!mb.window.isVisible()) return
  mb.window.webContents.send('render', data)
}

function updateIcon () {
  if (!mb.tray) return

  var isError = Object.keys(data).some(url => {
    return data[url][0].status < 200 || data[url][0].status >= 300
  })

  mb.tray.setImage(isError ? Icons.error : Icons.default)
}

ipcMain.on('height', (event, height) => setWindowSize(400, height))

var setWindowSize = debounce((w, h) => {
  if (h < 50) h = 50
  mb.window.setSize(w, h, true)
}, 500)
<|endoftext|>


<commit_before>"use strict";

const //weather = require("canada-weather"),
	mkdirp = require("mkdirp"),
	path = require("path"),
	root = path.join(__dirname, "data"),
	config = require(path.join(__dirname, "config.json")),
	messages = require(path.join(__dirname, "lib", "messages.js")),
	lcd = require(path.join(__dirname, "lib", "lcd.js"));

let on = true,
	center = true,
	timer = void 0;

function poll () {
	setTimeout(() => {
		lcd.message({msg: messages.dataLoading});
	}, config.poll || 60);
}

function quit () {
	lcd.kill(true);
	process.nextTick(() => {
		process.exit(0);
	});
}

function toggle () {
	on = !on;

	if (on) {
		lcd.last();
		decay();
	} else {
		lcd.dot3k.reset();
	}
}

function decay () {
	if (timer) {
		clearTimeout(timer);
	}

	timer = setTimeout(() => {
		if (on) {
			toggle();
		}

		timer = void 0;
	}, config.decay);
}

function datum (idx) {
	let msg;

	switch (idx) {
		default:
			msg = i.toUpperCase();
	}

	lcd.message({msg: msg});
	decay();
	center = false;
}

process.on("uncaughtException", quit);
process.on("SIGINT", quit);

// Joystick (shows datums)
["up", "down", "left", "right"].forEach((i, idx) => {
	lcd.dot3k.joystick.on(i, () => {
		datum(idx);
	});
});

// Joystick press (toggle LCD)
lcd.dot3k.joystick.on("button", () => {
	if (center) {
		toggle();
	} else {
		center = true;
		lcd.message({msg: messages.default});
	}
});

lcd.contrast();
lcd.message({msg: messages.default});
decay();

setTimeout(() => {
	mkdirp(root, e => {
		if (e) {
			console.error(e.stack);
			lcd.kill(true);
			process.exit(1);
		} else {
			console.log(messages.dirCreated);
			lcd.message({msg: messages.dirCreated});
			poll();
		}
	});
}, 1000);
<commit_msg>Tweaks<commit_after>"use strict";

const //weather = require("canada-weather"),
	mkdirp = require("mkdirp"),
	path = require("path"),
	root = path.join(__dirname, "data"),
	config = require(path.join(__dirname, "config.json")),
	messages = require(path.join(__dirname, "lib", "messages.js")),
	lcd = require(path.join(__dirname, "lib", "lcd.js"));

let on = true,
	center = true,
	timer = void 0;

function poll () {
	setTimeout(() => {
		lcd.message({msg: messages.dataLoading});
	}, config.poll || 60);
}

function quit () {
	lcd.kill(true);
	setTimeout(() => {
		process.exit(0);
	}, 250);
}

function toggle () {
	on = !on;

	if (on) {
		lcd.last();
		decay();
	} else {
		lcd.dot3k.reset();
	}
}

function decay () {
	if (timer) {
		clearTimeout(timer);
	}

	timer = setTimeout(() => {
		if (on) {
			toggle();
		}

		timer = void 0;
	}, config.decay);
}

function datum (idx) {
	let msg;

	switch (idx) {
		default:
			msg = i.toUpperCase();
	}

	lcd.message({msg: msg});
	decay();
	center = false;
}

process.on("uncaughtException", quit);
process.on("SIGINT", quit);

// Joystick (shows datums)
["up", "down", "left", "right"].forEach((i, idx) => {
	lcd.dot3k.joystick.on(i, () => {
		datum(idx);
	});
});

// Joystick press (toggle LCD)
lcd.dot3k.joystick.on("button", () => {
	if (center) {
		toggle();
	} else {
		center = true;
		lcd.message({msg: messages.default});
	}
});

lcd.contrast();
lcd.message({msg: messages.default});
decay();

setTimeout(() => {
	mkdirp(root, e => {
		if (e) {
			console.error(e.stack);
			lcd.kill(true);
			process.exit(1);
		} else {
			console.log(messages.dirCreated);
			lcd.message({msg: messages.dirCreated});
			poll();
		}
	});
}, 1000);
<|endoftext|>


<commit_before>/*
	# BCS-46x Brewery Automation Controller adapter.

	(The MIT License)
	Copyright © 2013 Carson S. Christian <cscade@gmail.com>
*/
/*jshint node:true */

var Device = require('bcs.client');

/*
	# Adapter

	The device adapter object. Provides all connectivity to the controller.

	@param {String} host ex. 192.168.1.10
	@param {Number} [port] || 80
	@param {Function} next(e, adapter)
*/
var Adapter = function (host, port, next) {
	var adapter = this;

	if (typeof port === 'function') {
		next = port;
		port = undefined;
	}
	this.ready = false;
	// BCS.client does not support https connections, so it expects an IP address or FQDN, with no scheme.
	if (/:\/\//.test(host)) host = host.split('://')[1];
	this.device = new Device(host, port || 80, function (e, deviceInfo) {
		if (e) return next(e);
		adapter.ready = deviceInfo.ready;
		next(null, adapter);
	});
};

/*
	## expose
*/
module.exports = Adapter;<commit_msg>expose deviceType property<commit_after>/*
	# BCS-46x Brewery Automation Controller adapter.

	(The MIT License)
	Copyright © 2013 Carson S. Christian <cscade@gmail.com>
*/
/*jshint node:true */

var Device = require('bcs.client');

/*
	# Adapter

	The device adapter object. Provides all connectivity to the controller.

	Public properties;
		adapter.ready {Boolean}
		adapter.deviceType {String} Descriptive string for the kind of device.

	@param {String} host ex. 192.168.1.10
	@param {Number} [port] || 80
	@param {Function} next(e, adapter)
*/
var Adapter = function (host, port, next) {
	var adapter = this;

	if (typeof port === 'function') {
		next = port;
		port = undefined;
	}
	this.ready = false;
	// BCS.client does not support https connections, so it expects an IP address or FQDN, with no scheme.
	if (/:\/\//.test(host)) host = host.split('://')[1];
	this.device = new Device(host, port || 80, function (e, deviceInfo) {
		if (e) return next(e);
		adapter.ready = deviceInfo.ready;
		adapter.deviceType = deviceInfo.firmware;
		next(null, adapter);
	});
};

/*
	## expose
*/
module.exports = Adapter;<|endoftext|>


<commit_before>var express = require('express')
	, request = require('request')
	, path = require('path')
	, multer = require('multer')
	, redis = require("redis")
	, lwip = require('lwip')
	, sha1 = require('sha1')
	, fs = require('fs')
	, freegeoip = require('node-freegeoip')
	, qs = require('querystring');

// Configuration.
var appURL = 'https://plex-discord-webhook.herokuapp.com';
var webhookKey = process.env.DISCORD_WEBHOOK_KEY;

var redisClient = redis.createClient(process.env.REDISCLOUD_URL, { return_buffers: true });
var upload = multer({ storage: multer.memoryStorage() });
var app = express();

app.use(express.static('images'));

function formatTitle(metadata) {
	if (metadata.grandparentTitle) {
		return metadata.grandparentTitle;
	} else {
		var ret = metadata.title;
		if (metadata.year) {
			ret += ' (' + metadata.year + ')';
		}
		return ret;
	}
}

function formatSubtitle(metadata) {
	var ret = '';
	if (metadata.grandparentTitle) {
		if (metadata.type == 'track') {
			ret = metadata.parentTitle;
		} else if (metadata.index && metadata.parentIndex) {
			ret = "S" + metadata.parentIndex + " E" + metadata.index;
		} else if (metadata.originallyAvailableAt) {
			ret = metadata.originallyAvailableAt;
		}

		if (metadata.title) {
			ret += ' - ' + metadata.title;
		}
	} else if (metadata.type == 'movie') {
		ret = metadata.tagline;
	}

	return ret;
}

function formatSummary(summary) {
	var ret = '';

	if (summary && summary.length) {
		if (summary.length > 300) {
			ret += summary.substring(0, 300) + '...';
		}
		else {
			ret += summary;
		}

		if (ret.length > 0) {
			ret = '\r\n' + ret;
		}
	}

	return ret;
}

function notifyDiscord(imageUrl, payload, location, action) {
	var locationText = '';
	if (location) {
		if (location.city) {
			locationText = ' near ' + location.city + ', ' + (location.country_code == 'US' ? location.region_name : location.country_name);
		}
		else {
			locationText = ', ' + (location.country_code == 'US' ? location.region_name : location.country_name);
		}
	}

	var data = {
		"content": "",
		"username": "Plex",
		"avatar_url": appURL + "/plex-icon.png",
		"embeds": [
			{
				"title": formatTitle(payload.Metadata),
				"description": formatSubtitle(payload.Metadata) + formatSummary(payload.Metadata.summary),
				"footer": {
					"text": action + " by " + payload.Account.title + " on " + payload.Player.title + " from " + payload.Server.title + locationText,
					"icon_url": payload.Account.thumb
				},
				"thumbnail": {
					"url": imageUrl,
					"height": 200,
					"width": "200"
				}
			}
		]
	};

	request.post('https://discordapp.com/api/webhooks/' + webhookKey,
		{ json: data },
		function (error, response, body) {
			if (!error && response.statusCode == 200) {
				//console.log(body)
			}
		}
	);
}

app.post('/', upload.single('thumb'), function (req, res, next) {
	var payload = JSON.parse(req.body.payload);
	var isVideo = (payload.Metadata.librarySectionType == "movie" || payload.Metadata.librarySectionType == "show");
	var isAudio = (payload.Metadata.librarySectionType == "artist");

	if (payload.user == true && payload.Metadata && (isAudio || isVideo)) {
		var key = sha1(payload.Server.uuid + payload.Metadata.guid);

		if (payload.event == "media.play" || payload.event == "media.rate") {
			// Save the image.
			if (req.file && req.file.buffer) {
				lwip.open(req.file.buffer, 'jpg', function (err, image) {
					image.contain(75, 75, 'white', function (err, smallerImage) {
						smallerImage.toBuffer('jpg', function (err, buffer) {
							redisClient.setex(key, 7 * 24 * 60 * 60, buffer);
						});
					});
				});
			}
		}

		if ((payload.event == "media.scrobble" && isVideo) || payload.event == "media.rate") {
			// Geolocate player.
			freegeoip.getLocation(payload.Player.publicAddress, function (err, location) {

				var action;
				if (payload.event == "media.scrobble") {
					action = "played";
				} else {
					if (payload.rating > 0) {
						action = "rated ";
						for (var i = 0; i < payload.rating / 2; i++)
							action += "★";
					} else {
						action = "unrated";
					}
				}

				// Send the event to Discord.
				redisClient.get(key, function (err, reply) {
					console.log('location', location);
					if (!location || (location && location.city && location.city.length > 1)) {
						if (reply) {
							notifyDiscord(appURL + '/images/' + key, payload, location, action);
						} else {
							notifyDiscord(null, payload, location, action);
						}
					}
					else {
						console.log('location city missing, trying OSM lat lng lookup');

						var options = {
							url: 'http://nominatim.openstreetmap.org/reverse?format=json&lat=' + location.latitude + '&lon=' + location.longitude + '&accept-language=en',
							method: 'GET',
							headers: {
								'User-Agent': 'hoglund.joakim@gmail.com'
							}
						};

						request(options, function (error, response, body) {
								if (error) console.log('OSM lookup error', error);

								if (!error && response.statusCode == 200) {
									location = JSON.parse(body).address;
									location.region_name = location.state;
								}

								if (reply) {
									notifyDiscord(appURL + '/images/' + key, payload, location, action);
								} else {
									notifyDiscord(null, payload, location, action);
								}
							}
						);
					}
				});
			});
		}
	}

	res.sendStatus(200);
});

app.get('/images/:key', function (req, res, next) {
	redisClient.get(req.params.key, function (err, value) {
		if (err) {
			next(err);
		} else {
			if (!value) {
				next();
			} else {
				res.setHeader('Content-Type', 'image/jpeg');
				res.end(value);
			}
		}
	});
});

app.listen(process.env.PORT || 11000);<commit_msg>last fix for OSM<commit_after>var express = require('express')
	, request = require('request')
	, path = require('path')
	, multer = require('multer')
	, redis = require("redis")
	, lwip = require('lwip')
	, sha1 = require('sha1')
	, fs = require('fs')
	, freegeoip = require('node-freegeoip')
	, qs = require('querystring');

// Configuration.
var appURL = 'https://plex-discord-webhook.herokuapp.com';
var webhookKey = process.env.DISCORD_WEBHOOK_KEY;

var redisClient = redis.createClient(process.env.REDISCLOUD_URL, { return_buffers: true });
var upload = multer({ storage: multer.memoryStorage() });
var app = express();

app.use(express.static('images'));

function formatTitle(metadata) {
	if (metadata.grandparentTitle) {
		return metadata.grandparentTitle;
	} else {
		var ret = metadata.title;
		if (metadata.year) {
			ret += ' (' + metadata.year + ')';
		}
		return ret;
	}
}

function formatSubtitle(metadata) {
	var ret = '';
	if (metadata.grandparentTitle) {
		if (metadata.type == 'track') {
			ret = metadata.parentTitle;
		} else if (metadata.index && metadata.parentIndex) {
			ret = "S" + metadata.parentIndex + " E" + metadata.index;
		} else if (metadata.originallyAvailableAt) {
			ret = metadata.originallyAvailableAt;
		}

		if (metadata.title) {
			ret += ' - ' + metadata.title;
		}
	} else if (metadata.type == 'movie') {
		ret = metadata.tagline;
	}

	return ret;
}

function formatSummary(summary) {
	var ret = '';

	if (summary && summary.length) {
		if (summary.length > 300) {
			ret += summary.substring(0, 300) + '...';
		}
		else {
			ret += summary;
		}

		if (ret.length > 0) {
			ret = '\r\n' + ret;
		}
	}

	return ret;
}

function notifyDiscord(imageUrl, payload, location, action) {
	var locationText = '';
	if (location) {
		if (location.city) {
			locationText = ' near ' + location.city + ', ' + (location.country_code == 'US' ? location.region_name : location.country_name);
		}
		else {
			locationText = ', ' + (location.country_code == 'US' ? location.region_name : location.country_name);
		}
	}

	var data = {
		"content": "",
		"username": "Plex",
		"avatar_url": appURL + "/plex-icon.png",
		"embeds": [
			{
				"title": formatTitle(payload.Metadata),
				"description": formatSubtitle(payload.Metadata) + formatSummary(payload.Metadata.summary),
				"footer": {
					"text": action + " by " + payload.Account.title + " on " + payload.Player.title + " from " + payload.Server.title + locationText,
					"icon_url": payload.Account.thumb
				},
				"thumbnail": {
					"url": imageUrl,
					"height": 200,
					"width": "200"
				}
			}
		]
	};

	request.post('https://discordapp.com/api/webhooks/' + webhookKey,
		{ json: data },
		function (error, response, body) {
			if (!error && response.statusCode == 200) {
				//console.log(body)
			}
		}
	);
}

app.post('/', upload.single('thumb'), function (req, res, next) {
	var payload = JSON.parse(req.body.payload);
	var isVideo = (payload.Metadata.librarySectionType == "movie" || payload.Metadata.librarySectionType == "show");
	var isAudio = (payload.Metadata.librarySectionType == "artist");

	if (payload.user == true && payload.Metadata && (isAudio || isVideo)) {
		var key = sha1(payload.Server.uuid + payload.Metadata.guid);

		if (payload.event == "media.play" || payload.event == "media.rate") {
			// Save the image.
			if (req.file && req.file.buffer) {
				lwip.open(req.file.buffer, 'jpg', function (err, image) {
					image.contain(75, 75, 'white', function (err, smallerImage) {
						smallerImage.toBuffer('jpg', function (err, buffer) {
							redisClient.setex(key, 7 * 24 * 60 * 60, buffer);
						});
					});
				});
			}
		}

		if ((payload.event == "media.scrobble" && isVideo) || payload.event == "media.rate") {
			// Geolocate player.
			freegeoip.getLocation(payload.Player.publicAddress, function (err, location) {

				var action;
				if (payload.event == "media.scrobble") {
					action = "played";
				} else {
					if (payload.rating > 0) {
						action = "rated ";
						for (var i = 0; i < payload.rating / 2; i++)
							action += "★";
					} else {
						action = "unrated";
					}
				}

				// Send the event to Discord.
				redisClient.get(key, function (err, reply) {
					console.log('location', location);
					if (!location || (location && location.city && location.city.length > 1)) {
						if (reply) {
							notifyDiscord(appURL + '/images/' + key, payload, location, action);
						} else {
							notifyDiscord(null, payload, location, action);
						}
					}
					else {
						console.log('location city missing, trying OSM lat lng lookup');

						var options = {
							url: 'http://nominatim.openstreetmap.org/reverse?format=json&lat=' + location.latitude + '&lon=' + location.longitude + '&accept-language=en',
							method: 'GET',
							headers: {
								'User-Agent': 'hoglund.joakim@gmail.com'
							}
						};

						request(options, function (error, response, body) {
								if (error) console.log('OSM lookup error', error);

								if (!error && response.statusCode == 200) {
									location = JSON.parse(body).address;
									location.region_name = location.state;
									location.country_name = location.country;
								}

								if (reply) {
									notifyDiscord(appURL + '/images/' + key, payload, location, action);
								} else {
									notifyDiscord(null, payload, location, action);
								}
							}
						);
					}
				});
			});
		}
	}

	res.sendStatus(200);
});

app.get('/images/:key', function (req, res, next) {
	redisClient.get(req.params.key, function (err, value) {
		if (err) {
			next(err);
		} else {
			if (!value) {
				next();
			} else {
				res.setHeader('Content-Type', 'image/jpeg');
				res.end(value);
			}
		}
	});
});

app.listen(process.env.PORT || 11000);<|endoftext|>


<commit_before>;(function () {
	/* Lightweight EventEmitter implementation */
	var EventEmitter = function () {}
	EventEmitter.prototype._events = {}

	EventEmitter.prototype.on = function (evt, fn) {
		this._events[evt] = this._events[evt] || []
		this._events[evt].push(fn)
	}
	EventEmitter.prototype.off = function (evt, fn) {
		if (evt in this._events === false) return
		this._events[evt].splice(this._events[evt].indexOf(fn), 1)
	}
	EventEmitter.prototype.emit = function (evt) {
		if (evt in this._events === false) return

		for (var i = 0, l = this._events[evt].length; i < l; i++) {
			this._events[evt][i].apply(this, Array.prototype.slice.call(arguments, 1))
		}
	}

	/* Copy the stuff from Array to FileList */
	FileList.prototype.forEach = Array.prototype.forEach
	FileList.prototype.every = Array.prototype.every
	FileList.prototype.some = Array.prototype.some
	FileList.prototype.filter = Array.prototype.filter
	FileList.prototype.map = Array.prototype.map
	FileList.prototype.reduce = Array.prototype.reduce
	FileList.prototype.reduceRight = Array.prototype.reduceRight

	Object.defineProperty(FileList.prototype, "size", {
		get: function getSize () {
			return this.map(function(item) {
				return item.size
			}).reduce(function (prev, curr) {
				return prev + curr
			})
		}
	})

	/* Utility to convert bytes into human units */
	var humanSize = {
		get: function humanSize (size) {
			var units = ["B", "KiB", "MIB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
			var e = Math.floor(Math.log(this.size) / Math.log(1024))
			return (this.size / Math.pow(1024, e)).toFixed(2) + " " + units[e]
		}
	}
	Object.defineProperty(FileList.prototype, "humanSize", humanSize)
	Object.defineProperty(File.prototype, "humanSize", humanSize)

	var percentUploaded = {
		get: function percentUploaded () {
			return this.uploadedSize / this.size
		}
	}
	Object.defineProperty(FileList.prototype, "percentUploaded", percentUploaded)
	Object.defineProperty(File.prototype, "percentUploaded", percentUploaded)

	Object.defineProperty(FileList.prototype, "uploadedSize", {
		get: function getUploadedSize () {
			return this.map(function(item) {
				return item.uploadedSize || 0
			}).reduce(function (prev, curr) {
				return prev + curr
			})
		}
	})

	/* Object URL stuff */
	Object.defineProperty(File.prototype, "url", {
		get: function getURL () {
			return window.URL.createObjectURL(this);
		}
	})
	File.revokeURL = function revokeURL (url) {
		window.URL.revokeObjectURL(url)
	}

	// b gets merged as defaults for a
	var defaults = function (a, b) {
		var out = {}
		for (var key in b) {
			out[key] = (a[key] === void 0) ? b[key] : a[key]
		}
		return out
	}

	var FileListUploader = function (url, files, opts) {
		this.url = url
		this.files = files

		opts = opts || {}

		this.opts = defaults(opts, {
			'field': 'files[]',
		   'method': 'POST'
		})
	}
	FileListUploader.prototype = Object.create(EventEmitter.prototype)
	FileListUploader.prototype.upload = function (cb) {
		if (cb) this.on('uploadcomplete', cb)

		var opts = this.opts
		var files = this.files
		var events = this

		var data = new FormData()
		files.forEach(function (file) {
			data.append(opts.field, file)
		})

		var xhr = new XMLHttpRequest()

		xhr.open(opts.method, this.url, true)
		xhr.upload.addEventListener('progress', function (e) {
			if (e.lengthComputable) {
				size = e.loaded
				// We know the size of the files, the order they're in, and how
				// much we've uploaded.  Based on this data, we can do some magic
				// to figure out which file we're on, and how much we've uploaded
				// of that file.
				// TODO: This math has trouble on later uploads.  Leak somewhere
				for (var i = 0, l = files.length; i < l; i++) {
					files[i].uploadedSize = Math.min(size, files[i].size)
					size -= files[i].uploadedSize
					if (size <= 0) {
						console.log((i+1) + '/' + l + ': ' + files[i].name + ': ' + humanSize(files[i].uploadedSize) + '/' + humanSize(files[i].size));
						files.current = files[i]
						size = 0
						break
					}
				}
			}
			events.emit('uploadprogress', e, files)
		}, false)
		xhr.upload.addEventListener('loadstart', function (e) { events.emit('uploadstart', e) })
		xhr.upload.addEventListener('load', function (e) { events.emit('uploadcomplete', e) })
		xhr.addEventListener('progress', function (e) { events.emit('progress', e) })
		xhr.addEventListener('load', function (e) { events.emit('load', e, xhr.responseText) })

		xhr.send(data)
		/* TODO: Add more event passthroughs, maybe abstract it into a helper? */
	}

	FileList.prototype.upload = function uploadFileList (url, opts) {
		return new FileListUploader(url, this, opts)
	}
})()
<commit_msg>Clean up a bit; no logic changes (but some logging changes)<commit_after>;(function () {
	/* Lightweight EventEmitter implementation */
	var EventEmitter = function () {}
	EventEmitter.prototype._events = {}

	EventEmitter.prototype.on = function (evt, fn) {
		this._events[evt] = this._events[evt] || []
		this._events[evt].push(fn)
	}
	EventEmitter.prototype.off = function (evt, fn) {
		if (evt in this._events === false) return
		this._events[evt].splice(this._events[evt].indexOf(fn), 1)
	}
	EventEmitter.prototype.emit = function (evt) {
		if (evt in this._events === false) return

		for (var i = 0, l = this._events[evt].length; i < l; i++) {
			this._events[evt][i].apply(this, Array.prototype.slice.call(arguments, 1))
		}
	}

	/* Copy the stuff from Array to FileList */
	FileList.prototype.forEach = Array.prototype.forEach
	FileList.prototype.every = Array.prototype.every
	FileList.prototype.some = Array.prototype.some
	FileList.prototype.filter = Array.prototype.filter
	FileList.prototype.map = Array.prototype.map
	FileList.prototype.reduce = Array.prototype.reduce
	FileList.prototype.reduceRight = Array.prototype.reduceRight

	Object.defineProperty(FileList.prototype, "size", {
		get: function getSize () {
			return this.map(function(item) {
				return item.size
			}).reduce(function (prev, curr) {
				return prev + curr
			})
		}
	})

	/* Utility to convert bytes into human units */
	var humanSize = {
		get: function humanSize () {
			var units = ["B", "KiB", "MIB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
			var e = Math.floor(Math.log(this.size) / Math.log(1024))
			return (this.size / Math.pow(1024, e)).toFixed(2) + " " + units[e]
		}
	}
	Object.defineProperty(FileList.prototype, "humanSize", humanSize)
	Object.defineProperty(File.prototype, "humanSize", humanSize)

	var percentUploaded = {
		get: function percentUploaded () {
			return this.uploadedSize / this.size
		}
	}
	Object.defineProperty(FileList.prototype, "percentUploaded", percentUploaded)
	Object.defineProperty(File.prototype, "percentUploaded", percentUploaded)

	Object.defineProperty(FileList.prototype, "uploadedSize", {
		get: function getUploadedSize () {
			return this.map(function(item) {
				return item.uploadedSize || 0
			}).reduce(function (prev, curr) {
				return prev + curr
			})
		}
	})

	/* Object URL stuff */
	Object.defineProperty(File.prototype, "url", {
		get: function getURL () {
			return window.URL.createObjectURL(this);
		}
	})
	File.revokeURL = function revokeURL (url) {
		window.URL.revokeObjectURL(url)
	}

	// b gets merged as defaults for a
	var defaults = function (a, b) {
		var out = {}
		for (var key in b) {
			out[key] = (a[key] === void 0) ? b[key] : a[key]
		}
		return out
	}

	var FileListUploader = function (url, files, opts) {
		this.url = url
		this.files = files

		opts = opts || {}

		this.opts = defaults(opts, {
			'field': 'files[]',
		   'method': 'POST'
		})
	}
	FileListUploader.prototype = Object.create(EventEmitter.prototype)
	FileListUploader.prototype.upload = function (cb) {
		if (cb) this.on('uploadcomplete', cb)

		var opts = this.opts
		var files = this.files
		var events = this

		var data = new FormData()
		files.forEach(function (file) {
			data.append(opts.field, file)
		})

		var xhr = new XMLHttpRequest()

		xhr.open(opts.method, this.url, true)
		xhr.upload.addEventListener('progress', function (e) {
			if (e.lengthComputable) {
				size = e.loaded
				// We know the size of the files, the order they're in, and how
				// much we've uploaded.  Based on this data, we can do some magic
				// to figure out which file we're on, and how much we've uploaded
				// of that file.
				// TODO: This math has trouble on later uploads.  Leak somewhere
				for (var i = 0, l = files.length; i < l; i++) {
					files[i].uploadedSize = Math.min(size, files[i].size)
					size -= files[i].uploadedSize
					if (size <= 0) {
						files.current = files[i]
						size = 0
						break
					}
				}
			}
			events.emit('uploadprogress', e, files)
		}, false)
		xhr.upload.addEventListener('loadstart', function (e) { events.emit('uploadstart', e) })
		xhr.upload.addEventListener('load', function (e) { events.emit('uploadcomplete', e) })
		xhr.addEventListener('progress', function (e) { events.emit('progress', e) })
		xhr.addEventListener('load', function (e) { events.emit('load', e, xhr.responseText) })

		xhr.send(data)
		/* TODO: Add more event passthroughs, maybe abstract it into a helper? */
	}

	FileList.prototype.upload = function uploadFileList (url, opts) {
		return new FileListUploader(url, this, opts)
	}
})()
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Parses an equation given as a command-line argument
 * into an object and computes it. Prints the result into stdout.
 *
 * Usage:
 *   ./index.js 1+2-3*4/5%6^7
 */

'use strict';

var EquationParser = require('./EquationParser');

var EquationParser = new EquationParser();
var equationStr = process.argv[2];

if (!equationStr) {
  return console.log('Usage: ./index.js 1+2-3*4/5%6^7');
}

var equation = EquationParser.parseEquation(equationStr);

console.log(equation.compute());
<commit_msg>Fix a typo in instance name<commit_after>#!/usr/bin/env node

/**
 * Parses an equation given as a command-line argument
 * into an object and computes it. Prints the result into stdout.
 *
 * Usage:
 *   ./index.js 1+2-3*4/5%6^7
 */

'use strict';

var EquationParser = require('./EquationParser');

var equationParser = new EquationParser();
var equationStr = process.argv[2];

if (!equationStr) {
  return console.log('Usage: ./index.js 1+2-3*4/5%6^7');
}

var equation = equationParser.parseEquation(equationStr);

console.log(equation.compute());
<|endoftext|>


<commit_before>/* jshint ignore:start */
'use strict';

const BbPromise = require('bluebird');
const fse = require('fs-extra');
const values = require('lodash.values');
const {
  addVendorHelper,
  removeVendorHelper,
  packRequirements
} = require('./lib/zip');
const { injectAllRequirements } = require('./lib/inject');
const { layerRequirements } = require('./lib/layer');
const { installAllRequirements } = require('./lib/pip');
const { pipfileToRequirements } = require('./lib/pipenv');
const { pyprojectTomlToRequirements } = require('./lib/poetry');
const { cleanup, cleanupCache } = require('./lib/clean');

BbPromise.promisifyAll(fse);

/**
 * Plugin for Serverless 1.x that bundles python requirements!
 */
class ServerlessPythonRequirements {
  /**
   * get the custom.pythonRequirements contents, with defaults set
   * @return {Object}
   */
  get options() {
    const options = Object.assign(
      {
        slim: false,
        slimPatterns: false,
        slimPatternsAppendDefaults: true,
        zip: false,
        layer: false,
        cleanupZipHelper: true,
        invalidateCaches: false,
        fileName: 'requirements.txt',
        usePipenv: true,
        usePoetry: true,
        pythonBin:
          process.platform === 'win32'
            ? 'python.exe'
            : this.serverless.service.provider.runtime || 'python',
        dockerizePip: false,
        dockerSsh: false,
        dockerImage: null,
        dockerFile: null,
        dockerEnv: false,
        dockerBuildCmdExtraArgs: [],
        dockerRunCmdExtraArgs: [],
        useStaticCache: false,
        useDownloadCache: false,
        cacheLocation: false,
        staticCacheMaxVersions: 0,
        pipCmdExtraArgs: [],
        noDeploy: [],
        vendor: ''
      },
      (this.serverless.service.custom &&
        this.serverless.service.custom.pythonRequirements) ||
        {}
    );
    if (options.dockerizePip === 'non-linux') {
      options.dockerizePip = process.platform !== 'linux';
    }
    if (options.dockerizePip && process.platform === 'win32') {
      options.pythonBin = 'python';
    }
    if (
      !options.dockerizePip &&
      (options.dockerSsh || options.dockerImage || options.dockerFile)
    ) {
      if (!this.warningLogged) {
        this.serverless.cli.log(
          'WARNING: You provided a docker related option but dockerizePip is set to false.'
        );
        this.warningLogged = true;
      }
    }
    if (options.dockerImage && options.dockerFile) {
      throw new Error(
        'Python Requirements: you can provide a dockerImage or a dockerFile option, not both.'
      );
    } else if (!options.dockerFile) {
      // If no dockerFile is provided, use default image
      const defaultImage = `lambci/lambda:build-${
        this.serverless.service.provider.runtime
      }`;
      options.dockerImage = options.dockerImage || defaultImage;
    }
    if (options.layer) {
      // If layer was set as a boolean, set it to an empty object to use the layer defaults.
      if (options.layer === true) {
        options.layer = {};
      }
    }
    return options;
  }

  get targetFuncs() {
    let inputOpt = this.serverless.processedInput.options;
    return inputOpt.function
      ? [inputOpt.functionObj]
      : values(this.serverless.service.functions);
  }

  /**
   * The plugin constructor
   * @param {Object} serverless
   * @param {Object} options
   * @return {undefined}
   */
  constructor(serverless) {
    this.serverless = serverless;
    this.servicePath = this.serverless.config.servicePath;
    this.warningLogged = false;

    this.commands = {
      requirements: {
        usage: 'Serverless plugin to bundle Python packages',
        lifecycleEvents: ['requirements'],
        commands: {
          clean: {
            usage: 'Remove .requirements and requirements.zip',
            lifecycleEvents: ['clean']
          },
          install: {
            usage: 'install requirements manually',
            lifecycleEvents: ['install']
          },
          cleanCache: {
            usage:
              'Removes all items in the pip download/static cache (if present)',
            lifecycleEvents: ['cleanCache']
          }
        }
      }
    };

    const isFunctionRuntimePython = args => {
      // If functionObj.runtime is undefined, python.
      if (!args[1].functionObj || !args[1].functionObj.runtime) {
        return true;
      }
      return args[1].functionObj.runtime.startsWith('python');
    };

    const clean = () =>
      BbPromise.bind(this)
        .then(cleanup)
        .then(removeVendorHelper);

    const before = () => {
      if (!isFunctionRuntimePython(arguments)) {
        return;
      }
      return BbPromise.bind(this)
        .then(pipfileToRequirements)
        .then(pyprojectTomlToRequirements)
        .then(addVendorHelper)
        .then(installAllRequirements)
        .then(packRequirements);
    };

    const after = () => {
      if (!isFunctionRuntimePython(arguments)) {
        return;
      }
      return BbPromise.bind(this)
        .then(removeVendorHelper)
        .then(layerRequirements)
        .then(() =>
          injectAllRequirements.bind(this)(
            arguments[1].functionObj &&
              arguments[1].functionObj.package.artifact
          )
        );
    };

    const invalidateCaches = () => {
      if (this.options.invalidateCaches) {
        return clean;
      }
      return BbPromise.resolve();
    };

    const cleanCache = () => BbPromise.bind(this).then(cleanupCache);

    this.hooks = {
      'after:package:cleanup': invalidateCaches,
      'before:package:createDeploymentArtifacts': before,
      'after:package:createDeploymentArtifacts': after,
      'before:deploy:function:packageFunction': before,
      'after:deploy:function:packageFunction': after,
      'requirements:requirements': () => {
        this.serverless.cli.generateCommandsHelp(['requirements']);
        return BbPromise.resolve();
      },
      'requirements:install:install': before,
      'requirements:clean:clean': clean,
      'requirements:cleanCache:cleanCache': cleanCache
    };
  }
}

module.exports = ServerlessPythonRequirements;
<commit_msg>Fix lint failure on index.js<commit_after>/* jshint ignore:start */
'use strict';

const BbPromise = require('bluebird');
const fse = require('fs-extra');
const values = require('lodash.values');
const {
  addVendorHelper,
  removeVendorHelper,
  packRequirements
} = require('./lib/zip');
const { injectAllRequirements } = require('./lib/inject');
const { layerRequirements } = require('./lib/layer');
const { installAllRequirements } = require('./lib/pip');
const { pipfileToRequirements } = require('./lib/pipenv');
const { pyprojectTomlToRequirements } = require('./lib/poetry');
const { cleanup, cleanupCache } = require('./lib/clean');

BbPromise.promisifyAll(fse);

/**
 * Plugin for Serverless 1.x that bundles python requirements!
 */
class ServerlessPythonRequirements {
  /**
   * get the custom.pythonRequirements contents, with defaults set
   * @return {Object}
   */
  get options() {
    const options = Object.assign(
      {
        slim: false,
        slimPatterns: false,
        slimPatternsAppendDefaults: true,
        zip: false,
        layer: false,
        cleanupZipHelper: true,
        invalidateCaches: false,
        fileName: 'requirements.txt',
        usePipenv: true,
        usePoetry: true,
        pythonBin:
          process.platform === 'win32'
            ? 'python.exe'
            : this.serverless.service.provider.runtime || 'python',
        dockerizePip: false,
        dockerSsh: false,
        dockerImage: null,
        dockerFile: null,
        dockerEnv: false,
        dockerBuildCmdExtraArgs: [],
        dockerRunCmdExtraArgs: [],
        useStaticCache: false,
        useDownloadCache: false,
        cacheLocation: false,
        staticCacheMaxVersions: 0,
        pipCmdExtraArgs: [],
        noDeploy: [],
        vendor: ''
      },
      (this.serverless.service.custom &&
        this.serverless.service.custom.pythonRequirements) ||
        {}
    );
    if (options.dockerizePip === 'non-linux') {
      options.dockerizePip = process.platform !== 'linux';
    }
    if (options.dockerizePip && process.platform === 'win32') {
      options.pythonBin = 'python';
    }
    if (
      !options.dockerizePip &&
      (options.dockerSsh || options.dockerImage || options.dockerFile)
    ) {
      if (!this.warningLogged) {
        this.serverless.cli.log(
          'WARNING: You provided a docker related option but dockerizePip is set to false.'
        );
        this.warningLogged = true;
      }
    }
    if (options.dockerImage && options.dockerFile) {
      throw new Error(
        'Python Requirements: you can provide a dockerImage or a dockerFile option, not both.'
      );
    } else if (!options.dockerFile) {
      // If no dockerFile is provided, use default image
      const defaultImage = `lambci/lambda:build-${this.serverless.service.provider.runtime}`;
      options.dockerImage = options.dockerImage || defaultImage;
    }
    if (options.layer) {
      // If layer was set as a boolean, set it to an empty object to use the layer defaults.
      if (options.layer === true) {
        options.layer = {};
      }
    }
    return options;
  }

  get targetFuncs() {
    let inputOpt = this.serverless.processedInput.options;
    return inputOpt.function
      ? [inputOpt.functionObj]
      : values(this.serverless.service.functions);
  }

  /**
   * The plugin constructor
   * @param {Object} serverless
   * @param {Object} options
   * @return {undefined}
   */
  constructor(serverless) {
    this.serverless = serverless;
    this.servicePath = this.serverless.config.servicePath;
    this.warningLogged = false;

    this.commands = {
      requirements: {
        usage: 'Serverless plugin to bundle Python packages',
        lifecycleEvents: ['requirements'],
        commands: {
          clean: {
            usage: 'Remove .requirements and requirements.zip',
            lifecycleEvents: ['clean']
          },
          install: {
            usage: 'install requirements manually',
            lifecycleEvents: ['install']
          },
          cleanCache: {
            usage:
              'Removes all items in the pip download/static cache (if present)',
            lifecycleEvents: ['cleanCache']
          }
        }
      }
    };

    const isFunctionRuntimePython = args => {
      // If functionObj.runtime is undefined, python.
      if (!args[1].functionObj || !args[1].functionObj.runtime) {
        return true;
      }
      return args[1].functionObj.runtime.startsWith('python');
    };

    const clean = () =>
      BbPromise.bind(this)
        .then(cleanup)
        .then(removeVendorHelper);

    const before = () => {
      if (!isFunctionRuntimePython(arguments)) {
        return;
      }
      return BbPromise.bind(this)
        .then(pipfileToRequirements)
        .then(pyprojectTomlToRequirements)
        .then(addVendorHelper)
        .then(installAllRequirements)
        .then(packRequirements);
    };

    const after = () => {
      if (!isFunctionRuntimePython(arguments)) {
        return;
      }
      return BbPromise.bind(this)
        .then(removeVendorHelper)
        .then(layerRequirements)
        .then(() =>
          injectAllRequirements.bind(this)(
            arguments[1].functionObj &&
              arguments[1].functionObj.package.artifact
          )
        );
    };

    const invalidateCaches = () => {
      if (this.options.invalidateCaches) {
        return clean;
      }
      return BbPromise.resolve();
    };

    const cleanCache = () => BbPromise.bind(this).then(cleanupCache);

    this.hooks = {
      'after:package:cleanup': invalidateCaches,
      'before:package:createDeploymentArtifacts': before,
      'after:package:createDeploymentArtifacts': after,
      'before:deploy:function:packageFunction': before,
      'after:deploy:function:packageFunction': after,
      'requirements:requirements': () => {
        this.serverless.cli.generateCommandsHelp(['requirements']);
        return BbPromise.resolve();
      },
      'requirements:install:install': before,
      'requirements:clean:clean': clean,
      'requirements:cleanCache:cleanCache': cleanCache
    };
  }
}

module.exports = ServerlessPythonRequirements;
<|endoftext|>