<commit_before>var config = require("./config"),
    kefir = require("kefir"),
    Twitter = require("twitter"),
    twitter = new Twitter(config.oauth);

function handleError (error) {
    console.error(error);
}

function unique(array) {
    var unique = [];

    array.forEach(index => {
        if (unique.indexOf(index) === -1) {
            unique.push(index);
        }
    });

    return unique;
}

var api = {
	search: function (params) {
        return kefir
            .fromNodeCallback(done => {
                twitter.get("search/tweets", params, done);
            })
            .onError(handleError)
            .map(result => {
                return result.statuses
            });
    },

	retweet: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post(`statuses/retweet/${id}`, {id: id}, done)
            })
            .onError(handleError);
	},

	favorite: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("favorites/create", {id: id}, done)
            })
            .onError(handleError);
	},

	follow: function (screenName) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("friendships/create", { "screen_name": screenName}, done)
            })
            .onError(handleError);
	},

    unFollow: function (userId) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("friendships/destroy", { "user_id": userId }, done)
            })
            .onError(handleError);
    },

	getBlockedUsers: function () {
        return kefir
            .fromNodeCallback(done => {
                return twitter.get("blocks/list", done);
            })
            .onError(handleError)
            .map(result => {
                return result.users;
            });
	},

    getFriends: function(cursor, friends) {
        var csr = cursor || -1,
            friendNames = friends || [];

        return kefir
            .fromNodeCallback(done => {
                return twitter.get("friends/list", {cursor: csr, count: 200}, done);
            })
            .onError(handleError)
            .flatMap(results => {
                friendNames = unique(friendIds.concat(results.users.map(user => {
                    return user.screen_name;
                })));

                if (results.next_cursor === 0) {
                    return kefir.constant(friendNames);
                } else {
                    return api.getFriends(results.next_cursor, friendNames);
                }
            })
    },

    lookup: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.get("statuses/lookup", {id: id}, done);
            })
            .onError(handleError)
    },

    tweetStream: function (track) {
        return kefir.stream(emitter => {
            twitter.stream("statuses/filter", {track: track}, stream => {
                stream.on("data", tweet => {
                    emitter.emit(tweet)
                });

                stream.on("error", error => {
                    emitter.error(error);
                })
            })
        })
        .onError(handleError);
    }
};

module.exports = api;
<commit_msg>fix typo<commit_after>var config = require("./config"),
    kefir = require("kefir"),
    Twitter = require("twitter"),
    twitter = new Twitter(config.oauth);

function handleError (error) {
    console.error(error);
}

function unique(array) {
    var unique = [];

    array.forEach(index => {
        if (unique.indexOf(index) === -1) {
            unique.push(index);
        }
    });

    return unique;
}

var api = {
	search: function (params) {
        return kefir
            .fromNodeCallback(done => {
                twitter.get("search/tweets", params, done);
            })
            .onError(handleError)
            .map(result => {
                return result.statuses
            });
    },

	retweet: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post(`statuses/retweet/${id}`, {id: id}, done)
            })
            .onError(handleError);
	},

	favorite: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("favorites/create", {id: id}, done)
            })
            .onError(handleError);
	},

	follow: function (screenName) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("friendships/create", { "screen_name": screenName}, done)
            })
            .onError(handleError);
	},

    unFollow: function (userId) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.post("friendships/destroy", { "user_id": userId }, done)
            })
            .onError(handleError);
    },

	getBlockedUsers: function () {
        return kefir
            .fromNodeCallback(done => {
                return twitter.get("blocks/list", done);
            })
            .onError(handleError)
            .map(result => {
                return result.users;
            });
	},

    getFriends: function(cursor, friends) {
        var csr = cursor || -1,
            friendNames = friends || [];

        return kefir
            .fromNodeCallback(done => {
                return twitter.get("friends/list", {cursor: csr, count: 200}, done);
            })
            .onError(handleError)
            .flatMap(results => {
                friendNames = unique(friendNames.concat(results.users.map(user => {
                    return user.screen_name;
                })));

                if (results.next_cursor === 0) {
                    return kefir.constant(friendNames);
                } else {
                    return api.getFriends(results.next_cursor, friendNames);
                }
            })
    },

    lookup: function (id) {
        return kefir
            .fromNodeCallback(done => {
                return twitter.get("statuses/lookup", {id: id}, done);
            })
            .onError(handleError)
    },

    tweetStream: function (track) {
        return kefir.stream(emitter => {
            twitter.stream("statuses/filter", {track: track}, stream => {
                stream.on("data", tweet => {
                    emitter.emit(tweet)
                });

                stream.on("error", error => {
                    emitter.error(error);
                })
            })
        })
        .onError(handleError);
    }
};

module.exports = api;
<|endoftext|>


<commit_before>var _ = require('lazy.js');
var lodash = require('lodash');
var blessed = require('blessed');
var Promise = require('bluebird');
var path = require('path');
var clap = require('node-clap');
var mkdirp = Promise.promisify(require('mkdirp'));

var util = require('slap-util');

var BaseWidget = require('base-widget');
var Editor = require('editor-widget');

function Slap (opts) {
  var self = this;

  if (!(self instanceof Slap)) return new Slap(opts);

  if (!Slap.global) Slap.global = this;
  if (opts.screen && !opts.screen.slap) opts.screen.slap = self;
  BaseWidget.call(self, opts);

  self.panes = [];

  self.header = new Header({parent: self});

  self.fileBrowser = new FileBrowser({
    parent: self,
    top:    self.header.options.headerPosition === 'top'    ? 1 : 0,
    bottom: self.header.options.headerPosition === 'bottom' ? 1 : 0,
    left: 0,
  });
  self.fileBrowser.focus();
}
Slap.global = null;
Slap.prototype.__proto__ = BaseWidget.prototype;

Slap.prototype.paneForPath = function (panePath) {
  var self = this;
  var pane;
  panePath = util.resolvePath(panePath);
  self.panes.some(function (openPane) {
    if (openPane.editor.textBuf.getPath() === panePath) {
      pane = openPane;
      return true;
    }
  });
  return pane;
};
Slap.prototype.open = Promise.method(function (filePath, current) {
  var self = this;

  var pane = self.paneForPath(filePath);
  pane = pane || new Pane({parent: self});
  return pane.editor.open(filePath)
    .then(function () {
      if (current) pane.setCurrent();
      return pane;
    })
    .catch(function (err) {
      pane.close();
      switch ((err.cause || err).code) {
        case 'EACCES':
          self.header.message(err.message, 'error');
          break;
        case 'EISDIR':
          self.fileBrowser.refresh(filePath, _.noop);
          self.fileBrowser.focus();
          break;
        default: throw err;
      }
    });
});

Slap.prototype.quit = function () {
  var self = this;
  var quit = Promise.resolve();

  if (Editor.highlightClient) quit = quit
    .return(Editor.highlightClient)
    .then(function (client) {
      if (!client) return;
      client.dontRespawn = true;
      self.panes.forEach(function (pane) { pane.editor.detach(); });
    });

  quit
    .delay(20) // FIXME: .delay(20) hack for I/O flush
    .then(function () { process.exit(0); })
    .done();

  // this.program.input.removeAllListeners();

  return this;
};
Slap.prototype.help = function () {
  return this
    .open(path.join(__dirname, '../../slap.ini'), true)
    .tap(function (pane) { pane.editor.readOnly(true); });
};

Slap.prototype._stopKeyPropagation = function () {
  // FIXME: ugly hack to stop enter from last keypress from propagating too far
  var self = this;
  self.lockKeys = true;
  return Promise.delay(0).then(function () { self.lockKeys = false; });
};

Slap.prototype._initHandlers = function () {
  var self = this;

  self.on('element keypress', function (el, ch, key) {
    var binding = self.resolveBinding(key);

    var logLine = "keypress " + key.full;
    if (key.full !== key.sequence) logLine += " [raw: " + JSON.stringify(key.sequence) + "]";
    var focused = {parent: self.screen.focused}, focusedBinding;
    while ((focused = focused.parent) && !(focusedBinding = BaseWidget.prototype.resolveBinding.call(focused, key)));
    if (focusedBinding) logLine += " (bound to "+focusedBinding+" on "+util.typeOf(focused) + ")";
    util.logger.silly(logLine);

    switch (binding) {
      case 'new': new Pane({parent: self}).setCurrent(); return false;
      case 'open':
        if (!self.fileBrowser.visible) {
          self.fileBrowser.show();
          self.panes.forEach(function (pane) {
            pane.left = self.fileBrowser.width;
            pane.editor._updateContent();
          });
        }
        self.fileBrowser.focus();
        return false;
      case 'nextPane': self.panes[util.mod(self.data.currentPane + 1, self.panes.length)].setCurrent(); return false;
      case 'prevPane': self.panes[util.mod(self.data.currentPane - 1, self.panes.length)].setCurrent(); return false;
      case 'toggleFileBrowser':
        self.fileBrowser.toggle();
        self.panes.forEach(function (pane) {
          pane.left = self.fileBrowser.visible ? self.fileBrowser.width : 0;
          pane.editor._updateContent();
        });
        return false;
      case 'toggleInsertMode': self.toggleInsertMode(); return false;
      case 'quit':
        if (!self._panesBlockingQuit) {
          var currentPane = self.panes[self.data.currentPane];
          if (currentPane) currentPane.requestClose(); // ensures self.panes[0] doesn't steal focus
          self._panesBlockingQuit = self.panes.slice().filter(function (pane) {
            if (!pane.requestClose()) {
              pane.once('close', function () {
                if (self._panesBlockingQuit) {
                  var paneIndex = self._panesBlockingQuit.indexOf(pane);
                  self._panesBlockingQuit.splice(paneIndex, 1);
                  if (self._panesBlockingQuit.length) {
                    self.panes[self.data.currentPane].saveAsCloseForm.show();
                  } else {
                    self.quit();
                  }
                }
              });
              pane.saveAsCloseForm.once('cancel', function () {
                self._panesBlockingQuit.forEach(function (blockingPane) { blockingPane.saveAsCloseForm.hide(); });
                self._panesBlockingQuit = null;
              });
              return true;
            }
          });
          var numPanesBlockingQuit = self._panesBlockingQuit.length;
          if (numPanesBlockingQuit > 1) {
            self.header.message(numPanesBlockingQuit + " unsaved file" + (numPanesBlockingQuit !== 1 ? "s" : "") + ", please save or discard", 'warning');
          } else if (!numPanesBlockingQuit) {
            self.quit();
          }
        }
        return false;
      case 'help': self.help(); return false;
    }
  });

  self.on('mouse', function (mouseData) { util.logger.silly("mouse", mouseData); });

  ['element blur', 'element focus'].forEach(function (evt) {
    self.on(evt, function (el) {
      if (el._updateCursor) el._updateCursor();
    });
  });

  self.on('element show', function (el) { if (el instanceof Pane) self.header.render(); });

  ['resize', 'element focus'].forEach(function (evt) {
    self.on(evt, function () { self.render(); });
  });

  return self._initPlugins().then(function () {
    return BaseWidget.prototype._initHandlers.apply(self, arguments);
  });
};

