<commit_before>/* alerts
 */

module.exports = function(config, db) {
  'use strict';

  var express = require('express');
  var request = require('superagent');
  var async = require('async');
  var fs = require('fs');
  var util = require('util');
  var twilio = require('twilio');

  var moment = require('moment');

  var nexmo = require('easynexmo');

  nexmo.initialize(
    config.gateway.key,
    config.gateway.secret,
    config.gateway.protocol,
    config.gateway.debug
  );

  var twilio = require('twilio');
  var client = new twilio.RestClient('AC843270d590f2988caf4993adb06e0294', 'bada3f2f91251f3c0f6edefe94022366');

  var create = function(req, res, next) {

    req.checkBody('name', 'Title should not be empty').notEmpty();
    req.checkBody('number', 'Number should not be empty.').notEmpty();
    req.checkBody('start', 'Start date should not be empty.').notEmpty();
    req.checkBody('end', 'End date should not be empty.').notEmpty();
    req.checkBody('message', 'Message should not be empty.').notEmpty();

    var name = req.body.name.trim();
    var userName = req.body.userName.trim();
    var companyName = req.body.message.trim();

    var message = req.body.message.trim();

    var number = req.body.number.replace(/[-() ]/gi, '');
    var startDate = new Date(req.body.start);
    var endDate = new Date(req.body.end);

    // TODO add multiple validations after transforms
    var errors = req.validationErrors();

    if (errors) {
      res.status(400).json(errors);
      return;
    }

    var event = {
      status: false,
      name: name,
      userName: userName,
      companyName: companyName,
      title: name,
      number: number,
      start: startDate,
      end: endDate,
      calendarId: req.params.calendarId,
      message: message
    };

    db.events.insert(event, function (err, newEvent) {

      res.json({
        message: 'Create successful.',
        event: newEvent
      });

    });

    var contact = {
      name: name,
      title: name,
      number: number,
      calendarId: req.params.calendarId
    };

    db.contacts.findOne({'name': contact.name, 'number': contact.number, 'calendarId': contact.calendarId}, function (err, doc) {

      if (err) {
        res.json(util.inspect(errors), 400);
        return;
      }

      if (!doc) {

        db.contacts.insert(contact, function (err, newContact) {

          if (err) {
            res.json(util.inspect(errors), 400);
            return;
          }

        });
      }
    });

  };

  var update = function (req, res, next) {
    req.checkBody('name', 'Title should not be empty').notEmpty();
    req.checkBody('number', 'Number should not be empty.').notEmpty();
    req.checkBody('start', 'Start date should not be empty.').notEmpty();
    req.checkBody('end', 'End date should not be empty.').notEmpty();
    req.checkBody('message', 'Message should not be empty.').notEmpty();
    req.checkBody('_id', 'ID should not be empty.').notEmpty();

    var name = req.body.name.trim();
    var number = req.body.number.replace(/[-() ]/gi, '');
    var startDate = Date.create(req.body.start);
    var endDate = Date.create(req.body.end);
    var message = req.body.message;
    var eventId = req.body._id;

    startDate = moment(startDate).toDate();
    endDate = moment(endDate).toDate();

    // TODO add multiple validations after transforms

    var errors = req.validationErrors();

    if (errors) {
      res.json(util.inspect(errors), 400);
      return;
    }

    var event = {
      status: false,
      name: name,
      title: name,
      number: number,
      start: startDate,
      end: endDate,
      calendarId: req.params.calendarId,
      message: message
    };

    db.events.update({'_id': eventId}, event, function (err, num, newEvent) {

      if (num > 0) {

        db.events.findOne({'_id': eventId}, function (err, doc) {

          res.json({
            message: 'Update successfull.',
            event: doc
          });

        });

      } else {

        res.json(util.inspect(errors), 400);

      }

    });
  }

  var list = function(req, res, next) {

    db.events.find({
      calendarId: req.params.calendarId
    }).sort({
      date: -1
    }).exec(function (err, events) {

      if(err) {
        return res.send(err, 400);
      }

      if (!events.length) {
        events = [];
      }

      res.json(events);

    });

  };

  var get = function(req, res, next) {

    db.events.findOne({
      _id: req.params.eventId
    }).exec(function (err, event) {

      if(err) {
        return res.send(err, 400);
      }

      if (!alert) {
        event = {};
      }

      res.json(event);

    });

  };

  var remove = function(req, res, next) {
    var id = req.params.alertId;
    db.events.remove({
      _id: req.params.eventId
    },function (err, num) {

      if(err) {
        return res.send(err, 400);
      }

      res.json({message: 'Delete successful ' + id, num: num});

    });

  };

  var remind = function (req, res, next) {

    var lte = moment().add(1, 'hours').toDate();
    var gte = moment().toDate();

    db.events.find({
      start: {
        $lte: lte,
        $gte: gte
      },
      sent: {
        $ne: true
      }
    }).sort(
    {
      start: -1
    }
    ).exec(function (err, alerts) {

      if (alerts.length) {

        alerts.forEach(function (alert) {

          // since the server is UTC - 5 (Detroig)

          client.sms.messages.create({

              to: alert.number,
              from:'+13475146545',
              body: alert.message

          }, function(error, message) {

              // The HTTP request to Twilio will run asynchronously. This callback
              // function will be called when a response is received from Twilio
              // The "error" variable will contain error information, if any.
              // If the request was successful, this value will be "falsy"
              if (!error) {
                  // The second argument to the callback will contain the information
                  // sent back by Twilio for the request. In this case, it is the
                  // information about the text messsage you just sent:
                  db.events.update({
                    _id: alert._id
                  }, {
                    $set: {
                      sent: true,
                      twilioRes: message
                    }
                  }, {}, function(err, num, alert) {

                    res.json({
                      sid: message.sid,
                      dateCreated: message.dateCreated,
                      alert: alert
                    });

                  });

              } else {

                res.json({
                  error: true,
                  errorObj: error
                });

              }

          });

        });
      } else {
        res.json({
          alerts: []
        });
      }

    });

  };

  var sendAll = function(req, res, next) {

    // find alerts that had to be sent in the last two minutes
    // and have not been already sent

    console.log('send-all');
    res.json({resp: 'send-all'});

    // db.alerts.find({
    //   start: {
    //     $gte: moment().subtract(2, 'minutes').toDate(),
    //     $lte: moment().toDate()
    //   },
    //   set: {
    //     $ne: true
    //   }
    // }).sort({
    //   $ne: true
    // }).exec(function (err, alerts) {
    //   console.log(alerts);
    // });

    // db.alerts.find({
    //   start: {
    //     $gte: moment().subtract(2, 'minutes').toDate(),
    //     $lte: moment().toDate()
    //   },
    //   sent: {
    //     $ne: true
    //   }
    // }).sort({
    //   date: -1
    // }).exec(function (err, alerts) {

    //   if(err) {
    //     return res.send(err, 400);
    //   }

    //   // TODO integrate gateway and send alert
    //   // on success set sent true

    //   alerts.forEach(function(alert) {

    //     client.sms.messages.create({
    //         to:'+40755052956',
    //         from:'+13475146545',
    //         body:'ahoy hoy! Testing Twilio and node.js'
    //     }, function(error, message) {
    //         // The HTTP request to Twilio will run asynchronously. This callback
    //         // function will be called when a response is received from Twilio
    //         // The "error" variable will contain error information, if any.
    //         // If the request was successful, this value will be "falsy"
    //         if (!error) {
    //             // The second argument to the callback will contain the information
    //             // sent back by Twilio for the request. In this case, it is the
    //             // information about the text messsage you just sent:
    //             console.log('Success! The SID for this SMS message is:');
    //             console.log(message.sid);

    //             console.log('Message sent on:');
    //             console.log(message.dateCreated);
    //         } else {
    //             console.log(error);
    //             console.log('Oops! There was an error.');
    //         }
    //     });

    //     // client.makeCall({
    //     //   to:'+40743307087',
    //     //   from:'+13475146545',
    //     //   url:'http://demo.twilio.com/welcome/voice/'
    //     // }, function(err, call) {
    //     //     console.log('This call\'s unique ID is: ' + call.sid);
    //     //     console.log('This call was created at: ' + call.dateCreated);
    //     // });

    //     // nexmo.sendTextMessage(
    //     //   config.sender,
    //     //   alert.number,
    //     //   alert.message,
    //     //   {},
    //     //   function(err, response) {

    //     //     // set sent to true in db
    //     //     db.alerts.update({
    //     //       _id: alert._id
    //     //     }, {
    //     //       $set: {
    //     //         sent: true
    //     //       }
    //     //     }, {}, function(err, alert) {

    //     //       //console.log(alert);

    //     //     });

    //     //   });

    //   });

    //   res.json(alerts);

    // });

  };

  return {
    create: create,
    list: list,
    sendAll: sendAll,
    get: get,
    remove: remove,
    update: update,
    remind: remind
  };

};
<commit_msg>Added extra branding message<commit_after>/* alerts
 */

