<commit_before>/*
Copyright (c) 2013 Iain Hamilton & Edward Smyth

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/***

jsiso/img/ImageLoader

Simply takes an array of image paths and
preloads them ready for use

**/
define(function() {

  // Private properties for ImageLoader

  return function() {

    var _loaded = 0; // Images total the preloader has loaded

    var _loading = 0; // Images total the preloader needs to load

    var _onloadfn = null;

    function _splitSpriteSheet(spritesheet) {

      var images = [];
      var ctx = document.createElement('canvas');
      var tileManip;
      var imageFilePathArray = [];
      var spriteID = 0;

      var tileRow;
      var tileCol;
      var spritesheetCols = Math.floor(spritesheet.files[spritesheet.dictionary[0]].width / (spritesheet.width));
      var spritesheetRows = Math.floor(spritesheet.files[spritesheet.dictionary[0]].height / (spritesheet.height));
      _loading +=  spritesheetCols * spritesheetRows;
      ctx.width = spritesheet.width;
      ctx.height = spritesheet.height;
      tileManip = ctx.getContext('2d');
      for (var i = 0; i < spritesheetRows; i++) {
        for (var j = 0; j < spritesheetCols; j++) {
          tileManip.drawImage(spritesheet.files[spritesheet.dictionary[0]], j * (spritesheet.width + spritesheet.offsetX  + spritesheet.spacing) + spritesheet.spacing, i * (spritesheet.height + spritesheet.offsetY + spritesheet.spacing) + spritesheet.spacing,  spritesheet.width + spritesheet.offsetX - spritesheet.spacing, spritesheet.height  + spritesheet.offsetY - spritesheet.spacing, 0, 0, spritesheet.width, spritesheet.height);
          imageFilePathArray[spriteID] = spriteID;
          images[spriteID] = new Image();
          images[spriteID].src = ctx.toDataURL();
          tileManip.clearRect (0, 0, spritesheet.width, spritesheet.height);
          images[spriteID].onload = function () {
            _loaded ++;
            if (_loaded === _loading && _onloadfn) {
              _onload({files: images, dictionary: imageFilePathArray});
            }
          };
          spriteID ++;
        }
      }

    }

    function _loadArray(imageFilePathArray, removePath, spritesheet) {
      var images = [];
      _loading += imageFilePathArray.length;
      imageFilePathArray.map(function(img) {
        imgName = img;
        if (removePath) {
          imgName = img.split("/").pop();
        }
        images[imgName] = new Image();
        images[imgName].src = img;
        images[imgName].onload = function() {
          _loaded ++;
          if (_loaded === _loading && _onloadfn && !spritesheet) {
            _onload({files: images, dictionary: imageFilePathArray});
          }
          if (_loaded === _loading && spritesheet) {
            _splitSpriteSheet({files: images,
              dictionary: imageFilePathArray,
              width: spritesheet.width,
              height: spritesheet.height,
              offsetX: (spritesheet.offsetX || 0),
              offsetY: (spritesheet.offsetY || 0),
              spacing: (spritesheet.spacing || 0)
            });
          }
        };
      });
      if (removePath) {
        for (var i = 0; i < imageFilePathArray.length; i++) {
          imageFilePathArray[i] = imageFilePathArray[i].split("/").pop();
        }
      }
      return {files: images, dictionary: imageFilePathArray};
    }

    function _onload(images) {
      _onloadfn(images);
    }

    // ----
    // -- Public properties for ImageLoader
    // ----

    return {

      status: function() {
        return {loaded: _loaded, loading: _loading};
      },

      onload: function (fn) {
        _onloadfn = fn;
      },

      /**
      * Loads an Array of images and returns an object containing preloaded
        images and dictionary of images for calling
      * @param {Array} Contains all the paths and files.extenstion to be preloaded
      * @param {Boolean} If path should be removed from dictionary so lookup is via filename.ext only
      * @return {Object} via _loadArray returns an object containing { files: {Array} preloadedImages, dictionary: {Array} imageNames}
      */
      loadImageArray: function(imageFilePathArray, removePath, spritesheet) {
        // imageFilePathArray - Array of paths and file name locations to be preloaded in.
        // removePath - Bool if true will remove paths from dictionary leaving only filenames and image extension.
        return _loadArray(imageFilePathArray, removePath, spritesheet);
      }

    };
  };
});<commit_msg>Spritesheets allow for Tiled ID offsets<commit_after>/*
Copyright (c) 2013 Iain Hamilton & Edward Smyth

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/***

jsiso/img/ImageLoader

Simply takes an array of image paths and
preloads them ready for use

**/
define(function() {

  // Private properties for ImageLoader

  return function() {

    var _loaded = 0; // Images total the preloader has loaded

    var _loading = 0; // Images total the preloader needs to load

    var _onloadfn = null;

    function _splitSpriteSheet(spritesheet) {

      var images = [];
      var ctx = document.createElement('canvas');
      var tileManip;
      var imageFilePathArray = [];
      var spriteID = (spritesheet.firstgid || 0);
      var tileRow;
      var tileCol;
      var spritesheetCols = Math.floor(spritesheet.files[spritesheet.dictionary[0]].width / (spritesheet.width));
      var spritesheetRows = Math.floor(spritesheet.files[spritesheet.dictionary[0]].height / (spritesheet.height));
      _loading +=  spritesheetCols * spritesheetRows;
      ctx.width = spritesheet.width;
      ctx.height = spritesheet.height;
      tileManip = ctx.getContext('2d');
      for (var i = 0; i < spritesheetRows; i++) {
        for (var j = 0; j < spritesheetCols; j++) {
          tileManip.drawImage(spritesheet.files[spritesheet.dictionary[0]], j * (spritesheet.width + spritesheet.offsetX  + spritesheet.spacing) + spritesheet.spacing, i * (spritesheet.height + spritesheet.offsetY + spritesheet.spacing) + spritesheet.spacing,  spritesheet.width + spritesheet.offsetX - spritesheet.spacing, spritesheet.height  + spritesheet.offsetY - spritesheet.spacing, 0, 0, spritesheet.width, spritesheet.height);
          imageFilePathArray[spriteID] = spriteID;
          images[spriteID] = new Image();
          images[spriteID].src = ctx.toDataURL();
          tileManip.clearRect (0, 0, spritesheet.width, spritesheet.height);
          images[spriteID].onload = function () {
            _loaded ++;
            if (_loaded === _loading && _onloadfn) {
              _onload({files: images, dictionary: imageFilePathArray});
            }
          };
          spriteID ++;
        }
      }
    }

    function _loadArray(imageFilePathArray, removePath, spritesheet) {
      var images = [];
      _loading += imageFilePathArray.length;
      imageFilePathArray.map(function(img) {
        imgName = img;
        if (removePath) {
          imgName = img.split("/").pop();
        }
        images[imgName] = new Image();
        images[imgName].src = img;
        images[imgName].onload = function() {
          _loaded ++;
          if (_loaded === _loading && _onloadfn && !spritesheet) {
            _onload({files: images, dictionary: imageFilePathArray});
          }
          if (_loaded === _loading && spritesheet) {
            _splitSpriteSheet({files: images,
              dictionary: imageFilePathArray,
              width: spritesheet.width,
              height: spritesheet.height,
              offsetX: (spritesheet.offsetX || 0),
              offsetY: (spritesheet.offsetY || 0),
              spacing: (spritesheet.spacing || 0),
              firstgid: (spritesheet.firstgid || 0)
            });
          }
        };
      });
      if (removePath) {
        for (var i = 0; i < imageFilePathArray.length; i++) {
          imageFilePathArray[i] = imageFilePathArray[i].split("/").pop();
        }
      }
      return {files: images, dictionary: imageFilePathArray};
    }

    function _onload(images) {
      _onloadfn(images);
    }

    // ----
    // -- Public properties for ImageLoader
    // ----

    return {

      status: function() {
        return {loaded: _loaded, loading: _loading};
      },

      onload: function (fn) {
        _onloadfn = fn;
      },

      /**
      * Loads an Array of images and returns an object containing preloaded
        images and dictionary of images for calling
      * @param {Array} Contains all the paths and files.extenstion to be preloaded
      * @param {Boolean} If path should be removed from dictionary so lookup is via filename.ext only
      * @return {Object} via _loadArray returns an object containing { files: {Array} preloadedImages, dictionary: {Array} imageNames}
      */
      loadImageArray: function(imageFilePathArray, removePath, spritesheet) {
        // imageFilePathArray - Array of paths and file name locations to be preloaded in.
        // removePath - Bool if true will remove paths from dictionary leaving only filenames and image extension.
        return _loadArray(imageFilePathArray, removePath, spritesheet);
      }

    };
  };
});<|endoftext|>


<commit_before>import React from 'react';
import firebase from '../firebase';

export default class TaskItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      newSubTask: {value: '', key: Date.now()},
      sublist:[],
    };
  }

  componentDidMount(){
    let user = this.props.user.uid
    let listKey = this.props.firebaseId
    firebase.database().ref(user+'/'+listKey+'/sublist/').on('value', (snapshot) => {
      let tasksFromFirebase = this.createTaskArray(snapshot.val())
      this.setState({sublist: tasksFromFirebase || []})
    })
  }

  createTaskArray(object) {
    if (!object) {
      return []
    }
    let fireBaseKeys = Object.keys(object)
    let allFromFireBase = fireBaseKeys.map((singleKey) => {
      let singleItem = object[singleKey];
      singleItem['firebaseId'] = singleKey;
      return singleItem;
    });
    return allFromFireBase
  }

  handleChange(e){
    let subTask = this.state.newSubTask
    subTask.value = e.target.value
    this.setState({newSubTask: subTask})
  }

  handleSave(){
    this.setState({newSubTask: {value: '', key: Date.now()} })
    this.props.addSubList(this.props.firebaseId, this.state.newSubTask)
  }

  handleDelete(subtaskId){
    this.props.deleteSubTask(this.props.firebaseId, subtaskId)
  }

  render() {
    return (

        <button
          className="cyclerButton"
          onClick = {() => this.props.typeCycler(this.props.type, this.props.index)}
        >
          {this.props.type}
        </button>

            {this.props.value}

              <input
                className="sub-list-input"
                value={this.state.newSubTask.value}
                onChange={(e) => this.handleChange(e)}
                ></input>

                  {this.state.sublist.map((task) => {
                    return

                      {task.value}<button onClick={()=>this.handleDelete(task.firebaseId)}>delete</button>
                  })}

          <button className = "deleteButton"
          onClick={()=>this.props.deleteTask(this.props.firebaseId)}
          >delete</button>
          <button
          className="sub-list-submit-btn"
          onClick={() => this.handleSave()}
          >submit</button>
        <input type="checkbox"
          checked={this.props.completed}
          className="completeButton"
          onClick = {() => this.props.toggleComplete(this.props.completed, this.props.index)}>
          </input>

completed

    );
  }
}
<commit_msg>moved closing list tag to right line<commit_after>import React from 'react';
import firebase from '../firebase';