Slap.prototype._initPlugins = function () {
  var self = this;

  return Slap.getUserDir().then(function (userDir) {
      return clap({
        val: self,
        module: require.main,
        keyword: 'slap-plugin',
        paths: [path.join(userDir, 'plugins')]
      });
    })
    .map(function (obj) {
      return obj.promise
        .then(function () { util.logger.info("loaded plugin "+obj.plugin); })
        .catch(function (err) { util.logger.error("failed loading plugin "+obj.plugin+": "+(err.stack || err)); });
    });
};

Slap.getUserDir = function () {
  var userDir = util.resolvePath('~/.' + require('../../package').name);
  return mkdirp(userDir).return(userDir);
};

module.exports = Slap;

// circular imports
var Header = require('./Header');
var FileBrowser = require('./FileBrowser');
var Pane = require('./Pane');
<commit_msg>fix(plugins): init plugins after ready<commit_after>var _ = require('lazy.js');
var lodash = require('lodash');
var blessed = require('blessed');
var Promise = require('bluebird');
var path = require('path');
var clap = require('node-clap');
var mkdirp = Promise.promisify(require('mkdirp'));

var util = require('slap-util');

var BaseWidget = require('base-widget');
var Editor = require('editor-widget');

function Slap (opts) {
  var self = this;

  if (!(self instanceof Slap)) return new Slap(opts);

  if (!Slap.global) Slap.global = this;
  if (opts.screen && !opts.screen.slap) opts.screen.slap = self;
  BaseWidget.call(self, opts);

  self.panes = [];

  self.header = new Header({parent: self});

  self.fileBrowser = new FileBrowser({
    parent: self,
    top:    self.header.options.headerPosition === 'top'    ? 1 : 0,
    bottom: self.header.options.headerPosition === 'bottom' ? 1 : 0,
    left: 0,
  });
  self.fileBrowser.focus();
}
Slap.global = null;
Slap.prototype.__proto__ = BaseWidget.prototype;

Slap.prototype.paneForPath = function (panePath) {
  var self = this;
  var pane;
  panePath = util.resolvePath(panePath);
  self.panes.some(function (openPane) {
    if (openPane.editor.textBuf.getPath() === panePath) {
      pane = openPane;
      return true;
    }
  });
  return pane;
};
Slap.prototype.open = Promise.method(function (filePath, current) {
  var self = this;

  var pane = self.paneForPath(filePath);
  pane = pane || new Pane({parent: self});
  return pane.editor.open(filePath)
    .then(function () {
      if (current) pane.setCurrent();
      return pane;
    })
    .catch(function (err) {
      pane.close();
      switch ((err.cause || err).code) {
        case 'EACCES':
          self.header.message(err.message, 'error');
          break;
        case 'EISDIR':
          self.fileBrowser.refresh(filePath, _.noop);
          self.fileBrowser.focus();
          break;
        default: throw err;
      }
    });
});

Slap.prototype.quit = function () {
  var self = this;
  var quit = Promise.resolve();

  if (Editor.highlightClient) quit = quit
    .return(Editor.highlightClient)
    .then(function (client) {
      if (!client) return;
      client.dontRespawn = true;
      self.panes.forEach(function (pane) { pane.editor.detach(); });
    });

  quit
    .delay(20) // FIXME: .delay(20) hack for I/O flush
    .then(function () { process.exit(0); })
    .done();

  // this.program.input.removeAllListeners();

  return this;
};
Slap.prototype.help = function () {
  return this
    .open(path.join(__dirname, '../../slap.ini'), true)
    .tap(function (pane) { pane.editor.readOnly(true); });
};

Slap.prototype._stopKeyPropagation = function () {
  // FIXME: ugly hack to stop enter from last keypress from propagating too far
  var self = this;
  self.lockKeys = true;
  return Promise.delay(0).then(function () { self.lockKeys = false; });
};

Slap.prototype._initHandlers = function () {
  var self = this;

  self.on('element keypress', function (el, ch, key) {
    var binding = self.resolveBinding(key);

    var logLine = "keypress " + key.full;
    if (key.full !== key.sequence) logLine += " [raw: " + JSON.stringify(key.sequence) + "]";
    var focused = {parent: self.screen.focused}, focusedBinding;
    while ((focused = focused.parent) && !(focusedBinding = BaseWidget.prototype.resolveBinding.call(focused, key)));
    if (focusedBinding) logLine += " (bound to "+focusedBinding+" on "+util.typeOf(focused) + ")";
    util.logger.silly(logLine);

    switch (binding) {
      case 'new': new Pane({parent: self}).setCurrent(); return false;
      case 'open':
        if (!self.fileBrowser.visible) {
          self.fileBrowser.show();
          self.panes.forEach(function (pane) {
            pane.left = self.fileBrowser.width;
            pane.editor._updateContent();
          });
        }
        self.fileBrowser.focus();
        return false;
      case 'nextPane': self.panes[util.mod(self.data.currentPane + 1, self.panes.length)].setCurrent(); return false;
      case 'prevPane': self.panes[util.mod(self.data.currentPane - 1, self.panes.length)].setCurrent(); return false;
      case 'toggleFileBrowser':
        self.fileBrowser.toggle();
        self.panes.forEach(function (pane) {
          pane.left = self.fileBrowser.visible ? self.fileBrowser.width : 0;
          pane.editor._updateContent();
        });
        return false;
      case 'toggleInsertMode': self.toggleInsertMode(); return false;
      case 'quit':
        if (!self._panesBlockingQuit) {
          var currentPane = self.panes[self.data.currentPane];
          if (currentPane) currentPane.requestClose(); // ensures self.panes[0] doesn't steal focus
          self._panesBlockingQuit = self.panes.slice().filter(function (pane) {
            if (!pane.requestClose()) {
              pane.once('close', function () {
                if (self._panesBlockingQuit) {
                  var paneIndex = self._panesBlockingQuit.indexOf(pane);
                  self._panesBlockingQuit.splice(paneIndex, 1);
                  if (self._panesBlockingQuit.length) {
                    self.panes[self.data.currentPane].saveAsCloseForm.show();
                  } else {
                    self.quit();
                  }
                }
              });
              pane.saveAsCloseForm.once('cancel', function () {
                self._panesBlockingQuit.forEach(function (blockingPane) { blockingPane.saveAsCloseForm.hide(); });
                self._panesBlockingQuit = null;
              });
              return true;
            }
          });
          var numPanesBlockingQuit = self._panesBlockingQuit.length;
          if (numPanesBlockingQuit > 1) {
            self.header.message(numPanesBlockingQuit + " unsaved file" + (numPanesBlockingQuit !== 1 ? "s" : "") + ", please save or discard", 'warning');
          } else if (!numPanesBlockingQuit) {
            self.quit();
          }
        }
        return false;
      case 'help': self.help(); return false;
    }
  });

  self.on('mouse', function (mouseData) { util.logger.silly("mouse", mouseData); });

  ['element blur', 'element focus'].forEach(function (evt) {
    self.on(evt, function (el) {
      if (el._updateCursor) el._updateCursor();
    });
  });

  self.on('element show', function (el) { if (el instanceof Pane) self.header.render(); });

  ['resize', 'element focus'].forEach(function (evt) {
    self.on(evt, function () { self.render(); });
  });

  self.ready.call('_initPlugins').done();

  return BaseWidget.prototype._initHandlers.apply(self, arguments);
};

Slap.prototype._initPlugins = function () {
  var self = this;

  return Slap.getUserDir().then(function (userDir) {
      return clap({
        val: self,
        module: require.main,
        keyword: 'slap-plugin',
        paths: [path.join(userDir, 'plugins')]
      });
    })
    .map(function (obj) {
      return obj.promise
        .then(function () { util.logger.info("loaded plugin "+obj.plugin); })
        .catch(function (err) { util.logger.error("failed loading plugin "+obj.plugin+": "+(err.stack || err)); });
    });
};

Slap.getUserDir = function () {
  var userDir = util.resolvePath('~/.' + require('../../package').name);
  return mkdirp(userDir).return(userDir);
};

module.exports = Slap;

// circular imports
var Header = require('./Header');
var FileBrowser = require('./FileBrowser');
var Pane = require('./Pane');
<|endoftext|>


<commit_before>var templates = require('duality/templates'),
    events = require('duality/events'),
    dutils = require('duality/utils'),
    ksutils = require('./utils'),
    utils = require('kujua-utils'),
    appinfo = require('./appinfo'),
    _ = require('underscore'),
    schema = require('lib/schema'),
    moment = require('moment');