module.exports = function(config, db) {
  'use strict';

  var express = require('express');
  var request = require('superagent');
  var async = require('async');
  var fs = require('fs');
  var util = require('util');
  var twilio = require('twilio');

  var moment = require('moment');

  var nexmo = require('easynexmo');

  nexmo.initialize(
    config.gateway.key,
    config.gateway.secret,
    config.gateway.protocol,
    config.gateway.debug
  );

  var twilio = require('twilio');
  var client = new twilio.RestClient('AC843270d590f2988caf4993adb06e0294', 'bada3f2f91251f3c0f6edefe94022366');

  var create = function(req, res, next) {

    req.checkBody('name', 'Title should not be empty').notEmpty();
    req.checkBody('number', 'Number should not be empty.').notEmpty();
    req.checkBody('start', 'Start date should not be empty.').notEmpty();
    req.checkBody('end', 'End date should not be empty.').notEmpty();
    req.checkBody('message', 'Message should not be empty.').notEmpty();

    var name = req.body.name.trim();
    var userName = req.body.userName.trim();
    var companyName = req.body.message.trim();

    var message = req.body.message.trim();

    var number = req.body.number.replace(/[-() ]/gi, '');
    var startDate = new Date(req.body.start);
    var endDate = new Date(req.body.end);

    // TODO add multiple validations after transforms
    var errors = req.validationErrors();

    if (errors) {
      res.status(400).json(errors);
      return;
    }

    var event = {
      status: false,
      name: name,
      userName: userName,
      companyName: companyName,
      title: name,
      number: number,
      start: startDate,
      end: endDate,
      calendarId: req.params.calendarId,
      message: message
    };

    db.events.insert(event, function (err, newEvent) {

      res.json({
        message: 'Create successful.',
        event: newEvent
      });

    });

    var contact = {
      name: name,
      title: name,
      number: number,
      calendarId: req.params.calendarId
    };

    db.contacts.findOne({'name': contact.name, 'number': contact.number, 'calendarId': contact.calendarId}, function (err, doc) {

      if (err) {
        res.json(util.inspect(errors), 400);
        return;
      }

      if (!doc) {

        db.contacts.insert(contact, function (err, newContact) {

          if (err) {
            res.json(util.inspect(errors), 400);
            return;
          }

        });
      }
    });

  };

  var update = function (req, res, next) {
    req.checkBody('name', 'Title should not be empty').notEmpty();
    req.checkBody('number', 'Number should not be empty.').notEmpty();
    req.checkBody('start', 'Start date should not be empty.').notEmpty();
    req.checkBody('end', 'End date should not be empty.').notEmpty();
    req.checkBody('message', 'Message should not be empty.').notEmpty();
    req.checkBody('_id', 'ID should not be empty.').notEmpty();

    var name = req.body.name.trim();
    var number = req.body.number.replace(/[-() ]/gi, '');
    var startDate = Date.create(req.body.start);
    var endDate = Date.create(req.body.end);
    var message = req.body.message;
    var eventId = req.body._id;

    startDate = moment(startDate).toDate();
    endDate = moment(endDate).toDate();

    // TODO add multiple validations after transforms

    var errors = req.validationErrors();

    if (errors) {
      res.json(util.inspect(errors), 400);
      return;
    }

    var event = {
      status: false,
      name: name,
      title: name,
      number: number,
      start: startDate,
      end: endDate,
      calendarId: req.params.calendarId,
      message: message
    };

    db.events.update({'_id': eventId}, event, function (err, num, newEvent) {

      if (num > 0) {

        db.events.findOne({'_id': eventId}, function (err, doc) {

          res.json({
            message: 'Update successfull.',
            event: doc
          });

        });

      } else {

        res.json(util.inspect(errors), 400);

      }

    });
  }

  var list = function(req, res, next) {

    db.events.find({
      calendarId: req.params.calendarId
    }).sort({
      date: -1
    }).exec(function (err, events) {

      if(err) {
        return res.send(err, 400);
      }

      if (!events.length) {
        events = [];
      }

      res.json(events);

    });

  };

  var get = function(req, res, next) {

    db.events.findOne({
      _id: req.params.eventId
    }).exec(function (err, event) {

      if(err) {
        return res.send(err, 400);
      }

      if (!alert) {
        event = {};
      }

      res.json(event);

    });

  };

  var remove = function(req, res, next) {
    var id = req.params.alertId;
    db.events.remove({
      _id: req.params.eventId
    },function (err, num) {

      if(err) {
        return res.send(err, 400);
      }

      res.json({message: 'Delete successful ' + id, num: num});

    });

  };

  var remind = function (req, res, next) {

    var lte = moment().add(1, 'hours').toDate();
    var gte = moment().toDate();

    db.events.find({
      start: {
        $lte: lte,
        $gte: gte
      },
      sent: {
        $ne: true
      }
    }).sort(
    {
      start: -1
    }
    ).exec(function (err, alerts) {

      if (alerts.length) {

        alerts.forEach(function (alert) {

          client.sms.messages.create({

              to: alert.number,
              from:'+13475146545',
              body: alert.message.append(' Reminded by Apunto')

          }, function(error, message) {

              // The HTTP request to Twilio will run asynchronously. This callback
              // function will be called when a response is received from Twilio
              // The "error" variable will contain error information, if any.
              // If the request was successful, this value will be "falsy"
              if (!error) {
                  // The second argument to the callback will contain the information
                  // sent back by Twilio for the request. In this case, it is the
                  // information about the text messsage you just sent:
                  db.events.update({
                    _id: alert._id
                  }, {
                    $set: {
                      sent: true,
                      twilioRes: message
                    }
                  }, {}, function(err, num, alert) {

                    res.json({
                      sid: message.sid,
                      dateCreated: message.dateCreated,
                      alert: alert
                    });

                  });

              } else {

                res.json({
                  error: true,
                  errorObj: error
                });

              }

          });

        });
      } else {
        res.json({
          alerts: []
        });
      }

    });

  };

  var sendAll = function(req, res, next) {

    // find alerts that had to be sent in the last two minutes
    // and have not been already sent

    console.log('send-all');
    res.json({resp: 'send-all'});

    // db.alerts.find({
    //   start: {
    //     $gte: moment().subtract(2, 'minutes').toDate(),
    //     $lte: moment().toDate()
    //   },
    //   set: {
    //     $ne: true
    //   }
    // }).sort({
    //   $ne: true
    // }).exec(function (err, alerts) {
    //   console.log(alerts);
    // });

    // db.alerts.find({
    //   start: {
    //     $gte: moment().subtract(2, 'minutes').toDate(),
    //     $lte: moment().toDate()
    //   },
    //   sent: {
    //     $ne: true
    //   }
    // }).sort({
    //   date: -1
    // }).exec(function (err, alerts) {

    //   if(err) {
    //     return res.send(err, 400);
    //   }

    //   // TODO integrate gateway and send alert
    //   // on success set sent true

    //   alerts.forEach(function(alert) {

    //     client.sms.messages.create({
    //         to:'+40755052956',
    //         from:'+13475146545',
    //         body:'ahoy hoy! Testing Twilio and node.js'
    //     }, function(error, message) {
    //         // The HTTP request to Twilio will run asynchronously. This callback
    //         // function will be called when a response is received from Twilio
    //         // The "error" variable will contain error information, if any.
    //         // If the request was successful, this value will be "falsy"
    //         if (!error) {
    //             // The second argument to the callback will contain the information
    //             // sent back by Twilio for the request. In this case, it is the
    //             // information about the text messsage you just sent:
    //             console.log('Success! The SID for this SMS message is:');
    //             console.log(message.sid);

    //             console.log('Message sent on:');
    //             console.log(message.dateCreated);
    //         } else {
    //             console.log(error);
    //             console.log('Oops! There was an error.');
    //         }
    //     });

    //     // client.makeCall({
    //     //   to:'+40743307087',
    //     //   from:'+13475146545',
    //     //   url:'http://demo.twilio.com/welcome/voice/'
    //     // }, function(err, call) {
    //     //     console.log('This call\'s unique ID is: ' + call.sid);
    //     //     console.log('This call was created at: ' + call.dateCreated);
    //     // });

    //     // nexmo.sendTextMessage(
    //     //   config.sender,
    //     //   alert.number,
    //     //   alert.message,
    //     //   {},
    //     //   function(err, response) {

    //     //     // set sent to true in db
    //     //     db.alerts.update({
    //     //       _id: alert._id
    //     //     }, {
    //     //       $set: {
    //     //         sent: true
    //     //       }
    //     //     }, {}, function(err, alert) {

    //     //       //console.log(alert);

    //     //     });

    //     //   });

    //   });

    //   res.json(alerts);

    // });

  };

  return {
    create: create,
    list: list,
    sendAll: sendAll,
    get: get,
    remove: remove,
    update: update,
    remind: remind
  };

};
<|endoftext|>


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

    var EventEmitter= require('events').EventEmitter,

        versionio   = require('version-io'),
        changelog   = require('changelog-io'),
        rendy       = require('rendy'),
        spawnify    = require('spawnify'),
        series      = require('async/series'),
        minor       = require('minor'),
        prepend     = require('prepend'),
        grizzly     = require('grizzly'),
        readjson    = require('readjson'),
        writejson   = require('writejson'),
        jessy       = require('jessy'),

        Cmd         = [
            'git add --all',
            'git commit -m "chore(package) v{{ version }}"',
            'git pull --rebase',
            'git push origin {{ branch }}',
        ].join('&&'),

        CmdTag      = [
            'git tag v{{ version }}',
            'git push origin v{{ version }}'
        ].join('&&'),

        MSG         = [ 'publish <version>',
                        'package: {{ name }} v{{ version }}'
                    ].join('\n');

    module.exports  = function(version) {
        var emitter = new EventEmitter(),
            name    = process.cwd() + '/package.json';

        readjson(name, function(error, info) {
            var msg;

            if (error) {
                msg             = error.message;
                error.message   = 'Error reading package.json: ' + msg;
                emitter.emit('error', error);
            } else if (!version) {
                emitter.emit('data', rendy(MSG, {
                    name    : info.name,
                    version : info.version
                }));
            } else {
                publish(version, info, emitter);
            }
        });

        return emitter;
    };

    function publish(version, info, emitter) {
        var cmd,
            cmdTag,
            type        = '--',
            chlog       = '';

        if (!version.indexOf('v')) {
            version  = version.slice(1);
            type    += 'v' + version;
        } else if (/major|minor|patch/.test(version)) {
            type    += version;
            version  = minor(version, info.version);
        }

        cmd = rendy(Cmd, {
            version: version,
            branch: info.branch || 'master'
        });

        cmdTag = rendy(CmdTag, {
            version: version
        });

        series([
            function beforePublish(callback) {
                var cmd     = jessy('scripts.wisdom', info);

                if (!cmd)
                    callback();
                else
                    runWisdom('wisdom', type, emitter, callback);
            },

            function(callback) {
                var isUndefined = typeof info.changelog === 'undefined';

                if (!isUndefined && !info.changelog) {
                    emitter.emit('data', 'changelog: false\n');
                    callback();
                } else {
                    changelog(version, function(error, data) {
                        if (error) {
                            error.message += '\n';
                            callback(error);
                        } else {
                            prepend('ChangeLog', data, callback);

                            chlog = rmLines(data, 2);
                            chlog = markdown(chlog);
                        }
                    });
                }
            },

            function(callback) {
                versionio(version, callback);
            },

            function(callback) {
                readjson('bower.json', function(error, json) {
                    if (error && error.code !== 'ENOENT')
                        return emitter.emit('error', error);

                    if (error || !json.version) {
                        callback();
                    } else {
                        emitter.emit('data', 'bower.version is deprecated (https://github.com/bower/spec/blob/master/json.md#version). Removing...');
                        delete json.version;
                        writejson('bower.json', {space: 2}, json, callback);
                    }
                });
            },

            function(callback) {
               execute(cmd, emitter, callback);
            },

            function release(callback) {
                if (!info.release && info.release !== undefined) {
                    emitter.emit('data', 'release: false\n');
                    callback();
                } else {
                    execute(cmdTag, emitter, callback);
                }
            },

            function publish(callback) {
                if (!info.release && info.release !== undefined)
                    return callback();

                var v       = 'v' + version,
                    repo    = getRepoName(info),
                    owner   = getOwner(info),
                    data    = {
                        owner       : owner,
                        repo        : repo,
                        tag_name    : v,
                        name        : info.name + ' ' + v,
                        body        : chlog
                    };

                grizzly(null, data, function(error) {
                    if (!error) {
                        emitter.emit('data', 'release: ok\n');
                        callback();
                    } else {
                        emitter.emit('data', 'Error releasing on github. Trying again.\n');
                        publish(callback);
                    }
                });
            },

            function npmPublish(callback) {
                if (info.private)
                    callback();
                else
                    execute('npm publish', emitter, callback);
            },

            function afterPublish(callback) {
                var cmd = jessy('scripts.wisdom:done', info);

                if (!cmd)
                    callback();
                else
                    runWisdom('wisdom:done', null, emitter, callback);
            },
        ], function(error) {
            if (error)
                emitter.emit('error', error);

            emitter.emit('exit');
        });

        return emitter;
    }

    function execute(cmd, emitter, callback) {
        var rejected,
            spawn = spawnify(cmd);

        spawn.on('error', function(error) {
            rejected = ~error.message.indexOf('rejected');

            emitter.emit('error', error);

            if (rejected)
                callback(error);
        });

        spawn.on('data', function(data) {
            emitter.emit('data', data);
        });

        spawn.on('exit', function() {
            spawn = null;

            if (!rejected)
                callback();
        });
    }

    function runWisdom(name, type, emitter, callback) {
        var isError,
            cmd,
            spawn,
            array = ['npm', 'run', name];

        if (type)
            array = array.concat('--', type);

        cmd     = array.join(' ');
        spawn   = spawnify(cmd);

        spawn.on('error', function(error) {
            isError = true;
            emitter.emit('error', error);
        });

        spawn.on('data', function(data) {
            emitter.emit('data', data);
        });

        spawn.on('close', function() {
            callback();
        });
    }

    function rmLines(str, count) {
        return str
            .split('\n')
            .slice(count)
            .join('\n');
    }

    function markdown(str) {
        return str
            .replace(/\bfix\b:/g, '## fix')
            .replace(/\bfeature\b:/g, '## feature');
    }

    function getRepoName(json) {
        return json.repository.url
            .split('/')
            .pop()
            .replace('.git', '');
    }

    function getOwner(json) {
        var FROM_OWNER   = 3,
            WITHOUT_REPO = -1;

        return json.repository.url
            .split('/')
            .slice(FROM_OWNER, WITHOUT_REPO)
            .pop();
    }
})();
<commit_msg>fix(wisdom) writejson: options, data -> data, options<commit_after>(function() {
    'use strict';

    var EventEmitter= require('events').EventEmitter,

        versionio   = require('version-io'),
        changelog   = require('changelog-io'),
        rendy       = require('rendy'),
        spawnify    = require('spawnify'),
        series      = require('async/series'),
        minor       = require('minor'),
        prepend     = require('prepend'),
        grizzly     = require('grizzly'),
        readjson    = require('readjson'),
        writejson   = require('writejson'),
        jessy       = require('jessy'),

        Cmd         = [
            'git add --all',
            'git commit -m "chore(package) v{{ version }}"',
            'git pull --rebase',
            'git push origin {{ branch }}',
        ].join('&&'),

        CmdTag      = [
            'git tag v{{ version }}',
            'git push origin v{{ version }}'
        ].join('&&'),

        MSG         = [ 'publish <version>',
                        'package: {{ name }} v{{ version }}'
                    ].join('\n');

    module.exports  = function(version) {
        var emitter = new EventEmitter(),
            name    = process.cwd() + '/package.json';

        readjson(name, function(error, info) {
            var msg;

            if (error) {
                msg             = error.message;
                error.message   = 'Error reading package.json: ' + msg;
                emitter.emit('error', error);
            } else if (!version) {
                emitter.emit('data', rendy(MSG, {
                    name    : info.name,
                    version : info.version
                }));
            } else {
                publish(version, info, emitter);
            }
        });

        return emitter;
    };

    function publish(version, info, emitter) {
        var cmd,
            cmdTag,
            type        = '--',
            chlog       = '';

        if (!version.indexOf('v')) {
            version  = version.slice(1);
            type    += 'v' + version;
        } else if (/major|minor|patch/.test(version)) {
            type    += version;
            version  = minor(version, info.version);
        }

        cmd = rendy(Cmd, {
            version: version,
            branch: info.branch || 'master'
        });

        cmdTag = rendy(CmdTag, {
            version: version
        });

        series([
            function beforePublish(callback) {
                var cmd     = jessy('scripts.wisdom', info);

                if (!cmd)
                    callback();
                else
                    runWisdom('wisdom', type, emitter, callback);
            },

            function(callback) {
                var isUndefined = typeof info.changelog === 'undefined';

                if (!isUndefined && !info.changelog) {
                    emitter.emit('data', 'changelog: false\n');
                    callback();
                } else {
                    changelog(version, function(error, data) {
                        if (error) {
                            error.message += '\n';
                            callback(error);
                        } else {
                            prepend('ChangeLog', data, callback);

                            chlog = rmLines(data, 2);
                            chlog = markdown(chlog);
                        }
                    });
                }
            },

            function(callback) {
                versionio(version, callback);
            },

            function(callback) {
                readjson('bower.json', function(error, json) {
                    if (error && error.code !== 'ENOENT')
                        return emitter.emit('error', error);

                    if (error || !json.version) {
                        callback();
                    } else {
                        emitter.emit('data', 'bower.version is deprecated (https://github.com/bower/spec/blob/master/json.md#version). Removing...\n');
                        delete json.version;
                        writejson('bower.json', json, {space: 2}, callback);
                    }
                });
            },

            function(callback) {
               execute(cmd, emitter, callback);
            },

            function release(callback) {
                if (!info.release && info.release !== undefined) {
                    emitter.emit('data', 'release: false\n');
                    callback();
                } else {
                    execute(cmdTag, emitter, callback);
                }
            },

            function publish(callback) {
                if (!info.release && info.release !== undefined)
                    return callback();

                var v       = 'v' + version,
                    repo    = getRepoName(info),
                    owner   = getOwner(info),
                    data    = {
                        owner       : owner,
                        repo        : repo,
                        tag_name    : v,
                        name        : info.name + ' ' + v,
                        body        : chlog
                    };

                grizzly(null, data, function(error) {
                    if (!error) {
                        emitter.emit('data', 'release: ok\n');
                        callback();
                    } else {
                        emitter.emit('data', 'Error releasing on github. Trying again.\n');
                        publish(callback);
                    }
                });
            },

            function npmPublish(callback) {
                if (info.private)
                    callback();
                else
                    execute('npm publish', emitter, callback);
            },

            function afterPublish(callback) {
                var cmd = jessy('scripts.wisdom:done', info);

                if (!cmd)
                    callback();
                else
                    runWisdom('wisdom:done', null, emitter, callback);
            },
        ], function(error) {
            if (error)
                emitter.emit('error', error);

            emitter.emit('exit');
        });

        return emitter;
    }

    function execute(cmd, emitter, callback) {
        var rejected,
            spawn = spawnify(cmd);

        spawn.on('error', function(error) {
            rejected = ~error.message.indexOf('rejected');

            emitter.emit('error', error);

            if (rejected)
                callback(error);
        });

        spawn.on('data', function(data) {
            emitter.emit('data', data);
        });

        spawn.on('exit', function() {
            spawn = null;

            if (!rejected)
                callback();
        });
    }

    function runWisdom(name, type, emitter, callback) {
        var isError,
            cmd,
            spawn,
            array = ['npm', 'run', name];

        if (type)
            array = array.concat('--', type);

        cmd     = array.join(' ');
        spawn   = spawnify(cmd);

        spawn.on('error', function(error) {
            isError = true;
            emitter.emit('error', error);
        });

        spawn.on('data', function(data) {
            emitter.emit('data', data);
        });

        spawn.on('close', function() {
            callback();
        });
    }

    function rmLines(str, count) {
        return str
            .split('\n')
            .slice(count)
            .join('\n');
    }

    function markdown(str) {
        return str
            .replace(/\bfix\b:/g, '## fix')
            .replace(/\bfeature\b:/g, '## feature');
    }

    function getRepoName(json) {
        return json.repository.url
            .split('/')
            .pop()
            .replace('.git', '');
    }

    function getOwner(json) {
        var FROM_OWNER   = 3,
            WITHOUT_REPO = -1;

        return json.repository.url
            .split('/')
            .slice(FROM_OWNER, WITHOUT_REPO)
            .pop();
    }
})();
<|endoftext|>


