<commit_before>import React from 'react/addons';

import NowPlayingStore from '../stores/NowPlayingStore.js';
import NowPlayingActions from '../actions/NowPlayingActions.js';

import PlayingStatusStore from '../stores/PlayingStatusStore.js';

function getNowPlayingState() {
  return {
    buffered: PlayingStatusStore.getBuffered(),
    duration: PlayingStatusStore.getDuration(),
    currentTime: PlayingStatusStore.getTime(),
  };
}

function _getOffsetLeft(elem) {
    var offsetLeft = 0;
    do {
      if (!isNaN(elem.offsetLeft)) {
          offsetLeft += elem.offsetLeft;
      }
    } while ((elem = elem.offsetParent));
    return offsetLeft;
}

export default class PlayProgress extends React.Component {
  constructor(props) {
    super(props);

    this.state = getNowPlayingState();

    this._onChange = this._onChange.bind(this);
    this._onClick = this._onClick.bind(this);
    this._onWheel = this._onWheel.bind(this);
  }

  componentDidMount() {
    NowPlayingStore.addChangeListener(this._onChange);
    PlayingStatusStore.addChangeListener(this._onChange);
  }

  componentWillUnmount() {
    NowPlayingStore.removeChangeListener(this._onChange);
    PlayingStatusStore.removeChangeListener(this._onChange);
  }

  _onChange() {
    this.setState(getNowPlayingState());
  }

  render() {
    var wpc = (this.state.currentTime / this.state.duration) * 100;
    var w = "calc("+Math.min(wpc, 100.0)+"% - " + this.props.markerWidth + "px)";
    var bpc = (this.state.buffered / this.state.duration) * 100 - wpc;
    var b = "calc("+Math.min(bpc, 100.0)+"% - " + this.props.markerWidth + "px)";

    return (

    );
  }

  _onClick(evt) {
    var pos = evt.pageX - _getOffsetLeft(evt.currentTarget);
    var width = evt.currentTarget.offsetWidth;
    NowPlayingActions.setCurrentTime((pos / width) * this.props.duration);
  }

  _onWheel(evt) {
    evt.stopPropagation();
    var t = this.props.current + (0.01 * this.props.duration * evt.deltaY);
    if (t > this.props.duration) {
      t = this.props.duration;
    } else if (t < 0.00) {
      t = 0.0;
    }
    NowPlayingActions.setCurrentTime(t);
  }
}
<commit_msg>[PlayProgress] Fix seeking within the current track<commit_after>import React from 'react/addons';

import NowPlayingStore from '../stores/NowPlayingStore.js';
import NowPlayingActions from '../actions/NowPlayingActions.js';

import PlayingStatusStore from '../stores/PlayingStatusStore.js';

function getNowPlayingState() {
  return {
    buffered: PlayingStatusStore.getBuffered(),
    duration: PlayingStatusStore.getDuration(),
    currentTime: PlayingStatusStore.getTime(),
  };
}

function _getOffsetLeft(elem) {
    var offsetLeft = 0;
    do {
      if (!isNaN(elem.offsetLeft)) {
          offsetLeft += elem.offsetLeft;
      }
    } while ((elem = elem.offsetParent));
    return offsetLeft;
}

export default class PlayProgress extends React.Component {
  constructor(props) {
    super(props);

    this.state = getNowPlayingState();

    this._onChange = this._onChange.bind(this);
    this._onClick = this._onClick.bind(this);
    this._onWheel = this._onWheel.bind(this);
  }

  componentDidMount() {
    NowPlayingStore.addChangeListener(this._onChange);
    PlayingStatusStore.addChangeListener(this._onChange);
  }

  componentWillUnmount() {
    NowPlayingStore.removeChangeListener(this._onChange);
    PlayingStatusStore.removeChangeListener(this._onChange);
  }

  _onChange() {
    this.setState(getNowPlayingState());
  }

  render() {
    var wpc = (this.state.currentTime / this.state.duration) * 100;
    var w = "calc("+Math.min(wpc, 100.0)+"% - " + this.props.markerWidth + "px)";
    var bpc = (this.state.buffered / this.state.duration) * 100 - wpc;
    var b = "calc("+Math.min(bpc, 100.0)+"% - " + this.props.markerWidth + "px)";

    return (

    );
  }

  _onClick(evt) {
    var pos = evt.pageX - _getOffsetLeft(evt.currentTarget);
    var width = evt.currentTarget.offsetWidth;
    var time = (pos / width) * this.state.duration;
    NowPlayingActions.setCurrentTime(time);
  }

  _onWheel(evt) {
    evt.stopPropagation();
    var t = this.state.current + (0.01 * this.state.duration * evt.deltaY);
    if (t > this.state.duration) {
      t = this.props.duration;
    } else if (t < 0.00) {
      t = 0.0;
    }
    NowPlayingActions.setCurrentTime(t);
  }
}
<|endoftext|>


<commit_before>var Serialport = require('serialport');
var intelhex = require('intel-hex');
var Stk500v1 = require('stk500');
var Stk500v2 = require('stk500-v2');
var avr109 = require('chip.avr.avr109');
var async = require('async');
var fs = require('graceful-fs');
var boards = require('./boards');
var colors = require('colors');

/**
 * Constructor
 *
 * @param {object} options - options for consumer to pass in
 */
var Avrgirl_arduino = function(opts) {
  var opts = opts || {};

  this.options = {
    debug: opts.debug || false,
    board: opts.board || 'uno',
    port: opts.port || ''
  };

  this.debug = this.options.debug ? console.log.bind(console) : function() {};

  this.chip = undefined;

  // get board properties
  this.board = boards.byName[this.options.board];
  if (!this.board) {
    return;
  }

  // assign the correct module to the protocol of the chosen board
  if (this.board.protocol === 'stk500v1') {
    this.chip = new Stk500v1({
      quiet: true
    });
  } else if (this.board.protocol === 'stk500v2') {
    this.chip = Stk500v2;
  } else if (this.board.protocol === 'avr109') {
    this.chip = avr109;
  }
};

/**
 * Create new serialport instance for the Arduino board, but do not immediately connect.
 */
Avrgirl_arduino.prototype._setUpSerial = function() {
  this.serialPort = new Serialport.SerialPort(this.options.port, {
    baudRate: this.board.baud,
  }, false);
};

/**
 * Opens and parses a given hex file
 */
Avrgirl_arduino.prototype._parseHex = function(file) {
  var data = fs.readFileSync(file, {
    encoding: 'utf8'
  });
  return intelhex.parse(data).data;
};