exports.patient = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The patient's data has been saved"
        }));

        utils.updateTopNav('patient', "Patient");

        var alpaca_options = {
            "schemaSource": "patient.json",
            "optionsSource": "patient.json",
            "postRender": function() {
                $("#patient #patient-form #form").show()
                $('#loader').hide();
            },
            "ui": "bootstrap"
        }

        //console.log(doc)
        alpaca_options.data = doc
        $("#patient #patient-form #form").alpaca(alpaca_options).hide();
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the patient's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/patient.json",
            collection: "patients",
            date_created: new Date().toISOString(),
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    var date_fields= Array()

    var form = _.chain(req.form)
                .map(function (value, key) { return {value: value, key: key} })
                .filter(function (item) { return (item.value !== "") && (item.key != "_submit") && (doc[item.key] != item.value) })
                .value()

    submitted_date_fields = _.chain(form)
                             .filter(function (item) { return ((item.key.indexOf("date_") == 0) || (item.key.indexOf("current_") == 0))})
                             .value()

    _.each(form, function (item) { // copy to doc submitted value from form at same key except date fields (date_ or current_)
        if (!(_.contains(_.pluck(submitted_date_fields, "key"), item.key))) doc[item.key] = item.value
    })

    submitted_dates = _.chain(submitted_date_fields)
                       .reduce(function (memo, item) {
                           var m = {}, n = {}
                           n[item.key.split("_")[0]] = item.key
                           if (memo[item.key.split("_")[1]]) {
                               m = _.extend(memo[item.key.split("_")[1]], n)
                           } else {
                               m[item.key.split("_")[1]] = n
                           }
                           return _.extend(memo,  m)
                       }, {})
                       .value()

    // get date fields from the patient schema that relate to submitted date fields
    schema_date_fields = _.chain(schema.load('forms/schema/patient').properties)
                          .map(function (value, key) { return {value: value, key: key}})
                          .filter(function (item) {
                              return (_.contains(_.keys(submitted_dates), item.key.split("_")[1]))
                          })
                          .value()

    schema_date_periods = _.chain(schema_date_fields)
                           .reduce(function (memo, item) {
                               var m = {}, n = {}
                               if (item.key.split("_")[0] === "current") {
                                   n[item.key.split("_")[2]] = item.key
                                   if (memo[item.key.split("_")[1]]) {
                                       m = _.extend(memo[item.key.split("_")[1]], n)
                                   } else {
                                       m[item.key.split("_")[1]] = n
                                   }
                                   memo = _.extend(memo, m)
                               }
                               return memo
                           }, {})
                           .value()

  	// update and schedule date variables

    _.each(submitted_dates, function (value, key){
        if (value.date) {
            var date = _.chain(form).reduce(function(o, i) { o[i.key] = i.value; return o }, {}).value()[value.date]

            _.chain(schema_date_periods[key])
             .map(function (value, key) { return {value: value, key: key}})
             .each(function (item) {
                 doc = ksutils.updateCurrent(doc, "patients", date, item.value.split("_")[1], item.key)
             })

            doc["date_" + key] = date

        } else if (value.current) {
            var current = _.chain(form).reduce(function(o, i) { o[i.key] = i.value; return o }, {}).value()[value.current]
            doc = ksutils.updateDate(doc, "patients", current, value.current.split("_")[1], value.current.split("_")[2])

            _.chain(schema_date_periods[key])
             .map(function (value, key) { return {value: value, key: key}})
             .each(function (item) {
                 var date = doc["date_" + item.value.split("_")[1]]
                 doc = ksutils.updateCurrent(doc, "patients", date, item.value.split("_")[1], item.key)
             })
       }
    })

    var submit = req.form._submit

    if (submit == "save_visit") {
        return [doc, dutils.redirect(req, '/visit/' + doc._id)];
    } else {
        return [doc, dutils.redirect(req, '/patient/' + doc._id + '?reload=true')];
    }
};

exports.visit = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The visit's data has been saved"
        }));
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the visit's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/visit.json",
            collection: "visits",
            date_created: new Date().toISOString(),
            patient_id: req.query.patient_id
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    var db = require('db').use(ksutils.getDBName())

    db.getDoc(req.query.patient_id, function(err, data) { // include current patient data inside the visit object.
        doc.patient = data
    })

    var formdata = JSON.parse(req.form._formdata)
    for (var k in formdata) {
//        console.log("k:" + k + "/ formdata[k]:" + formdata[k])
        if (k != "_formdata" && formdata[k] != "-1" && formdata[k] != [] && k.indexOf("subforms_") == -1) {
            if (k == "subforms") {
                for (var l in formdata[k]) {
                    if (typeof formdata[k][l] === "object") {
                        for (var m in formdata[k][l]) {
//                            console.log("k:" + k + " / l:" + l + " / m:" + m + " / formdata[k][l][m]:" + formdata[k][l][m])
                            if (formdata[k][l][m] != -1 && formdata[k][l][m].length != 0) { // skip empty number fields and empty multiples/arrays
                                if (typeof doc[k] === "undefined") doc[k] = formdata[k]
                                if (typeof doc[k][l] === "undefined") doc[k][l] = formdata[k][l]
                                doc[k][l][m] = formdata[k][l][m]
                            }
                        }
                    } else {
                        doc[k][l] = formdata[k][l]
                    }
                }
            } else {
                doc[k] = formdata[k] // copy to doc submitted value from form at same key.
            }
        }
    }

	// update and schedule date variables
    _.each(doc, function (e, k) {
        if (k.indexOf('current_') == 0) {
            doc = ksutils.updateDate(doc, k.split("_")[1], k.split("_")[2])
        }
    })

  //redirects to visits
    return [doc, dutils.redirect(req, '/visits')];

};

exports.report = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The report's data has been saved"
        }));
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the report's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/report.json",
            collection: "reports",
            date_created: new Date().toISOString()
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    console.log(req)

    for (var k in req.form) { // copy to doc submitted value from form at same key.
        if (k != "_submit") { // except special hidden field _submit holding clicked submit button value.
            doc[k] = req.form[k]
        }
    }

    var submit = req.form._submit

    if (submit == "save_approve") {
      doc.status="Approved"
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    } else if (submit == "unapprove") {
      doc.status="Unapproved"
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    } else {
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    }

};

exports.schedule = function(doc,req) {
	return [doc, null]
}<commit_msg>Trying to show spinner when loading visit form. Doesnt work<commit_after>var templates = require('duality/templates'),
    events = require('duality/events'),
    dutils = require('duality/utils'),
    ksutils = require('./utils'),
    utils = require('kujua-utils'),
    appinfo = require('./appinfo'),
    _ = require('underscore'),
    schema = require('lib/schema'),
    moment = require('moment');

exports.patient = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The patient's data has been saved"
        }));

        utils.updateTopNav('patient', "Patient");

        var alpaca_options = {
            "schemaSource": "patient.json",
            "optionsSource": "patient.json",
            "postRender": function() {
                $("#patient #patient-form #form").show()
                $('#loader').hide();
            },
            "ui": "bootstrap"
        }

        //console.log(doc)
        alpaca_options.data = doc
        $("#patient #patient-form #form").alpaca(alpaca_options).hide();
        $('#loader').show();
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the patient's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/patient.json",
            collection: "patients",
            date_created: new Date().toISOString(),
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    var date_fields= Array()

    var form = _.chain(req.form)
                .map(function (value, key) { return {value: value, key: key} })
                .filter(function (item) { return (item.value !== "") && (item.key != "_submit") && (doc[item.key] != item.value) })
                .value()

    submitted_date_fields = _.chain(form)
                             .filter(function (item) { return ((item.key.indexOf("date_") == 0) || (item.key.indexOf("current_") == 0))})
                             .value()

    _.each(form, function (item) { // copy to doc submitted value from form at same key except date fields (date_ or current_)
        if (!(_.contains(_.pluck(submitted_date_fields, "key"), item.key))) doc[item.key] = item.value
    })

    submitted_dates = _.chain(submitted_date_fields)
                       .reduce(function (memo, item) {
                           var m = {}, n = {}
                           n[item.key.split("_")[0]] = item.key
                           if (memo[item.key.split("_")[1]]) {
                               m = _.extend(memo[item.key.split("_")[1]], n)
                           } else {
                               m[item.key.split("_")[1]] = n
                           }
                           return _.extend(memo,  m)
                       }, {})
                       .value()

    // get date fields from the patient schema that relate to submitted date fields
    schema_date_fields = _.chain(schema.load('forms/schema/patient').properties)
                          .map(function (value, key) { return {value: value, key: key}})
                          .filter(function (item) {
                              return (_.contains(_.keys(submitted_dates), item.key.split("_")[1]))
                          })
                          .value()

    schema_date_periods = _.chain(schema_date_fields)
                           .reduce(function (memo, item) {
                               var m = {}, n = {}
                               if (item.key.split("_")[0] === "current") {
                                   n[item.key.split("_")[2]] = item.key
                                   if (memo[item.key.split("_")[1]]) {
                                       m = _.extend(memo[item.key.split("_")[1]], n)
                                   } else {
                                       m[item.key.split("_")[1]] = n
                                   }
                                   memo = _.extend(memo, m)
                               }
                               return memo
                           }, {})
                           .value()

  	// update and schedule date variables

    _.each(submitted_dates, function (value, key){
        if (value.date) {
            var date = _.chain(form).reduce(function(o, i) { o[i.key] = i.value; return o }, {}).value()[value.date]

            _.chain(schema_date_periods[key])
             .map(function (value, key) { return {value: value, key: key}})
             .each(function (item) {
                 doc = ksutils.updateCurrent(doc, "patients", date, item.value.split("_")[1], item.key)
             })

            doc["date_" + key] = date

        } else if (value.current) {
            var current = _.chain(form).reduce(function(o, i) { o[i.key] = i.value; return o }, {}).value()[value.current]
            doc = ksutils.updateDate(doc, "patients", current, value.current.split("_")[1], value.current.split("_")[2])

            _.chain(schema_date_periods[key])
             .map(function (value, key) { return {value: value, key: key}})
             .each(function (item) {
                 var date = doc["date_" + item.value.split("_")[1]]
                 doc = ksutils.updateCurrent(doc, "patients", date, item.value.split("_")[1], item.key)
             })
       }
    })

    var submit = req.form._submit

    if (submit == "save_visit") {
        return [doc, dutils.redirect(req, '/visit/' + doc._id)];
    } else {
        return [doc, dutils.redirect(req, '/patient/' + doc._id + '?reload=true')];
    }
};