<commit_before>/**
 * Dependencies.
 */
var _ = require('lodash');
var async = require('async');
var sequelize = require('sequelize');
var utils = require('../lib/utils');

/**
 * Controller.
 */
module.exports = function(app) {

  /**
   * Internal Dependencies.
   */
  var errors = app.errors;
  var models = app.set('models');
  var Group = models.Group;
  var Activity = models.Activity;
  var Transaction = models.Transaction;
  var StripeManagedAccount = models.StripeManagedAccount;
  var transactions = require('../controllers/transactions')(app);

  /**
   * Private methods.
   */
  var addGroupMember = function(group, user, options, callback) {
    group
      .addMember(user, {role: options.role})
      .then(function(usergroup) {
        callback();

        // Create activities.
        var activity = {
          type: 'group.user.added',
          GroupId: group.id,
          data: {
            group: group.info,
            user: options.remoteUser.info,
            target: user.info,
            usergroup: usergroup.info
          }
        };
        Activity.create(_.extend({UserId: options.remoteUser.id}, activity));
        if (user.id !== options.remoteUser.id)
          Activity.create(_.extend({UserId: user.id}, activity));
      })
      .catch(callback);
  };

  /**
   * Public methods.
   */
  return {

    /**
     * Create a group.
     */
    create: function(req, res, next) {
      Group
        .create(req.required.group)
        .then(function(group) {

          // Create activity.
          Activity.create({
            type: 'group.created',
            UserId: req.remoteUser.id,
            GroupId: group.id,
            data: {
              group: group.info,
              user: req.remoteUser.info
            }
          });

          async.series({
            addMember: function(cb) {
              // Add caller to the group if `role` specified.
              var role = req.body.role;
              if (!role)
                return cb();
              var options = {
                role: role,
                remoteUser: req.remoteUser
              };
              addGroupMember(group, req.remoteUser, options, cb);
            },
            createStripeManagedAccount: function(cb) {
              app.stripe.accounts.create({
                managed: true
              }, function(e, account) {
                if (e) return cb(e);
                StripeManagedAccount
                  .create({
                    stripeId: account.id,
                    stripeSecret: account.keys.secret,
                    stripeKey: account.keys.publishable
                  })
                  .then(function(account) {
                    account.addGroup(group.id).done(cb);
                  })
                  .catch(cb);
              });
            }
          }, function(e) {
            if (e) return next(e);
            res.send(group.info);
          });

        })
        .catch(next);
    },

    /**
     * Update.
     */
    update: function(req, res, next) {
      ['name', 'description', 'budget', 'currency', 'membership_type', 'membershipfee'].forEach(function(prop) {
        if (req.required.group[prop])
          req.group[prop] = req.required.group[prop];
      });
      req.group.updatedAt = new Date();

      req.group
        .save()
        .then(function(group) {
          res.send(group.info);
        })
        .catch(next);
    },

    /**
     * Get group content.
     */
    get: function(req, res, next) {

      async.auto({

        getPositivesTransactions: function(cb) {
          Transaction
            .find({
              attributes: [
                [sequelize.fn('SUM', sequelize.col('amount')), 'total']
              ],
              where: {
                GroupId: req.group.id,
                amount: {$gt: 0}
              }
            })
            .then(function(result) {
              cb(null, result.toJSON().total);
            })
            .catch(cb);
        },

        getNegativesTransactions: function(cb) {
          Transaction
            .find({
              attributes: [
                [sequelize.fn('SUM', sequelize.col('amount')), 'total']
              ],
              where: {
                GroupId: req.group.id,
                amount: {$lt: 0}
              }
            })
            .then(function(result) {
              cb(null, result.toJSON().total);
            })
            .catch(cb);
        },

        getActivities: function(cb) {
          if (!req.query.activities && !req.body.activities)
            return cb();

          var query = {
            where: {
              GroupId: req.group.id
            },
            order: [['createdAt', 'DESC']],
            offset: 0,
            limit: 20 // [TODO] I need to put this default value
            // as a global parameter. Using mw.paginate?
          };

          Activity
            .findAndCountAll(query)
            .then(function(activities) {
              cb(null, activities.rows);
            })
            .catch(cb);
        },

        getStripeManagedAccount: function(cb) {
          req.group.getStripeManagedAccount()
            .done(cb);
        }

      }, function(e, results) {
        if (e) return next(e);

        var group = req.group.info;

        // hack for YC demo, to remove
        group.budget = group.budget - results.getPositivesTransactions;
        group.budgetLeft = group.budget + results.getNegativesTransactions;
        if (results.getActivities) {
          group.activities = results.getActivities;
        }

        if (results.getStripeManagedAccount) {
          group.stripeManagedAccount = _.pick(results.getStripeManagedAccount,
                                              'stripeKey');
        }

        res.send(group);
      });

    },

    /**
     * Add a user to a group.
     */
    addMember: function(req, res, next) {
      var options = {
        role: req.body.role || 'viewer',
        remoteUser: req.remoteUser
      };
      addGroupMember(req.group, req.user, options, function(e) {
        if (e) return next(e);
        else res.send({success: true});
      });
    },

    /**
     * Update a member.
     */
    updateMember: function(req, res, next) {
      var query = {
        where: {
          GroupId: req.group.id,
          UserId: req.user.id
        }
      };

      models
        .UserGroup
        .findOne(query)
        .then(function(usergroup) {
          if (!usergroup) {
            throw (new errors.NotFound('The user is not part of the group yet.'));
          }

          return usergroup;
        })
        .then(function(usergroup) {
          ['role'].forEach(function(prop) {
            if (req.body[prop])
              usergroup[prop] = req.body[prop];
          });
          usergroup.updatedAt = new Date();

          return usergroup
            .save();
        })
        .then(function(usergroup) {
          // Create activities.
          var remoteUser = (req.remoteUser && req.remoteUser.info) || (req.application && req.application.info);
          var activity = {
            type: 'group.user.updated',
            GroupId: req.group.id,
            data: {
              group: req.group.info,
              user: remoteUser,
              target: req.user.info,
              usergroup: usergroup.info
            }
          };
          Activity.create(_.extend({UserId: req.user.id}, activity));
          if (req.remoteUser && req.user.id !== req.remoteUser.id)
            Activity.create(_.extend({UserId: req.remoteUser.id}, activity));

          return usergroup;
        })
        .then(function(usergroup) {
          res.send(usergroup);
        })
        .catch(next);
    },

    /**
     * Delete a member.
     */
    deleteMember: function(req, res, next) {
      var query = {
        where: {
          GroupId: req.group.id,
          UserId: req.user.id
        }
      };

      models
        .UserGroup
        .findOne(query)
        .then(function(usergroup) {
          if (!usergroup) {
            throw (new errors.NotFound('The user is not part of the group yet.'));
          }

          return usergroup;
        })
        .then(function(usergroup) {
          return usergroup.destroy();
        })
        .then(function() {
          // Create activities.
          var remoteUser = (req.remoteUser && req.remoteUser.info) || (req.application && req.application.info);
          var activity = {
            type: 'group.user.deleted',
            GroupId: req.group.id,
            data: {
              group: req.group.info,
              user: remoteUser,
              target: req.user.info
            }
          };
          Activity.create(_.extend({UserId: req.user.id}, activity));
          if (req.remoteUser && req.user.id !== req.remoteUser.id)
            Activity.create(_.extend({UserId: req.remoteUser.id}, activity));
          return;
        })
        .then(function() {
          res.send({success: true});
        })
        .catch(next);
    },

    /**
     * Create a transaction and add it to a group.
     */
    createTransaction: function(req, res, next) {
      var transaction = req.required.transaction;
      var group = req.group;

      // Caller.
      var user = req.remoteUser || transaction.user || {};

      var t = {
        transaction: transaction,
        group: group,
        user: user
      };
      transactions._create(t, function(e, transactionCreated) {
        if (e) return next(e);
        res.send(transactionCreated);
      });

    },

    /**
     * Delete a transaction.
     */
    deleteTransaction: function(req, res, next) {
       var transaction = req.transaction;
       var group = req.group;
       var user = req.remoteUser || {};

       async.auto({

         deleteTransaction: function(cb) {
           transaction
             .destroy()
             .done(cb);
         },

         createActivity: ['deleteTransaction', function(cb) {
           Activity.create({
             type: 'group.transaction.deleted',
             UserId: user.id,
             GroupId: group.id,
             data: {
               group: group.info,
               transaction: transaction,
               user: user.info
             }
           }).done(cb);
         }]

       }, function(e) {
         if (e) return next(e);
         res.send({success: true});
       });

     },

    /**
     * Get group's transactions.
     */
    getTransactions: function(req, res, next) {
      var query = _.merge({
        where: {
          GroupId: req.group.id
        },
        order: [[req.sorting.key, req.sorting.dir]]
      }, req.pagination);

      Transaction
        .findAndCountAll(query)
        .then(function(transactions) {

          // Set headers for pagination.
          req.pagination.total = transactions.count;
          res.set({
            Link: utils.getLinkHeader(utils.getRequestedUrl(req),
                                        req.pagination)
          });

          res.send(transactions.rows);
        })
        .catch(next);
    },

    /**
     * Get a group's transaction.
     */
    getTransaction: function(req, res, next) {
      res.json(req.transaction.info);
    }

  };

};
<commit_msg>Revert "TO REVERSE: Hack for YC demo"<commit_after>/**
 * Dependencies.
 */