export default class TaskItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      newSubTask: {value: '', key: Date.now()},
      sublist:[],
    };
  }

  componentDidMount(){
    let user = this.props.user.uid
    let listKey = this.props.firebaseId
    firebase.database().ref(user+'/'+listKey+'/sublist/').on('value', (snapshot) => {
      let tasksFromFirebase = this.createTaskArray(snapshot.val())
      this.setState({sublist: tasksFromFirebase || []})
    })
  }

  createTaskArray(object) {
    if (!object) {
      return []
    }
    let fireBaseKeys = Object.keys(object)
    let allFromFireBase = fireBaseKeys.map((singleKey) => {
      let singleItem = object[singleKey];
      singleItem['firebaseId'] = singleKey;
      return singleItem;
    });
    return allFromFireBase
  }

  handleChange(e){
    let subTask = this.state.newSubTask
    subTask.value = e.target.value
    this.setState({newSubTask: subTask})
  }

  handleSave(){
    this.setState({newSubTask: {value: '', key: Date.now()} })
    this.props.addSubList(this.props.firebaseId, this.state.newSubTask)
  }

  handleDelete(subtaskId){
    this.props.deleteSubTask(this.props.firebaseId, subtaskId)
  }

  render() {
    return (

        <button
          className="cyclerButton"
          onClick = {() => this.props.typeCycler(this.props.type, this.props.index)}
        >
          {this.props.type}
        </button>

            {this.props.value}

              <input
                className="sub-list-input"
                value={this.state.newSubTask.value}
                onChange={(e) => this.handleChange(e)}
                ></input>

                  {this.state.sublist.map((task) => {
                    return

                      {task.value}<button onClick={()=>this.handleDelete(task.firebaseId)}>delete</button>

                  })}

          <button className = "deleteButton"
          onClick={()=>this.props.deleteTask(this.props.firebaseId)}
          >delete</button>
          <button
          className="sub-list-submit-btn"
          onClick={() => this.handleSave()}
          >submit</button>
        <input type="checkbox"
          checked={this.props.completed}
          className="completeButton"
          onClick = {() => this.props.toggleComplete(this.props.completed, this.props.index)}>
          </input>

completed

    );
  }
}
<|endoftext|>


<commit_before>const ZERO_DECIMAL_CURRENCIES = [
  'BIF',
  'CLP',
  'DJF',
  'GNF',
  'JPY',
  'KMF',
  'KRW',
  'MGA',
  'PYG',
  'RWF',
  'VND',
  'VUV',
  'XAF',
  'XOF',
  'XPF'
];

// Config
var Habitat = require('habitat');
Habitat.load();

var stripe = require('stripe')(process.env.STRIPE_API_KEY);
var oxr = require('open-exchange-rates');
var money = require('money');
var moment = require('moment');

oxr.set({ app_id: process.env.OXR_APP_ID });

function update_money(done) {
  if (!done) {
    done = function() {};
  }

  return function() {
    money.rates = oxr.rates;
    money.base = oxr.base;
    done();
  };
}

function update_exchange_rates(date, done) {
  done = update_money(done);

  if (date) {
    return oxr.historical(date, done);
  }

  oxr.latest(done);
}

update_exchange_rates();

// update exchange rates every hour
setInterval(update_exchange_rates, 1000 * 60 * 60);

var pg;
try {
  pg = require('pg').native;
} catch (ignore_error) {
  pg = require('pg');
}

var insert_query = 'INSERT INTO stripe (id, timestamp, amount, settle_amount, ' +
                   'refunded, currency, status, country_code, name, email, recurring ) ' +
                   'SELECT $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11';
var update_query = 'UPDATE stripe SET timestamp=$2, amount=$3, settle_amount=$4, ' +
                   'refunded=$5, currency=$6, status=$7, country_code=$8, ' +
                   ' name=$9, email=$10, recurring=$11 WHERE id=$1';
var upsert_query = `WITH upsert AS (${update_query} RETURNING *) ${insert_query}` +
                   ' WHERE NOT EXISTS (SELECT * FROM upsert);';

function process_charge(charge, callback) {
  if (!callback) {
    callback = function() {};
  }

  pg.connect(process.env.STRIPE_DB_CONNECTION_STRING, function(err, client, done) {
    if (err) {
      console.error(`Error while connecting to db: ${err.toString()}`);
      done();
      return callback(err);
    }

    var adjusted_amount = charge.amount;
    var adjusted_amount_refunded = charge.amount_refunded;
    var currency = charge.currency.toUpperCase();

    if (ZERO_DECIMAL_CURRENCIES.indexOf(currency) === -1) {
      adjusted_amount = adjusted_amount / 100;
      // don't divide with 0 :)
      if (adjusted_amount_refunded) {
        adjusted_amount_refunded = adjusted_amount_refunded / 100;
      }
    }

    var settle_amount = money(adjusted_amount).from(currency).to('USD');

    client.query(upsert_query, [
      charge.id,
      moment.unix(charge.created).toISOString(),
      adjusted_amount,
      settle_amount,
      adjusted_amount_refunded,
      currency,
      charge.status,
      charge.source.country,
      charge.source.name,
      charge.metadata.email,
      !!charge.invoice
    ], function(err, result) {
      done();
      if (err) {
        console.error(`Error while upserting charge: ${err.toString()}`);
        return callback(err);
      }
      callback();
    });
  });
}

module.exports = {
  process_charge,
  stripe,
  update_exchange_rates
};
<commit_msg>Use email from customer object<commit_after>const ZERO_DECIMAL_CURRENCIES = [
  'BIF',
  'CLP',
  'DJF',
  'GNF',
  'JPY',
  'KMF',
  'KRW',
  'MGA',
  'PYG',
  'RWF',
  'VND',
  'VUV',
  'XAF',
  'XOF',
  'XPF'
];

// Config
var Habitat = require('habitat');
Habitat.load();

var stripe = require('stripe')(process.env.STRIPE_API_KEY);
var oxr = require('open-exchange-rates');
var money = require('money');
var moment = require('moment');

oxr.set({ app_id: process.env.OXR_APP_ID });

function update_money(done) {
  if (!done) {
    done = function() {};
  }

  return function() {
    money.rates = oxr.rates;
    money.base = oxr.base;
    done();
  };
}

function update_exchange_rates(date, done) {
  done = update_money(done);

  if (date) {
    return oxr.historical(date, done);
  }

  oxr.latest(done);
}

update_exchange_rates();

// update exchange rates every hour
setInterval(update_exchange_rates, 1000 * 60 * 60);

var pg;
try {
  pg = require('pg').native;
} catch (ignore_error) {
  pg = require('pg');
}

var insert_query = 'INSERT INTO stripe (id, timestamp, amount, settle_amount, ' +
                   'refunded, currency, status, country_code, name, email, recurring ) ' +
                   'SELECT $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11';
var update_query = 'UPDATE stripe SET timestamp=$2, amount=$3, settle_amount=$4, ' +
                   'refunded=$5, currency=$6, status=$7, country_code=$8, ' +
                   ' name=$9, email=$10, recurring=$11 WHERE id=$1';
var upsert_query = `WITH upsert AS (${update_query} RETURNING *) ${insert_query}` +
                   ' WHERE NOT EXISTS (SELECT * FROM upsert);';

function process_charge(charge, callback) {
  if (!callback) {
    callback = function() {};
  }

  stripe.customers.retrieve(charge.customer, (customer_error, customer) => {
    if (customer_error) {
      return callback(customer_error);
    }

    charge.customer = customer;

    pg.connect(process.env.STRIPE_DB_CONNECTION_STRING, function(connect_error, client, done) {
      if (connect_error) {
        console.error(`Error while connecting to db: ${connect_error.toString()}`);
        done();
        return callback(connect_error);
      }

      var adjusted_amount = charge.amount;
      var adjusted_amount_refunded = charge.amount_refunded;
      var currency = charge.currency.toUpperCase();

      if (ZERO_DECIMAL_CURRENCIES.indexOf(currency) === -1) {
        adjusted_amount = adjusted_amount / 100;
        // don't divide with 0 :)
        if (adjusted_amount_refunded) {
          adjusted_amount_refunded = adjusted_amount_refunded / 100;
        }
      }

      var settle_amount = money(adjusted_amount).from(currency).to('USD');

      client.query(upsert_query, [
        charge.id,
        moment.unix(charge.created).toISOString(),
        adjusted_amount,
        settle_amount,
        adjusted_amount_refunded,
        currency,
        charge.status,
        charge.source.country,
        charge.source.name,
        charge.customer.email,
        !!charge.invoice
      ], function(query_error, result) {
        done();
        if (query_error) {
          console.error(`Error while upserting charge: ${query_error.toString()}`);
          return callback(query_error);
        }
        callback();
      });
    });
  });
}

module.exports = {
  process_charge,
  stripe,
  update_exchange_rates
};
<|endoftext|>


<commit_before>const os = require('os');
const utils = require('./utils.js');
const fs = require('fs');
const exec = require('child_process').execSync;