/**
 * Public method for flashing a hex file to the main program allocation of the Arduino
 *
 * @param {string} file - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype.flash = function(file, callback) {
  var self = this;
  var hex = file;

  // if we don't have a valid board, we cannot continue.
  if (!self.board) {
    return callback(new Error('"' + self.options.board + '" is not a supported board type.'));
  }

  // if we haven't been supplied an explicit port to connect to, auto sniff one.
  if (self.options.port === '') {
    // if this is a pro-mini, we cannot auto-sniff so return an error
    if (self.options.board === 'pro-mini') {
      var error = new Error('you\'re using a pro-mini, please specify the port in your options.');
      return callback(error);
    }

    self._sniffPort(function(port) {
      if (port !== null) {
        self.debug('found ' + self.options.board + ' on port ' + port);
        // found a port, save it
        self.options.port = port;
        // upload hex
        self._upload(hex, callback);
      } else {
        // we didn't find the board
        return callback(new Error('no Arduino found.'));
      }
    });
  } else {
    // we already know the port, so upload
    self._upload(hex, callback);
  }
};

/**
 * Calls the correct upload method, depending on which protocol the Arduino uses
 *
 * @param {string} hex - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._upload = function(hex, callback) {
  var self = this;
  var eggs = hex;
  var cb = callback;

  if (self.board.protocol === 'stk500v1') {
    self._uploadSTK500v1(eggs, cb);
  } else if (self.board.protocol === 'stk500v2') {
    self._uploadSTK500v2(eggs, cb);
  } else if (self.board.protocol === 'avr109') {
    self._resetAVR109(function(error) {
      if (error) {
        return cb(error);
      }
      self.debug('reset complete.');
      self._uploadAVR109(eggs, cb);
    });
  } else {
    cb(new Error('not a supported programming protocol: ' + self.board.protocol));
  }
};

/**
 * Sets the DTR/RTS lines to either true or false
 *
 * @param {boolean} bool - value to set DTR and RTS to
 * @param {number} timeout - number in milliseconds to delay after
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._setDTR = function (bool, timeout, callback) {
  var self = this;
  var props = {
    rts: bool,
    dtr: bool
  };

  self.serialPort.set(props, function(error) {
    if (error) { return callback(error); }
    setTimeout(function() {
      callback(error);
    }, timeout);
  });
};

/**
 * Checks the list of ports 4 times for a device to show up
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._pollForPort = function (callback) {
  var self = this;
  var tries = 0;
  var delay = 300;

  function checkList() {
    Serialport.list(function(error, ports) {
      // iterate through ports looking for the one port to rule them all
      for (var i = 0; i < ports.length; i++) {
        if (ports[i].comName === self.options.port) {
          return callback(true);
        }
      }
      tries += 1;
      if (tries < 4) {
        setTimeout(checkList, delay);
      } else {
        // timeout on too many tries
        return callback(false);
      }
    });
  }
  setTimeout(checkList, delay);
};

/**
 * Pulse the DTR/RTS lines low then high
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._cycleDTR = function(callback) {
  var self = this;

  async.series([
    self._setDTR.bind(self, true, 250),
    self._setDTR.bind(self, false, 50)
  ],
  function(error) {
    return callback(error);
  });
};

/**
 * Resets an Arduino STK500 bootloaded chip by pulsing DTR high.
 *
 * Avoids the dreaded timeout bug if the serialport was opened since the device
 * was powered.
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._resetSTK500 = function(callback) {
  var self = this;

  // cycle DTR/RTS from low to high
  self._cycleDTR(function(error) {
    if (!error) {
      self.debug('reset complete.');
    }
    return callback(error);
  });
};

/**
 * Upload method for the STK500v1 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._uploadSTK500v1 = function(eggs, callback) {
  var self = this;
  // do we have a connection instance yet?
  if (!self.serialPort) {
    self._setUpSerial();
  }

  // open connection
  self.serialPort.open(function(error) {
    if (error) {
      return callback(error);
    }

    self.debug('connected');

    // open/parse supplied hex file
    var hex = self._parseHex(eggs);

    // reset
    self._resetSTK500(function(error) {
      self.debug('flashing, please wait...');
      // flash
      self.chip.bootload(self.serialPort, hex, self.board, function(error) {
        var color = (error ? colors.red : colors.green);

        self.debug(color('flash complete.'));

        // Always close the serialport
        self.serialPort.close();

        return callback(error);
      });
    });
  });
};

/**
 * Upload method for the STK500v2 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._uploadSTK500v2 = function(eggs, callback) {
  var self = this;

  // do we have a connection instance yet?
  if (!self.serialPort) {
    self._setUpSerial();
  }

  // open connection
  self.serialPort.open(function(error) {
    if (error) {
      return callback(error);
    }

    // instantiate stk500v2 with newly open serialport
    self.chip = self.chip(self.serialPort);

    self.debug('connected');

    // open/parse supplied hex file
    var hex = self._parseHex(eggs);

    async.series([
        function(callback) {
          self._resetSTK500(callback);
        },
        function(callback) {
          self.chip.sync(5, callback);
        },
        function(callback) {
          self.chip.verifySignature(self.board.signature, callback);
        },
        function(callback) {
          self.chip.enterProgrammingMode(self.board, callback);
        },
        function(callback) {
          self.debug('flashing, please wait...');
          self.chip.upload(hex, self.board.pageSize, callback);
        },
        function(callback) {
          self.chip.exitProgrammingMode(callback);
        }
      ],
      function(err, results) {
        var color = (err ? colors.red : colors.green);

        self.debug(color('flash complete.'));

        // Always close the serialport
        self.serialPort.close();

        return callback(err);
      });
  });
};

/**
 * Software resets an Arduino AVR109 bootloaded chip into bootloader mode
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._resetAVR109 = function(callback) {
  var self = this;

  self.debug('resetting board...');

  self.serialPort = new Serialport.SerialPort(self.options.port, {
    baudRate: 1200,
  });

  // open a connection, then immediately close to perform the reset of the board.
  self.serialPort.open(function() {
    self._cycleDTR(function(error) {
      if (error) { return callback(error); }
      self._pollForPort(function(connected) {
        var status = connected ? null : new Error('could not complete reset.');
        return callback(status);
      });
    });
  });
};

/**
 * Upload method for the AVR109 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._uploadAVR109 = function(eggs, callback) {
  var self = this;

  // do we have a connection instance yet?
  if (!self.serialPort) {
    self._setUpSerial();
  }

  self.serialPort.open(function(error) {
    if (error) {
      return callback(error);
    }
    self.debug('connected');

    fs.readFile(eggs, function(error, data) {
      if (error) {
        return callback(error);
      }

      self.chip.init(self.serialPort, {
        signature: self.board.signature.toString()
      }, function(error, flasher) {
        if (error) {
          return callback(error);
        }
        self.debug('flashing, please wait...');

        async.series([
            function(callback) {
              flasher.erase(callback);
            },
            function(callback) {
              flasher.program(data.toString(), callback);
            },
            function(callback) {
              flasher.verify(callback);
            },
            function(callback) {
              flasher.fuseCheck(callback);
            }
          ],
          function(err, results) {
            var color = (err ? colors.red : colors.green);

            self.debug(color('flash complete.'));
            return callback(err);
          });
      });
    });
  });
};

/**
 * Return a list of devices on serial ports. In addition to the output provided
 * by SerialPort.list, it adds a platform independent PID in _pid
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.listPorts = function (callback) {
  var foundPorts = [];
  // list all available ports
  Serialport.list(function (err, ports) {
    if (err) { return callback(err) };
    // iterate through ports
    for (var i = 0; i < ports.length; i++) {
      var pid;
      // are we on windows or unix?
      if (ports[i].productId) {
        pid = ports[i].productId;
      } else if (ports[i].pnpId) {
        pid = '0x' + /PID_\d*/.exec(ports[i].pnpId)[0].substr(4);
      } else {
        pid = '';
      }
      ports[i]._standardPid = pid;
      foundPorts.push(ports[i]);
    }
    return callback(null, foundPorts);
  });
};

/**
 * Finds a list of available USB ports, and matches for the right pid
 * Auto finds the correct port for the chosen Arduino
 *
 * @param {function} callback - function to run upon completion/error
 */
Avrgirl_arduino.prototype._sniffPort = function(callback) {
  var self = this;
  Avrgirl_arduino.listPorts(function (err, ports) {
    // iterate through ports
    for (var i = 0; i < ports.length; i++) {
      // iterate through all possible pid's
      for (var j = 0; j < self.board.productId.length; j ++) {
        if (ports[i]._standardPid === self.board.productId[j]) {
          // match! Return the port/path
          return callback(ports[i].comName);
        }
      }
    }
    // didn't find a match :(
    return callback(null);
  });
};

module.exports = Avrgirl_arduino;
<commit_msg>fix style on main<commit_after>var Serialport = require('serialport');
var intelhex = require('intel-hex');
var Stk500v1 = require('stk500');
var Stk500v2 = require('stk500-v2');
var avr109 = require('chip.avr.avr109');
var async = require('async');
var fs = require('graceful-fs');
var boards = require('./boards');
var colors = require('colors');

/**
 * Constructor
 *
 * @param {object} options - options for consumer to pass in
 */
var AvrgirlArduino = function(opts) {
  opts = opts || {};

  this.options = {
    debug: opts.debug || false,
    board: opts.board || 'uno',
    port: opts.port || ''
  };

  this.debug = this.options.debug ? console.log.bind(console) : function() {};

  this.chip = undefined;

  // get board properties
  this.board = boards.byName[this.options.board];
  if (!this.board) {
    return;
  }

  // assign the correct module to the protocol of the chosen board
  if (this.board.protocol === 'stk500v1') {
    this.chip = new Stk500v1({
      quiet: true
    });
  } else if (this.board.protocol === 'stk500v2') {
    this.chip = Stk500v2;
  } else if (this.board.protocol === 'avr109') {
    this.chip = avr109;
  }
};

/**
 * Create new serialport instance for the Arduino board, but do not immediately connect.
 */
AvrgirlArduino.prototype._setUpSerial = function() {
  this.serialPort = new Serialport.SerialPort(this.options.port, {
    baudRate: this.board.baud,
  }, false);
};

/**
 * Opens and parses a given hex file
 */
AvrgirlArduino.prototype._parseHex = function(file) {
  var data = fs.readFileSync(file, {
    encoding: 'utf8'
  });
  return intelhex.parse(data).data;
};