var _ = require('lodash');
var async = require('async');
var sequelize = require('sequelize');
var utils = require('../lib/utils');

/**
 * Controller.
 */
module.exports = function(app) {

  /**
   * Internal Dependencies.
   */
  var errors = app.errors;
  var models = app.set('models');
  var Group = models.Group;
  var Activity = models.Activity;
  var Transaction = models.Transaction;
  var StripeManagedAccount = models.StripeManagedAccount;
  var transactions = require('../controllers/transactions')(app);

  /**
   * Private methods.
   */
  var addGroupMember = function(group, user, options, callback) {
    group
      .addMember(user, {role: options.role})
      .then(function(usergroup) {
        callback();

        // Create activities.
        var activity = {
          type: 'group.user.added',
          GroupId: group.id,
          data: {
            group: group.info,
            user: options.remoteUser.info,
            target: user.info,
            usergroup: usergroup.info
          }
        };
        Activity.create(_.extend({UserId: options.remoteUser.id}, activity));
        if (user.id !== options.remoteUser.id)
          Activity.create(_.extend({UserId: user.id}, activity));
      })
      .catch(callback);
  };

  /**
   * Public methods.
   */
  return {

    /**
     * Create a group.
     */
    create: function(req, res, next) {
      Group
        .create(req.required.group)
        .then(function(group) {

          // Create activity.
          Activity.create({
            type: 'group.created',
            UserId: req.remoteUser.id,
            GroupId: group.id,
            data: {
              group: group.info,
              user: req.remoteUser.info
            }
          });

          async.series({
            addMember: function(cb) {
              // Add caller to the group if `role` specified.
              var role = req.body.role;
              if (!role)
                return cb();
              var options = {
                role: role,
                remoteUser: req.remoteUser
              };
              addGroupMember(group, req.remoteUser, options, cb);
            },
            createStripeManagedAccount: function(cb) {
              app.stripe.accounts.create({
                managed: true
              }, function(e, account) {
                if (e) return cb(e);
                StripeManagedAccount
                  .create({
                    stripeId: account.id,
                    stripeSecret: account.keys.secret,
                    stripeKey: account.keys.publishable
                  })
                  .then(function(account) {
                    account.addGroup(group.id).done(cb);
                  })
                  .catch(cb);
              });
            }
          }, function(e) {
            if (e) return next(e);
            res.send(group.info);
          });

        })
        .catch(next);
    },

    /**
     * Update.
     */
    update: function(req, res, next) {
      ['name', 'description', 'budget', 'currency', 'membership_type', 'membershipfee'].forEach(function(prop) {
        if (req.required.group[prop])
          req.group[prop] = req.required.group[prop];
      });
      req.group.updatedAt = new Date();

      req.group
        .save()
        .then(function(group) {
          res.send(group.info);
        })
        .catch(next);
    },

    /**
     * Get group content.
     */
    get: function(req, res, next) {

      async.auto({

        getPositivesTransactions: function(cb) {
          Transaction
            .find({
              attributes: [
                [sequelize.fn('SUM', sequelize.col('amount')), 'total']
              ],
              where: {
                GroupId: req.group.id,
                amount: {$gt: 0}
              }
            })
            .then(function(result) {
              cb(null, result.toJSON().total);
            })
            .catch(cb);
        },

        getNegativesTransactions: function(cb) {
          Transaction
            .find({
              attributes: [
                [sequelize.fn('SUM', sequelize.col('amount')), 'total']
              ],
              where: {
                GroupId: req.group.id,
                amount: {$lt: 0}
              }
            })
            .then(function(result) {
              cb(null, result.toJSON().total);
            })
            .catch(cb);
        },

        getActivities: function(cb) {
          if (!req.query.activities && !req.body.activities)
            return cb();

          var query = {
            where: {
              GroupId: req.group.id
            },
            order: [['createdAt', 'DESC']],
            offset: 0,
            limit: 20 // [TODO] I need to put this default value
            // as a global parameter. Using mw.paginate?
          };

          Activity
            .findAndCountAll(query)
            .then(function(activities) {
              cb(null, activities.rows);
            })
            .catch(cb);
        },

        getStripeManagedAccount: function(cb) {
          req.group.getStripeManagedAccount()
            .done(cb);
        }

      }, function(e, results) {
        if (e) return next(e);

        var group = req.group.info;
        group.budget = group.budget + results.getPositivesTransactions;
        group.budgetLeft = group.budget + results.getNegativesTransactions;
        if (results.getActivities) {
          group.activities = results.getActivities;
        }

        if (results.getStripeManagedAccount) {
          group.stripeManagedAccount = _.pick(results.getStripeManagedAccount,
                                              'stripeKey');
        }

        res.send(group);
      });

    },

    /**
     * Add a user to a group.
     */
    addMember: function(req, res, next) {
      var options = {
        role: req.body.role || 'viewer',
        remoteUser: req.remoteUser
      };
      addGroupMember(req.group, req.user, options, function(e) {
        if (e) return next(e);
        else res.send({success: true});
      });
    },

    /**
     * Update a member.
     */
    updateMember: function(req, res, next) {
      var query = {
        where: {
          GroupId: req.group.id,
          UserId: req.user.id
        }
      };

      models
        .UserGroup
        .findOne(query)
        .then(function(usergroup) {
          if (!usergroup) {
            throw (new errors.NotFound('The user is not part of the group yet.'));
          }

          return usergroup;
        })
        .then(function(usergroup) {
          ['role'].forEach(function(prop) {
            if (req.body[prop])
              usergroup[prop] = req.body[prop];
          });
          usergroup.updatedAt = new Date();

          return usergroup
            .save();
        })
        .then(function(usergroup) {
          // Create activities.
          var remoteUser = (req.remoteUser && req.remoteUser.info) || (req.application && req.application.info);
          var activity = {
            type: 'group.user.updated',
            GroupId: req.group.id,
            data: {
              group: req.group.info,
              user: remoteUser,
              target: req.user.info,
              usergroup: usergroup.info
            }
          };
          Activity.create(_.extend({UserId: req.user.id}, activity));
          if (req.remoteUser && req.user.id !== req.remoteUser.id)
            Activity.create(_.extend({UserId: req.remoteUser.id}, activity));

          return usergroup;
        })
        .then(function(usergroup) {
          res.send(usergroup);
        })
        .catch(next);
    },

    /**
     * Delete a member.
     */
    deleteMember: function(req, res, next) {
      var query = {
        where: {
          GroupId: req.group.id,
          UserId: req.user.id
        }
      };

      models
        .UserGroup
        .findOne(query)
        .then(function(usergroup) {
          if (!usergroup) {
            throw (new errors.NotFound('The user is not part of the group yet.'));
          }

          return usergroup;
        })
        .then(function(usergroup) {
          return usergroup.destroy();
        })
        .then(function() {
          // Create activities.
          var remoteUser = (req.remoteUser && req.remoteUser.info) || (req.application && req.application.info);
          var activity = {
            type: 'group.user.deleted',
            GroupId: req.group.id,
            data: {
              group: req.group.info,
              user: remoteUser,
              target: req.user.info
            }
          };
          Activity.create(_.extend({UserId: req.user.id}, activity));
          if (req.remoteUser && req.user.id !== req.remoteUser.id)
            Activity.create(_.extend({UserId: req.remoteUser.id}, activity));
          return;
        })
        .then(function() {
          res.send({success: true});
        })
        .catch(next);
    },

    /**
     * Create a transaction and add it to a group.
     */
    createTransaction: function(req, res, next) {
      var transaction = req.required.transaction;
      var group = req.group;

      // Caller.
      var user = req.remoteUser || transaction.user || {};

      var t = {
        transaction: transaction,
        group: group,
        user: user
      };
      transactions._create(t, function(e, transactionCreated) {
        if (e) return next(e);
        res.send(transactionCreated);
      });

    },

    /**
     * Delete a transaction.
     */
    deleteTransaction: function(req, res, next) {
       var transaction = req.transaction;
       var group = req.group;
       var user = req.remoteUser || {};

       async.auto({

         deleteTransaction: function(cb) {
           transaction
             .destroy()
             .done(cb);
         },

         createActivity: ['deleteTransaction', function(cb) {
           Activity.create({
             type: 'group.transaction.deleted',
             UserId: user.id,
             GroupId: group.id,
             data: {
               group: group.info,
               transaction: transaction,
               user: user.info
             }
           }).done(cb);
         }]

       }, function(e) {
         if (e) return next(e);
         res.send({success: true});
       });

     },

    /**
     * Get group's transactions.
     */
    getTransactions: function(req, res, next) {
      var query = _.merge({
        where: {
          GroupId: req.group.id
        },
        order: [[req.sorting.key, req.sorting.dir]]
      }, req.pagination);

      Transaction
        .findAndCountAll(query)
        .then(function(transactions) {

          // Set headers for pagination.
          req.pagination.total = transactions.count;
          res.set({
            Link: utils.getLinkHeader(utils.getRequestedUrl(req),
                                        req.pagination)
          });

          res.send(transactions.rows);
        })
        .catch(next);
    },

    /**
     * Get a group's transaction.
     */
    getTransaction: function(req, res, next) {
      res.json(req.transaction.info);
    }

  };

};
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const childProcess = require('child_process');
const defaultsDeep = require('lodash.defaultsdeep');
const promiseify = require('./promiseify');
const access = promiseify(fs.access);