/**
 * Returns hostname
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @returns {string}  Hostname
 */

var hostname = function(errors){
	return os.hostname();
}

/**
 * Returns server IP
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @param   {Object}  config    configuration
 * @returns {string}  Server    local IP
 */
var getLanIp = function(errors, config) {
	if(config.ip===false) {
		return '';
	}
	try {
		var interfaces = os.networkInterfaces();
		if(interfaces[config.interface]) {
			var iface = interfaces[config.interface];
			var ret = []
			for(var i in iface) {
				ret.push(iface[i].address);
			}
			return ret;
		}
	} catch(err) {
		return '';
		errors.push("Cannot get Server IP");
	}
}

/**
 * Returns CPU cores number
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array} errors           errors in this function are written to this array
 * @returns {int}   Number of cores
 */

var getCpuCoresNumber = function(errors) {
	try {
		return os.cpus().length;
	} catch(err) {
		errors.push("Cannot get number of cores");
		return '';
	}
}

/**
 * Returns the operating system
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  name of OS
 */
var getOperatingSystem = function(errors) {
	var rl = utils.runCommand('lsb_release',['-d','-s']);
	if(!rl.error && rl.stdout && rl.stdout !== '') {
		return rl.stdout;
	}
	if(os.platform==="win32") {
		return "Windows " + os.release();
	}
	try {
		return fs.readFileSync('/etc/issue.net').toString().trim();
	} catch(err) {
		errors.push("Cannot get OS release");
		return os.platform();
	}
}

/**
 * Returns the kernel name
 *
 * @returns {string}  name of the kernel
 */
var getKernel = function() {
	return os.release();
}

/**
 * Returns the current uptime in human readable format
 *
 * @returns {string}  the current uptime
 */
var getUptime = function() {
	return utils.getHumanTime(os.uptime());
}

/**
 * Returns the model of the first CPU
 *
 * @returns {string}  the cpu model
 */
var getCpuModel = function() {
	return os.cpus()[0].model;
}

/**
 * Returns the frequency of the first CPU
 *
 * @returns {string}  the cpu frequency
 */
var getCpuFrequency = function() {
	return parseInt(os.cpus()[0].speed)/1000+' GHz';
}

/**
 * Returns the cache size of the first CPU.
 * Uses nasty `sh -c` instead of doing it properly. Should probably not do this.
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu cache size
 */
var getCpuCacheSize = function(errors) {
	var out = utils.runCommand('sh',['-c','cat /proc/cpuinfo|grep cache\\ size|head -n 1']);
	if(out.error || !out.stdout) {
		errors.push("CPU cache size could not be determined");
		return '';
	}
	out = out.stdout.split(' ');
	out.splice(0,2);
	return out.join(' ');
}

/**
 * Returns the temperature of the first CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu temperature
 */
var getCpuTemperature = function(errors) {
	var out = utils.runCommand('sh',['-c','/usr/bin/sensors | grep -E "^(CPU Temp|Core 0)" | cut -d \'+\' -f2 | cut -d \'.\' -f1']);
	if(out.stdout) {
		out = out.stdout.split(' ');
		out.splice(0,2);
		return out.join(' ') + "°C";
	}
	try {
		return parseInt(fs.readFileSync('/sys/class/thermal/thermal_zone0/temp')) / 1000 + "°C";
	} catch(err) {
		errors.push("CPU temperature could not be determined");
		return '';
	}
}

/**
 * Returns the load data of the CPU
 *
 * @returns {array}  the cpu load data
 */
/*
 * I'm assuming this is supposed to return multiple values? I'm not sure what the $cores
 * reference is doing I don't have a multi-core linux system handy (my server is single-core)
 * so I'll just return os.loadavg()
*/
var getCpuLoadData = function() {
	var loadavg = os.loadavg();
	for(var i in loadavg) {
		loadavg[i] *= 100;
	}
	return loadavg;
}

/**
 * parses and returns info about memory
 * Part of this function was borrowed from http://stackoverflow.com/a/23588793
 *
 * @returns {Object} parsed object containing values from /proc/meminfo
 */

var getMeminfo = function(errors){
	var info = {};
	try {
		var data = fs.readFileSync('/proc/meminfo').toString();
	} catch(err) {
		errors.push('Could not read RAM data');
		return {};
	}
	data.split(/\n/g).forEach(function(line){
		line = line.split(':');

		// Ignore invalid lines, if any
		if (line.length < 2) {
			return;
		}

		// Remove parseInt call to make all values strings
		info[line[0]] = parseInt(line[1].trim(), 10);
	});
	return info;
}

/**
 * Returns the various data about the RAM
 * You can get free memory with os.freemem()
 * @returns {array}  the ram data
 */

var getRamInfo = function(errors) {
	var info = getMeminfo(errors);
	if(!info.MemFree) {
		errors.push('Could not read RAM data: free memory');
	}
	if(!info.MemTotal) {
		errors.push('Could not read RAM data: total memory');
	}
	if(!info.Buffers) {
		errors.push('Could not read RAM data: buffers');
	}
	if(!info.Cached) {
		errors.push('Could not read RAM data: cached');
	}
	var free = info.MemFree || 0;
	var buffers = info.Buffers || 0;
	var cached = info.Cached || 0;
	var total = info.MemTotal || 0;
	free = free + buffers + cached;
	var used = total - free;

	var percent = (total > 0) ? (100 - Math.floor(free / total * 100)) : 0;

	return {
		used: utils.getSize(used*1024),
		free: utils.getSize(free*1024),
		total: utils.getSize(total*1024),
		percent_used: percent
	}
}

/**
 * Returns the boot up time
 *
 * @returns {array}  the time since last boot
 */
var getBootupTime = function() {
	var uptime = os.uptime();
	var date = new Date();
	date.setSeconds(date.getSeconds()-uptime);
	var m = date.getMonth()+1; //counts from 0
	if(m<10) {
		m = "0" + m;
	}
	var H = date.getHours();
	if(H<10) {
		H = "0" + H;
	}
	var i = date.getMinutes();
	if(i<10) {
		i = "0" + i;
	}
	var s = date.getSeconds();
	if(s<10) {
		s = "0" + s;
	}

	//I have no idea why this is an array, but it's easier to leave it...
	return {
		last_boot : date.getFullYear() + "-" + m + "-" +
			date.getDate() + " " + H + ":" + i + ":" + s
	}
}

/**
 * Returns the data about the system swap space
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the swap data
 */
var getSwapData = function(errors) {
	var info = getMeminfo(errors);

	var free = info.SwapFree || 0;
	if(!info.SwapFree) {
		errors.push("Could not read swap data: free swap");
	}

	var total = info.SwapTotal || 0;
	if(!info.SwapFree) {
		errors.push("Could not read swap data: total swap");
	}

	var used = total-free;

	var percent = total === 0 ? 0 : (100 - Math.floor(free / total * 100));

	return {
		used: utils.getSize(used * 1024),
		free: utils.getSize(free * 1024),
		total: utils.getSize(total * 1024),
		"percent_used": percent
	}
}

/**
 * Returns the data about the network usage
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the network data
 */
var getNetworkData = function(errors) {
	var datas = [];
	var ifaces = os.networkInterfaces();
	for(var iface in ifaces) {
		var info = {
			interface: iface,
			ip: ifaces[iface][0].address,
		}
		try {
			info.transmit = fs.readFileSync('/sys/class/net/' + iface + '/statistics/tx_bytes').toString().trim();
			info.receive = fs.readFileSync('/sys/class/net/' + iface + '/statistics/rx_bytes').toString().trim();
		} catch(err) {
			errors.push("Could not get network stats for" + iface);
			info.transmit = 0;
			info.receive = 0;
		}
		datas.push(info);
	}
	return datas;
}

/**
 * Returns the data about the disk usage
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the disk data
 */
var getDiskData = function(errors) {
	try {
		var df = exec('/bin/df -T | awk -v c=`/bin/df -T | grep -bo "Type" | awk -F: \'{print $2}\'` \'{print substr($0,c);}\' | tail -n +2 | awk \'{print $1","$2","$3","$4","$5","$6","$7}\'').toString();
	} catch(err) {
		errors.push("Could not get disk data");
		return {
			total:'N/A',
			used:'N/A',
			free:'N/A',
			"percent_used":0,
			mount:'N/A',
			filesytstem:'N/A'
		}
	}
	var datas = [];
	var mounts = [];
	var key = 0;
	var parsed = df.trim().split('\n');
	for(var item in parsed) {
		var it = parsed[item];
		if(it.indexOf('tmpfs') > -1) {
			continue;
		}

		it = it.split(',');
		for(var p in it) {
			//trim spaces
			it[p] = it[p].toString().trim();
			//convert numbers
			var sint = parseInt(it[p]).toString();
			if(sint===it[p]||sint+"%"===it[p]) {
				it[p] = sint;
			}
		}
		datas.push({
			total: utils.getSize(it[2] * 1024),
			used: utils.getSize(it[3] * 1024),
			free: utils.getSize(it[4] * 1024),
			"percent_used": it[5],
			mount: it[6].trim(),
			filesystem: it[0].trim()
		})
	}
	return datas;
}

module.exports = {
	getSystemHostname: hostname,
	getLanIp: getLanIp,
	getCpuCoresNumber: getCpuCoresNumber,
	getOperatingSystem: getOperatingSystem,
	getKernel: getKernel,
	getUptime: getUptime,
	getCpuModel: getCpuModel,
	getCpuFrequency: getCpuFrequency,
	getCpuCacheSize: getCpuCacheSize,
	getCpuTemperature: getCpuTemperature,
	getCpuLoadData: getCpuLoadData,
	getMeminfo: getMeminfo,
	getRamInfo: getRamInfo,
	getBootupTime: getBootupTime,
	getSwapData: getSwapData,
	getNetworkData: getNetworkData,
	getDiskData: getDiskData
}
<commit_msg>Never return a string in getLanIP, fixes #1<commit_after>const os = require('os');
const utils = require('./utils.js');
const fs = require('fs');
const exec = require('child_process').execSync;