/**
 * Public method for flashing a hex file to the main program allocation of the Arduino
 *
 * @param {string} file - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype.flash = function(file, callback) {
  var _this = this;
  var hex = file;

  // if we don't have a valid board, we cannot continue.
  if (!_this.board) {
    return callback(new Error('"' + _this.options.board + '" is not a supported board type.'));
  }

  // if we haven't been supplied an explicit port to connect to, auto sniff one.
  if (_this.options.port === '') {
    // if this is a pro-mini, we cannot auto-sniff so return an error
    if (_this.options.board === 'pro-mini') {
      var error = new Error('you\'re using a pro-mini, please specify the port in your options.');
      return callback(error);
    }

    _this._sniffPort(function(port) {
      if (port !== null) {
        _this.debug('found ' + _this.options.board + ' on port ' + port);

        // found a port, save it
        _this.options.port = port;

        // upload hex
        _this._upload(hex, callback);
      } else {
        // we didn't find the board
        return callback(new Error('no Arduino found.'));
      }
    });
  } else {
    // we already know the port, so upload
    _this._upload(hex, callback);
  }
};

/**
 * Calls the correct upload method, depending on which protocol the Arduino uses
 *
 * @param {string} hex - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._upload = function(hex, callback) {
  var _this = this;
  var eggs = hex;
  var cb = callback;

  if (_this.board.protocol === 'stk500v1') {
    _this._uploadSTK500v1(eggs, cb);
  } else if (_this.board.protocol === 'stk500v2') {
    _this._uploadSTK500v2(eggs, cb);
  } else if (_this.board.protocol === 'avr109') {
    _this._resetAVR109(function(error) {
      if (error) {
        return cb(error);
      }

      _this.debug('reset complete.');
      _this._uploadAVR109(eggs, cb);
    });
  } else {
    cb(new Error('not a supported programming protocol: ' + _this.board.protocol));
  }
};

/**
 * Sets the DTR/RTS lines to either true or false
 *
 * @param {boolean} bool - value to set DTR and RTS to
 * @param {number} timeout - number in milliseconds to delay after
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._setDTR = function(bool, timeout, callback) {
  var _this = this;
  var props = {
    rts: bool,
    dtr: bool
  };

  _this.serialPort.set(props, function(error) {
    if (error) { return callback(error); }

    setTimeout(function() {
      callback(error);
    }, timeout);
  });
};

/**
 * Checks the list of ports 4 times for a device to show up
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._pollForPort = function(callback) {
  var _this = this;
  var tries = 0;
  var delay = 300;

  function checkList() {
    Serialport.list(function(error, ports) {
      // iterate through ports looking for the one port to rule them all
      for (var i = 0; i < ports.length; i++) {
        if (ports[i].comName === _this.options.port) {
          return callback(true);
        }
      }

      tries += 1;
      if (tries < 4) {
        setTimeout(checkList, delay);
      } else {
        // timeout on too many tries
        return callback(false);
      }
    });
  }

  setTimeout(checkList, delay);
};

/**
 * Pulse the DTR/RTS lines low then high
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._cycleDTR = function(callback) {
  var _this = this;

  async.series([
    _this._setDTR.bind(_this, true, 250),
    _this._setDTR.bind(_this, false, 50)
  ],
  function(error) {
    return callback(error);
  });
};

/**
 * Resets an Arduino STK500 bootloaded chip by pulsing DTR high.
 *
 * Avoids the dreaded timeout bug if the serialport was opened since the device
 * was powered.
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._resetSTK500 = function(callback) {
  var _this = this;

  // cycle DTR/RTS from low to high
  _this._cycleDTR(function(error) {
    if (!error) {
      _this.debug('reset complete.');
    }

    return callback(error);
  });
};

/**
 * Upload method for the STK500v1 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._uploadSTK500v1 = function(eggs, callback) {
  var _this = this;

  // do we have a connection instance yet?
  if (!_this.serialPort) {
    _this._setUpSerial();
  }

  // open connection
  _this.serialPort.open(function(error) {
    if (error) { return callback(error); }

    _this.debug('connected');

    // open/parse supplied hex file
    var hex = _this._parseHex(eggs);

    // reset
    _this._resetSTK500(function(error) {
      if (error) { return callback(error); }

      _this.debug('flashing, please wait...');

      // flash
      _this.chip.bootload(_this.serialPort, hex, _this.board, function(error) {
        var color = (error ? colors.red : colors.green);

        _this.debug(color('flash complete.'));

        // Always close the serialport
        _this.serialPort.close();

        return callback(error);
      });
    });
  });
};

/**
 * Upload method for the STK500v2 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._uploadSTK500v2 = function(eggs, callback) {
  var _this = this;

  // do we have a connection instance yet?
  if (!_this.serialPort) {
    _this._setUpSerial();
  }

  // open connection
  _this.serialPort.open(function(error) {
    if (error) {
      return callback(error);
    }

    // instantiate stk500v2 with newly open serialport
    _this.chip = _this.chip(_this.serialPort);

    _this.debug('connected');

    // open/parse supplied hex file
    var hex = _this._parseHex(eggs);

    async.series([
        function(callback) {
          _this._resetSTK500(callback);
        },

        function(callback) {
          _this.chip.sync(5, callback);
        },

        function(callback) {
          _this.chip.verifySignature(_this.board.signature, callback);
        },

        function(callback) {
          _this.chip.enterProgrammingMode(_this.board, callback);
        },

        function(callback) {
          _this.debug('flashing, please wait...');
          _this.chip.upload(hex, _this.board.pageSize, callback);
        },

        function(callback) {
          _this.chip.exitProgrammingMode(callback);
        }
      ],
      function(error) {
        var color = (error ? colors.red : colors.green);

        _this.debug(color('flash complete.'));

        // Always close the serialport
        _this.serialPort.close();

        return callback(error);
      });
  });
};

/**
 * Software resets an Arduino AVR109 bootloaded chip into bootloader mode
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._resetAVR109 = function(callback) {
  var _this = this;

  _this.debug('resetting board...');

  _this.serialPort = new Serialport.SerialPort(_this.options.port, {
    baudRate: 1200,
  });

  // open a connection, then immediately close to perform the reset of the board.
  _this.serialPort.open(function() {
    _this._cycleDTR(function(error) {
      if (error) { return callback(error); }

      _this._pollForPort(function(connected) {
        var status = connected ? null : new Error('could not complete reset.');
        return callback(status);
      });
    });
  });
};

/**
 * Upload method for the AVR109 protocol
 *
 * @param {string} eggs - path to hex file for uploading
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._uploadAVR109 = function(eggs, callback) {
  var _this = this;

  // do we have a connection instance yet?
  if (!_this.serialPort) {
    _this._setUpSerial();
  }

  _this.serialPort.open(function(error) {
    if (error) {
      return callback(error);
    }

    _this.debug('connected');

    fs.readFile(eggs, function(error, data) {
      if (error) {
        return callback(error);
      }

      _this.chip.init(_this.serialPort, {
        signature: _this.board.signature.toString()
      }, function(error, flasher) {
        if (error) {
          return callback(error);
        }

        _this.debug('flashing, please wait...');

        async.series([
            function(callback) {
              flasher.erase(callback);
            },

            function(callback) {
              flasher.program(data.toString(), callback);
            },

            function(callback) {
              flasher.verify(callback);
            },

            function(callback) {
              flasher.fuseCheck(callback);
            }
          ],
          function(error) {
            var color = (error ? colors.red : colors.green);

            _this.debug(color('flash complete.'));
            return callback(error);
          });
      });
    });
  });
};

/**
 * Return a list of devices on serial ports. In addition to the output provided
 * by SerialPort.list, it adds a platform independent PID in _pid
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.listPorts = function(callback) {
  var foundPorts = [];

  // list all available ports
  Serialport.list(function(err, ports) {
    if (err) { return callback(err); }

    // iterate through ports
    for (var i = 0; i < ports.length; i += 1) {
      var pid;

      // are we on windows or unix?
      if (ports[i].productId) {
        pid = ports[i].productId;
      } else if (ports[i].pnpId) {
        pid = '0x' + /PID_\d*/.exec(ports[i].pnpId)[0].substr(4);
      } else {
        pid = '';
      }

      ports[i]._standardPid = pid;
      foundPorts.push(ports[i]);
    }

    return callback(null, foundPorts);
  });
};

/**
 * Finds a list of available USB ports, and matches for the right pid
 * Auto finds the correct port for the chosen Arduino
 *
 * @param {function} callback - function to run upon completion/error
 */
AvrgirlArduino.prototype._sniffPort = function(callback) {
  var _this = this;
  AvrgirlArduino.listPorts(function(error, ports) {
    // iterate through ports
    for (var i = 0; i < ports.length; i += 1) {
      // iterate through all possible pid's
      for (var j = 0; j < _this.board.productId.length; j += 1) {
        if (ports[i]._standardPid === _this.board.productId[j]) {
          // match! Return the port/path
          return callback(ports[i].comName);
        }
      }
    }

    // didn't find a match :(
    return callback(null);
  });
};

module.exports = AvrgirlArduino;
<|endoftext|>


<commit_before>'use strict';

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import {Validation} from '../lib/Validation';
import {ObjectToJoi} from '../lib/ObjectToJoi';
import {RuntimeMock} from './Mock/RuntimeMock';
import {Exception} from '../lib/Exception/Exception';
import {ValidationSchemaNotFoundException} from '../lib/Exception/ValidationSchemaNotFoundException';
import {InvalidJoiSchemaException} from '../lib/Exception/InvalidJoiSchemaException';
import {ObjectValidationFailedException} from '../lib/Exception/ObjectValidationFailedException';
import Kernel from 'deep-kernel';
import KernelFactory from './common/KernelFactory';

chai.use(sinonChai);