const WORKER_ENV = 'WORKER_ENV';

const DATA_TAG = 'WORKER_JSON_MESSAGE';
const DATA_TAG_OPEN = `<${DATA_TAG}>`;
const DATA_TAG_CLOSE = `</${DATA_TAG}>`;
const DATA_TAG_REG = new RegExp(`${DATA_TAG_OPEN}(.*?)${DATA_TAG_CLOSE}`);

process.env[WORKER_ENV] = WORKER_ENV;

const decode = content => {
    let match = String(content).match(DATA_TAG_REG);
    if (match) {
        return JSON.parse(match[1]);
    }
};

const encode = data => {
    let json = JSON.stringify(data);
    json = `${DATA_TAG_OPEN}${json}${DATA_TAG_CLOSE}`;
    return json;
};

/**
 * 使用子进程运行命令
 * @see https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
 * @param   {string}    command     命令
 * @param   {Object}    options     进程选项
 * @return  {Promise}
 */
const worker = (command, options = {}) => {

    return new Promise((resolve, reject) => {

        // 子进程继承父进程的环境变量
        options = defaultsDeep({}, options, { env: process.env});

        // 将 node_modules/.bin 加入环境变量，优先使用本地模块执行命令
        let addPath = cwd => {
            let env = options.env;
            if (cwd && env) {
                let localBin = path.resolve(cwd, 'node_modules', '.bin');
                if (env.PATH && !env.PATH.includes(localBin)) {
                    return access(localBin).then(() => {
                        env.PATH = localBin + ':' + env.PATH;
                    }).catch(() => {});
                }
            }
        };

        Promise.all([
            addPath(process.cwd()),
            addPath(options.cwd)
        ]).then(() => {
            let child;
            let timer = null;

            let jsonMode = false;
            let buffers = [];
            let nread = 0;

            let callback = (errors, data) => {
                callback = () => { };
                clearTimeout(timer);

                if (errors) {
                    console.error(`> ${command}`);
                    reject(errors);
                } else {
                    resolve(data);
                }

                if (child) {
                    child.kill();
                }
            };

            try {
                child = childProcess.exec(command, options)
            } catch (errors) {
                callback(errors);
            }

            child.stdout.on('data', content => {

                if (!jsonMode) {
                    content = content.toString();
                    jsonMode = content.includes(DATA_TAG_OPEN);
                }

                if (jsonMode) {
                    buffers.push(content);
                    nread += content.length;
                } else {
                    process.stdout.write(content);
                }
            });

            child.stdout.on('end', () => {
                if (!jsonMode) {
                    return;
                }

                let buffer = null;

                switch (buffers.length) {
                    case 0:
                        buffer = new Buffer(0);
                        break;
                    case 1:
                        buffer = buffers[0];
                        break;
                    default:
                        buffer = new Buffer(nread);
                        for (let i = 0, pos = 0, l = buffers.length; i < l; i++) {
                            let chunk = buffers[i];
                            chunk.copy(buffer, pos);
                            pos += chunk.length;
                        }
                        break;
                }

                let content = buffer.toString();
                let log = content.replace(DATA_TAG_REG, '');
                let data = decode(content);

                if (log) {
                    process.stdout.write(log);
                }

                if (data) {
                    callback(null, data);
                }

            });

            child.stderr.on('data', content => {
                process.stderr.write(content);
            });

            child.on('exit', code => {
                if (code === 0) {
                    callback(null);
                } else {
                    callback(new Error(`"${command}": child process exited with code ${code}.`));
                }
            });

            // 解决 node timeout 不会走异常流程的问题
            if (options.timeout) {
                timer = setTimeout(() => {
                    callback(new Error(`"${command}": child process timeout.`));
                }, options.timeout);
            }

        }).catch(reject);
    });
};

/**
 * 向父进程发送消息 - 子进程只有一次机会发送消息，发送完毕后会被父进程关闭
 * worker.js 是使用 childProcess.exec() 来运行的子进程，
 * nodejs 没有为 exec() 提供进程之间发送消息的方法，所以这里创建私有协议来通讯
 * @param   {Object}    data    JSON 数据
 */
worker.send = (data) => {
    if (process.env[WORKER_ENV] === WORKER_ENV) {
        process.stdout.write(encode(data));
    }
};

module.exports = worker;<commit_msg>重构worker，降低复杂度<commit_after>const fs = require('fs');
const path = require('path');
const childProcess = require('child_process');
const defaultsDeep = require('lodash.defaultsdeep');
const promiseify = require('./promiseify');
const access = promiseify(fs.access);

const WORKER_ENV = 'WORKER_ENV';