/**
 * Returns hostname
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @returns {string}  Hostname
 */

var hostname = function(errors){
	return os.hostname();
}

/**
 * Returns server IP
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @param   {Object}  config    configuration
 * @returns {string}  Server    local IP
 */
var getLanIp = function(errors, config) {
	if(config.ip===false) {
		return [];
	}
	try {
		var interfaces = os.networkInterfaces();
		if(interfaces[config.interface]) {
			var iface = interfaces[config.interface];
			var ret = []
			for(var i in iface) {
				ret.push(iface[i].address);
			}
			return ret;
		}
	} catch(err) {
		return [];
		errors.push("Cannot get Server IP");
	}
}

/**
 * Returns CPU cores number
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array} errors           errors in this function are written to this array
 * @returns {int}   Number of cores
 */

var getCpuCoresNumber = function(errors) {
	try {
		return os.cpus().length;
	} catch(err) {
		errors.push("Cannot get number of cores");
		return '';
	}
}

/**
 * Returns the operating system
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  name of OS
 */
var getOperatingSystem = function(errors) {
	var rl = utils.runCommand('lsb_release',['-d','-s']);
	if(!rl.error && rl.stdout && rl.stdout !== '') {
		return rl.stdout;
	}
	if(os.platform==="win32") {
		return "Windows " + os.release();
	}
	try {
		return fs.readFileSync('/etc/issue.net').toString().trim();
	} catch(err) {
		errors.push("Cannot get OS release");
		return os.platform();
	}
}

/**
 * Returns the kernel name
 *
 * @returns {string}  name of the kernel
 */
var getKernel = function() {
	return os.release();
}

/**
 * Returns the current uptime in human readable format
 *
 * @returns {string}  the current uptime
 */
var getUptime = function() {
	return utils.getHumanTime(os.uptime());
}

/**
 * Returns the model of the first CPU
 *
 * @returns {string}  the cpu model
 */
var getCpuModel = function() {
	return os.cpus()[0].model;
}

/**
 * Returns the frequency of the first CPU
 *
 * @returns {string}  the cpu frequency
 */
var getCpuFrequency = function() {
	return parseInt(os.cpus()[0].speed)/1000+' GHz';
}

/**
 * Returns the cache size of the first CPU.
 * Uses nasty `sh -c` instead of doing it properly. Should probably not do this.
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu cache size
 */
var getCpuCacheSize = function(errors) {
	var out = utils.runCommand('sh',['-c','cat /proc/cpuinfo|grep cache\\ size|head -n 1']);
	if(out.error || !out.stdout) {
		errors.push("CPU cache size could not be determined");
		return '';
	}
	out = out.stdout.split(' ');
	out.splice(0,2);
	return out.join(' ');
}

/**
 * Returns the temperature of the first CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu temperature
 */
var getCpuTemperature = function(errors) {
	var out = utils.runCommand('sh',['-c','/usr/bin/sensors | grep -E "^(CPU Temp|Core 0)" | cut -d \'+\' -f2 | cut -d \'.\' -f1']);
	if(out.stdout) {
		out = out.stdout.split(' ');
		out.splice(0,2);
		return out.join(' ') + "°C";
	}
	try {
		return parseInt(fs.readFileSync('/sys/class/thermal/thermal_zone0/temp')) / 1000 + "°C";
	} catch(err) {
		errors.push("CPU temperature could not be determined");
		return '';
	}
}

/**
 * Returns the load data of the CPU
 *
 * @returns {array}  the cpu load data
 */
/*
 * I'm assuming this is supposed to return multiple values? I'm not sure what the $cores
 * reference is doing I don't have a multi-core linux system handy (my server is single-core)
 * so I'll just return os.loadavg()
*/
var getCpuLoadData = function() {
	var loadavg = os.loadavg();
	for(var i in loadavg) {
		loadavg[i] *= 100;
	}
	return loadavg;
}

/**
 * parses and returns info about memory
 * Part of this function was borrowed from http://stackoverflow.com/a/23588793
 *
 * @returns {Object} parsed object containing values from /proc/meminfo
 */

var getMeminfo = function(errors){
	var info = {};
	try {
		var data = fs.readFileSync('/proc/meminfo').toString();
	} catch(err) {
		errors.push('Could not read RAM data');
		return {};
	}
	data.split(/\n/g).forEach(function(line){
		line = line.split(':');

		// Ignore invalid lines, if any
		if (line.length < 2) {
			return;
		}

		// Remove parseInt call to make all values strings
		info[line[0]] = parseInt(line[1].trim(), 10);
	});
	return info;
}

/**
 * Returns the various data about the RAM
 * You can get free memory with os.freemem()
 * @returns {array}  the ram data
 */

var getRamInfo = function(errors) {
	var info = getMeminfo(errors);
	if(!info.MemFree) {
		errors.push('Could not read RAM data: free memory');
	}
	if(!info.MemTotal) {
		errors.push('Could not read RAM data: total memory');
	}
	if(!info.Buffers) {
		errors.push('Could not read RAM data: buffers');
	}
	if(!info.Cached) {
		errors.push('Could not read RAM data: cached');
	}
	var free = info.MemFree || 0;
	var buffers = info.Buffers || 0;
	var cached = info.Cached || 0;
	var total = info.MemTotal || 0;
	free = free + buffers + cached;
	var used = total - free;

	var percent = (total > 0) ? (100 - Math.floor(free / total * 100)) : 0;

	return {
		used: utils.getSize(used*1024),
		free: utils.getSize(free*1024),
		total: utils.getSize(total*1024),
		percent_used: percent
	}
}

/**
 * Returns the boot up time
 *
 * @returns {array}  the time since last boot
 */
var getBootupTime = function() {
	var uptime = os.uptime();
	var date = new Date();
	date.setSeconds(date.getSeconds()-uptime);
	var m = date.getMonth()+1; //counts from 0
	if(m<10) {
		m = "0" + m;
	}
	var H = date.getHours();
	if(H<10) {
		H = "0" + H;
	}
	var i = date.getMinutes();
	if(i<10) {
		i = "0" + i;
	}
	var s = date.getSeconds();
	if(s<10) {
		s = "0" + s;
	}

	//I have no idea why this is an array, but it's easier to leave it...
	return {
		last_boot : date.getFullYear() + "-" + m + "-" +
			date.getDate() + " " + H + ":" + i + ":" + s
	}
}

/**
 * Returns the data about the system swap space
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the swap data
 */
var getSwapData = function(errors) {
	var info = getMeminfo(errors);

	var free = info.SwapFree || 0;
	if(!info.SwapFree) {
		errors.push("Could not read swap data: free swap");
	}

	var total = info.SwapTotal || 0;
	if(!info.SwapFree) {
		errors.push("Could not read swap data: total swap");
	}

	var used = total-free;

	var percent = total === 0 ? 0 : (100 - Math.floor(free / total * 100));

	return {
		used: utils.getSize(used * 1024),
		free: utils.getSize(free * 1024),
		total: utils.getSize(total * 1024),
		"percent_used": percent
	}
}

/**
 * Returns the data about the network usage
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the network data
 */
var getNetworkData = function(errors) {
	var datas = [];
	var ifaces = os.networkInterfaces();
	for(var iface in ifaces) {
		var info = {
			interface: iface,
			ip: ifaces[iface][0].address,
		}
		try {
			info.transmit = fs.readFileSync('/sys/class/net/' + iface + '/statistics/tx_bytes').toString().trim();
			info.receive = fs.readFileSync('/sys/class/net/' + iface + '/statistics/rx_bytes').toString().trim();
		} catch(err) {
			errors.push("Could not get network stats for" + iface);
			info.transmit = 0;
			info.receive = 0;
		}
		datas.push(info);
	}
	return datas;
}

/**
 * Returns the data about the disk usage
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the disk data
 */
var getDiskData = function(errors) {
	try {
		var df = exec('/bin/df -T | awk -v c=`/bin/df -T | grep -bo "Type" | awk -F: \'{print $2}\'` \'{print substr($0,c);}\' | tail -n +2 | awk \'{print $1","$2","$3","$4","$5","$6","$7}\'').toString();
	} catch(err) {
		errors.push("Could not get disk data");
		return {
			total:'N/A',
			used:'N/A',
			free:'N/A',
			"percent_used":0,
			mount:'N/A',
			filesytstem:'N/A'
		}
	}
	var datas = [];
	var mounts = [];
	var key = 0;
	var parsed = df.trim().split('\n');
	for(var item in parsed) {
		var it = parsed[item];
		if(it.indexOf('tmpfs') > -1) {
			continue;
		}

		it = it.split(',');
		for(var p in it) {
			//trim spaces
			it[p] = it[p].toString().trim();
			//convert numbers
			var sint = parseInt(it[p]).toString();
			if(sint===it[p]||sint+"%"===it[p]) {
				it[p] = sint;
			}
		}
		datas.push({
			total: utils.getSize(it[2] * 1024),
			used: utils.getSize(it[3] * 1024),
			free: utils.getSize(it[4] * 1024),
			"percent_used": it[5],
			mount: it[6].trim(),
			filesystem: it[0].trim()
		})
	}
	return datas;
}

module.exports = {
	getSystemHostname: hostname,
	getLanIp: getLanIp,
	getCpuCoresNumber: getCpuCoresNumber,
	getOperatingSystem: getOperatingSystem,
	getKernel: getKernel,
	getUptime: getUptime,
	getCpuModel: getCpuModel,
	getCpuFrequency: getCpuFrequency,
	getCpuCacheSize: getCpuCacheSize,
	getCpuTemperature: getCpuTemperature,
	getCpuLoadData: getCpuLoadData,
	getMeminfo: getMeminfo,
	getRamInfo: getRamInfo,
	getBootupTime: getBootupTime,
	getSwapData: getSwapData,
	getNetworkData: getNetworkData,
	getDiskData: getDiskData
}
<|endoftext|>