exports.visit = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The visit's data has been saved"
        }));
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the visit's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/visit.json",
            collection: "visits",
            date_created: new Date().toISOString(),
            patient_id: req.query.patient_id
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    var db = require('db').use(ksutils.getDBName())

    db.getDoc(req.query.patient_id, function(err, data) { // include current patient data inside the visit object.
        doc.patient = data
    })

    var formdata = JSON.parse(req.form._formdata)
    for (var k in formdata) {
//        console.log("k:" + k + "/ formdata[k]:" + formdata[k])
        if (k != "_formdata" && formdata[k] != "-1" && formdata[k] != [] && k.indexOf("subforms_") == -1) {
            if (k == "subforms") {
                for (var l in formdata[k]) {
                    if (typeof formdata[k][l] === "object") {
                        for (var m in formdata[k][l]) {
//                            console.log("k:" + k + " / l:" + l + " / m:" + m + " / formdata[k][l][m]:" + formdata[k][l][m])
                            if (formdata[k][l][m] != -1 && formdata[k][l][m].length != 0) { // skip empty number fields and empty multiples/arrays
                                if (typeof doc[k] === "undefined") doc[k] = formdata[k]
                                if (typeof doc[k][l] === "undefined") doc[k][l] = formdata[k][l]
                                doc[k][l][m] = formdata[k][l][m]
                            }
                        }
                    } else {
                        doc[k][l] = formdata[k][l]
                    }
                }
            } else {
                doc[k] = formdata[k] // copy to doc submitted value from form at same key.
            }
        }
    }

	// update and schedule date variables
    _.each(doc, function (e, k) {
        if (k.indexOf('current_') == 0) {
            doc = ksutils.updateDate(doc, k.split("_")[1], k.split("_")[2])
        }
    })

  //redirects to visits
    return [doc, dutils.redirect(req, '/visits')];

};

exports.report = function(doc, req) {
    events.once('afterResponse', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "success",
            body: "The report's data has been saved"
        }));
    })

    events.once('updateFailure', function() {
        $('.page-header .alerts').html(templates.render('alert.html', {}, {
            type: "warning",
            body: "Error when attempting to save the report's data"
        }));
    })

    if (!doc) {
        doc = {
            _id: req.uuid,
            class: "entry",
            schema: "http://ltfhc.iilab.org/schema/0.4.0/report.json",
            collection: "reports",
            date_created: new Date().toISOString()
        }
    } else {
        doc.date_updated = new Date().toISOString();
    }

    console.log(req)

    for (var k in req.form) { // copy to doc submitted value from form at same key.
        if (k != "_submit") { // except special hidden field _submit holding clicked submit button value.
            doc[k] = req.form[k]
        }
    }

    var submit = req.form._submit

    if (submit == "save_approve") {
      doc.status="Approved"
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    } else if (submit == "unapprove") {
      doc.status="Unapproved"
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    } else {
      return [doc, dutils.redirect(req, '/reports')] //'/' + doc._id)];
    }

};

exports.schedule = function(doc,req) {
	return [doc, null]
}<|endoftext|>


<commit_before>"use strict";

module.exports = {
  center: center,
  parseMonth: parseMonth,
  parseYear: parseYear,
  buildMonth: buildMonth,
  buildYear: buildYear,
  leapCheck: leapCheck
};

const environment = process.platform;
const zellers = require("./zellers");
const months = [
  ["jan", "January", 31],
  ["feb", "February"],
  ["mar", "March", 31],
  ["apr", "April", 30],
  ["may", "May", 31],
  ["jun", "June", 30],
  ["jul", "July", 31],
  ["aug", "August", 31],
  ["sep", "September", 30],
  ["oct", "October", 31],
  ["nov", "November", 30],
  ["dec", "December", 31]
];

function center(calWidth, first, second) {
  let header = first.toString();
  if(second) {
    header += " " + second;
  }
  const headPadding = Math.floor((calWidth - header.length)/2);
  const fullHeadLength = headPadding + header.length;
  while(header.length < fullHeadLength) {
    header = " " + header;
  }
  return header;
}

function parseMonth(month) {
  if(isNaN(month)) {
    for(let i = 0; i < months.length; ++i) {
      if(month.toLowerCase().indexOf(months[i][0]) !== -1){
        return i;
      }
    }
  } else if(month > 12 && month > 0) {
  } else {
    return month - 1;
  }
  throw new RangeError(`cal: ${month} is neither a month number (1-12) nor name`);
}

function parseYear(year) {
  if(year > 1752 && year < 10000) {
    return year;
  } else {
    throw new RangeError(`cal: year ${year} not in range 1753-9999`);
  }
}

function buildMonth(month, year, isYear, testEnv) {
  let highlight = false;
  let date;
  let today;
  let thisMonth;
  let thisYear;
  if(environment != "darwin" || testEnv) {
    date = new Date();
    today = date.getDate();
    thisMonth = date.getMonth();
    thisYear = date.getFullYear();
    if(month === thisMonth && year === thisYear) {
      highlight = true;
    }
  }
  const startDay = zellers.getDay(year, month + 1, 1);
  let header;
  if(isYear) {
    header = center(20, months[month][1]);
  } else {
    header = center(20, months[month][1], year);
  }
  let calendar = [header, "Su Mo Tu We Th Fr Sa"];
  let lastDay;
  if(month === 1) {
    lastDay = leapCheck(year);
  } else {
    lastDay = months[month][2];
  }
  let line = "";
  let day = 1;
  constructor();
  function constructor() {
    for(let i = 0; i < 7; ++i) {
      if(i !== 0) {
        line += " ";
      }
      if(calendar.length === 2 && i < startDay) {
        line += "  ";
      } else {
        if(day < 10) {
          if(highlight && today === day) {
            line += "_\b " + "_\b" + day;
          } else {
            line += " " + day;
          }
        } else {
          if(highlight && today === day) {
            line += "_\b" + day[0] + "_\b" + day[1];
          } else {
            line += day;
          }
        }
        ++day;
        if(day > lastDay) {
          return;
        }
      }
    }
    calendar[calendar.length] = line;
    line = "";
    constructor();
  }
  calendar[calendar.length] = line;
  while(calendar.length < 8) {
    calendar[calendar.length] = "";
  }
  if((environment != "darwin" && !testEnv) || isYear) {
    calendar.forEach((item, i) => {
      if(item.length === 22) {
        item += "  ";
      }
      while(item.length < 22) {
        item += " ";
      }
      calendar[i] = item;
    });
  }
  return calendar;
}

function buildYear(year, testEnv) {
  let calendar = [];
  let monthsArr = [];
  for(let i = 0; i < 12; ++i) {
    monthsArr[monthsArr.length] = buildMonth(i, year, true);
  }
  let rowOffset = 0;
  for(let monthOffset = 0; monthOffset < 12; monthOffset += 3, rowOffset += 8) {
    for(let calRow = 0; calRow < 8; ++calRow) {
      for(let monthCal = 0; monthCal < 3; ++monthCal) {
        const rowIndex = calRow + rowOffset;
        const monthIndex = monthCal + monthOffset;
        if(!calendar[rowIndex]) {
          calendar[rowIndex] = "";
        }
        if(((environment === "darwin" && !testEnv) || (environment != "darwin" && testEnv)) && monthCal === 2) {
          monthsArr[monthIndex][calRow] = monthsArr[monthIndex][calRow].trimRight();
        }
        calendar[rowIndex] += monthsArr[monthIndex][calRow];
      }
    }
  }
  if((environment === "darwin" && !testEnv) || (environment != "darwin" && testEnv)) {
    calendar.unshift("");
    calendar.unshift(center(62, year));
  } else {
    for(let i = 24; i > 0; i-=8) {
      calendar.splice(i, 0, "");
    }
    calendar.unshift(center(61, year));
  }
  return calendar;
}

function leapCheck(year) {
  if(year % 4 === 0) {
    if(year % 100 === 0) {
      if(year % 400 === 0) {
        return 29;
      }
      return 28;
    }
    return 29;
  } else {
    return 28;
  }
}
<commit_msg>Changed test to look for the highlight characters themselves instead of the length<commit_after>"use strict";

module.exports = {
  center: center,
  parseMonth: parseMonth,
  parseYear: parseYear,
  buildMonth: buildMonth,
  buildYear: buildYear,
  leapCheck: leapCheck
};

const environment = process.platform;
const zellers = require("./zellers");
const months = [
  ["jan", "January", 31],
  ["feb", "February"],
  ["mar", "March", 31],
  ["apr", "April", 30],
  ["may", "May", 31],
  ["jun", "June", 30],
  ["jul", "July", 31],
  ["aug", "August", 31],
  ["sep", "September", 30],
  ["oct", "October", 31],
  ["nov", "November", 30],
  ["dec", "December", 31]
];

function center(calWidth, first, second) {
  let header = first.toString();
  if(second) {
    header += " " + second;
  }
  const headPadding = Math.floor((calWidth - header.length)/2);
  const fullHeadLength = headPadding + header.length;
  while(header.length < fullHeadLength) {
    header = " " + header;
  }
  return header;
}

function parseMonth(month) {
  if(isNaN(month)) {
    for(let i = 0; i < months.length; ++i) {
      if(month.toLowerCase().indexOf(months[i][0]) !== -1){
        return i;
      }
    }
  } else if(month > 12 && month > 0) {
  } else {
    return month - 1;
  }
  throw new RangeError(`cal: ${month} is neither a month number (1-12) nor name`);
}

function parseYear(year) {
  if(year > 1752 && year < 10000) {
    return year;
  } else {
    throw new RangeError(`cal: year ${year} not in range 1753-9999`);
  }
}

function buildMonth(month, year, isYear, testEnv) {
  let highlight = false;
  let date;
  let today;
  let thisMonth;
  let thisYear;
  if(environment != "darwin" || testEnv) {
    date = new Date();
    today = date.getDate();
    thisMonth = date.getMonth();
    thisYear = date.getFullYear();
    if(month === thisMonth && year === thisYear) {
      highlight = true;
    }
  }
  const startDay = zellers.getDay(year, month + 1, 1);
  let header;
  if(isYear) {
    header = center(20, months[month][1]);
  } else {
    header = center(20, months[month][1], year);
  }
  let calendar = [header, "Su Mo Tu We Th Fr Sa"];
  let lastDay;
  if(month === 1) {
    lastDay = leapCheck(year);
  } else {
    lastDay = months[month][2];
  }
  let line = "";
  let day = 1;
  constructor();
  function constructor() {
    for(let i = 0; i < 7; ++i) {
      if(i !== 0) {
        line += " ";
      }
      if(calendar.length === 2 && i < startDay) {
        line += "  ";
      } else {
        if(day < 10) {
          if(highlight && today === day) {
            line += "_\b " + "_\b" + day;
          } else {
            line += " " + day;
          }
        } else {
          if(highlight && today === day) {
            line += "_\b" + day[0] + "_\b" + day[1];
          } else {
            line += day;
          }
        }
        ++day;
        if(day > lastDay) {
          return;
        }
      }
    }
    calendar[calendar.length] = line;
    line = "";
    constructor();
  }
  calendar[calendar.length] = line;
  while(calendar.length < 8) {
    calendar[calendar.length] = "";
  }
  if((environment != "darwin" && !testEnv) || isYear) {
    calendar.forEach((item, i) => {
      if(item.indexOf("_\b") != -1) {
        item += "  ";
      }
      while(item.length < 22) {
        item += " ";
      }
      calendar[i] = item;
    });
  }
  return calendar;
}