const DATA_TAG = 'WORKER_JSON_MESSAGE';
const DATA_TAG_OPEN = `<${DATA_TAG}>`;
const DATA_TAG_CLOSE = `</${DATA_TAG}>`;
const DATA_TAG_REG = new RegExp(`${DATA_TAG_OPEN}(.*?)${DATA_TAG_CLOSE}`);

process.env[WORKER_ENV] = WORKER_ENV;

const decode = content => {
    let match = String(content).match(DATA_TAG_REG);
    if (match) {
        return JSON.parse(match[1]);
    }
};

const encode = data => {
    let json = JSON.stringify(data);
    json = `${DATA_TAG_OPEN}${json}${DATA_TAG_CLOSE}`;
    return json;
};

/**
 * 使用子进程运行命令
 * @see https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
 * @param   {string}    command     命令
 * @param   {Object}    options     进程选项
 * @return  {Promise}
 */
const worker = (command, options = {}) => {

    return new Promise((resolve, reject) => {

        // 子进程继承父进程的环境变量
        options = defaultsDeep({}, options, { env: process.env });

        // 将 node_modules/.bin 加入环境变量，优先使用本地模块执行命令
        let addPath = cwd => {
            let env = options.env;
            if (cwd && env) {
                let localBin = path.resolve(cwd, 'node_modules', '.bin');
                if (env.PATH && !env.PATH.includes(localBin)) {
                    return access(localBin).then(() => {
                        env.PATH = localBin + ':' + env.PATH;
                    }).catch(() => { });
                }
            }
        };

        Promise.all([
            addPath(process.cwd()),
            addPath(options.cwd)
        ]).then(() => {
            let child;
            let timer = null;

            let cache = '';
            let jsonMode = false;

            let callback = (errors, data) => {
                callback = () => { };
                clearTimeout(timer);

                if (errors) {
                    console.error(`> ${command}`);
                    reject(errors);
                } else {
                    resolve(data);
                }

                if (child) {
                    child.kill();
                }
            };

            try {
                child = childProcess.exec(command, options)
            } catch (errors) {
                callback(errors);
            }

            child.stdout.setEncoding('utf8');
            child.stdout.on('data', content => {

                if (!jsonMode) {
                    jsonMode = content.includes(DATA_TAG_OPEN);
                }

                if (jsonMode) {
                    cache += content;
                } else {
                    process.stdout.write(content);
                }
            });

            child.stdout.on('end', () => {
                if (!jsonMode) {
                    return;
                }

                let log = cache.replace(DATA_TAG_REG, '');
                let data = decode(cache);

                if (log) {
                    process.stdout.write(log);
                }

                if (data) {
                    callback(null, data);
                }

            });

            child.stderr.on('data', content => {
                process.stderr.write(content);
            });

            child.on('exit', code => {
                if (code === 0) {
                    callback(null);
                } else {
                    callback(new Error(`"${command}": child process exited with code ${code}.`));
                }
            });

            // 解决 node timeout 不会走异常流程的问题
            if (options.timeout) {
                timer = setTimeout(() => {
                    callback(new Error(`"${command}": child process timeout.`));
                }, options.timeout);
            }

        }).catch(reject);
    });
};

/**
 * 向父进程发送消息 - 子进程只有一次机会发送消息，发送完毕后会被父进程关闭
 * worker.js 是使用 childProcess.exec() 来运行的子进程，
 * nodejs 没有为 exec() 提供进程之间发送消息的方法，所以这里创建私有协议来通讯
 * @param   {Object}    data    JSON 数据
 */
worker.send = (data) => {
    if (process.env[WORKER_ENV] === WORKER_ENV) {
        process.stdout.write(encode(data));
    }
};

module.exports = worker;<|endoftext|>


<commit_before>//jshint strict: false
exports.config = {

  //Sets the amount of time to wait for an asynchronous script to finish execution before throwing an error.
  allScriptsTimeout: 600000,
  //When navigating to a new page using browser.get, Protractor waits for the page to be loaded and the new URL to appear before continuing.
  getPageTimeout: 600000,
  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),

  specs: [
      'features/factsheets.feature'
  ],
  cucumberOpts: {
    // require step definitions
    require: [
      'features/step_definitions/homeSteps.js',
      'features/step_definitions/mortalitySteps.js',
      'features/step_definitions/yrbsSteps.js',
      'features/step_definitions/commonSteps.js',
      'features/step_definitions/bridgeRaceSteps.js',
      'features/step_definitions/natalitySteps.js',
      'features/step_definitions/pramsSteps.js',
      'features/step_definitions/infant_mortality_steps.js',
      'features/step_definitions/stdSteps.js',
      'features/step_definitions/tbSteps.js',
      'features/step_definitions/aidsSteps.js',
      'features/step_definitions/cancerIncidenceSteps.js',
      'features/step_definitions/cancerMortalitySteps.js',
      'features/step_definitions/dataDocumentationSteps.js',
      'features/step_definitions/factsheetsSteps.js',
      'features/support/hook.js'
    ],
      format: 'pretty'
  },

  capabilities: {
    'browserName': 'chrome',
      chromeOptions: {
          args: [ "--disable-gpu", "--window-size=1920,1080" ]
      }
  },

 baseUrl: process.env.E2E_BASE_URL || 'http://localhost:9900/'

};
<commit_msg>Updated specs in config files<commit_after>//jshint strict: false
exports.config = {

  //Sets the amount of time to wait for an asynchronous script to finish execution before throwing an error.
  allScriptsTimeout: 600000,
  //When navigating to a new page using browser.get, Protractor waits for the page to be loaded and the new URL to appear before continuing.
  getPageTimeout: 600000,
  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),

  specs: [
      'features/*.feature'
  ],
  cucumberOpts: {
    // require step definitions
    require: [
      'features/step_definitions/homeSteps.js',
      'features/step_definitions/mortalitySteps.js',
      'features/step_definitions/yrbsSteps.js',
      'features/step_definitions/commonSteps.js',
      'features/step_definitions/bridgeRaceSteps.js',
      'features/step_definitions/natalitySteps.js',
      'features/step_definitions/pramsSteps.js',
      'features/step_definitions/infant_mortality_steps.js',
      'features/step_definitions/stdSteps.js',
      'features/step_definitions/tbSteps.js',
      'features/step_definitions/aidsSteps.js',
      'features/step_definitions/cancerIncidenceSteps.js',
      'features/step_definitions/cancerMortalitySteps.js',
      'features/step_definitions/dataDocumentationSteps.js',
      'features/step_definitions/factsheetsSteps.js',
      'features/support/hook.js'
    ],
      format: 'pretty'
  },

  capabilities: {
    'browserName': 'chrome',
      chromeOptions: {
          args: [ "--disable-gpu", "--window-size=1920,1080" ]
      }
  },

 baseUrl: process.env.E2E_BASE_URL || 'http://localhost:9900/'

};
<|endoftext|>


<commit_before>var aws = require('aws-sdk'),
	_ = require('underscore'),
	config = require('./config').Config,
	Grabber = require('./grabber').Grabber,
	Thumbnailer = require('./thumbnailer').Thumbnailer,
	Saver = require('./saver').Saver,
	fs = require('fs'),
	async = require('async');

/**
 * Initialize the Worker
 *
 * @param object opts Worker configuration. Optional.
 */
function Worker(opts) {
	_.extend(this, {
		thumbnailer: null,
		grabber: null,
		saver: null
	}, opts);

	this.sqs = new aws.SQS({
		accessKeyId: config.get('awsKey'),
		secretAccessKey: config.get('awsSecret'),
		region: config.get('awsRegion')
	});

	config.set('sqsQueueUrl', this.sqs.endpoint.protocol + '//' + this.sqs.endpoint.hostname + '/' + config.get('sqsQueue'));
}

/**
 * Start the worker
 */
Worker.prototype.start = function() {
	this._processSQSMessage();
};

/**
 * Process the next message in the queue
 */
Worker.prototype._processSQSMessage = function() {
	var _this = this;

	console.log('wait for message on ' + config.get('sqsQueue'));

	this.sqs.receiveMessage( { QueueUrl: config.get('sqsQueueUrl'), MaxNumberOfMessages: 1 }, function (err, job) {
		if (err) {
			console.log(err);
			_this._processSQSMessage();
			return;
		}

		if (!job.Messages || job.Messages.length === 0) {
			_this._processSQSMessage();
			return;
		}

		// Handle the message we pulled off the queue.
		var handle = job.Messages[0].ReceiptHandle,
			body = null;

		try { // a JSON string message body is accepted.
			body = JSON.parse( job.Messages[0].Body );
		} catch(e) {
			if (e instanceof SyntaxError) {
				// a Base64 encoded JSON string message body is also accepted.
				body = JSON.parse( new Buffer(job.Messages[0].Body, 'base64').toString( 'binary' ) );
			} else {
				throw e;
			}
		}

		_this._runJob(handle, body, function() {
			_this._processSQSMessage();
		});
	});
};

/**
 * Process a job from the queue
 *
 * @param string handle The SQS message handle
 * @param object job The job parameters
 * @param function callback The callback function
 */
Worker.prototype._runJob = function(handle, job, callback) {
	/**
		job = {
			"original": "/foo/awesome.jpg",
			"descriptions": [{
				"suffix": "small",
				"width": 64,
				"height": 64
			}],
		}
	*/
	var _this = this;

	this._downloadFromS3(job.original, function(err, localPath) {

		if (err) {
			console.log(err);
			callback();
			return;
		}

		_this._createThumbnails(localPath, job, function(err) {
			//fs.unlink(localPath, function() {
				if (!err) {
					_this._deleteJob(handle);
				}
				callback();
			//});
		});

	});
};

/**
 * Download the image from S3
 *
 * @param string remoteImagePath The s3 path to the image
 * @param function callback The callback function
 */
Worker.prototype._downloadFromS3 = function(remoteImagePath, callback) {
	this.grabber.download(remoteImagePath, function(err, localPath) {

		// Leave the job in the queue if an error occurs.
		if (err) {
			callback(err);
			return;
		}

		callback(null, localPath);
	});
};

/**
 * Create thumbnails for the image
 *
 * @param string localPath The local path to store the images
 * @param object job The job description
 * @param function callback The callback function
 */
Worker.prototype._createThumbnails = function(localPath, job, callback) {

	var _this = this,
		work = [];

	// Create thumbnailing work for each thumbnail description.
	job.descriptions.forEach(function(description) {
		work.push(function(done) {

			var remoteImagePath = _this._thumbnailKey(job.original, description.suffix, description.format),
				thumbnailer = new Thumbnailer();

			thumbnailer.execute(description, localPath, function(err, convertedImagePath) {

				if (err) {
					console.log(err);
					done();
				} else {
					_this._saveThumbnailToS3(convertedImagePath, remoteImagePath, function(err) {
						if (err) console.log(err);
						done();
					});
				}

			});

		});
	});

	// perform thumbnailing in parallel.
	async.parallel(work, function(err, results) {
		callback(err);
	});

};