<commit_before>const os = require('os');
const utils = require('./utils');

/**
 * Returns hostname
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @returns {string}  Hostname
 */

var hostname = function(errors){
	return os.hostname();
}

/**
 * Returns server IP
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @param   {Object}  config    configuration
 * @returns {string}  Server    local IP
 */
var getLanIp = function(errors, config) {
	if(config.ip===false) {
		return '';
	}
	if(config.ip && config.ip.constructor===String) {
		return config.ip.constructor;
	}
	try {
		return os.networkInterfaces()[cfg.interface][0].address;
	} catch(err) {
		return '';
		errors.push("Cannot get Server IP");
	}
}

/**
 * Returns CPU cores number
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array} errors           errors in this function are written to this array
 * @returns {int}   Number of cores
 */

var getCpuCoresNumber = function(errors) {
	try {
		return os.cpus().length;
	} catch(err) {
		errors.push("Cannot get number of cores");
		return '';
	}
}

/**
 * Returns the operating system
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  name of OS
 */
var getOperatingSystem = function(errors) {
	var rl = utils.runCommand('lsb_release',['-d','-s']);
	if(!rl.error && rl.stdout && rl.stdout !== '') {
		return rl.stdout;
	}
	if(os.platform==="win32") {
		return "Windows " + os.release();
	}
	try {
		return fs.readFileSync('/etc/issue.net').toString().trim();
	} catch(err) {
		errors.push("Cannot get OS release");
		return os.platform();
	}
}

/**
 * Returns the kernel name
 *
 * @returns {string}  name of the kernel
 */
var getKernel = function() {
	return os.release();
}

/**
 * Returns the current uptime in human readable format
 *
 * @returns {string}  the current uptime
 */
var getUptime = function() {
	return utils.getHumanTime(os.uptime());
}

/**
 * Returns the model of the first CPU
 *
 * @returns {string}  the cpu model
 */
var getCpuModel = function() {
	return os.cpus()[0].model;
}

/**
 * Returns the frequency of the first CPU
 *
 * @returns {string}  the cpu frequency
 */
var getCpuFrequency = function() {
	return parseInt(os.cpus()[0].speed)/1000+' GHz';
}

/**
 * Returns the cache size of the first CPU.
 * Uses nasty `sh -c` instead of doing it properly. Should probably not do this.
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu cache size
 */
var getCpuCacheSize = function(errors) {
	var out = utils.runCommand('sh',['-c','cat /proc/cpuinfo|grep cache\\ size|head -n 1']);
	if(out.error || !out.stdout) {
		errors.push("CPU cache size could not be determined");
		return '';
	}
	out = out.stdout.split(' ');
	out.splice(0,2);
	return out.join(' ');
}

/**
 * Returns the temperature of the first CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu temperature
 */
var getCpuTemperature = function(errors) {
	var out = utils.runCommand('sh',['-c','/usr/bin/sensors | grep -E "^(CPU Temp|Core 0)" | cut -d \'+\' -f2 | cut -d \'.\' -f1']);
	if(out.stdout) {
		out = out.stdout.split(' ');
		out.splice(0,2);
		return out.join(' ') + "°C";
	}
	try {
		return parseInt(fs.readFileSync('/sys/class/thermal/thermal_zone0/temp')) / 1000 + "°C";
	} catch(err) {
		errors.push("CPU temperature could not be determined");
		return '';
	}
}

/**
 * Returns the load data of the CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the cpu load data
 */
/*
 * I have no idea how the rest of this works
 * I don't have a multi-core linux system handy (my server is single-core)
 * so I'll just return nothing for now
*/
var getCpuLoadData = function(errors) {
	errors.push("CPU load data could not be determined");
	return [0,0,0];
}

/*	var out = utils.runCommand('sh',['-c','cat /proc/loadavg | awk \'{print $1","$2","$3}\'']);
	if(!out.stdout) {
		errors.push("CPU load data could not be determined");
		return [0,0,0];
	}

	var cores = getCpuCoresNumber();
	var load_exp = out.stdout.split(',');
//original php resumes here
        $cpuloaddata = array_map(
            function ($value, $cores) {
                $v = (int)($value * 100 / $cores);
                if ($v > 100)
                    $v = 100;
                return $v;
            },
            $load_exp,
            array_fill(0, 3, $cores)
        );
    }
    return $cpuloaddata;
}
*/

//to be finished...
<commit_msg>add getCpuLoadData, getRamInfo, getBootupTime<commit_after>const os = require('os');
const utils = require('./utils');

/**
 * Returns hostname
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @returns {string}  Hostname
 */

var hostname = function(errors){
	return os.hostname();
}

/**
 * Returns server IP
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array}   errors    errors in this function are written to this array
 * @param   {Object}  config    configuration
 * @returns {string}  Server    local IP
 */
var getLanIp = function(errors, config) {
	if(config.ip===false) {
		return '';
	}
	if(config.ip && config.ip.constructor===String) {
		return config.ip.constructor;
	}
	try {
		return os.networkInterfaces()[cfg.interface][0].address;
	} catch(err) {
		return '';
		errors.push("Cannot get Server IP");
	}
}

/**
 * Returns CPU cores number
 * Lifted from github.com/shevabam/ezservermonitor-web
 *
 * @param   {array} errors           errors in this function are written to this array
 * @returns {int}   Number of cores
 */

var getCpuCoresNumber = function(errors) {
	try {
		return os.cpus().length;
	} catch(err) {
		errors.push("Cannot get number of cores");
		return '';
	}
}

/**
 * Returns the operating system
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  name of OS
 */
var getOperatingSystem = function(errors) {
	var rl = utils.runCommand('lsb_release',['-d','-s']);
	if(!rl.error && rl.stdout && rl.stdout !== '') {
		return rl.stdout;
	}
	if(os.platform==="win32") {
		return "Windows " + os.release();
	}
	try {
		return fs.readFileSync('/etc/issue.net').toString().trim();
	} catch(err) {
		errors.push("Cannot get OS release");
		return os.platform();
	}
}

/**
 * Returns the kernel name
 *
 * @returns {string}  name of the kernel
 */
var getKernel = function() {
	return os.release();
}

/**
 * Returns the current uptime in human readable format
 *
 * @returns {string}  the current uptime
 */
var getUptime = function() {
	return utils.getHumanTime(os.uptime());
}

/**
 * Returns the model of the first CPU
 *
 * @returns {string}  the cpu model
 */
var getCpuModel = function() {
	return os.cpus()[0].model;
}

/**
 * Returns the frequency of the first CPU
 *
 * @returns {string}  the cpu frequency
 */
var getCpuFrequency = function() {
	return parseInt(os.cpus()[0].speed)/1000+' GHz';
}

/**
 * Returns the cache size of the first CPU.
 * Uses nasty `sh -c` instead of doing it properly. Should probably not do this.
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu cache size
 */
var getCpuCacheSize = function(errors) {
	var out = utils.runCommand('sh',['-c','cat /proc/cpuinfo|grep cache\\ size|head -n 1']);
	if(out.error || !out.stdout) {
		errors.push("CPU cache size could not be determined");
		return '';
	}
	out = out.stdout.split(' ');
	out.splice(0,2);
	return out.join(' ');
}

/**
 * Returns the temperature of the first CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {string}  the cpu temperature
 */
var getCpuTemperature = function(errors) {
	var out = utils.runCommand('sh',['-c','/usr/bin/sensors | grep -E "^(CPU Temp|Core 0)" | cut -d \'+\' -f2 | cut -d \'.\' -f1']);
	if(out.stdout) {
		out = out.stdout.split(' ');
		out.splice(0,2);
		return out.join(' ') + "°C";
	}
	try {
		return parseInt(fs.readFileSync('/sys/class/thermal/thermal_zone0/temp')) / 1000 + "°C";
	} catch(err) {
		errors.push("CPU temperature could not be determined");
		return '';
	}
}

/**
 * Returns the load data of the CPU
 *
 * @param {array} errors errors in this function are written to this array
 * @returns {array}  the cpu load data
 */
/*
 * I'm assuming this is supposed to return multiple values? I'm not sure what the $cores
 * reference is doing I don't have a multi-core linux system handy (my server is single-core)
 * so I'll just return os.loadavg()
*/
var getCpuLoadData = function(errors) {
	errors.push("CPU load data could not be determined");
	return os.loadavg();
}

/*	var out = utils.runCommand('sh',['-c','cat /proc/loadavg | awk \'{print $1","$2","$3}\'']);
	if(!out.stdout) {
		errors.push("CPU load data could not be determined");
		return [0,0,0];
	}

	var cores = getCpuCoresNumber();
	var load_exp = out.stdout.split(',');
//original php resumes here
        $cpuloaddata = array_map(
            function ($value, $cores) {
                $v = (int)($value * 100 / $cores);
                if ($v > 100)
                    $v = 100;
                return $v;
            },
            $load_exp,
            array_fill(0, 3, $cores)
        );
    }
    return $cpuloaddata;
}
*/

/**
 * Returns the various data about the RAM
 * Part of this function was borrowed from http://stackoverflow.com/a/23588793
 * You can get free memory with os.freemem()
 * @returns {array}  the ram data
 */
var getRamInfo = function(errors) {
	var info = {};
	try {
		var data = fs.readFileSync('/proc/meminfo').toString();
	} catch(err) {
		errors.push('Could not read RAM data');
		return {};
	}
	data.split(/\n/g).forEach(function(line){
		line = line.split(':');

		// Ignore invalid lines, if any
		if (line.length < 2) {
			return;
		}

		// Remove parseInt call to make all values strings
		info[line[0]] = parseInt(line[1].trim(), 10);
	});
	if(!info.MemFree) {
		errors.push('Could not read RAM data: free memory');
	}
	if(!info.MemTotal) {
		errors.push('Could not read RAM data: total memory');
	}
	if(!info.Buffers) {
		errors.push('Could not read RAM data: buffers');
	}
	if(!info.Cached) {
		errors.push('Could not read RAM data: cached');
	}
	var free = info.MemFree || 0;
	var buffers = info.Buffers || 0;
	var cached = info.Cached || 0;
	var total = info.MemTotal || 0;
	free = free + buffers + cached;
	var used = total - free;

	var percent = (total > 0) ? (100 - Math.floor(free / total * 100)) : 0;

	return {
		used: utils.getSize(used*1024),
		free: utils.getSize(free*1024),
		total: utils.getSize(total*1024),
		percent_used: utils.getSize(percent)
	}
}