suite('Validation', function() {
  let validation = null;
  let modelName = 'ConfigurationModel';
  let rawModelSchema = {username: 'string'};
  let backendKernelInstance = null;
  let frontendKernelInstance = null;
  let testModelSchema = {
    Configuration: 'string',
    Status: 'number',
  };

  test('Class Validation exists in Validation', function() {
    chai.expect(typeof Validation).to.equal('function');
  });

  test('Load Kernels by using Kernel.load()', function(done) {
    let callback = (frontendKernel, backendKernel) => {
      chai.assert.instanceOf(
        backendKernel, Kernel, 'backendKernel is an instance of Kernel'
      );
      chai.assert.instanceOf(
        frontendKernel, Kernel, 'frontendKernel is an instance of Kernel'
      );

      backendKernelInstance = backendKernel;
      frontendKernelInstance = frontendKernel;

      validation = frontendKernel.get('validation');

      chai.assert.instanceOf(
        validation, Validation, 'validation is an instance of Validation'
      );

      // complete the async
      done();
    };

    KernelFactory.create({Validation: Validation}, callback);
  });

  test('Check constructor sets schemas', function() {
    chai.assert.instanceOf(
      validation.schemas, Object, 'schemas is an instance of Object'
    );
    chai.expect(validation.schemasNames).to.be.eql(['Name']);
  });

  test('Check hasSchema() returns true', function() {
    chai.expect(validation.hasSchema('Name')).to.be.equal(true);
  });

  test('Check hasSchema() returns false', function() {
    chai.expect(validation.hasSchema('None-exsting name')).to.be.equal(false);
  });

  test('Check getSchema() returns valid object', function() {
    let actualResult = validation.getSchema('Name');

    chai.assert.instanceOf(
      actualResult, Object, 'getSchema() returns an instance of Object'
    );
    chai.expect(actualResult.isJoi).to.be.equal(true);
  });

  test('Check getSchema() method throws ValidationSchemaNotFoundException',
    function() {
      let error = null;

      try {
        validation.getSchema('invalidSchemaName');
      } catch (e) {
        error = e;
      }

      chai.expect(error).to.be.an.instanceOf(ValidationSchemaNotFoundException);
    }
  );

  test('Check setSchema() method throws InvalidJoiSchemaException', function() {
    let error = null;
    let invalidSchema = {firstKey: 'value1'};

    try {
      validation.setSchema('invalidSchemaName', invalidSchema);
    } catch (e) {
      error = e;
    }

    chai.expect(error).to.be.an.instanceOf(InvalidJoiSchemaException);
  });

  test('Check setSchema() method create new model schema', function() {
    let joi = ObjectToJoi._transform(rawModelSchema);
    let actualResult = validation.setSchema('NewSchema', joi);

    chai.expect(actualResult).to.be.an.instanceOf(Validation);
    chai.expect(validation.schemasNames).to.be.eql(['Name', 'NewSchema']);
  });

  test('Check normalizeSchema() returns valid ObjectToJoi object', function() {
    let actualResult = Validation.normalizeSchema({testKey: 'string'});

    chai.assert.instanceOf(actualResult, Object, 'is an instance of Object');
    chai.expect(actualResult.isJoi).to.be.equal(true);
    chai.expect(actualResult._type).to.be.equal('object');

    chai.expect(actualResult._inner.children[0].key).to.be.equal('testKey');
    chai.expect(actualResult._inner.children[0].schema.isJoi).to.be.equal(true);
    chai.expect(actualResult._inner.children[0].schema._type).to.be.equal('string');
  });

  test('Check setSchemaRaw() set normalized schema to schemas[]', function() {
    let actualResult = validation.setSchemaRaw(modelName, testModelSchema);

    chai.expect(actualResult).to.be.an.instanceOf(Validation);
    chai.expect(validation.schemasNames).to.be.eql(['Name', 'NewSchema', modelName]);
  });

  test('Check _rawModelsToSchemas() returns valid object', function() {
    let validRawSchema = {
      Backend: {
        IAM: {
          Configuration: 'string',
          Status: 'string',
        },
        Lambda: {
          Configuration: 'string',
          Status: 'string',
        },
      },
    };
    let actualResult = validation._rawModelsToSchemas(validRawSchema);

    chai.assert.instanceOf(actualResult, Object, 'is an instance of Object');
  });

  test('Check validate() method throws ObjectValidationFailedException',
    function() {
      let error = null;
      let inputObject = {
        Configuration: 'test configuration',
        Status: 'should be number here',
      };

      try {
        validation.validate(modelName, inputObject);
      } catch (e) {
        error = e;
      }

      chai.expect(error).to.be.an.instanceOf(ObjectValidationFailedException);
      chai.expect(error.message).to.be.contains(
        'Object validation failed on schema'
      );
    }
  );

  test('Check validate() returns valid object for !returnRaw', function() {
    let inputObject = {
      Configuration: 'test configuration',
      Status: 0,
    };

    let actualResult = validation.validate(modelName, inputObject);

    chai.expect(actualResult).to.be.eql(inputObject);
  });

  test('Check validate() returns valid object for returnRaw', function() {
    let inputObject = {
      Configuration: 'test configuration',
      Status: 0,
    };
    let expectedResult = {
      error: null,
      value: inputObject,
    };

    let actualResult = validation.validate(modelName, inputObject, true);

    chai.expect(actualResult).to.be.eql(expectedResult);
  });

  test('Check boot() returns valid object', function() {
    let spyCallback = sinon.spy();
    let validationInstance = new Validation();

    validationInstance.boot(backendKernelInstance, spyCallback);

    chai.expect(validationInstance.schemasNames).to.be.eql(['Name']);

    chai.expect(
      validationInstance.schemas.Name._inner.children[0].key
    ).to.be.equal('Name');
    chai.expect(
      validationInstance.schemas.Name._inner.children[0].schema._type
    ).to.be.equal('string');
    chai.expect(
      validationInstance.schemas.Name._inner.children[0].schema.isJoi
    ).to.be.equal(true);

    chai.expect(
      validationInstance.schemas.Name._inner.children[1].key
    ).to.be.equal('Id');
    chai.expect(
      validationInstance.schemas.Name._inner.children[1].schema._type
    ).to.be.equal('string');
    chai.expect(
      validationInstance.schemas.Name._inner.children[1].schema.isJoi
    ).to.be.equal(true);

    chai.expect(spyCallback).to.have.been.calledWithExactly();
  });

  test('Check validateRuntimeInput() sends ErrorResponse for none-exisiting schema',
    function() {
      let spyCallback = sinon.spy();
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, 'none-exisiting schema name', spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.not.have.been.calledWith();
    }
  );

  test('Check validateRuntimeInput() returns validation result in cb',
    function() {
      let inputObject = {
        Configuration: 'test configuration',
        Status: 0,
      };
      let spyCallback = sinon.spy();
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);
      lambdaRuntime._request = {data: inputObject};

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, modelName, spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.have.been.calledWithExactly(inputObject);
    }
  );

  test('Check validateRuntimeInput() sends ErrorResponse for validation schema error',
    function() {
      let inputObject = {
        Configuration: 'test configuration',
        Status: '',
      };
      let spyCallback = sinon.spy();
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);
      lambdaRuntime._request = {data: inputObject};

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, modelName, spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.not.have.been.calledWith();
    }
  );

});
<commit_msg>Update unit tests for validateRuntimeInput()<commit_after>'use strict';

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import {Validation} from '../lib/Validation';
import {ObjectToJoi} from '../lib/ObjectToJoi';
import {RuntimeMock} from './Mock/RuntimeMock';
import {Context} from '../node_modules/deep-core/lib.compiled/AWS/Lambda/Context'
import {Exception} from '../lib/Exception/Exception';
import {ValidationSchemaNotFoundException} from '../lib/Exception/ValidationSchemaNotFoundException';
import {InvalidJoiSchemaException} from '../lib/Exception/InvalidJoiSchemaException';
import {ObjectValidationFailedException} from '../lib/Exception/ObjectValidationFailedException';
import Kernel from 'deep-kernel';
import KernelFactory from './common/KernelFactory';

chai.use(sinonChai);

suite('Validation', function() {
  let validation = null;
  let modelName = 'ConfigurationModel';
  let rawModelSchema = {username: 'string'};
  let backendKernelInstance = null;
  let frontendKernelInstance = null;
  let testModelSchema = {
    Configuration: 'string',
    Status: 'number',
  };

  test('Class Validation exists in Validation', function() {
    chai.expect(typeof Validation).to.equal('function');
  });

  test('Load Kernels by using Kernel.load()', function(done) {
    let callback = (frontendKernel, backendKernel) => {
      chai.assert.instanceOf(
        backendKernel, Kernel, 'backendKernel is an instance of Kernel'
      );
      chai.assert.instanceOf(
        frontendKernel, Kernel, 'frontendKernel is an instance of Kernel'
      );

      backendKernelInstance = backendKernel;
      frontendKernelInstance = frontendKernel;

      validation = frontendKernel.get('validation');

      chai.assert.instanceOf(
        validation, Validation, 'validation is an instance of Validation'
      );

      // complete the async
      done();
    };

    KernelFactory.create({Validation: Validation}, callback);
  });

  test('Check constructor sets schemas', function() {
    chai.assert.instanceOf(
      validation.schemas, Object, 'schemas is an instance of Object'
    );
    chai.expect(validation.schemasNames).to.be.eql(['Name']);
  });

  test('Check hasSchema() returns true', function() {
    chai.expect(validation.hasSchema('Name')).to.be.equal(true);
  });

  test('Check hasSchema() returns false', function() {
    chai.expect(validation.hasSchema('None-exsting name')).to.be.equal(false);
  });

  test('Check getSchema() returns valid object', function() {
    let actualResult = validation.getSchema('Name');

    chai.assert.instanceOf(
      actualResult, Object, 'getSchema() returns an instance of Object'
    );
    chai.expect(actualResult.isJoi).to.be.equal(true);
  });

  test('Check getSchema() method throws ValidationSchemaNotFoundException',
    function() {
      let error = null;

      try {
        validation.getSchema('invalidSchemaName');
      } catch (e) {
        error = e;
      }

      chai.expect(error).to.be.an.instanceOf(ValidationSchemaNotFoundException);
    }
  );

  test('Check setSchema() method throws InvalidJoiSchemaException', function() {
    let error = null;
    let invalidSchema = {firstKey: 'value1'};

    try {
      validation.setSchema('invalidSchemaName', invalidSchema);
    } catch (e) {
      error = e;
    }

    chai.expect(error).to.be.an.instanceOf(InvalidJoiSchemaException);
  });

  test('Check setSchema() method create new model schema', function() {
    let joi = ObjectToJoi._transform(rawModelSchema);
    let actualResult = validation.setSchema('NewSchema', joi);

    chai.expect(actualResult).to.be.an.instanceOf(Validation);
    chai.expect(validation.schemasNames).to.be.eql(['Name', 'NewSchema']);
  });

  test('Check normalizeSchema() returns valid ObjectToJoi object', function() {
    let actualResult = Validation.normalizeSchema({testKey: 'string'});

    chai.assert.instanceOf(actualResult, Object, 'is an instance of Object');
    chai.expect(actualResult.isJoi).to.be.equal(true);
    chai.expect(actualResult._type).to.be.equal('object');

    chai.expect(actualResult._inner.children[0].key).to.be.equal('testKey');
    chai.expect(actualResult._inner.children[0].schema.isJoi).to.be.equal(true);
    chai.expect(actualResult._inner.children[0].schema._type).to.be.equal('string');
  });

  test('Check setSchemaRaw() set normalized schema to schemas[]', function() {
    let actualResult = validation.setSchemaRaw(modelName, testModelSchema);

    chai.expect(actualResult).to.be.an.instanceOf(Validation);
    chai.expect(validation.schemasNames).to.be.eql(['Name', 'NewSchema', modelName]);
  });

  test('Check _rawModelsToSchemas() returns valid object', function() {
    let validRawSchema = {
      Backend: {
        IAM: {
          Configuration: 'string',
          Status: 'string',
        },
        Lambda: {
          Configuration: 'string',
          Status: 'string',
        },
      },
    };
    let actualResult = validation._rawModelsToSchemas(validRawSchema);

    chai.assert.instanceOf(actualResult, Object, 'is an instance of Object');
  });

  test('Check validate() method throws ObjectValidationFailedException',
    function() {
      let error = null;
      let inputObject = {
        Configuration: 'test configuration',
        Status: 'should be number here',
      };

      try {
        validation.validate(modelName, inputObject);
      } catch (e) {
        error = e;
      }

      chai.expect(error).to.be.an.instanceOf(ObjectValidationFailedException);
      chai.expect(error.message).to.be.contains(
        'Object validation failed on schema'
      );
    }
  );

  test('Check validate() returns valid object for !returnRaw', function() {
    let inputObject = {
      Configuration: 'test configuration',
      Status: 0,
    };

    let actualResult = validation.validate(modelName, inputObject);

    chai.expect(actualResult).to.be.eql(inputObject);
  });

  test('Check validate() returns valid object for returnRaw', function() {
    let inputObject = {
      Configuration: 'test configuration',
      Status: 0,
    };
    let expectedResult = {
      error: null,
      value: inputObject,
    };

    let actualResult = validation.validate(modelName, inputObject, true);

    chai.expect(actualResult).to.be.eql(expectedResult);
  });

  test('Check boot() returns valid object', function() {
    let spyCallback = sinon.spy();
    let validationInstance = new Validation();

    validationInstance.boot(backendKernelInstance, spyCallback);

    chai.expect(validationInstance.schemasNames).to.be.eql(['Name']);

    chai.expect(
      validationInstance.schemas.Name._inner.children[0].key
    ).to.be.equal('Name');
    chai.expect(
      validationInstance.schemas.Name._inner.children[0].schema._type
    ).to.be.equal('string');
    chai.expect(
      validationInstance.schemas.Name._inner.children[0].schema.isJoi
    ).to.be.equal(true);

    chai.expect(
      validationInstance.schemas.Name._inner.children[1].key
    ).to.be.equal('Id');
    chai.expect(
      validationInstance.schemas.Name._inner.children[1].schema._type
    ).to.be.equal('string');
    chai.expect(
      validationInstance.schemas.Name._inner.children[1].schema.isJoi
    ).to.be.equal(true);

    chai.expect(spyCallback).to.have.been.calledWithExactly();
  });

  test('Check validateRuntimeInput() sends ErrorResponse for none-exisiting schema',
    function() {
      let inputObject = {
        Configuration: 'test configuration',
        Status: 0,
      };
      let spyCallback = sinon.spy();
      let context = new Context({
        contextTest: 'Test',
        fail: () => {
          return this;
        },
      });
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);

      lambdaRuntime._request = {data: inputObject};
      lambdaRuntime._context = context;

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, 'none-exisiting schema name', spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.not.have.been.calledWith();
      chai.expect(lambdaRuntime.contextSent).to.equal(true);
    }
  );

  test('Check validateRuntimeInput() returns validation result in cb',
    function() {
      let inputObject = {
        Configuration: 'test configuration',
        Status: 0,
      };
      let spyCallback = sinon.spy();
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);
      lambdaRuntime._request = {data: inputObject};

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, modelName, spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.have.been.calledWithExactly(inputObject);
    }
  );

  test('Check validateRuntimeInput() sends ErrorResponse for validation schema error',
    function() {
      let inputObject = {
        Configuration: 'test configuration',
        Status: '',
      };
      let spyCallback = sinon.spy();
      let context = new Context({
        contextTest: 'Test',
        fail: () => {
          return this;
        },
      });
      let lambdaRuntime = new RuntimeMock(backendKernelInstance);
      lambdaRuntime._request = {data: inputObject};
      lambdaRuntime._context = context;

      let actualResult = validation.validateRuntimeInput(
        lambdaRuntime, modelName, spyCallback
      );

      chai.expect(actualResult).to.be.an.instanceOf(Validation);
      chai.expect(spyCallback).to.not.have.been.calledWith();
      chai.expect(lambdaRuntime.contextSent).to.equal(true);
    }
  );

});
<|endoftext|>