/**
 * Save the thumbnail to S3
 *
 * @param string convertedImagePath The local path to the image
 * @param string remoteImagePath The S3 path for the image
 * @param function callback The callback function
 */
Worker.prototype._saveThumbnailToS3 = function(convertedImagePath, remoteImagePath, callback) {
	this.saver.save(convertedImagePath, remoteImagePath, function(err) {
		fs.unlink(convertedImagePath, function() {
			callback(err);
		});
	});
};

/**
 * Generate a path for this thumbnail
 *
 * @param string original The original image path
 * @param string suffix The thumbnail suffix. e.g. "small"
 * @param string format The thumbnail format. e.g. "jpg". Optional.
 */
Worker.prototype._thumbnailKey = function(original, suffix, format) {
	var extension = original.split('.').pop(),
		prefix = original.split('.').slice(0, -1).join('.');

	return prefix + '_' + suffix + '.' + (format || 'jpg');
};

/**
 * Remove a job from the queue
 *
 * @param string handle The SQS message handle
 */
Worker.prototype._deleteJob = function(handle) {
	this.sqs.deleteMessage({QueueUrl: config.get('sqsQueueUrl'), ReceiptHandle: handle}, function(err, resp) {
		if (err) {
			console.log("error deleting thumbnail job " + handle, err);
			return;
		}
		console.log('deleted thumbnail job ' + handle);
	});
};

exports.Worker = Worker;
<commit_msg>removed commented out line.<commit_after>var aws = require('aws-sdk'),
	_ = require('underscore'),
	config = require('./config').Config,
	Grabber = require('./grabber').Grabber,
	Thumbnailer = require('./thumbnailer').Thumbnailer,
	Saver = require('./saver').Saver,
	fs = require('fs'),
	async = require('async');

/**
 * Initialize the Worker
 *
 * @param object opts Worker configuration. Optional.
 */
function Worker(opts) {
	_.extend(this, {
		thumbnailer: null,
		grabber: null,
		saver: null
	}, opts);

	this.sqs = new aws.SQS({
		accessKeyId: config.get('awsKey'),
		secretAccessKey: config.get('awsSecret'),
		region: config.get('awsRegion')
	});

	config.set('sqsQueueUrl', this.sqs.endpoint.protocol + '//' + this.sqs.endpoint.hostname + '/' + config.get('sqsQueue'));
}

/**
 * Start the worker
 */
Worker.prototype.start = function() {
	this._processSQSMessage();
};

/**
 * Process the next message in the queue
 */
Worker.prototype._processSQSMessage = function() {
	var _this = this;

	console.log('wait for message on ' + config.get('sqsQueue'));

	this.sqs.receiveMessage( { QueueUrl: config.get('sqsQueueUrl'), MaxNumberOfMessages: 1 }, function (err, job) {
		if (err) {
			console.log(err);
			_this._processSQSMessage();
			return;
		}

		if (!job.Messages || job.Messages.length === 0) {
			_this._processSQSMessage();
			return;
		}

		// Handle the message we pulled off the queue.
		var handle = job.Messages[0].ReceiptHandle,
			body = null;

		try { // a JSON string message body is accepted.
			body = JSON.parse( job.Messages[0].Body );
		} catch(e) {
			if (e instanceof SyntaxError) {
				// a Base64 encoded JSON string message body is also accepted.
				body = JSON.parse( new Buffer(job.Messages[0].Body, 'base64').toString( 'binary' ) );
			} else {
				throw e;
			}
		}

		_this._runJob(handle, body, function() {
			_this._processSQSMessage();
		});
	});
};

/**
 * Process a job from the queue
 *
 * @param string handle The SQS message handle
 * @param object job The job parameters
 * @param function callback The callback function
 */
Worker.prototype._runJob = function(handle, job, callback) {
	/**
		job = {
			"original": "/foo/awesome.jpg",
			"descriptions": [{
				"suffix": "small",
				"width": 64,
				"height": 64
			}],
		}
	*/
	var _this = this;

	this._downloadFromS3(job.original, function(err, localPath) {

		if (err) {
			console.log(err);
			callback();
			return;
		}

		_this._createThumbnails(localPath, job, function(err) {
			fs.unlink(localPath, function() {
				if (!err) {
					_this._deleteJob(handle);
				}
				callback();
			});
		});

	});
};

/**
 * Download the image from S3
 *
 * @param string remoteImagePath The s3 path to the image
 * @param function callback The callback function
 */
Worker.prototype._downloadFromS3 = function(remoteImagePath, callback) {
	this.grabber.download(remoteImagePath, function(err, localPath) {

		// Leave the job in the queue if an error occurs.
		if (err) {
			callback(err);
			return;
		}

		callback(null, localPath);
	});
};

/**
 * Create thumbnails for the image
 *
 * @param string localPath The local path to store the images
 * @param object job The job description
 * @param function callback The callback function
 */
Worker.prototype._createThumbnails = function(localPath, job, callback) {

	var _this = this,
		work = [];

	// Create thumbnailing work for each thumbnail description.
	job.descriptions.forEach(function(description) {
		work.push(function(done) {

			var remoteImagePath = _this._thumbnailKey(job.original, description.suffix, description.format),
				thumbnailer = new Thumbnailer();

			thumbnailer.execute(description, localPath, function(err, convertedImagePath) {

				if (err) {
					console.log(err);
					done();
				} else {
					_this._saveThumbnailToS3(convertedImagePath, remoteImagePath, function(err) {
						if (err) console.log(err);
						done();
					});
				}

			});

		});
	});

	// perform thumbnailing in parallel.
	async.parallel(work, function(err, results) {
		callback(err);
	});

};

/**
 * Save the thumbnail to S3
 *
 * @param string convertedImagePath The local path to the image
 * @param string remoteImagePath The S3 path for the image
 * @param function callback The callback function
 */
Worker.prototype._saveThumbnailToS3 = function(convertedImagePath, remoteImagePath, callback) {
	this.saver.save(convertedImagePath, remoteImagePath, function(err) {
		fs.unlink(convertedImagePath, function() {
			callback(err);
		});
	});
};

/**
 * Generate a path for this thumbnail
 *
 * @param string original The original image path
 * @param string suffix The thumbnail suffix. e.g. "small"
 * @param string format The thumbnail format. e.g. "jpg". Optional.
 */
Worker.prototype._thumbnailKey = function(original, suffix, format) {
	var extension = original.split('.').pop(),
		prefix = original.split('.').slice(0, -1).join('.');

	return prefix + '_' + suffix + '.' + (format || 'jpg');
};

/**
 * Remove a job from the queue
 *
 * @param string handle The SQS message handle
 */
Worker.prototype._deleteJob = function(handle) {
	this.sqs.deleteMessage({QueueUrl: config.get('sqsQueueUrl'), ReceiptHandle: handle}, function(err, resp) {
		if (err) {
			console.log("error deleting thumbnail job " + handle, err);
			return;
		}
		console.log('deleted thumbnail job ' + handle);
	});
};

exports.Worker = Worker;
<|endoftext|>


<commit_before>//Constants
const SERIAL = 0;
const BEGIN_IP = 1;
const END_IP = 2;
const TOTAL_COUNT = 3;
const CIDR_MAX = 32;
const EXCLUDE_NETWORK_ADDRESS = 1;

//Imports
var CIDR = require('cidr-js');
var cidr = CIDR();
var csv_writer = require('fast-csv');
var csvReaderStream = require('csv-reader');
var fs = require('fs');

exports.generate_ip_list = function (read_file_path, write_file_path) {
    // CSV Stream
    var csv_stream = fs.createReadStream(read_file_path, 'utf-8');

    var ip_count_dict = [];
    var ip_list = [];

    // Get CIDR based on count
    function get_CIDR(count) {
        return (CIDR_MAX - Math.log2(count))
    }

    // Returns list of valid ip
    function get_valid_ip_list(start_ip, count) {
        var _cidr = get_CIDR(+count);
        var query_ip = start_ip + "/" + _cidr;
        return cidr.list(query_ip).slice(EXCLUDE_NETWORK_ADDRESS, count - EXCLUDE_NETWORK_ADDRESS);
    }

    function generate_csv(generated_ip_list, filepath) {
        // Store the IP Addresses as 2D
        var ip_matrix = [];

        // Adding all ip
        generated_ip_list.forEach(function (ip) {
            ip_matrix.push([ip]);
        });

        // Adding Header to the CSV
        ip_matrix.unshift(["ip_address"]);

        // Writing the csv file
        csv_writer.writeToPath(filepath, ip_matrix, {
            headers: true
        }).on('finish', function () {
            console.log("Finished Writing the CSV File");
        });
    }

    // Load each row after finished reading write in a file
    csv_stream.pipe(csvReaderStream()).on('data', function (row) {
            ip_count_dict.push({
                'ip': "" + row[BEGIN_IP],
                'count': "" + row[TOTAL_COUNT]
            });
        })
        .on('end', function (data) {
            console.log("FINISHED READING");
            // Finally generate all ips
            ip_count_dict.slice(1, ip_count_dict.length).forEach(function (ip) {
                var generated_ip_from_range = get_valid_ip_list(ip['ip'], ip['count']);
                ip_list = ip_list.concat(generated_ip_from_range);
            });
        });

};

exports.read_csv = function (read_file_path) {

    var ips = [];
    // CSV Stream
    var csv_stream = fs.createReadStream(read_file_path, 'utf-8');

    csv_stream.pipe(csvReaderStream()).on('data', function (row) {
            // console.log(row);
            ips.push(row);
        })
        .on('end', function (data) {
            console.log("FINISHED READING");
        });

    return ips;
};<commit_msg>fix read csv<commit_after>//Constants
const SERIAL = 0;
const BEGIN_IP = 1;
const END_IP = 2;
const TOTAL_COUNT = 3;
const CIDR_MAX = 32;
const EXCLUDE_NETWORK_ADDRESS = 1;

//Imports
var CIDR = require('cidr-js');
var cidr = CIDR();
var csv_writer = require('fast-csv');
var csvReaderStream = require('csv-reader');
var fs = require('fs');