/**
 * Returns the boot up time
 *
 * @returns {array}  the time since last boot
 */
function getBootupTime() {
	var uptime = os.uptime();
	var date = new Date();
	date.setSeconds(date.getSeconds()-uptime);
	var m = date.getMonth()+1; //counts from 0
	if(m<10) {
		m = "0" + m;
	}
	var H = date.getHours();
	if(H<10) {
		H = "0" + H;
	}
	var i = date.getMinutes();
	if(i<10) {
		i = "0" + i;
	}
	var s = date.getSeconds();
	if(s<10) {
		s = "0" + s;
	}

	//I have no idea why this is an array, but it's easier to leave it...
	return {
		"last_boot" : date.getFullYear() + "-" + m + "-" +
			date.getDate() + " " + H + ":" + i + ":" + s;
	}
}

//to be finished...
<|endoftext|>


<commit_before>/***********************************************************************

    Check uit, check in

    Copyright 2010, Martijn Vermaat <martijn@vermaat.name>

      http://checkuitcheckin.nl
      http://svn.vermaat.name/checkuitcheckin

    Licensed under the MIT license, see the LICENSE file

      http://en.wikipedia.org/wiki/Mit_license

    Some of the Twitter handling code was adapted from the jQuery
    plugin Tweet!, found at http://tweet.seaofclouds.com/

    This code uses:
      jQuery          http://jquery.com
      jQuery Timers   http://plugins.jquery.com/project/timers

***********************************************************************/

$(document).ready(function() {

    var twitterSearch = 'ovchipkaart OR chipkaart OR ovchip';
    var twitterCount = 50;
    /*
      We filter out any tweet containing a link. The idea is that we are
      probably left with only honest personal tweets about the card (but we
      mis out on some as well).
      This effectively filters a lot of spam and news feeds. Currently, about
      half of the search results are filtered this way.
    */
    var twitterFilter = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/i;
    // And then there are some really persistent feeds we don't want to show
    var twitterBlacklist = ['ov_chipkaart',      // only retweets
                            'politiekretweet',   // only retweets
                            'Uitgekotst',        // not interesting
                            'DonaldDuckvideo'];  // spam
    var twitterDisplayTime = 1000 * 8;
    var twitterFadeTime = 800;
    /*
      There seems to be a bug, where animations are not smooth when the
      interval is specified as a string, e.g. '5s'.
    */
    var twitterReloadTime = 1000 * 60 * 5;

    var deliciousUser = 'checkuitcheckin';
    var deliciousTag = 'nieuws';
    var deliciousCount = 10;

    // Unfortunately, twitter query cannot exceed 140 characters
    var twitterUrl = 'http://search.twitter.com/search?&q='
        + encodeURIComponent(twitterSearch);
    var twitterApiUrl = 'http://search.twitter.com/search.json?&q='
        + encodeURIComponent(twitterSearch)
        + '&rpp=' + twitterCount + '&callback=?';
    var initialTweet = true;
    var tweets = [];
    var currentTweet = 0;

    var deliciousUrl = 'http://delicious.com/' + deliciousUser
        + '/' + deliciousTag;
    var deliciousApiUrl = 'http://feeds.delicious.com/v2/json/'
        + deliciousUser + '/' + deliciousTag
        + '?count=' + deliciousCount + '&callback=?';

    // Load Twitter search results and call callback function
    function updateTwitter(callback) {

        // http://apiwiki.twitter.com/Return-Values

        $.getJSON(twitterApiUrl, function(data) {

            currentTweet = 0;
            tweets = [];

            $.each((data.results || data), function(i, tweet) {
                var user = tweet.from_user || tweet.user.screen_name;
                if ($.inArray(user, twitterBlacklist) == -1
                    && !twitterFilter.test(tweet.text)) {
                    tweets.push({
                        text    : twittify(tweet.text),
                        user    : user,
                        date    : relativeTime(tweet.created_at),
                        url     : 'http://twitter.com/' + user
                                  + '/statuses/' + tweet.id,
                        userUrl : 'http://twitter.com/' + user
                    });
                }
            });

            if ($.isFunction(callback)) callback();

        });

    }

    // Load Delicious links and show them on the page
    function updateDelicious() {

        // http://delicious.com/help/feeds

        $.getJSON(deliciousApiUrl, function(data) {
            var list = $('
').appendTo($('#delicious'));
            $.each((data.results || data), function(i, item) {
                list.append($('
').text(shortDate(item.dt)));
                list.append($('
').append(
                    $('').attr('href', item.u).text(item.d)));
            });
            $('#delicious').append($('
').append(
                $('Meer nieuwsberichten...').attr('href', deliciousUrl)));
        });

    }

    // Advance to the next twee
    function showNextTweet() {
        if (tweets.length < 1) return;
        currentTweet = (currentTweet + 1) % tweets.length;
        showTweet();
    }

    // Like the function above, with a minor difference
    function showPreviousTweet() {
        if (tweets.length < 1) return;
        currentTweet = (tweets.length + currentTweet - 1) % tweets.length;
        showTweet();
    }

    /*
      Show the current tweet on the page. If this is the first twee we show,
      do just that. Otherwise fadeout the old tweet and fadein the new.
    */
    function showTweet() {

        var show = function() {
            var tweet = tweets[currentTweet];
            var pane = $('#content .tweet');
            /*
              The documentation (and experience) tells us we get the tweet
              text 'escaped and HTML encoded'.
              I still don't like to .html() this into the page, but being more
              cautious would make twittify() much more involved.

              http://apiwiki.twitter.com/Return-Values
            */
            pane.find('.text').html(tweet.text);
            pane.find('h2').empty().append(
                $('').attr('href', tweet.userUrl).text('@' + tweet.user));
            pane.find('h2').append(
                $('').attr('href', tweet.url).text(tweet.date).addClass(
                    'date'));
        }

        if (initialTweet)
            show();
        else
            $("#content .tweet").fadeOut(twitterFadeTime, function () {
                show();
                $("#content .tweet").fadeIn(twitterFadeTime);
            });

        initialTweet = false;

    }

    // Setup the Twitter stream
    function setupTwitter() {

        // Get tweets, show the first one, and skip to next tweet every 5 seconds
        updateTwitter(function() {

            if (tweets.length > 0)
                showTweet();

            if (tweets.length > 1) {

                $(document).everyTime(twitterDisplayTime,
                                      'next',
                                      showNextTweet);

                // We add navigation links and reset the skip timer on click
                $('#content').append($('
').append(
                    $('
<
').click(function() {
                        showPreviousTweet();
                        $(document).stopTime('next');
                        $(document).everyTime(twitterDisplayTime,
                                              'next',
                                              showNextTweet);
                    })
                ).append(
                    $('
>
').click(function() {
                        showNextTweet();
                        $(document).stopTime('next');
                        $(document).everyTime(twitterDisplayTime,
                                              'next',
                                              showNextTweet);
                    })
                ));

            }

        });

        // Every 5 minutes, get tweets and start at the latest tweet again
        $(document).everyTime(twitterReloadTime, 'reload', updateTwitter);

        // Show link to Twitter search results
        $('#content').append($('
').append(
            $('meer...').attr('href', twitterUrl)));

        // Pause auto advancing of tweets on mouse hover
        $('#content .tweet').hover(function() {
            $(document).stopTime('next');
        }, function() {
            if (tweets.length > 1) {
                // If we directly want to advance on hover-out, uncomment this
                //showNextTweet();
                $(document).everyTime(twitterDisplayTime,
                                      'next',
                                      showNextTweet);
            }
        });

    }

    // Show Delicious links
    updateDelicious();

    // If this is the index page, setup the Twitter stream
    if ($('body').hasClass('index'))
        setupTwitter();

});

// Create links for users, and hashtags (tweets with links are filtered)
function twittify(tweet) {

    var linkUser = function(s) {
        var returning = [];
        var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
        return s.replace(regexp,"@$1");
    }

    var linkHash = function(s) {
        var returning = [];
        var regexp = / [\#]+([A-Za-z0-9-_]+)/gi;
        return s.replace(regexp, ' #$1');
    }

    return linkHash(linkUser(tweet));

}

/*
  The non-search twitter APIs return inconsistently-formatted dates, which
  Date.parse cannot handle in IE. We therefore perform the following
  transformation:

  Wed Apr 29 08:53:31 +0000 2009
  =>
  Wed, Apr 29 2009 08:53:31 +0000
*/
function parseDate(s) {
    return Date.parse(s.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i,
                                '$1,$2$4$3'));
}

// Turn a date/time string into a relative time
function relativeTime(time) {

    var parsedDate = parseDate(time);
    var relativeTo = (arguments.length > 1) ? arguments[1] : new Date();
    var delta = parseInt((relativeTo.getTime() - parsedDate) / 1000);

    var pluralize = function(singular, n) {
        var plurals = {
            'minuut' : 'minuten',
            'uur'    : 'uur',
            'dag'    : 'dagen'
        };
        return '' + n + ' ' + (n == 1 ? singular : plurals[singular]);
    };

    if (delta < 60)
        return 'seconden geleden';
    else if (delta < (60 * 60))
        return pluralize('minuut', parseInt(delta / 60)) + ' geleden';
    else if (delta < (24 * 60 * 60))
        return pluralize('uur', parseInt(delta / 3600)) + ' geleden';
    else
        return pluralize('dag', parseInt(delta / 86400)) + ' geleden';

}

// Create a short description from a date string
function shortDate(s) {

    var months = ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
                  'jul', 'aug', 'sep', 'okt', 'nov', 'dec'];

    if (!s)
        return (new Date).getDate() + ' ' + months[(new Date).getMonth() + 1];

    var d = s.match(/^\d{4}-(\d{2})-(\d{2}).*$/);
    if (d != null)
        return d[2] + ' ' + months[parseInt(d[1]) - 1];

    return '';

}
<commit_msg>Fixed naughty bug where parseInt gets a string starting with a zero and treats it as octal.<commit_after>/***********************************************************************

    Check uit, check in

    Copyright 2010, Martijn Vermaat <martijn@vermaat.name>

      http://checkuitcheckin.nl
      http://svn.vermaat.name/checkuitcheckin

    Licensed under the MIT license, see the LICENSE file

      http://en.wikipedia.org/wiki/Mit_license

    Some of the Twitter handling code was adapted from the jQuery
    plugin Tweet!, found at http://tweet.seaofclouds.com/

    This code uses:
      jQuery          http://jquery.com
      jQuery Timers   http://plugins.jquery.com/project/timers

***********************************************************************/