<commit_before>// @Author: Joshua Tanner
// @Date: 12/8/2014
// @Description: Easy way to create shapefiles from ArcGIS Server services
// @services.txt format :: serviceLayerURL|layerName

// Node Modules
var esrigeo = require('esri2geo');
var ogr2ogr = require('ogr2ogr');
var q = require('q');
var request = q.nfbind(require('request'));
var fs = require('fs');

// Make request to each service
fs.readFile('services.txt', function (err, data) {
	if (err) throw err;
	data.toString().split('\n').forEach(function (service) {
		var service = service.split('|');
		//get total number of records | assume 1000 max each request
		request({
			url : service[0].trim() + '/query',
			qs : {
				where : '1=1',
				returnCountOnly : true,
				f : 'json'
			},
			method : 'GET',
			json : true
		}, function (err, response, body) {
			if(err) throw err;
			requestService(service[0].trim(), service[1].trim(), body.count);
		});
	})
});

// Resquest JSON from AGS
// assumption 1 = 1000 max requests on service
// assumption 2 = objectid always auto incremented
function requestService(serviceUrl, serviceName, totalRecords) {
	var requests = [];
	for(var i = 0 ; i < Math.ceil(totalRecords / 1000); i++) {
		var r = request({
			url : serviceUrl + '/query',
			qs : {
				where : 'OBJECTID > ' +  (i * 1000) + ' and OBJECTID <= ' + ((i+1) * 1000),
				geometryType : 'esriGeometryEnvelope',
				returnGeometry : true,
				returnIdsOnly : false,
				returnZ : false,
				returnM : false,
				outFields : '*',
				outSR : '4326',
				f : 'json'
			},
			method : 'GET',
			json : true
		});

		requests.push(r);
	};

	q.allSettled(requests).then(function (results) {
		var allFeatures = null;
		for(var i = 0; i < results.length; i++) {
			if(i == 0) {
				allFeatures = results[i].value[0].body;
			} else {
				allFeatures.features = allFeatures.features.concat(results[i].value[0].body.features);
			}
		}

		console.log(allFeatures.features.length)

		console.log('creating', serviceName, 'geojson');
		var geojson = esrigeo(allFeatures);
		fs.writeFile('./output/' + serviceName + '.geojson', JSON.stringify(geojson), function (err) {
			if(err) throw err;

			// Create Shapefile
			console.log('creating', serviceName, 'shapefile');
			var shapefile = ogr2ogr('./output/' + serviceName + '.geojson')
								.format('ESRI Shapefile')
								.skipfailures();

			shapefile.stream().pipe(fs.createWriteStream('./output/' + serviceName + '.zip'));
		});

	}).catch(function (err) {
		console.log(x);
		throw err;
	});
}<commit_msg>Add command line input<commit_after>// @Author: Joshua Tanner
// @Date: 12/8/2014
// @Description: Easy way to create shapefiles from ArcGIS Server services
// @services.txt format :: serviceLayerURL|layerName

// Node Modules
var esrigeo = require('esri2geo');
var ogr2ogr = require('ogr2ogr');
var q = require('q');
var request = q.nfbind(require('request'));
var fs = require('fs');

var serviceFile = process.argv[2] || 'services.txt';
var outDir = process.argv[3] || './output/';
if(outDir[outDir.length - 1] !== '/') {
	outDir += '/';
}

// Make request to each service
fs.readFile(serviceFile, function (err, data) {
	if (err) throw err;
	data.toString().split('\n').forEach(function (service) {
		var service = service.split('|');
		//get total number of records | assume 1000 max each request
		request({
			url : service[0].trim() + '/query',
			qs : {
				where : '1=1',
				returnCountOnly : true,
				f : 'json'
			},
			method : 'GET',
			json : true
		}, function (err, response, body) {
			if(err) throw err;
			requestService(service[0].trim(), service[1].trim(), body.count);
		});
	})
});

// Resquest JSON from AGS
// assumption 1 = 1000 max requests on service
// assumption 2 = objectid always auto incremented
function requestService(serviceUrl, serviceName, totalRecords) {
	var requests = [];
	for(var i = 0 ; i < Math.ceil(totalRecords / 1000); i++) {
		var r = request({
			url : serviceUrl + '/query',
			qs : {
				where : 'OBJECTID > ' +  (i * 1000) + ' and OBJECTID <= ' + ((i+1) * 1000),
				geometryType : 'esriGeometryEnvelope',
				returnGeometry : true,
				returnIdsOnly : false,
				returnZ : false,
				returnM : false,
				outFields : '*',
				outSR : '4326',
				f : 'json'
			},
			method : 'GET',
			json : true
		});

		requests.push(r);
	};

	q.allSettled(requests).then(function (results) {
		var allFeatures = null;
		for(var i = 0; i < results.length; i++) {
			if(i == 0) {
				allFeatures = results[i].value[0].body;
			} else {
				allFeatures.features = allFeatures.features.concat(results[i].value[0].body.features);
			}
		}

		console.log('creating', serviceName, 'geojson');
		var geojson = esrigeo(allFeatures);
		fs.writeFile(outDir + serviceName + '.geojson', JSON.stringify(geojson), function (err) {
			if(err) throw err;

			// Create Shapefile
			console.log('creating', serviceName, 'shapefile');
			var shapefile = ogr2ogr(outDir + serviceName + '.geojson')
								.format('ESRI Shapefile')
								.skipfailures();

			shapefile.stream().pipe(fs.createWriteStream(outDir + serviceName + '.zip'));
		});

	}).catch(function (err) {
		console.log(x);
		throw err;
	});
}<|endoftext|>