function buildYear(year, testEnv) {
  let calendar = [];
  let monthsArr = [];
  for(let i = 0; i < 12; ++i) {
    monthsArr[monthsArr.length] = buildMonth(i, year, true);
  }
  let rowOffset = 0;
  for(let monthOffset = 0; monthOffset < 12; monthOffset += 3, rowOffset += 8) {
    for(let calRow = 0; calRow < 8; ++calRow) {
      for(let monthCal = 0; monthCal < 3; ++monthCal) {
        const rowIndex = calRow + rowOffset;
        const monthIndex = monthCal + monthOffset;
        if(!calendar[rowIndex]) {
          calendar[rowIndex] = "";
        }
        if(((environment === "darwin" && !testEnv) || (environment != "darwin" && testEnv)) && monthCal === 2) {
          monthsArr[monthIndex][calRow] = monthsArr[monthIndex][calRow].trimRight();
        }
        calendar[rowIndex] += monthsArr[monthIndex][calRow];
      }
    }
  }
  if((environment === "darwin" && !testEnv) || (environment != "darwin" && testEnv)) {
    calendar.unshift("");
    calendar.unshift(center(62, year));
  } else {
    for(let i = 24; i > 0; i-=8) {
      calendar.splice(i, 0, "");
    }
    calendar.unshift(center(61, year));
  }
  return calendar;
}

function leapCheck(year) {
  if(year % 4 === 0) {
    if(year % 100 === 0) {
      if(year % 400 === 0) {
        return 29;
      }
      return 28;
    }
    return 29;
  } else {
    return 28;
  }
}
<|endoftext|>


<commit_before>// npm version <newver>

module.exports = version

var exec = require("./utils/exec")
  , readJson = require("./utils/read-json")
  , semver = require("semver")
  , path = require("path")
  , fs = require("./utils/graceful-fs")
  , chain = require("./utils/chain")
  , log = require("./utils/log")
  , npm = require("../npm")

version.usage = "npm version <newversion>\n(run in package dir)\n"
              + "'npm -v' or 'npm --version' to print npm version\n"
              + "(which is "+npm.version+")"

function version (args, cb) {
  if (args.length !== 1) return cb(version.usage)
  var newVer = semver.valid(args[0])
  if (!newVer) return cb(new Error("invalid version: "+args[0]))
  readJson(path.join(process.cwd(), "package.json"), function (er, data) {
    if (er) return log.er(cb, "No package.json found")(er)
    if (data.version === newVer) return cb(new Error("Version not changed"))
    data.version = newVer
    Object.keys(data).forEach(function (k) {
      if (k.charAt(0) === "_") delete data[k]
    })
    readJson.unParsePeople(data)
    fs.stat(path.join(process.cwd(), ".git"), function (er, s) {
      var doGit = !er && s.isDirectory()
      if (!doGit) return write(data, cb)
      else checkGit(data, cb)
    })
  })
}
function checkGit (data, cb) {
  exec( "git", ["status", "--porcelain"], process.env, false
      , function (er, code, stdout, stderr) {
    var lines = stdout.trim().split("\n").filter(function (line) {
      return line.trim() && !line.match(/^\?\? /)
    })
    if (lines.length) return cb(new Error(
      "Git working directory not clean.\n"+lines.join("\n")))
    write(data, function (er) {
      if (er) return cb(er)
      chain
        ( [ exec, "git", ["add","package.json"], process.env, false ]
        , [ exec, "git", ["commit", "-m", "version "+data.version]
          , process.env, false ]
        , [ exec, "git", ["tag", "v"+data.version], process.env, false ]
        , cb )
    })
  })
}
function write (data, cb) {
  fs.writeFile( path.join(process.cwd(), "package.json")
              , new Buffer(JSON.stringify(data, null, 2))
              , cb )
}
<commit_msg>Close #974 Better 'doing it wrong' output for 'npm version'<commit_after>// npm version <newver>

module.exports = version

var exec = require("./utils/exec")
  , readJson = require("./utils/read-json")
  , semver = require("semver")
  , path = require("path")
  , fs = require("./utils/graceful-fs")
  , chain = require("./utils/chain")
  , log = require("./utils/log")
  , npm = require("../npm")

version.usage = "npm version <newversion>\n(run in package dir)\n"
              + "'npm -v' or 'npm --version' to print npm version "
              + "("+npm.version+")\n"
              + "'npm view <pkg> version' to view a package's "
              + "published version"

function version (args, cb) {
  if (args.length !== 1) return cb(version.usage)
  var newVer = semver.valid(args[0])
  if (!newVer) return cb(version.usage)
  readJson(path.join(process.cwd(), "package.json"), function (er, data) {
    if (er) return log.er(cb, "No package.json found")(er)
    if (data.version === newVer) return cb(new Error("Version not changed"))
    data.version = newVer
    Object.keys(data).forEach(function (k) {
      if (k.charAt(0) === "_") delete data[k]
    })
    readJson.unParsePeople(data)
    fs.stat(path.join(process.cwd(), ".git"), function (er, s) {
      var doGit = !er && s.isDirectory()
      if (!doGit) return write(data, cb)
      else checkGit(data, cb)
    })
  })
}
function checkGit (data, cb) {
  exec( "git", ["status", "--porcelain"], process.env, false
      , function (er, code, stdout, stderr) {
    var lines = stdout.trim().split("\n").filter(function (line) {
      return line.trim() && !line.match(/^\?\? /)
    })
    if (lines.length) return cb(new Error(
      "Git working directory not clean.\n"+lines.join("\n")))
    write(data, function (er) {
      if (er) return cb(er)
      chain
        ( [ exec, "git", ["add","package.json"], process.env, false ]
        , [ exec, "git", ["commit", "-m", "version "+data.version]
          , process.env, false ]
        , [ exec, "git", ["tag", "v"+data.version], process.env, false ]
        , cb )
    })
  })
}
function write (data, cb) {
  fs.writeFile( path.join(process.cwd(), "package.json")
              , new Buffer(JSON.stringify(data, null, 2))
              , cb )
}
<|endoftext|>


<commit_before>import Hls from "hls.js";

var attachVideojsStreamrootProvider = function (window, videojs) {
    function StreamrootProviderHLS (source, tech) {
        tech.name_ = 'streamrootHLS';

        var playerConfig = tech.playerConfig;
        var _video = tech.el();
        var _hls;

        function _loadHls(url) {
            if (_hls === undefined || _hls.url !== url) {

                if(_hls) {
                    _hls.destroy();
                }

                var hlsjsConfig = playerConfig.hlsjsConfig || {};

                _hls = new Hls(hlsjsConfig);
                _hls.on(Hls.Events.MANIFEST_PARSED, _onMetaData);
                _hls.on(Hls.Events.ERROR, function (event, data) {
                    console.error('HLS.js error: ' + data.type + ' - fatal: ' + data.fatal + ' - ' + data.details);
                });

                _hls.loadSource(url);
                _hls.attachMedia(_video);
            } else {
                //TODO: seek to 0 ?
            }
        }

        function load(source) {
            var url = source.src;

            if (Hls !== undefined) {
                _loadHls(source.src);
            } else {
                console.error("Hls is not defined. Import Hls.js library");
            }
        }

        function switchQuality(qualityId, trackType) {
            _hls.nextLevel = qualityId;
        }

        function _onMetaData(event, data) {
            var cleanTracklist = [];

            if (data.levels.length > 1) {
                var autoLevel = {
                    id: -1,
                    label: "auto",
                    selected: -1 === _hls.manualLevel
                };
                cleanTracklist.push(autoLevel);
            }

            data.levels.forEach(function(level, index) {
                var quality = {}; // Don't write in level (shared reference with Hls.js)
                quality.id = index;
                quality.selected = index === _hls.manualLevel;
                quality.label = _levelLabel(level);

                cleanTracklist.push(quality);
            });

            var payload = {
                qualityData: {video: cleanTracklist},
                qualitySwitchCallback: switchQuality
            };

            tech.trigger('loadedqualitydata', payload);

            function _levelLabel(level) {
                if (level.height) return level.height + "p";
                else if (level.width) return Math.round(level.width * 9 / 16) + "p";
                else if (level.bitrate) return (level.bitrate / 1000) + "kbps";
                else return 0;
            }
        }

        load(source);
    }

    // Only add the SourceHandler if the browser supports MediaSourceExtensions
    if (!!window.MediaSource) {
        videojs.getComponent('Html5').registerSourceHandler({

            canHandleSource: function (source) {

                var hlsTypeRE = /^application\/x-mpegURL$/i;
                var hlsExtRE = /\.m3u8/i;
                var result;

                if (hlsTypeRE.test(source.type)) {
                    result = 'probably';
                } else if (hlsExtRE.test(source.src)) {
                    result = 'maybe';
                } else {
                    result = '';
                }

                return result;
            },

            handleSource: function (source, tech) {

                tech.playerConfig = this.options;

                return new StreamrootProviderHLS(source, tech);
            },

            options: videojs.options

        }, 0);

    } else {
        console.log("ERROR: MediaSourceExtensions are not supported in this browser!");
    }

    videojs.StreamrootProviderHLS = StreamrootProviderHLS;
};

attachVideojsStreamrootProvider(window, window.videojs);
<commit_msg>fixed unavailable MediaSourceExtensions logging<commit_after>import Hls from "hls.js";