$(document).ready(function() {

    var twitterSearch = 'ovchipkaart OR chipkaart OR ovchip';
    var twitterCount = 50;
    /*
      We filter out any tweet containing a link. The idea is that we are
      probably left with only honest personal tweets about the card (but we
      mis out on some as well).
      This effectively filters a lot of spam and news feeds. Currently, about
      half of the search results are filtered this way.
    */
    var twitterFilter = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/i;
    // And then there are some really persistent feeds we don't want to show
    var twitterBlacklist = ['ov_chipkaart',      // only retweets
                            'politiekretweet',   // only retweets
                            'Uitgekotst',        // not interesting
                            'DonaldDuckvideo'];  // spam
    var twitterDisplayTime = 1000 * 8;
    var twitterFadeTime = 800;
    /*
      There seems to be a bug, where animations are not smooth when the
      interval is specified as a string, e.g. '5s'.
    */
    var twitterReloadTime = 1000 * 60 * 5;

    var deliciousUser = 'checkuitcheckin';
    var deliciousTag = 'nieuws';
    var deliciousCount = 10;

    // Unfortunately, twitter query cannot exceed 140 characters
    var twitterUrl = 'http://search.twitter.com/search?&q='
        + encodeURIComponent(twitterSearch);
    var twitterApiUrl = 'http://search.twitter.com/search.json?&q='
        + encodeURIComponent(twitterSearch)
        + '&rpp=' + twitterCount + '&callback=?';
    var initialTweet = true;
    var tweets = [];
    var currentTweet = 0;

    var deliciousUrl = 'http://delicious.com/' + deliciousUser
        + '/' + deliciousTag;
    var deliciousApiUrl = 'http://feeds.delicious.com/v2/json/'
        + deliciousUser + '/' + deliciousTag
        + '?count=' + deliciousCount + '&callback=?';

    // Load Twitter search results and call callback function
    function updateTwitter(callback) {

        // http://apiwiki.twitter.com/Return-Values

        $.getJSON(twitterApiUrl, function(data) {

            currentTweet = 0;
            tweets = [];

            $.each((data.results || data), function(i, tweet) {
                var user = tweet.from_user || tweet.user.screen_name;
                if ($.inArray(user, twitterBlacklist) == -1
                    && !twitterFilter.test(tweet.text)) {
                    tweets.push({
                        text    : twittify(tweet.text),
                        user    : user,
                        date    : relativeTime(tweet.created_at),
                        url     : 'http://twitter.com/' + user
                                  + '/statuses/' + tweet.id,
                        userUrl : 'http://twitter.com/' + user
                    });
                }
            });

            if ($.isFunction(callback)) callback();

        });

    }

    // Load Delicious links and show them on the page
    function updateDelicious() {

        // http://delicious.com/help/feeds

        $.getJSON(deliciousApiUrl, function(data) {
            var list = $('
').appendTo($('#delicious'));
            $.each((data.results || data), function(i, item) {
                list.append($('
').text(shortDate(item.dt)));
                list.append($('
').append(
                    $('').attr('href', item.u).text(item.d)));
            });
            $('#delicious').append($('
').append(
                $('Meer nieuwsberichten...').attr('href', deliciousUrl)));
        });

    }

    // Advance to the next twee
    function showNextTweet() {
        if (tweets.length < 1) return;
        currentTweet = (currentTweet + 1) % tweets.length;
        showTweet();
    }

    // Like the function above, with a minor difference
    function showPreviousTweet() {
        if (tweets.length < 1) return;
        currentTweet = (tweets.length + currentTweet - 1) % tweets.length;
        showTweet();
    }

    /*
      Show the current tweet on the page. If this is the first twee we show,
      do just that. Otherwise fadeout the old tweet and fadein the new.
    */
    function showTweet() {

        var show = function() {
            var tweet = tweets[currentTweet];
            var pane = $('#content .tweet');
            /*
              The documentation (and experience) tells us we get the tweet
              text 'escaped and HTML encoded'.
              I still don't like to .html() this into the page, but being more
              cautious would make twittify() much more involved.

              http://apiwiki.twitter.com/Return-Values
            */
            pane.find('.text').html(tweet.text);
            pane.find('h2').empty().append(
                $('').attr('href', tweet.userUrl).text('@' + tweet.user));
            pane.find('h2').append(
                $('').attr('href', tweet.url).text(tweet.date).addClass(
                    'date'));
        }

        if (initialTweet)
            show();
        else
            $("#content .tweet").fadeOut(twitterFadeTime, function () {
                show();
                $("#content .tweet").fadeIn(twitterFadeTime);
            });

        initialTweet = false;

    }

    // Setup the Twitter stream
    function setupTwitter() {

        // Get tweets, show the first one, and skip to next tweet every 5 seconds
        updateTwitter(function() {

            if (tweets.length > 0)
                showTweet();

            if (tweets.length > 1) {

                $(document).everyTime(twitterDisplayTime,
                                      'next',
                                      showNextTweet);

                // We add navigation links and reset the skip timer on click
                $('#content').append($('
').append(
                    $('
<
').click(function() {
                        showPreviousTweet();
                        $(document).stopTime('next');
                        $(document).everyTime(twitterDisplayTime,
                                              'next',
                                              showNextTweet);
                    })
                ).append(
                    $('
>
').click(function() {
                        showNextTweet();
                        $(document).stopTime('next');
                        $(document).everyTime(twitterDisplayTime,
                                              'next',
                                              showNextTweet);
                    })
                ));

            }

        });

        // Every 5 minutes, get tweets and start at the latest tweet again
        $(document).everyTime(twitterReloadTime, 'reload', updateTwitter);

        // Show link to Twitter search results
        $('#content').append($('
').append(
            $('meer...').attr('href', twitterUrl)));

        // Pause auto advancing of tweets on mouse hover
        $('#content .tweet').hover(function() {
            $(document).stopTime('next');
        }, function() {
            if (tweets.length > 1) {
                // If we directly want to advance on hover-out, uncomment this
                //showNextTweet();
                $(document).everyTime(twitterDisplayTime,
                                      'next',
                                      showNextTweet);
            }
        });

    }

    // Show Delicious links
    updateDelicious();

    // If this is the index page, setup the Twitter stream
    if ($('body').hasClass('index'))
        setupTwitter();

});

// Create links for users, and hashtags (tweets with links are filtered)
function twittify(tweet) {

    var linkUser = function(s) {
        var returning = [];
        var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
        return s.replace(regexp,"@$1");
    }

    var linkHash = function(s) {
        var returning = [];
        var regexp = / [\#]+([A-Za-z0-9-_]+)/gi;
        return s.replace(regexp, ' #$1');
    }

    return linkHash(linkUser(tweet));

}

/*
  The non-search twitter APIs return inconsistently-formatted dates, which
  Date.parse cannot handle in IE. We therefore perform the following
  transformation:

  Wed Apr 29 08:53:31 +0000 2009
  =>
  Wed, Apr 29 2009 08:53:31 +0000
*/
function parseDate(s) {
    return Date.parse(s.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i,
                                '$1,$2$4$3'));
}

// Turn a date/time string into a relative time
function relativeTime(time) {

    var parsedDate = parseDate(time);
    var relativeTo = (arguments.length > 1) ? arguments[1] : new Date();
    var delta = parseInt((relativeTo.getTime() - parsedDate) / 1000);

    var pluralize = function(singular, n) {
        var plurals = {
            'minuut' : 'minuten',
            'uur'    : 'uur',
            'dag'    : 'dagen'
        };
        return '' + n + ' ' + (n == 1 ? singular : plurals[singular]);
    };

    if (delta < 60)
        return 'seconden geleden';
    else if (delta < (60 * 60))
        return pluralize('minuut', parseInt(delta / 60)) + ' geleden';
    else if (delta < (24 * 60 * 60))
        return pluralize('uur', parseInt(delta / 3600)) + ' geleden';
    else
        return pluralize('dag', parseInt(delta / 86400)) + ' geleden';

}

// Create a short description from a date string
function shortDate(s) {

    var months = ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
                  'jul', 'aug', 'sep', 'okt', 'nov', 'dec'];

    if (!s)
        return (new Date).getDate() + ' ' + months[(new Date).getMonth() + 1];

    var d = s.match(/^\d{4}-(\d{2})-(\d{2}).*$/);
    if (d != null)
        return d[2] + ' ' + months[parseInt(d[1], 10) - 1];

    return '';

}
<|endoftext|>