<commit_before>var controller = (function(){

    var data = {};

    function init(){
        update();
        addListeners();
        setInterval(function(){
            update();
        },250);
    }

    function addListeners(){
        ui.addListener("add-miner", function(){
            $.get("/miner/start",{
                "threads": data.miner.Threads + 1
            }, function(e){
                // TODO: handle error
                console.log(e);
            });
        });
        ui.addListener("remove-miner", function(){
            $.get("/miner/start",{
                "threads": data.miner.Threads - 1 < 0 ? 0 : data.miner.Threads - 1
            }, function(e){
                // TODO: handle error
                console.log(e);
            });
        });
        ui.addListener("toggle-mining", function(){
            if (data.miner.State == "Off"){
                $.get("/miner/start",{
                    "threads": data.miner.Threads
                }, function(e){
                    // TODO: handle error
                    console.log(e);
                });
            }else{
                $.get("/miner/stop", function(e){
                    // TODO: handle error
                    console.log(e);
                });
            }
        });
        ui.addListener("stop-mining", function(){
            $.get("/miner/stop", function(e){
                // TODO: handle error
                console.log(e);
            });
        });
    }

    function update(){
        // Get json objects from each source and merge
        $.getJSON("/wallet/status", function(response){
            data.wallet = {
                "Balance": response.Balance,
                "FullBalance": response.FullBalance,
                "USDBalance": util.USDConvert(response.Balance),
                "NumAddresses": response.NumAddresses,
                "DefaultAccount": "Main Account",
                "Accounts": [{
                    "Name" : "Main Account",
                    "Balance": response.Balance,
                    "USDBalance": util.USDConvert(response.Balance),
                    "NumAddresses": response.NumAddresses,
                    "Addresses": [],
                    "Transactions": []
                }]
            };
            updateUI();
        });
        var lastUpdateTime = Date.now();
        var lastBalance = 0;
        $.getJSON("/miner/status", function(response){
            var timeDifference = (Date.now() - lastUpdateTime) * 1000;
            var balance = data.wallet ? data.wallet.Balance : 0;
            var balanceDifference = balance - lastBalance;
            var incomeRate = balanceDifference / timeDifference;
            data.miner = {
                "State": response.State,
                "Threads": response.Threads,
                "RunningThreads": response.RunningThreads,
                "Address": response.Address,
                "AccountName": "Main Account",
                "Balance": balance,
                "USDBalance": util.USDConvert(balance),
                "IncomeRate": incomeRate + " SC/s"
            };
            lastBalance = balance;
            lastUpdateTime = Date.now();
            updateUI();
        });
        $.getJSON("/json/status", function(response){
            data.status = response;
            updateUI();
        });
    }

    function updateUI(){
        if (data.wallet && data.miner && data.status){
            ui.update(data);
        }
    }

    return {
        "init": init,
        "update": update
    };
})();
<commit_msg>running average for income rate display<commit_after>var controller = (function(){

    var data = {};

    function init(){
        update();
        addListeners();
        setInterval(function(){
            update();
        },250);
    }

    function addListeners(){
        ui.addListener("add-miner", function(){
            $.get("/miner/start",{
                "threads": data.miner.Threads + 1
            }, function(e){
                // TODO: handle error
                console.log(e);
            });
        });
        ui.addListener("remove-miner", function(){
            $.get("/miner/start",{
                "threads": data.miner.Threads - 1 < 0 ? 0 : data.miner.Threads - 1
            }, function(e){
                // TODO: handle error
                console.log(e);
            });
        });
        ui.addListener("toggle-mining", function(){
            if (data.miner.State == "Off"){
                $.get("/miner/start",{
                    "threads": data.miner.Threads
                }, function(e){
                    // TODO: handle error
                    console.log(e);
                });
            }else{
                $.get("/miner/stop", function(e){
                    // TODO: handle error
                    console.log(e);
                });
            }
        });
        ui.addListener("stop-mining", function(){
            $.get("/miner/stop", function(e){
                // TODO: handle error
                console.log(e);
            });
        });
    }

    var lastUpdateTime = Date.now();
    var lastBalance = 0;
    var runningIncomeRateAverage = 0;

    function update(){
        // Get json objects from each source and merge
        $.getJSON("/wallet/status", function(response){
            data.wallet = {
                "Balance": response.Balance,
                "FullBalance": response.FullBalance,
                "USDBalance": util.USDConvert(response.Balance),
                "NumAddresses": response.NumAddresses,
                "DefaultAccount": "Main Account",
                "Accounts": [{
                    "Name" : "Main Account",
                    "Balance": response.Balance,
                    "USDBalance": util.USDConvert(response.Balance),
                    "NumAddresses": response.NumAddresses,
                    "Addresses": [],
                    "Transactions": []
                }]
            };
            updateUI();
        });
        $.getJSON("/miner/status", function(response){
            var timeDifference = (Date.now() - lastUpdateTime) * 1000;
            var balance = data.wallet ? data.wallet.Balance : 0;
            var balanceDifference = balance - lastBalance;
            var incomeRate = balanceDifference / timeDifference;
            runningIncomeRateAverage = (runningIncomeRateAverage * 49 + incomeRate)/50;
            data.miner = {
                "State": response.State,
                "Threads": response.Threads,
                "RunningThreads": response.RunningThreads,
                "Address": response.Address,
                "AccountName": "Main Account",
                "Balance": balance,
                "USDBalance": util.USDConvert(balance),
                "IncomeRate": runningIncomeRateAverage + " SC/s"
            };
            lastBalance = balance;
            lastUpdateTime = Date.now();
            updateUI();
        });
        $.getJSON("/json/status", function(response){
            data.status = response;
            updateUI();
        });
    }

    function updateUI(){
        if (data.wallet && data.miner && data.status){
            ui.update(data);
        }
    }

    return {
        "init": init,
        "update": update
    };
})();
<|endoftext|>


<commit_before>const fs = require('fs-extra')
const colors = require('colors')

const htaccess = `RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]`

fs.copy('./docs', './dist/docs')
    .then(() => {
        fs.writeFile('./dist/.htaccess', htaccess)
            .then(() => console.log(colors.green('\nFiles copy success')))
            .catch(err => console.error(err))
    })
    .catch(err => console.error(err))
<commit_msg>Copy changelog to dist<commit_after>const fs = require('fs-extra')
const colors = require('colors')

const htaccess = `RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]`

fs.copy('./docs', './dist/docs')
    .then(() => {
        fs.copy('./CHANGELOG.md', './dist/CHANGELOG.md')
    })
    .then(() => {
        fs.writeFile('./dist/.htaccess', htaccess)
            .then(() => console.log(colors.green('\nFiles copy success')))
            .catch(err => console.error(err))
    })
    .catch(err => console.error(err))
<|endoftext|>