exports.generate_ip_list = function (ip_cidr) {
    // CSV Stream
    var csv_stream = fs.createReadStream(read_file_path, 'utf-8');

    var ip_count_dict = [];
    var ip_list = [];

    // Returns list of valid ip
    function get_valid_ip_list(start_ip, count) {
        var _cidr = get_CIDR(+count);
        var query_ip = start_ip + "/" + _cidr;
        return cidr.list(query_ip).slice(EXCLUDE_NETWORK_ADDRESS, count - EXCLUDE_NETWORK_ADDRESS);
    }

};

exports.read_csv = function (read_file_path) {

    // exclude first row
    var first_row = true;

    // Get CIDR based on count
    function get_CIDR(count) {
        return (CIDR_MAX - Math.log2(count))
    }

    var ips = [];
    // CSV Stream
    var csv_stream = fs.createReadStream(read_file_path, 'utf-8');

    csv_stream.pipe(csvReaderStream()).on('data', function (row) {
            // console.log(row);
            if (!first_row) {
                ips.push({
                    ip: row[BEGIN_IP] + "/" + get_CIDR(+row[TOTAL_COUNT]),
                    count: +row[TOTAL_COUNT]
                });
            }
            first_row = false;
        })
        .on('end', function (data) {
            console.log("FINISHED READING");
        });

    return ips;
};<|endoftext|>


<commit_before>define(['backbone', 'places/utils', 'moxie.position'], function(Backbone, utils, userPosition) {
    var MapView = Backbone.View.extend({

        initialize: function() {
            _.bindAll(this);
            this.latlngs = [];
            this.markers = [];
            this.userPosition = null;
        },

        manage: true,
        id: "map",

        beforeRender: function() {
            this.map = utils.getMap(this.el);
            userPosition.follow(this.handle_geolocation_query);
            return this;
        },

        afterRender: function() {
            this.invalidateMapSize();
        },

        setCollection: function(collection) {
            this.unsetCollection();
            this.collection = collection;
            this.collection.on("reset", this.resetMapContents, this);
            this.collection.on("add", this.placePOI, this);
            if (this.collection.length) {
                this.resetMapContents();
            }
        },

        unsetCollection: function() {
            if (this.collection) {
                this.collection.off("reset", this.resetMapContents, this);
                this.collection.off("add", this.placePOI, this);
                this.collection = null;
            }
        },

        handle_geolocation_query: function(position) {
            this.user_position = [position.coords.latitude, position.coords.longitude];
            var you = new L.LatLng(position.coords.latitude, position.coords.longitude);
            if (this.user_marker) {
                this.map.removeLayer(this.user_marker);
            }
            this.user_marker = L.circle(you, 10, {color: 'red', fillColor: 'red', fillOpacity: 1.0});
            this.map.addLayer(this.user_marker);
        },

        placePOI: function(poi) {
            var latlng = new L.LatLng(poi.attributes.lat, poi.attributes.lon);
            var marker = new L.marker(latlng, {'title': poi.attributes.name});
            marker.addTo(this.map);
            this.latlngs.push(latlng);
            this.markers.push(marker);
        },

        invalidateMapSize: function() {
            this.map.invalidateSize();
            return this;
        },

        setMapBounds: function() {
            var bounds = new L.LatLngBounds(this.latlngs);
            if (this.user_position) {
                bounds.extend(this.user_position);
            }
            bounds.pad(5);
            this.map.fitBounds(bounds);
        },

        resetMapContents: function(){
            // Remove the existing map markers
            _.each(this.markers, function(marker) {
                this.map.removeLayer(marker);
            }, this);
            // Create new list of markers from search results
            this.latlngs = [];
            this.markers = [];
            this.collection.each(this.placePOI);
            this.setMapBounds();
        },

        onClose: function() {
            userPosition.unfollow(this.handle_geolocation_query);
        }
    });
    return MapView;
});
<commit_msg>onClose -> cleanup<commit_after>define(['backbone', 'places/utils', 'moxie.position'], function(Backbone, utils, userPosition) {
    var MapView = Backbone.View.extend({

        initialize: function() {
            _.bindAll(this);
            this.latlngs = [];
            this.markers = [];
            this.userPosition = null;
        },

        manage: true,
        id: "map",

        beforeRender: function() {
            this.map = utils.getMap(this.el);
            userPosition.follow(this.handle_geolocation_query);
            return this;
        },

        afterRender: function() {
            this.invalidateMapSize();
        },

        setCollection: function(collection) {
            this.unsetCollection();
            this.collection = collection;
            this.collection.on("reset", this.resetMapContents, this);
            this.collection.on("add", this.placePOI, this);
            if (this.collection.length) {
                this.resetMapContents();
            }
        },

        unsetCollection: function() {
            if (this.collection) {
                this.collection.off("reset", this.resetMapContents, this);
                this.collection.off("add", this.placePOI, this);
                this.collection = null;
            }
        },

        handle_geolocation_query: function(position) {
            this.user_position = [position.coords.latitude, position.coords.longitude];
            var you = new L.LatLng(position.coords.latitude, position.coords.longitude);
            if (this.user_marker) {
                this.map.removeLayer(this.user_marker);
            }
            this.user_marker = L.circle(you, 10, {color: 'red', fillColor: 'red', fillOpacity: 1.0});
            this.map.addLayer(this.user_marker);
        },

        placePOI: function(poi) {
            var latlng = new L.LatLng(poi.attributes.lat, poi.attributes.lon);
            var marker = new L.marker(latlng, {'title': poi.attributes.name});
            marker.addTo(this.map);
            this.latlngs.push(latlng);
            this.markers.push(marker);
        },

        invalidateMapSize: function() {
            this.map.invalidateSize();
            return this;
        },

        setMapBounds: function() {
            var bounds = new L.LatLngBounds(this.latlngs);
            if (this.user_position) {
                bounds.extend(this.user_position);
            }
            bounds.pad(5);
            this.map.fitBounds(bounds);
        },

        resetMapContents: function(){
            // Remove the existing map markers
            _.each(this.markers, function(marker) {
                this.map.removeLayer(marker);
            }, this);
            // Create new list of markers from search results
            this.latlngs = [];
            this.markers = [];
            this.collection.each(this.placePOI);
            this.setMapBounds();
        },

        cleanup: function() {
            console.log("Cleanup");
            this.unsetCollection();
            userPosition.unfollow(this.handle_geolocation_query);
        }
    });
    return MapView;
});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//
// Artillery Core worker process
//

'use strict';

const core = require('./dispatcher');
const createRunner = core.runner;
const debug = require('debug')('artillery:worker');

const path = require('path');

process.on('message', onMessage);
let shuttingDown = false;
function ignore() {
  debug('[%s] signal ignored', process.pid);
}
process.once('SIGTERM', ignore);
process.once('SIGINT', ignore);
process.on('error', onError);
process.on('uncaughtException', panic);

//
// Possible messages: run, stop
//

function onMessage(message) {
  if (message.command === 'run') {
    run(message.opts);
    return;
  }

  if (message.command === 'stop') {
    cleanup();
  }
}

function cleanup() {
  if (shuttingDown) {
    return;
  }
  debug('[%s] shutting down', process.pid);
  shuttingDown = true;
  process.exit(0);
}

function onError(err) {
  debug(err);
  debug('[%s] Worker can\'t send() to parent. Parent is probably dead. Shutting down.', process.pid);
  cleanup();
}

function panic(err) {
  console.log(err);
  process.exit(1);
}

function run(opts) {

  // load processor if needed:
  if (opts.script.config.processor) {
    let absoluteScriptPath = path.resolve(process.cwd(), opts.options.scriptPath);
    let processorPath = path.resolve(path.dirname(absoluteScriptPath), opts.script.config.processor);
    let processor = require(processorPath);
    opts.script.config.processor = processor;
  }

  createRunner(opts.script, opts.payload, opts.options).then(function(runner) {
    runner.on('phaseStarted', onPhaseStarted);
    runner.on('phaseCompleted', onPhaseCompleted);
    runner.on('stats', onStats);
    runner.on('done', onDone);

    runner.run();
  }).catch(function(err) {
    console.log(err);
  });

  function onPhaseStarted(phase) {
    send({ event: 'phaseStarted', phase: phase });
  }

  function onPhaseCompleted(phase) {
    send({ event: 'phaseCompleted', phase: phase });
  }

  function onStats(stats) {
    send({ event: 'stats', stats: stats });
  }

  function onDone(report) {
    send({ event: 'done', report: report });
  }
}

function send(data) {
  process.send(Object.assign({ pid: process.pid }, data));
}
<commit_msg>feat: Provide path to test script to worker processes<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//
// Artillery Core worker process
//

'use strict';

const core = require('./dispatcher');
const createRunner = core.runner;
const debug = require('debug')('artillery:worker');

const path = require('path');

process.on('message', onMessage);
let shuttingDown = false;
function ignore() {
  debug('[%s] signal ignored', process.pid);
}
process.once('SIGTERM', ignore);
process.once('SIGINT', ignore);
process.on('error', onError);
process.on('uncaughtException', panic);

//
// Possible messages: run, stop
//

function onMessage(message) {
  if (message.command === 'run') {
    run(message.opts);
    return;
  }

  if (message.command === 'stop') {
    cleanup();
  }
}

function cleanup() {
  if (shuttingDown) {
    return;
  }
  debug('[%s] shutting down', process.pid);
  shuttingDown = true;
  process.exit(0);
}

function onError(err) {
  debug(err);
  debug('[%s] Worker can\'t send() to parent. Parent is probably dead. Shutting down.', process.pid);
  cleanup();
}

function panic(err) {
  console.log(err);
  process.exit(1);
}

function run(opts) {

  let absoluteScriptPath = path.resolve(process.cwd(), opts.options.scriptPath);
  opts.options.absoluteScriptPath = absoluteScriptPath;

  // load processor if needed:
  if (opts.script.config.processor) {
    let processorPath = path.resolve(path.dirname(absoluteScriptPath), opts.script.config.processor);
    let processor = require(processorPath);
    opts.script.config.processor = processor;
  }

  createRunner(opts.script, opts.payload, opts.options).then(function(runner) {
    runner.on('phaseStarted', onPhaseStarted);
    runner.on('phaseCompleted', onPhaseCompleted);
    runner.on('stats', onStats);
    runner.on('done', onDone);

    runner.run();
  }).catch(function(err) {
    console.log(err);
  });

  function onPhaseStarted(phase) {
    send({ event: 'phaseStarted', phase: phase });
  }

  function onPhaseCompleted(phase) {
    send({ event: 'phaseCompleted', phase: phase });
  }

  function onStats(stats) {
    send({ event: 'stats', stats: stats });
  }

  function onDone(report) {
    send({ event: 'done', report: report });
  }
}

function send(data) {
  process.send(Object.assign({ pid: process.pid }, data));
}
<|endoftext|>