<commit_before>// Global Namespace
var Camera = Camera || function(minWidth, minHeight, video, canvas, image, scale) {
        this.video = video;

        this.scale = scale;

        this.canvas = canvas;

        this.image = image;

        this.resolution = {
            "mandatory": {
                "minWidth": minWidth,
                "minHeight": minHeight
            }
        };

        // Setting up the mediaStream so that when the user closes the video, the stream ends
        this.mediaStream = null;

        // Video rotation
        this.videoRotation = 0;

        // Video rotated recently?
        this.rotated = 0;

        // Camera status
        this.on = false;

        // Start Camera
        this.startCamera = function(success, error) {
            var self = this;

            navigator.getUserMedia(
                {
                    audio: false,
                    video: self.resolution
                },
                function successCallBack(stream) {
                    var retryCount = 0;
                    var retryLimit = 50;

                    self.mediaStream = stream;

                    self.video.src = (window.URL && window.URL.createObjectURL(stream));

                    self.video.play();

                    self.video.onplaying = function(e) {
                        var videoWidth = this.videoWidth;
                        var videoHeight = this.videoHeight;
                        self.video.width = videoWidth * self.scale;
                        self.video.height = videoHeight * self.scale;

                        if (!videoWidth || !videoHeight) {
                            if (retryCount < retryLimit) {
                                retryCount++;
                                window.setTimeout(function () {
                                    self.video.pause();
                                    self.video.play();
                                }, 100);
                            }

                        } else if (videoWidth && videoHeight) {
                            self.image.height = self.video.videoHeight;
                            self.image.width = self.video.videoWidth;

                            self.canvas.width = videoWidth;
                            self.canvas.height = videoHeight;

                            self.on = true;

                            success();
                        } else {
                            console.log("An error has occurred: Can't retrieve video width and height");

                            error();
                        }
                    };
                }, function errorCallback(e) {
                    error();
                }
            );
        };

        // Stop Camera
        this.stopCamera = function(success, error) {
            var self = this;

            self.mediaStream.getVideoTracks()[0].stop();

            if (self.mediaStream.getVideoTracks()[0]['readyState'] === "ended") {
                self.on = false;
                self.video.removeAttribute("style");

                success();
            } else {
                console.log("Error: Could not pause/stop camera");
                error();
            }
        };

        // Take a picture
        this.takePicture = function(callback) {
            var self = this;

            // Get the frame from the video
            var ctx = self.canvas.getContext('2d');

            if (self.rotated == 1) {
                // Base on the rotation
                switch (self.videoRotation) {
                    case -90:
                    case 270:
                        ctx.translate(0, self.canvas.height);
                        self.image.height = self.video.videoWidth;
                        self.image.width = self.video.videoHeight;
                        break;
                    case 90:
                    case -270:
                        ctx.translate(self.canvas.width, 0);
                        self.image.height = self.video.videoWidth;
                        self.image.width = self.video.videoHeight;
                        break;
                    case 180:
                    case -180:
                        ctx.translate(self.canvas.width, self.canvas.height);
                        self.image.height = self.video.videoHeight;
                        self.image.width = self.video.videoWidth;
                        break;
                    case 0:
                        self.image.height = self.video.videoHeight;
                        self.image.width = self.video.videoWidth;
                        break;
                    default:
                        console.log('Error: Can not translate ctx');
                        break;
                }

                self.rotated = 0;
                ctx.rotate(self.videoRotation * (Math.PI/180));
            }

            // Draw the image to the canvas
            ctx.drawImage(self.video, 0, 0);

            // Set the source
            self.image.src = self.canvas.toDataURL('image/png', 1.0);

            callback();
        };

        // Rotate the video/canvas left
        this.rotateLeft = function() {
            var self = this;
            self.videoRotation -= 90;

            if (self.videoRotation < -270) {
                self.videoRotation = 0;
            }

            // Switch base on video rotation
            switch (self.videoRotation) {
                case 90:
                case -90:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 180:
                case -180:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                case 270:
                case -270:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 0:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                default:
                    console.log('Error: Could not rotate canvas');
                    break;
            }

            self.rotated = 1;
            self.video.style.transform = ' rotate(' + this.videoRotation + 'deg)';
        };

        // Rotate the video/canvas right
        this.rotateRight = function() {
            var self = this;
            self.videoRotation += 90;

            if (self.videoRotation > 270) {
                self.videoRotation = 0;
            }

            // Switch base on video rotation
            switch (self.videoRotation) {
                case 90:
                case -90:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 180:
                case -180:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                case 270:
                case -270:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 0:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                default:
                    console.log('Error: Could not rotate canvas');
                    break;
            }

            self.rotated = 1;
            self.video.style.transform = ' rotate(' + this.videoRotation + 'deg)';
        };

        // Get camera options
        this.getOptions = function() {
            var self = this;
            return JSON.stringify(self);
        };

    };<commit_msg>Add files via upload<commit_after>// Global Namespace
var Camera = Camera || function(minWidth, minHeight, video, canvas, image, scale) {
        this.video = video;

        this.scale = scale;

        this.canvas = canvas;

        this.image = image;

        this.resolution = {
            "mandatory": {
                "minWidth": minWidth,
                "minHeight": minHeight
            }
        };

        // Setting up the mediaStream so that when the user closes the video, the stream ends
        this.mediaStream = null;

        // Video rotation
        this.videoRotation = 0;

        // Video rotated recently?
        this.rotated = 0;

        // Camera status
        this.on = false;

        // Start Camera
                this.startCamera = function(success, error) {
            var self = this;

            navigator.mediaDevices.getUserMedia(
                {
                    audio: false,
                    video: self.resolution
                })
            .then(function successCallBack(stream) {

				var retryCount = 0;
				var retryLimit = 50;

				self.mediaStream = stream;

				self.video.srcObject = stream;

				self.video.play();

				self.video.onloadedmetadata = function(e) {
					var videoWidth = this.videoWidth;
					var videoHeight = this.videoHeight;
					self.video.width = videoWidth * self.scale;
					self.video.height = videoHeight * self.scale;

					if (!videoWidth || !videoHeight) {
						if (retryCount < retryLimit) {
							retryCount++;
							window.setTimeout(function () {
								self.video.pause();
								self.video.play();
							}, 100);
						}

					} else if (videoWidth && videoHeight) {
						self.image.height = self.video.videoHeight;
						self.image.width = self.video.videoWidth;

						self.canvas.width = videoWidth;
						self.canvas.height = videoHeight;

						self.on = true;

						success();
					} else {
						console.log("An error has occurred: Can't retrieve video width and height");

						error();
					}
				}
            })
            .catch(function errorCallback(e) {
                error();
            });
        };

        // Stop Camera
        this.stopCamera = function(success, error) {
            var self = this;

            self.mediaStream.getVideoTracks()[0].stop();

            if (self.mediaStream.getVideoTracks()[0]['readyState'] === "ended") {
                self.on = false;
                self.video.removeAttribute("style");

                success();
            } else {
                console.log("Error: Could not pause/stop camera");
                error();
            }
        };

        // Take a picture
        this.takePicture = function(callback) {
            var self = this;

            // Get the frame from the video
            var ctx = self.canvas.getContext('2d');

            if (self.rotated == 1) {
                // Base on the rotation
                switch (self.videoRotation) {
                    case -90:
                    case 270:
                        ctx.translate(0, self.canvas.height);
                        self.image.height = self.video.videoWidth;
                        self.image.width = self.video.videoHeight;
                        break;
                    case 90:
                    case -270:
                        ctx.translate(self.canvas.width, 0);
                        self.image.height = self.video.videoWidth;
                        self.image.width = self.video.videoHeight;
                        break;
                    case 180:
                    case -180:
                        ctx.translate(self.canvas.width, self.canvas.height);
                        self.image.height = self.video.videoHeight;
                        self.image.width = self.video.videoWidth;
                        break;
                    case 0:
                        self.image.height = self.video.videoHeight;
                        self.image.width = self.video.videoWidth;
                        break;
                    default:
                        console.log('Error: Can not translate ctx');
                        break;
                }

                self.rotated = 0;
                ctx.rotate(self.videoRotation * (Math.PI/180));
            }

            // Draw the image to the canvas
            ctx.drawImage(self.video, 0, 0);

            // Set the source
            self.image.src = self.canvas.toDataURL('image/png', 1.0);

            callback();
        };

        // Rotate the video/canvas left
        this.rotateLeft = function() {
            var self = this;
            self.videoRotation -= 90;

            if (self.videoRotation < -270) {
                self.videoRotation = 0;
            }

            // Switch base on video rotation
            switch (self.videoRotation) {
                case 90:
                case -90:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 180:
                case -180:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                case 270:
                case -270:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 0:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                default:
                    console.log('Error: Could not rotate canvas');
                    break;
            }

            self.rotated = 1;
            self.video.style.transform = ' rotate(' + this.videoRotation + 'deg)';
        };

        // Rotate the video/canvas right
        this.rotateRight = function() {
            var self = this;
            self.videoRotation += 90;

            if (self.videoRotation > 270) {
                self.videoRotation = 0;
            }

            // Switch base on video rotation
            switch (self.videoRotation) {
                case 90:
                case -90:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 180:
                case -180:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                case 270:
                case -270:
                    self.canvas.height = self.video.videoWidth;
                    self.canvas.width = self.video.videoHeight;

                    self.video.height = self.video.videoWidth * self.scale;
                    break;
                case 0:
                    self.canvas.height = self.video.videoHeight;
                    self.canvas.width = self.video.videoWidth;

                    self.video.height = self.video.videoHeight * self.scale;
                    break;
                default:
                    console.log('Error: Could not rotate canvas');
                    break;
            }

            self.rotated = 1;
            self.video.style.transform = ' rotate(' + this.videoRotation + 'deg)';
        };

        // Get camera options
        this.getOptions = function() {
            var self = this;
            return JSON.stringify(self);
        };

    };<|endoftext|>


<commit_before>const actionCreator = function(type, payloadCreator) {
  const res = (...args) => {
    let action = { type }

    if (typeof payloadCreator == "function") {
      return Object.assign({}, payloadCreator(...args), action)
    }

    return action
  }
  res.type = type

  return res
}

export default actionCreator
<commit_msg>dashboard: refactor actionCreator function<commit_after>export default function(type, payloadCreator) {
  let creator
  if (payloadCreator) {
    creator = (...args) => {
      return Object.assign(payloadCreator(...args), {type})
    }
  } else {
    creator = () => {
      return {type}
    }
  }

  creator.type = type

  return creator
}
<|endoftext|>