<commit_before>(function($) {
  $.drappers = $.extend($.drappers, {
    autocomplete: function() {
      if(!$.isFunction($.fn.sortable)) {
        throw "Jquery plugin '$.fn.tokenInput' hasn't been required. "
            + "Check http://loopj.com/jquery-tokeninput/ "
      }

      if(!this.isDecoree) {
        throw "The object is not decoree!"
            + "See https://github.com/aratak/jquery.drapper/ for details."
      }

      var decoree = this;

      var getData = function(selectSelected) {
        return $(decoree).find('option' + (selectSelected ? '[selected]' : '')).map(function() {
          return {
            id: $(this).val(),
            queue: $(this).attr('data-drapper-keywords'),
            hint: $(this).attr('data-drapper-hint'),
            value: $(this).html()
          }
        });
      }

      var getOptionByItem = function(item) {
        return $(decoree).find('option[value=' + item['id'] + ']')
      }

      var optionsToTokenInput = function() {
        return $.extend({
          theme: 'facebook',
          propertyToSearch: "queue",
          resultsFormatter: function(item) { return "
" + item.hint + "
" },
          tokenFormatter: function(item) { return "
" + item.value + "
" },
          preventDuplicates: true,
          hintText: "Type in a search term",
          onAdd: function(item) {
            return getOptionByItem(item).attr('selected', 'selected');
          },
          onDelete: function(item) {
            return getOptionByItem(item).removeAttr('selected');
          },
          prePopulate: getData(true)
        }, decoree.config);
      }

      var tokenInput = function() {
        var findTokenInput = function() {
          decoree.wrapper().find('input[data-drapper-autocomplete-container]');
        }
        var createTokenInput = function() {
          return $(document.createElement('input')).attr({
            'type': 'text',
            'data-drapper-autocomplete-container': true
          }).appendTo(decoree.wrapper());
        }
        return findTokenInput() || createTokenInput();
      }

      var hideDecoree = function() {
        $(decoree).css({
          visibility: 'hidden',
          position: 'absolute',
          zIndex: -1
        })
        return true;
      };

      hideDecoree();
      $(tokenInput()).tokenInput(getData(), optionsToTokenInput());
    }
  });
})(jQuery);

<commit_msg>Fire event change on decoree after select attribute<commit_after>(function ($) {
  $.drappers = $.extend($.drappers, {
    autocomplete: function () {
      if (!$.isFunction($.fn.sortable)) {
        throw "Jquery plugin '$.fn.tokenInput' hasn't been required. " +
              "Check http://loopj.com/jquery-tokeninput/ ";
      }

      if (!this.isDecoree) {
        throw "The object is not decoree!" +
              "See https://github.com/aratak/jquery.drapper/ for details.";
      }

      var decoree = this;

      var getData = function (selectSelected) {
        return $(decoree).find('option' + (selectSelected ? '[selected]' : '')).map(function () {
          return {
            id: $(this).val(),
            queue: $(this).attr('data-drapper-keywords'),
            hint: $(this).attr('data-drapper-hint'),
            value: $(this).html()
          };
        });
      };

      var getOptionByItem = function (item) {
        return $(decoree).find('option[value=' + item['id'] + ']');
      };

      var optionsToTokenInput = function () {
        return $.extend({
          theme: 'facebook',
          propertyToSearch: "queue",
          resultsFormatter: function (item) { return "
" + item.hint + "
"; },
          tokenFormatter: function (item) { return "
" + item.value + "
"; },
          preventDuplicates: true,
          hintText: "Type in a search term",
          onAdd: function (item) {
            getOptionByItem(item).attr('selected', 'selected');
            $(decoree).trigger('change');
          },
          onDelete: function (item) {
            getOptionByItem(item).removeAttr('selected');
            $(decoree).trigger('change');
          },
          prePopulate: getData(true)
        }, decoree.config);
      };

      var tokenInput = function () {
        var findTokenInput = function () {
          decoree.wrapper().find('input[data-drapper-autocomplete-container]');
        };
        var createTokenInput = function () {
          return $(document.createElement('input')).attr({
            'type': 'text',
            'data-drapper-autocomplete-container': true
          }).appendTo(decoree.wrapper());
        };
        return findTokenInput() || createTokenInput();
      };

      var hideDecoree = function () {
        $(decoree).css({
          visibility: 'hidden',
          position: 'absolute',
          zIndex: -1
        });
        return true;
      };

      hideDecoree();
      $(tokenInput()).tokenInput(getData(), optionsToTokenInput());
    }
  });
}(jQuery));

<|endoftext|>


<commit_before>'use strict';

var request = require('request');

var internals = {};

internals.enable = function enableForwarding(sid, callback) {
  request.post(
    'http://192.168.1.1/internet/port_fw.lua',
    {
      form: {
        active_1: 1,
        active_2: 1,
        active_3: 1,
        box_upnp_control_activated: 1,
        sid: sid,
        apply: ''
      }
    },
    function (error, response, body) {

      if(error) {
        return callback(error);
      }

      callback(null, body);
    }
  );
};

internals.disable = function disableForwarding(sid, callback) {
  request.post(
    'http://192.168.1.1/internet/port_fw.lua',
    {
      form: {
        active_3: 1,
        box_upnp_control_activated: 1,
        sid: sid,
        apply: ''
      }
    },
    function (error, response, body) {

      if(error) {
        return callback(error);
      }

      callback(null, body);
    }
  );
};

module.exports = function portForwarding(sid, params, callback) {

  if(!params.length) {
    console.log('Missing parameter.\nUsage: node index.js port-forwarding [enable|disable]');
    return;
  }

  if(['enable', 'disable'].indexOf(params[0]) === -1) {
    console.log('Wrong parameter.\nUsage: node index.js port-forwarding [enable|disable]');
    return;
  }

  internals[params[0]].call(null, sid, callback);
};
<commit_msg>Added host parameter<commit_after>'use strict';

var request = require('request');

var internals = {};

internals.enable = function enableForwarding(host, sid, callback) {
  request.post(
    'http://' + host + '/internet/port_fw.lua',
    {
      form: {
        active_1: 1,
        active_2: 1,
        active_3: 1,
        box_upnp_control_activated: 1,
        sid: sid,
        apply: ''
      }
    },
    function (error, response, body) {

      if(error) {
        return callback(error);
      }

      callback(null, body);
    }
  );
};

internals.disable = function disableForwarding(host, sid, callback) {
  request.post(
    'http://' + host + '/internet/port_fw.lua',
    {
      form: {
        active_3: 1,
        box_upnp_control_activated: 1,
        sid: sid,
        apply: ''
      }
    },
    function (error, response, body) {

      if(error) {
        return callback(error);
      }

      callback(null, body);
    }
  );
};

module.exports = function portForwarding(host, sid, params, callback) {

  if(!params.length) {
    console.log('Missing parameter.\nUsage: node index.js port-forwarding [enable|disable]');
    return;
  }

  if(['enable', 'disable'].indexOf(params[0]) === -1) {
    console.log('Wrong parameter.\nUsage: node index.js port-forwarding [enable|disable]');
    return;
  }

  internals[params[0]].call(null, host, sid, callback);
};
<|endoftext|>


<commit_before>/*jslint node: true */

"use strict";

var ExifImage = require('exif').ExifImage;
var through = require('through2');

module.exports = function () {
	return through.obj(function (file, encoding, callback) {
		new ExifImage({image: file.contents}, function (error, exifData) {
			for (var prop in exifData) {
				file[prop] = exifData[prop];
			}

			callback(error, file);
		});
	});
};
<commit_msg>Don't polute file<commit_after>/*jslint node: true */

"use strict";

var ExifImage = require('exif').ExifImage;
var through = require('through2');

module.exports = function () {
	return through.obj(function (file, encoding, callback) {
		new ExifImage({image: file.contents}, function (error, exifData) {
			file.exif = exifData;

			callback(error, file);
		});
	});
};
<|endoftext|>


<commit_before>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2013 Sebastian Werner
==================================================================================================
*/

"use strict";

(function()
{
  var hexTable = "0123456789abcdef".split("");

  /**
   * A collection of utility methods for native JavaScript strings.
   */
  core.Module("core.String",
  {
    /**
     * {String} Converts the @str {String} into a hex string
     */
    toHex : function(str)
    {
      var output = "";
      var code;

      for (var i = 0, l = str.length; i < l; i++)
      {
        code = str.charCodeAt(i);
        output += hexTable[(code >>> 4) & 0x0F] + hexTable[code & 0x0F];
      }

      return output;
    },

    /**
     * {String} Encodes the @str {String} as UTF-8.
     *
     * Via: http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
     */
    encodeUtf8 : function(str) {
      return unescape(encodeURIComponent(str));
    },

    /**
     * {String} Decodes the @str {String} from UTF-8.
     *
     * Via: http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
     */
    decodeUtf8 : function(str) {
      return decodeURIComponent(escape(str));
    },

    /**
     * Whether the @str {String} contains the given @substring {String}.
     */
    contains : function(str, substring) {
      return str.indexOf(substring) != -1;
    },

    /**
     * {Boolean} Returns true if the @str {String} has a length of 0 or contains only whitespace.
     */
    isBlank : function(str) {
      return str.trim().length == 0;
    },

    /**
     * {String} Reverses the @str {String}.
     */
    reverse : function(str) {
      return str.split("").reverse().join("");
    },

    /**
     * {String} Removes double spaces and line breaks from the @str {String}.
     */
    compact : function(str) {
      return str.replace(/[\r\n]/g, " ").trim().replace(/([\s　])+/g, '$1');
    },

    /**
     * {String} Hyphenates the @str {String} like:
     *
     * - `camelCase` => `camel-case`
     * - `HelloWorld` => `-hello-world`
     */
    hyphenate : function(str) {
      return str.replace(/[A-Z]/g,'-$&').toLowerCase();
    },

    /**
     * {String} Camelizes this @str {String} like:
     *
     * - `camel-case => camelCase`
     * - `-hello-world => HelloWorld`
     */
    camelize : function(str)
    {
      return str.replace(/\-+(\S)?/g, function(match, chr) {
        return chr ? chr.toUpperCase() : '';
      });
    },

    /**
     * {String} Returns a new @str {String} which is a @nr {Integer} repeated copy of the original one.
     */
    repeat : function(str, nr)
    {
      // Optimized by: http://jsperf.com/repeat-vs-repeat/3
      if (nr < 1) {
        return '';
      }

      var pattern = str;
      var result = "";
      while (nr > 0)
      {
        if (nr & 1) {
          result += pattern;
        }

        nr >>= 1;
        pattern += pattern;
      }

      return result;
    },

    /**
     * {Boolean} Returns `true` if the @str {String} starts with the given substring @begin {String}
     */
    startsWith : function(str, begin) {
      return begin == str.slice(0, begin.length);
    },

    /**
     * {Boolean} Returns `true` if the @str {String} ends with the given substring @end {String}
     */
    endsWith : function(str, end) {
      return end == str.slice(-end.length);
    }
  });
})();
<commit_msg>Added new method interpret() to translate specific string values into primitive values.<commit_after>/*
==================================================================================================
  Core - JavaScript Foundation
  Copyright 2013 Sebastian Werner
==================================================================================================
*/

"use strict";

(function()
{
  /** {=Array} Used for looking up hex characters */
  var hexTable = "0123456789abcdef".split("");

  /** {=Map} Used to map specific string values to primitive counter parts */
  var interpreterMap =
  {
    true: true,
    false: false,
    null: null,
    yes: true,
    no: false
  };

  /**
   * A collection of utility methods for native JavaScript strings.
   */
  core.Module("core.String",
  {
    /**
     * {String} Converts the @str {String} into a hex string
     */
    toHex : function(str)
    {
      var output = "";
      var code;

      for (var i = 0, l = str.length; i < l; i++)
      {
        code = str.charCodeAt(i);
        output += hexTable[(code >>> 4) & 0x0F] + hexTable[code & 0x0F];
      }

      return output;
    },

    /**
     * {String|Boolean|null} Interprets the given @str {String} to make string values from e.g. localStorage
     * form values, etc. richer and mapping them to their actual primitive values.
     */
    interpret : function(str) {
      return str in interpreterMap ? interpreterMap[str] : str;
    },

    /**
     * {String} Encodes the @str {String} as UTF-8.
     *
     * Via: http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
     */
    encodeUtf8 : function(str) {
      return unescape(encodeURIComponent(str));
    },

    /**
     * {String} Decodes the @str {String} from UTF-8.
     *
     * Via: http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
     */
    decodeUtf8 : function(str) {
      return decodeURIComponent(escape(str));
    },

    /**
     * Whether the @str {String} contains the given @substring {String}.
     */
    contains : function(str, substring) {
      return str.indexOf(substring) != -1;
    },

    /**
     * {Boolean} Returns true if the @str {String} has a length of 0 or contains only whitespace.
     */
    isBlank : function(str) {
      return str.trim().length == 0;
    },

    /**
     * {String} Reverses the @str {String}.
     */
    reverse : function(str) {
      return str.split("").reverse().join("");
    },

    /**
     * {String} Removes double spaces and line breaks from the @str {String}.
     */
    compact : function(str) {
      return str.replace(/[\r\n]/g, " ").trim().replace(/([\s　])+/g, '$1');
    },

    /**
     * {String} Hyphenates the @str {String} like:
     *
     * - `camelCase` => `camel-case`
     * - `HelloWorld` => `-hello-world`
     */
    hyphenate : function(str) {
      return str.replace(/[A-Z]/g,'-$&').toLowerCase();
    },

    /**
     * {String} Camelizes this @str {String} like:
     *
     * - `camel-case => camelCase`
     * - `-hello-world => HelloWorld`
     */
    camelize : function(str)
    {
      return str.replace(/\-+(\S)?/g, function(match, chr) {
        return chr ? chr.toUpperCase() : '';
      });
    },

    /**
     * {String} Returns a new @str {String} which is a @nr {Integer} repeated copy of the original one.
     */
    repeat : function(str, nr)
    {
      // Optimized by: http://jsperf.com/repeat-vs-repeat/3
      if (nr < 1) {
        return '';
      }

      var pattern = str;
      var result = "";
      while (nr > 0)
      {
        if (nr & 1) {
          result += pattern;
        }

        nr >>= 1;
        pattern += pattern;
      }

      return result;
    },

    /**
     * {Boolean} Returns `true` if the @str {String} starts with the given substring @begin {String}
     */
    startsWith : function(str, begin) {
      return begin == str.slice(0, begin.length);
    },

    /**
     * {Boolean} Returns `true` if the @str {String} ends with the given substring @end {String}
     */
    endsWith : function(str, end) {
      return end == str.slice(-end.length);
    }
  });
})();
<|endoftext|>


<commit_before>
export default () => {
    return {
        require: '^moList',
        restrict: 'E',
        templateUrl: '../monad/directives/list/table/template.html',
        scope: {columns: '=', rows: '=', total: '@', page: '=', inlines: '='},
        controller: ['$scope', '$route', function($scope, $route) {
            this.handle = (item, handler) => {
                handler(item).success(() => {
                    $route.reset();
                //    $route.reload();
                });
            };
        }],
        controllerAs: 'tbody',
        link: (scope, elem, attrs, ctrl) => {
            scope.tbody.module = ctrl.module;
        },
        bindToController: true
    };
};

<commit_msg>reload, todo: think of a better way<commit_after>
export default () => {
    return {
        require: '^moList',
        restrict: 'E',
        templateUrl: '../monad/directives/list/table/template.html',
        scope: {columns: '=', rows: '=', total: '@', page: '=', inlines: '='},
        controller: ['$scope', '$route', function($scope, $route) {
            this.handle = (item, handler) => {
                handler(item).success(() => {
                    $route.reset();
                    $route.reload();
                });
            };
        }],
        controllerAs: 'tbody',
        link: (scope, elem, attrs, ctrl) => {
            scope.tbody.module = ctrl.module;
        },
        bindToController: true
    };
};

<|endoftext|>


<commit_before>// @Author: Joshua Tanner
// @Date: 12/8/2014
// @Description: Easy way to create shapefiles from ArcGIS Server services
// @services.txt format :: serviceLayerURL|layerName

// Node Modules
var esri2geo = require('esri2geo');
var ogr2ogr = require('ogr2ogr');
var q = require('q');
var request = q.nfbind(require('request'));
var fs = require('fs');

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

var serviceFile = process.argv[2] || 'services.txt';
var outDir = process.argv[3] || './output/';
if(outDir[outDir.length - 1] !== '/') {
	outDir += '/';
}

// Make request to each service
fs.readFile(serviceFile, function (err, data) {
	if (err) {
		console.log(err);
		throw err;
	}
	data.toString().split('\n').forEach(function (service) {
		var service = service.split('|');
		//get total number of records | assume 1000 max each request
		var baseUrl = getBaseUrl(service[0].trim()) + '/query'
		request({
			url : baseUrl,
			qs : {
				where : '1=1',
				returnIdsOnly : true,
				f : 'json'
			},
			method : 'GET',
			json : true
		}, function (err, response, body) {
			if(err) {
				console.log(err);
				throw err;
			}
			requestService(service[0].trim(), service[1].trim(), body.objectIds);
		});
	})
});

// Resquest JSON from AGS
// assumption 1 = 1000 max requests on service
// assumption 2 = objectid always auto incremented (from startId) - NOT TRUE
function requestService(serviceUrl, serviceName, objectIds) {
	var requests = [];

	for(var i = 0; i < Math.ceil(objectIds.length / 100); i++) {
		var ids = [];
		if ( ((i + 1) * 100) < objectIds.length ) {
			ids = objectIds.slice(i * 100, (i + 1) * 100);
		} else {
			ids = objectIds.slice(i * 100, objectIds.length);
		}
		// we need these query params
		var reqQS = {
			objectIds : ids.join(','),
			geometryType : 'esriGeometryEnvelope',
			returnGeometry : true,
			returnIdsOnly : false,
			outFields : '*',
			outSR : '4326',
			f : 'json'
		};
		// user provided query params
		var userQS = getUrlVars(serviceUrl);
		// mix one obj with another
		var qs = mixin(userQS, reqQS);
		var r = request({
			url : getBaseUrl(serviceUrl) + '/query',
			qs : qs,
			method : 'GET',
			json : true
		});

		requests.push(r);
	};

	q.allSettled(requests).then(function (results) {
		var allFeatures = null;
		for(var i = 0; i < results.length; i++) {
			if(i == 0) {
				allFeatures = results[i].value[0].body;
			} else {
				allFeatures.features = allFeatures.features.concat(results[i].value[0].body.features);
			}
		}
		console.log('creating', serviceName, 'geojson');
		var geojson = esri2geo(allFeatures);
		fs.writeFile(outDir + serviceName + '.geojson', JSON.stringify(geojson), function (err) {
			if(err) throw err;

			// Create Shapefile
			console.log('creating', serviceName, 'shapefile');
			var shapefile = ogr2ogr(outDir + serviceName + '.geojson')
								.format('ESRI Shapefile')
								.skipfailures();

			shapefile.stream().pipe(fs.createWriteStream(outDir + serviceName + '.zip'));
		});

	}).catch(function (err) {
		console.log(err);
		throw err;
	});
}

//http://stackoverflow.com/questions/4656843/jquery-get-querystring-from-url
function getUrlVars(url)
{
    var vars = {}, hash;
    var hashes = url.slice(url.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars[hash[0].toString()] = hash[1];
    }
    return vars;
}

// get base url for query
function getBaseUrl(url) {
	// remove any query params
	var url = url.split("?")[0];
	if((/\/$/ig).test(url)) {
		url = url.substring(0, url.length - 1);
	}
	return url;
}	<commit_msg>Switch from esri2geo to ogr2ogr<commit_after>// @Author: Joshua Tanner
// @Date: 12/8/2014
// @Description: Easy way to create shapefiles from ArcGIS Server services
// @services.txt format :: serviceLayerURL|layerName

// Node Modules
var ogr2ogr = require('ogr2ogr');
var q = require('q');
var request = q.nfbind(require('request'));
var fs = require('fs');

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

var serviceFile = process.argv[2] || 'services.txt';
var outDir = process.argv[3] || './output/';
if(outDir[outDir.length - 1] !== '/') {
	outDir += '/';
}

// Make request to each service
fs.readFile(serviceFile, function (err, data) {
	if (err) {
		console.log(err);
		throw err;
	}
	data.toString().split('\n').forEach(function (service) {
		var service = service.split('|');
		//get total number of records | assume 1000 max each request
		var baseUrl = getBaseUrl(service[0].trim()) + '/query'
		request({
			url : baseUrl,
			qs : {
				where : '1=1',
				returnIdsOnly : true,
				f : 'json'
			},
			method : 'GET',
			json : true
		}, function (err, response, body) {
			if(err) {
				console.log(err);
				throw err;
			}
			requestService(service[0].trim(), service[1].trim(), body.objectIds);
		});
	})
});

// Resquest JSON from AGS
// assumption 1 = 1000 max requests on service
// assumption 2 = objectid always auto incremented (from startId) - NOT TRUE
function requestService(serviceUrl, serviceName, objectIds) {
	var requests = [];

	for(var i = 0; i < Math.ceil(objectIds.length / 100); i++) {
		var ids = [];
		if ( ((i + 1) * 100) < objectIds.length ) {
			ids = objectIds.slice(i * 100, (i + 1) * 100);
		} else {
			ids = objectIds.slice(i * 100, objectIds.length);
		}
		// we need these query params
		var reqQS = {
			objectIds : ids.join(','),
			geometryType : 'esriGeometryEnvelope',
			returnGeometry : true,
			returnIdsOnly : false,
			outFields : '*',
			outSR : '4326',
			f : 'json'
		};
		// user provided query params
		var userQS = getUrlVars(serviceUrl);
		// mix one obj with another
		var qs = mixin(userQS, reqQS);
		var r = request({
			url : getBaseUrl(serviceUrl) + '/query',
			qs : qs,
			method : 'GET',
			json : true
		});

		requests.push(r);
	};

	q.allSettled(requests).then(function (results) {
		var allFeatures = null;
		for(var i = 0; i < results.length; i++) {
			if(i == 0) {
				allFeatures = results[i].value[0].body;
			} else {
				allFeatures.features = allFeatures.features.concat(results[i].value[0].body.features);
			}
		}
		console.log('creating', serviceName, 'json');
		var json = allFeatures;
		fs.writeFile(outDir + serviceName + '.json', JSON.stringify(json), function (err) {
			if(err) throw err;
			// Create Geojson
			console.log('creating', serviceName, 'geojson');
			var ogr = ogr2ogr(outDir + serviceName + '.json')
				.skipfailures();

			ogr.exec(function (er, data) {
				if (er) console.log(er);

				fs.writeFile(outDir + serviceName + '.geojson', JSON.stringify(data), function (err) {
					// Create Shapefile once geojson written
					if (er) console.log(er);
					console.log('creating', serviceName, 'shapefile');
					var shapefile = ogr2ogr(outDir + serviceName + '.geojson')
						.format('ESRI Shapefile')
						.skipfailures();

					shapefile.stream().pipe(fs.createWriteStream(outDir + serviceName + '.zip'));
				});
			});

		});

	}).catch(function (err) {
		console.log(err);
		throw err;
	});
}

//http://stackoverflow.com/questions/4656843/jquery-get-querystring-from-url
function getUrlVars(url)
{
    var vars = {}, hash;
    var hashes = url.slice(url.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars[hash[0].toString()] = hash[1];
    }
    return vars;
}

// get base url for query
function getBaseUrl(url) {
	// remove any query params
	var url = url.split("?")[0];
	if((/\/$/ig).test(url)) {
		url = url.substring(0, url.length - 1);
	}
	return url;
}	<|endoftext|>