var attachVideojsStreamrootProvider = function (window, videojs) {
    function StreamrootProviderHLS (source, tech) {
        tech.name_ = 'streamrootHLS';

        var playerConfig = tech.playerConfig;
        var _video = tech.el();
        var _hls;

        function _loadHls(url) {
            if (_hls === undefined || _hls.url !== url) {

                if(_hls) {
                    _hls.destroy();
                }

                var hlsjsConfig = playerConfig.hlsjsConfig || {};

                _hls = new Hls(hlsjsConfig);
                _hls.on(Hls.Events.MANIFEST_PARSED, _onMetaData);
                _hls.on(Hls.Events.ERROR, function (event, data) {
                    console.error('HLS.js error: ' + data.type + ' - fatal: ' + data.fatal + ' - ' + data.details);
                });

                _hls.loadSource(url);
                _hls.attachMedia(_video);
            } else {
                //TODO: seek to 0 ?
            }
        }

        function load(source) {
            var url = source.src;

            if (Hls !== undefined) {
                _loadHls(source.src);
            } else {
                console.error("Hls is not defined. Import Hls.js library");
            }
        }

        function switchQuality(qualityId, trackType) {
            _hls.nextLevel = qualityId;
        }

        function _onMetaData(event, data) {
            var cleanTracklist = [];

            if (data.levels.length > 1) {
                var autoLevel = {
                    id: -1,
                    label: "auto",
                    selected: -1 === _hls.manualLevel
                };
                cleanTracklist.push(autoLevel);
            }

            data.levels.forEach(function(level, index) {
                var quality = {}; // Don't write in level (shared reference with Hls.js)
                quality.id = index;
                quality.selected = index === _hls.manualLevel;
                quality.label = _levelLabel(level);

                cleanTracklist.push(quality);
            });

            var payload = {
                qualityData: {video: cleanTracklist},
                qualitySwitchCallback: switchQuality
            };

            tech.trigger('loadedqualitydata', payload);

            function _levelLabel(level) {
                if (level.height) return level.height + "p";
                else if (level.width) return Math.round(level.width * 9 / 16) + "p";
                else if (level.bitrate) return (level.bitrate / 1000) + "kbps";
                else return 0;
            }
        }

        load(source);
    }

    // Only add the SourceHandler if the browser supports MediaSourceExtensions
    if (!!window.MediaSource) {
        videojs.getComponent('Html5').registerSourceHandler({

            canHandleSource: function (source) {

                var hlsTypeRE = /^application\/x-mpegURL$/i;
                var hlsExtRE = /\.m3u8/i;
                var result;

                if (hlsTypeRE.test(source.type)) {
                    result = 'probably';
                } else if (hlsExtRE.test(source.src)) {
                    result = 'maybe';
                } else {
                    result = '';
                }

                return result;
            },

            handleSource: function (source, tech) {

                tech.playerConfig = this.options;

                return new StreamrootProviderHLS(source, tech);
            },

            options: videojs.options

        }, 0);

    } else {
        console.error("MediaSourceExtensions are not supported in this browser!");
    }

    videojs.StreamrootProviderHLS = StreamrootProviderHLS;
};

attachVideojsStreamrootProvider(window, window.videojs);
<|endoftext|>


<commit_before>/**
 * @since 150524 18:23
 * @author vivaxy
 */
var path = require('path'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,

    ip = require('ip'),
    ws = require('ws'),
    gaze = require('gaze'),
    log = require('log-util'),

    cwd = process.cwd(),
    hostname = ip.address(),

    /**
     *
     * @param options
     * @constructor
     */
    Watcher = function (options) {

        EventEmitter.apply(this, arguments);

        this.directory = options.directory;

        this.port = options.port;
        this.sockets = [];

        this.initialize();
        this.startup();

    };

util.inherits(Watcher, EventEmitter);
var p = Watcher.prototype;
p.constructor = Watcher;
module.exports = Watcher;

/**
 * create instances
 * @returns {Watcher}
 */
p.initialize = function () {
    var _this = this;
    var WebSocketServer = ws.Server,
        wss = new WebSocketServer({port: _this.port}, function () {
            log.info('watcher: listen http://' + hostname + ':' + _this.port + '/');
            _this.emit('success');
        });
    wss.on('connection', function (ws) {
        _this.sockets.push(ws);
        ws.on('close', function () {
            _this.sockets.splice(_this.sockets.indexOf(ws), 1);
        });
    });
    wss.on('error', function (err) {
        if (err.code === 'EADDRINUSE') {
            log.warn('watcher: port ' + _this.port + ' in use');
            _this.port = _this.port + 1;
            return _this.initialize();
        } else {
            log.error(err);
        }
    });
    return this;
};

/**
 * start web socket server
 * @returns {*}
 */
p.startup = function () {
    var _this = this,
        watcher = gaze(['**/*'], function (err, watcher) {
            if (err) {
                log.error(err);
            } else {
                var watched = watcher.watched();
                for (var i in watched) {
                    log.verbose('watcher:', 'watching', path.relative(cwd, i), watched[i].map(function (filePath) {
                        return path.relative(cwd, filePath);
                    }));
                }
            }
        }).on('all', function (action, filePath) {
            log.debug('watcher:', action, path.relative(cwd, filePath));
            log.debug('watcher: reload');
            _this.sockets.forEach(function (ws) {
                try {
                    ws.send('reload');
                } catch (e) {
                }
            });
        });
    return this;
};

/**
 *
 * @returns {*}
 */
p.getPort = function () {
    return this.port;
};
<commit_msg>add log<commit_after>/**
 * @since 150524 18:23
 * @author vivaxy
 */
var path = require('path'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,

    ip = require('ip'),
    ws = require('ws'),
    gaze = require('gaze'),
    log = require('log-util'),

    cwd = process.cwd(),
    hostname = ip.address(),

    /**
     *
     * @param options
     * @constructor
     */
    Watcher = function (options) {

        EventEmitter.apply(this, arguments);

        this.directory = options.directory;

        this.port = options.port;
        this.sockets = [];

        this.initialize();
        this.startup();

    };

util.inherits(Watcher, EventEmitter);
var p = Watcher.prototype;
p.constructor = Watcher;
module.exports = Watcher;

/**
 * create instances
 * @returns {Watcher}
 */
p.initialize = function () {
    var _this = this;
    var WebSocketServer = ws.Server,
        wss = new WebSocketServer({port: _this.port}, function () {
            log.info('watcher: listen http://' + hostname + ':' + _this.port + '/');
            _this.emit('success');
        });
    wss.on('connection', function (ws) {
        _this.sockets.push(ws);
        ws.on('close', function () {
            _this.sockets.splice(_this.sockets.indexOf(ws), 1);
        });
    });
    wss.on('error', function (err) {
        if (err.code === 'EADDRINUSE') {
            log.warn('watcher: port ' + _this.port + ' in use');
            _this.port = _this.port + 1;
            return _this.initialize();
        } else {
            log.error(err);
        }
    });
    return this;
};

/**
 * start web socket server
 * @returns {*}
 */
p.startup = function () {
    var _this = this,
        watcher = gaze(['**/*'], function (err, watcher) {
            if (err) {
                log.error(err);
            } else {
                var watched = watcher.watched();
                for (var i in watched) {
                    log.verbose('watcher:', 'watching', path.relative(cwd, i), watched[i].map(function (filePath) {
                        return path.relative(cwd, filePath);
                    }));
                }
            }
        }).on('all', function (action, filePath) {
            log.debug('watcher:', action, path.relative(cwd, filePath));
            log.debug('watcher: reload');
            _this.sockets.forEach(function (ws) {
                try {
                    ws.send('reload');
                } catch (e) {
                    log.debug(e);
                }
            });
        });
    return this;
};

/**
 *
 * @returns {*}
 */
p.getPort = function () {
    return this.port;
};
<|endoftext|>


<commit_before>/**
 * Adds dependency watching to the core fs.watchFile implementation.
 */
var _ = require('underscore'),
    fs = require('fs');

var watchedFiles = {};

function notifyWatch(filename, type, sourceChange, trigger) {
  var watchInfo = watchedFiles[filename];
  if (watchInfo) {
    var inQueue = _.find(watchInfo.queue, function(entry) {
      return entry.type === type
          && entry.filename === filename
          && entry.sourceChange === sourceChange;
    });

    if (!inQueue) {
      var entry = {type: type, filename: filename, sourceChange: sourceChange};
      watchInfo.queue.push(entry);

      function exec() {
        watchInfo.queue = _.without(watchInfo.queue, entry);

        if (watchInfo.callback) {
          watchInfo.callback(type, filename, sourceChange);
        }
        watchInfo.parents.forEach(function(parent) {
          notifyWatch(parent, type, sourceChange, trigger);
        });
      }

      if (trigger) {
        exec();
      } else {
        // Debounce so we don't output multiple instances of the same event on platforms
        // such as linux that may send multiple events on write, etc.
        _.defer(exec, 200);
      }
    }
  }
}

function watchFile(filename, callback, parent) {
    var watchInfo = {
      callback: callback,
      parents: [],
      queue: []
    };
    if (parent) {
      watchInfo.parents.push(parent);
    }
    watchedFiles[filename.virtual || filename] = watchInfo;

    if (!filename.virtual) {
      var hasRetried;

      (function watch(ignoreError) {
        try {
          var oldStat = fs.statSync(filename),
              lastType,
              rewatch;

          var changeHandler = _.debounce(function() {
            if (rewatch) {
              // Attempt to reattach on rename
              watchInfo.watch.close();
              watch(true);
            }
            notifyWatch(filename, lastType, filename);
          }, 1000);

          watchInfo.watch = fs.watch(filename, function(type) {
            try {
              var newStat = fs.statSync(filename);
              if (newStat.isDirectory()) {
                notifyWatch(filename, 'create', filename);
              } else if (newStat.size !== oldStat.size || newStat.mtime.getTime() > oldStat.mtime.getTime()) {
                oldStat = newStat;
                if (type === 'rename') {
                  rewatch = true;
                }
                lastType = type;
                changeHandler();
              }
            } catch (err) {
              if (err.code === 'ENOENT') {
                // The file was removed by the time we got to it. This could be a case of it actually being removed
                // or a race condtion with rewriting APIs.
                watchInfo.watch.close();

                // Pause a bit to see if this was a replace that we raced with...
                setTimeout(function() {
                  try {
                    fs.statSync(filename);    // No exception: file still exists, notify and restart the watch
                    notifyWatch(filename, 'change', filename);
                    watch(true);
                  } catch (err) {
                    // The file is really gone... or we just got hit with a race condtion twice. Give up.
                    notifyWatch(filename, 'remove', filename);
                  }
                }, 500);
              } else {
                throw err;
              }
            }
          });
        } catch (err) {
          if (!hasRetried && err.code === 'EMFILE') {
            hasRetried = true;
            setTimeout(function() {
              watch(ignoreError);
            }, 250);
          } else if (!ignoreError) {
            throw err;
          }
        }
      })();
    }
}

exports.watchFile = function(filename, dependencies, callback) {
  var watch = watchedFiles[filename.virtual || filename];
  if (!watch) {
    // Create a watch on this and all others
    watchFile(filename, callback);
  } else {
    watch.callback = callback;
  }

  filename = filename.virtual || filename;

  dependencies.forEach(function(depend) {
    var watch = watchedFiles[depend.virtual || depend];
    if (!watch) {
      watchFile(depend, undefined, filename);
    } else {
      if (!_.contains(watch.parents, filename)) {
        watch.parents.push(filename);
      }
    }
  });
};

exports.trigger = function(type, filename) {
  notifyWatch(filename, type, filename, true);
};

exports.unwatch = function(filename, dependencies) {
  var watch = watchedFiles[filename.virtual || filename];
  if (!watch) {
    return;
  }

  // Remove the callback
  if (!dependencies) {
    watch.callback = undefined;
  }

  // For each dependency remove the parent link
  filename = filename.virtual || filename;

  _.each(dependencies || watchedFiles, function(depend) {
    var watch = watchedFiles[depend.virtual || depend];
    if (!watch) {
      return;
    }

    watch.parents = _.without(watch.parents, filename);
  });

  // Kill this watch if it can't trigger or fire
  var canTrigger = watch.watch || _.some(watchedFiles, function(watch) {
    return _.contains(watch.parents, filename);
  });
  if (!watch.callback || !canTrigger) {
    unwatch(filename);
  }

  // Kill any other watches that might not be valid anymore
  _.each(_.clone(watchedFiles), function(watch, name) {
    if (!watch.callback && !watch.parents.length) {
      exports.unwatch(name);
    }
  });
};
exports.unwatchAll = function() {
  _.each(watchedFiles, function(watch, name) {
    unwatch(name);
  });
};

function unwatch(name) {
  if (!watchedFiles[name]) {
    return;
  }

  watchedFiles[name].callback = undefined;
  if (watchedFiles[name].watch) {
    watchedFiles[name].watch.close();
  }
  delete watchedFiles[name];
}
<commit_msg>Remove unused conditional<commit_after>/**
 * Adds dependency watching to the core fs.watchFile implementation.
 */
var _ = require('underscore'),
    fs = require('fs');

var watchedFiles = {};

function notifyWatch(filename, type, sourceChange, trigger) {
  var watchInfo = watchedFiles[filename];
  if (watchInfo) {
    var inQueue = _.find(watchInfo.queue, function(entry) {
      return entry.type === type
          && entry.filename === filename
          && entry.sourceChange === sourceChange;
    });

    if (!inQueue) {
      var entry = {type: type, filename: filename, sourceChange: sourceChange};
      watchInfo.queue.push(entry);

      function exec() {
        watchInfo.queue = _.without(watchInfo.queue, entry);

        if (watchInfo.callback) {
          watchInfo.callback(type, filename, sourceChange);
        }
        watchInfo.parents.forEach(function(parent) {
          notifyWatch(parent, type, sourceChange, trigger);
        });
      }

      if (trigger) {
        exec();
      } else {
        // Debounce so we don't output multiple instances of the same event on platforms
        // such as linux that may send multiple events on write, etc.
        _.defer(exec, 200);
      }
    }
  }
}

function watchFile(filename, callback, parent) {
    var watchInfo = {
      callback: callback,
      parents: [],
      queue: []
    };
    if (parent) {
      watchInfo.parents.push(parent);
    }
    watchedFiles[filename.virtual || filename] = watchInfo;

    if (!filename.virtual) {
      var hasRetried;

      (function watch(ignoreError) {
        try {
          var oldStat = fs.statSync(filename),
              lastType,
              rewatch;

          var changeHandler = _.debounce(function() {
            if (rewatch) {
              // Attempt to reattach on rename
              watchInfo.watch.close();
              watch(true);
            }
            notifyWatch(filename, lastType, filename);
          }, 1000);

          watchInfo.watch = fs.watch(filename, function(type) {
            try {
              var newStat = fs.statSync(filename);
              if (newStat.isDirectory()) {
                notifyWatch(filename, 'create', filename);
              } else if (newStat.size !== oldStat.size || newStat.mtime.getTime() > oldStat.mtime.getTime()) {
                oldStat = newStat;
                if (type === 'rename') {
                  rewatch = true;
                }
                lastType = type;
                changeHandler();
              }
            } catch (err) {
              if (err.code === 'ENOENT') {
                // The file was removed by the time we got to it. This could be a case of it actually being removed
                // or a race condtion with rewriting APIs.
                watchInfo.watch.close();

                // Pause a bit to see if this was a replace that we raced with...
                setTimeout(function() {
                  try {
                    fs.statSync(filename);    // No exception: file still exists, notify and restart the watch
                    notifyWatch(filename, 'change', filename);
                    watch(true);
                  } catch (err) {
                    // The file is really gone... or we just got hit with a race condtion twice. Give up.
                    notifyWatch(filename, 'remove', filename);
                  }
                }, 500);
              } else {
                throw err;
              }
            }
          });
        } catch (err) {
          if (!hasRetried && err.code === 'EMFILE') {
            hasRetried = true;
            setTimeout(function() {
              watch(ignoreError);
            }, 250);
          } else if (!ignoreError) {
            throw err;
          }
        }
      })();
    }
}

exports.watchFile = function(filename, dependencies, callback) {
  var watch = watchedFiles[filename.virtual || filename];
  if (!watch) {
    // Create a watch on this and all others
    watchFile(filename, callback);
  } else {
    watch.callback = callback;
  }

  filename = filename.virtual || filename;

  dependencies.forEach(function(depend) {
    var watch = watchedFiles[depend.virtual || depend];
    if (!watch) {
      watchFile(depend, undefined, filename);
    } else {
      if (!_.contains(watch.parents, filename)) {
        watch.parents.push(filename);
      }
    }
  });
};

exports.trigger = function(type, filename) {
  notifyWatch(filename, type, filename, true);
};

exports.unwatch = function(filename, dependencies) {
  var watch = watchedFiles[filename.virtual || filename];
  if (!watch) {
    return;
  }

  // Remove the callback
  if (!dependencies) {
    watch.callback = undefined;
  }

  // For each dependency remove the parent link
  filename = filename.virtual || filename;

  _.each(dependencies || watchedFiles, function(depend) {
    var watch = watchedFiles[depend.virtual || depend];
    if (!watch) {
      return;
    }

    watch.parents = _.without(watch.parents, filename);
  });

  // Kill this watch if it can't trigger or fire
  var canTrigger = watch.watch || _.some(watchedFiles, function(watch) {
    return _.contains(watch.parents, filename);
  });
  if (!watch.callback || !canTrigger) {
    unwatch(filename);
  }

  // Kill any other watches that might not be valid anymore
  _.each(_.clone(watchedFiles), function(watch, name) {
    if (!watch.callback && !watch.parents.length) {
      exports.unwatch(name);
    }
  });
};
exports.unwatchAll = function() {
  _.each(watchedFiles, function(watch, name) {
    unwatch(name);
  });
};

function unwatch(name) {
  watchedFiles[name].callback = undefined;
  if (watchedFiles[name].watch) {
    watchedFiles[name].watch.close();
  }
  delete watchedFiles[name];
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var path = require('path');
var fs = require('fs');
var async = require('async');
var _ = require('underscore');

var express = require('express');

var load_fixtures = require('./load_fixtures');
var load_idjson = require('./load_idjson');
var middleware = require('./middleware');
var routes = require('./routes');
var utils = require('../utils');
var settings = require('../settings');
var pollers = require('./pollers');
var settings = require('../settings');
var hooks = require('./hooks');
var db = require('./db');

var TEMPLATE_DIR = path.join(__dirname, 'views');

exports.run = function(argv) {
  var certificate, privateKey;
  var devops;
  var devops_directory = argv.d;
  var host = argv.l;
  var port = argv.p;
  var hooks_server;
  var redirect_app;
  var web_app;
  var idjson;

  if(!settings.private_key || !settings.cert){
    utils.die('No key/cert defined in settings; not starting the API.');
    return;
  }

  if (!settings.external_ipv4) {
    utils.die('external_ipv4 is not defined in settings.');
  }

  try{
    privateKey = fs.readFileSync(path.join(settings.private_key)).toString();
    certificate = fs.readFileSync(path.join(settings.cert)).toString();
  }catch(e){
    utils.die('Could not find the private key and/or cert; not starting the API.');
  }
  if (settings.valid_users.length <= 0){
    utils.die('You must define valid_users in settings; not starting the API.');
  }

  redirect_app = express.createServer();
  redirect_app.all("*", function (req, res, next) {
    res.header('location', "https://" + req.headers.host + req.url);
    res.send("", 301);
  });
  redirect_app.listen(80, host);

  web_app = express.createServer({key: privateKey, cert: certificate});

  web_app.set('views', TEMPLATE_DIR);
  web_app.set('view engine', 'jade');
  web_app.set('view options', {layout: false});
  web_app.use(middleware.logger());
  web_app.use(middleware.vpn_only);
  web_app.use('/static', express.static(path.join(__dirname, '..', '..', 'extern')));
  web_app.use('/static', express.static(path.join(__dirname, '..', '..', 'static')));
  if (settings.testing === true){
    web_app.enable('testing');
  }

  devops = load_fixtures(devops_directory);
  idjson = load_idjson.load();

  hooks_server = express.createServer();
  hooks_server.use(middleware.logger());

  db.create_tables(function (){
    async.series({
      polling_data: function (cb) {
        pollers.install(devops, cb);
      },
      github_data: function (cb) {
        hooks.install(devops, cb);
      }
    },
    function (err, results) {
      var polling_data;
      if (err) {
        if (!results.polling_data) {
          // Pollers didn't get set up. Uh-oh.
          utils.die(err);
        }
        else {
          // Probably an error creating github hooks. Keep on truckin'
          console.error(err);
        }
      }
      polling_data = results.polling_data;

      web_app.use(middleware.injector.inject(polling_data, devops));
      routes.web.install(web_app, devops, polling_data, idjson);
      web_app.listen(443, host);

      routes.hooks.install(hooks_server, devops);
      hooks_server.listen(port, host);
    });
  });
};
<commit_msg>Better<commit_after>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var path = require('path');
var fs = require('fs');
var async = require('async');
var _ = require('underscore');

var express = require('express');

var load_fixtures = require('./load_fixtures');
var load_idjson = require('./load_idjson');
var middleware = require('./middleware');
var routes = require('./routes');
var utils = require('../utils');
var settings = require('../settings');
var pollers = require('./pollers');
var settings = require('../settings');
var hooks = require('./hooks');
var db = require('./db');

var TEMPLATE_DIR = path.join(__dirname, 'views');

exports.run = function(argv) {
  var certificate, privateKey;
  var devops;
  var devops_directory = argv.d;
  var host = argv.l;
  var port = argv.p;
  var hooks_server;
  var redirect_app;
  var web_app;
  var idjson;

  if(!settings.private_key || !settings.cert){
    utils.die('No key/cert defined in settings; not starting the API.');
    return;
  }

  if (!settings.external_ipv4) {
    utils.die('external_ipv4 is not defined in settings.');
  }

  try{
    privateKey = fs.readFileSync(path.join(settings.private_key)).toString();
    certificate = fs.readFileSync(path.join(settings.cert)).toString();
  }catch(e){
    utils.die('Could not find the private key and/or cert; not starting the API.');
  }
  if (settings.valid_users.length <= 0){
    utils.die('You must define valid_users in settings; not starting the API.');
  }

  redirect_app = express.createServer();
  redirect_app.all("*", function (req, res, next) {
    res.header('location', "https://" + req.headers.host + req.url);
    res.send("", 301);
  });
  redirect_app.listen(80, host);

  web_app = express.createServer({key: privateKey, cert: certificate});

  web_app.set('views', TEMPLATE_DIR);
  web_app.set('view engine', 'jade');
  web_app.set('view options', {layout: false});
  web_app.use(middleware.logger());
  web_app.use(middleware.vpn_only);
  web_app.use('/static', express.static(path.join(__dirname, '..', '..', 'extern')));
  web_app.use('/static', express.static(path.join(__dirname, '..', '..', 'static')));
  if (settings.testing === true){
    web_app.enable('testing');
  }

  devops = load_fixtures(devops_directory);
  idjson = load_idjson.load();

  hooks_server = express.createServer();
  hooks_server.use(middleware.logger());

  db.create_tables(function (){
    async.series({
      polling_data: function (cb) {
        pollers.install(devops, cb);
      },
      github_data: function (cb) {
        hooks.install(devops, function (err, results) {
          if (err) {
            console.error(err);
          }
          cb(null, results);
        });
      }
    },
    function (err, results) {
      var polling_data;
      if (err) {
        utils.die(err);
      }
      polling_data = results.polling_data;

      web_app.use(middleware.injector.inject(polling_data, devops));
      routes.web.install(web_app, devops, polling_data, idjson);
      web_app.listen(443, host);

      routes.hooks.install(hooks_server, devops);
      hooks_server.listen(port, host);
    });
  });
};
<|endoftext|>


<commit_before>var pm2 = require('pm2'),
    crypto = require('crypto'),
    http = require('http');

var servers = {};
var webhooks = {};

/*module.exports = function () {

};*/

pm2.connect(function () {

    console.log('Module pm2-webhook connected to pm2');

    pm2.list(function (err, procs) {
        processList( procs );
    });

    pm2.launchBus(function (err, bus) {
        bus.on('process:event', function(args){
            if (args.event != 'stop' && args.event != 'exit') {
                pm2.list(function (err, procs) {
                    processList( procs );
                });
            }
            else {
                removeServer( webhooks[ args.process.name ].port )
            }
        })
    });
});

function processList(processes) {

    webhooks = {};
    var usedPorts = [];

    processes.forEach(function (proc) {
        if (!proc.pm2_env || !proc.pm2_env.env_webhook || !proc.pm2_env.env_webhook.port || !proc.pm2_env.versioning) {
            return;
        }
        console.log(proc.name);
        var env = proc.pm2_env.env_webhook;

        var port = parseInt(env.port);

        if (port <= 1024) {
            console.error('Port value "%s" is incorrect', env.port);
            return;
        }

        if (!servers[port]) {
            addServer(port);
        }
        webhooks[proc.name] = {
            port: port,
            path: env.path || '',
            secret: env.secret || ''
        };

        usedPorts.push(port);
    });

    // remove old servers
    for (var port in servers) {
        if (!~usedPorts.indexOf(parseInt(port))) {
            removeServer(port);
        }
    }

}

function processRequest(port, url, body, headers) {

    console.log('Received request', port, url);

    for (var name in webhooks) {
        var options = webhooks[name];

        if (options.port !== port) {
            continue;
        }

        if (options.path.length && options.path != url) {
            continue;
        }

        if (options.secret.length) {
            var hmac = crypto.createHmac('sha1', options.secret);
            hmac.update(body, 'utf-8');

            var xub = 'X-Hub-Signature';
            var received = headers[xub] || headers[xub.toLowerCase()];
            var expected = 'sha1=' + hmac.digest('hex');

            if (received !== expected) {
                console.error('Wrong secret. Expected %s, received %s', expected, received);
                continue;
            }

            console.info('Secret test passed');
        }

        pullAndReload(name);
    }
}

function addServer(port) {
    servers[port] = http
        .createServer(function (request, response) {
            response.writeHead(200, {'Content-Type': 'text/plain'});
            response.write('Received');
            response.end();

            if (request.method !== 'POST') {
                return;
            }

            var body = '';
            request
                .on('data', function(data) {
                    body += data;
                })
                .on('end', function () {
                    processRequest(port, request.url, body, request.headers);
                });

        })
        .listen(port)
        .unref();
}

function removeServer(port) {
    console.info('Remove server on port %d', port);
    if (!servers[port]) {
        return;
    }

    servers[port].close(function(err) {
        console.info('Server on port %d was closed', port);
        delete servers[port];
    });
}

function pullAndReload(name) {
    console.log('Pull and reload app %s', name);

    pm2.pullAndReload(name, function (err, meta) {
        if (err) {
            console.log('App %s already at latest version', name);
            return;
        }
        if (meta.rev) {
            console.log(
                'Successfully pulled ' + name + ' [Commit id: %s] [Repo: %s] [Branch: %s]',
                meta.rev.current_revision,
                meta.procs[0].pm2_env.versioning.repo_path,
                meta.procs[0].pm2_env.versioning.branch
            );
        }
    });
}<commit_msg>minor changes<commit_after>var pm2 = require('pm2'),
    crypto = require('crypto'),
    http = require('http');

var servers = {};
var webhooks = {};

module.exports = function () {
    pm2.connect(function () {

        console.log('Module pm2-webhook connected to pm2');

        pm2.list(function (err, procs) {
            processList(procs);
        });

        pm2.launchBus(function (err, bus) {
            bus.on('process:event', function (args) {
                if (args.event != 'stop' && args.event != 'exit') {
                    pm2.list(function (err, procs) {
                        processList(procs);
                    });
                }
                else {
                    removeServer(webhooks[args.process.name].port)
                }
            })
        });
    });
};

function processList(processes) {

    webhooks = {};
    var usedPorts = [];

    processes.forEach(function (proc) {
        if (!proc.pm2_env || !proc.pm2_env.env_webhook || !proc.pm2_env.env_webhook.port || !proc.pm2_env.versioning) {
            return;
        }
        console.log(proc.name);
        var env = proc.pm2_env.env_webhook;

        var port = parseInt(env.port);

        if (port <= 1024) {
            console.error('Port value "%s" is incorrect', env.port);
            return;
        }

        if (!servers[port]) {
            addServer(port);
        }
        webhooks[proc.name] = {
            port: port,
            path: env.path || '',
            secret: env.secret || ''
        };

        usedPorts.push(port);
    });

    // remove old servers
    for (var port in servers) {
        if (!~usedPorts.indexOf(parseInt(port))) {
            removeServer(port);
        }
    }

}

function processRequest(port, url, body, headers) {

    console.log('Received request', port, url);

    for (var name in webhooks) {
        var options = webhooks[name];

        if (options.port !== port) {
            continue;
        }

        if (options.path.length && options.path != url) {
            continue;
        }

        if (options.secret.length) {
            var hmac = crypto.createHmac('sha1', options.secret);
            hmac.update(body, 'utf-8');

            var xub = 'X-Hub-Signature';
            var received = headers[xub] || headers[xub.toLowerCase()];
            var expected = 'sha1=' + hmac.digest('hex');

            if (received !== expected) {
                console.error('Wrong secret. Expected %s, received %s', expected, received);
                continue;
            }

            console.info('Secret test passed');
        }

        pullAndReload(name);
    }
}

function addServer(port) {
    servers[port] = http
        .createServer(function (request, response) {
            response.writeHead(200, {'Content-Type': 'text/plain'});
            response.write('Received');
            response.end();

            if (request.method !== 'POST') {
                return;
            }

            var body = '';
            request
                .on('data', function(data) {
                    body += data;
                })
                .on('end', function () {
                    processRequest(port, request.url, body, request.headers);
                });

        })
        .listen(port)
        .unref();
}

function removeServer(port) {
    console.info('Remove server on port %d', port);
    if (!servers[port]) {
        return;
    }

    servers[port].close(function(err) {
        console.info('Server on port %d was closed', port);
        delete servers[port];
    });
}

function pullAndReload(name) {
    console.log('Pull and reload app %s', name);

    pm2.pullAndReload(name, function (err, meta) {
        if (err) {
            console.log('App %s already at latest version', name);
            return;
        }
        if (meta.rev) {
            console.log(
                'Successfully pulled ' + name + ' [Commit id: %s] [Repo: %s] [Branch: %s]',
                meta.rev.current_revision,
                meta.procs[0].pm2_env.versioning.repo_path,
                meta.procs[0].pm2_env.versioning.branch
            );
        }
    });
}<|endoftext|>