<commit_before>var Command  = require('./command');
var Packets  = require('../packets/index.js');
var util    = require('util');
var compileParser = require('../compile_text_parser.js');
var ServerStatus = require('../constants/server_status.js');

function Query(sql, options, callback)
{
  Command.call(this);
  this.query = sql;
  this.options = options;
  this.onResult = callback;
  this._fieldCount = 0;
  this._rowParser  = null;
  this._fields     = [];
  this._rows       = [];
  this._receivedFieldsCount = 0;
  this._resultIndex = 0;
}
util.inherits(Query, Command);

Query.prototype.start = function(packet, connection) {
  if (connection.config.debug) {
    console.log('        Sending query command: %s', this.query);
  }
  var cmdPacket = new Packets.Query(this.query);
  connection.writePacket(cmdPacket.toPacket(1));
  return Query.prototype.resultsetHeader;
};

Query.prototype.done = function() {
  var self = this;
  if (this.onResult) {
    var rows, fields;
    if (this._resultIndex === 0) {
      rows = this._rows[0];
      fields = this._fields[0];
    } else {
      rows = this._rows;
      fields = this._fields;
    }
    if (fields) {
      process.nextTick(function() {
        self.onResult(null, rows, fields);
      });
    } else {
      process.nextTick(function() {
        self.onResult(null, rows);
      });
    }
  }
  return null;
};

Query.prototype.resultsetHeader = function(packet, connection) {
  var rs = new Packets.ResultSetHeader(packet, connection.config.bigNumberStrings);
  this._fieldCount = rs.fieldCount;
  if (connection.config.debug) {
    console.log('        Resultset header received, expecting ' + rs.fieldCount + ' column definition packets');
  }
  if (this._fieldCount === 0) {
    this._rows.push(rs);
    this._fields.push(void(0));
    this.emit('result', rs, this._resultIndex);
    this.emit('fields', void(0), this._resultIndex);
    if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
      this._resultIndex++;
      return Query.prototype.resultsetHeader;
    }
    return this.done();
  }

  this._receivedFieldsCount = 0;
  this._rows.push([]);
  this._fields.push([]);
  return Query.prototype.readField;
};

// TODO: move to connection.js ?
function getFieldsKey(fields, options) {
  var res = (typeof options.nestTables) + '/' + options.nestTables + '/' + options.rowsAsHash;
  for (var i=0; i < fields.length; ++i)
    res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
  return res;
}

Query.prototype.readField = function(packet, connection) {

  this._receivedFieldsCount++;

  // Often there is much more data in the column definition than in the row itself
  // If you set manually _fields[0] to array of ColumnDefinition's (from previous call)
  // you can 'cache' result of parsing. Field packets still received, but ignored in that case
  // this is the reason _receivedFieldsCount exist (otherwise we could just use current length of fields array)

  if (this._fields[this._resultIndex].length != this._fieldCount) {
    var field = new Packets.ColumnDefinition(packet);
    this._fields[this._resultIndex].push(field);
    if (connection.config.debug) {
      console.log('        Column definition:');
      console.log('          name: ' + field.name);
      console.log('          type: ' + field.columnType);
      console.log('         flags: ' + field.flags);
    }
  }

  // last field received
  if (this._receivedFieldsCount == this._fieldCount) {
    var fields = this._fields[this._resultIndex];
    this.emit('fields', fields, this._resultIndex);
    var parserKey = getFieldsKey(fields, this.options);
    this.rowParser = connection.textProtocolParsers[parserKey];
    if (!this.rowParser) {
      this.rowParser = compileParser(fields, this.options, connection.config);
      connection.textProtocolParsers[parserKey] = this.rowParser;
    }
    return Query.prototype.fieldsEOF;
  }
  return Query.prototype.readField;
};

Query.prototype.fieldsEOF = function(packet) {
  // check EOF
  if (!packet.isEOF())
    throw "Expected EOF packet"; // !!!TODO don't crash if there is a protocol error
  return Query.prototype.row;
};

Query.prototype.row = function(packet)
{
  if (packet.isEOF()) {
    var status = packet.eofStatusFlags();
    var moreResults = packet.eofStatusFlags() & ServerStatus.SERVER_MORE_RESULTS_EXISTS;
    if (moreResults) {
      this._resultIndex++;
      return Query.prototype.resultsetHeader;
    }
    return this.done();
  }

  var row = new this.rowParser(packet);
  if (this.onResult)
    this._rows[this._resultIndex].push(row);
  else
    this.emit('result', row, this._resultIndex);

  return Query.prototype.row;
};

module.exports = Query;
<commit_msg>Query.sql as alias to Query.query fixes #121<commit_after>var Command  = require('./command');
var Packets  = require('../packets/index.js');
var util    = require('util');
var compileParser = require('../compile_text_parser.js');
var ServerStatus = require('../constants/server_status.js');

function Query(sql, options, callback)
{
  Command.call(this);
  this.query = sql;
  // node-mysql compatibility: query.sql as alias to query.query #121
  this.sql = this.query;
  this.options = options;
  this.onResult = callback;
  this._fieldCount = 0;
  this._rowParser  = null;
  this._fields     = [];
  this._rows       = [];
  this._receivedFieldsCount = 0;
  this._resultIndex = 0;
}
util.inherits(Query, Command);

Query.prototype.start = function(packet, connection) {
  if (connection.config.debug) {
    console.log('        Sending query command: %s', this.query);
  }
  var cmdPacket = new Packets.Query(this.query);
  connection.writePacket(cmdPacket.toPacket(1));
  return Query.prototype.resultsetHeader;
};

Query.prototype.done = function() {
  var self = this;
  if (this.onResult) {
    var rows, fields;
    if (this._resultIndex === 0) {
      rows = this._rows[0];
      fields = this._fields[0];
    } else {
      rows = this._rows;
      fields = this._fields;
    }
    if (fields) {
      process.nextTick(function() {
        self.onResult(null, rows, fields);
      });
    } else {
      process.nextTick(function() {
        self.onResult(null, rows);
      });
    }
  }
  return null;
};

Query.prototype.resultsetHeader = function(packet, connection) {
  var rs = new Packets.ResultSetHeader(packet, connection.config.bigNumberStrings);
  this._fieldCount = rs.fieldCount;
  if (connection.config.debug) {
    console.log('        Resultset header received, expecting ' + rs.fieldCount + ' column definition packets');
  }
  if (this._fieldCount === 0) {
    this._rows.push(rs);
    this._fields.push(void(0));
    this.emit('result', rs, this._resultIndex);
    this.emit('fields', void(0), this._resultIndex);
    if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
      this._resultIndex++;
      return Query.prototype.resultsetHeader;
    }
    return this.done();
  }

  this._receivedFieldsCount = 0;
  this._rows.push([]);
  this._fields.push([]);
  return Query.prototype.readField;
};

// TODO: move to connection.js ?
function getFieldsKey(fields, options) {
  var res = (typeof options.nestTables) + '/' + options.nestTables + '/' + options.rowsAsHash;
  for (var i=0; i < fields.length; ++i)
    res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
  return res;
}

Query.prototype.readField = function(packet, connection) {

  this._receivedFieldsCount++;

  // Often there is much more data in the column definition than in the row itself
  // If you set manually _fields[0] to array of ColumnDefinition's (from previous call)
  // you can 'cache' result of parsing. Field packets still received, but ignored in that case
  // this is the reason _receivedFieldsCount exist (otherwise we could just use current length of fields array)

  if (this._fields[this._resultIndex].length != this._fieldCount) {
    var field = new Packets.ColumnDefinition(packet);
    this._fields[this._resultIndex].push(field);
    if (connection.config.debug) {
      console.log('        Column definition:');
      console.log('          name: ' + field.name);
      console.log('          type: ' + field.columnType);
      console.log('         flags: ' + field.flags);
    }
  }

  // last field received
  if (this._receivedFieldsCount == this._fieldCount) {
    var fields = this._fields[this._resultIndex];
    this.emit('fields', fields, this._resultIndex);
    var parserKey = getFieldsKey(fields, this.options);
    this.rowParser = connection.textProtocolParsers[parserKey];
    if (!this.rowParser) {
      this.rowParser = compileParser(fields, this.options, connection.config);
      connection.textProtocolParsers[parserKey] = this.rowParser;
    }
    return Query.prototype.fieldsEOF;
  }
  return Query.prototype.readField;
};

Query.prototype.fieldsEOF = function(packet) {
  // check EOF
  if (!packet.isEOF())
    throw "Expected EOF packet"; // !!!TODO don't crash if there is a protocol error
  return Query.prototype.row;
};

Query.prototype.row = function(packet)
{
  if (packet.isEOF()) {
    var status = packet.eofStatusFlags();
    var moreResults = packet.eofStatusFlags() & ServerStatus.SERVER_MORE_RESULTS_EXISTS;
    if (moreResults) {
      this._resultIndex++;
      return Query.prototype.resultsetHeader;
    }
    return this.done();
  }

  var row = new this.rowParser(packet);
  if (this.onResult)
    this._rows[this._resultIndex].push(row);
  else
    this.emit('result', row, this._resultIndex);

  return Query.prototype.row;
};

module.exports = Query;
<|endoftext|>


<commit_before>/**
 * config/express.js
 *
 * Defines all express related configurations for the server
 */

'use strict';

var express = require('express');
var path = require('path');
// var jwt = require('express-jwt');
var modelsImport = require('../models/');
var mongoose = require('mongoose');
var cookieParser = require('cookie-parser');
var settings = require('../../settings');
var responseUtils = require('../utils/response');

module.exports = function(app) {
  var rootPath = path.normalize(__dirname + '/../..');

  mongoose.connect(settings.database);

  var Models = modelsImport(mongoose);

  // make models available in req variable
  app.use(function (req, res, next) {
    req.models = Models;
    return next();
  });

  // make error message function available in res variable
  app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');

    res.errorJson = function (err) {
      responseUtils.sendErrorJson(res, err);
    };
    return next();
  });

  app.configure('development', function(){
    app.use(require('connect-livereload')());

    app.use(express.errorHandler());
  });

  app.configure(function(){
    app.set('views', path.join(rootPath, 'views'));
    app.use(express.static(path.join(rootPath, 'public')));
    app.use('/docs', express.static(path.join(rootPath, 'docs')));
    // app.engine('ejs', engine);
    app.set('view engine', 'ejs');
    app.use(express.logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(express.methodOverride());
    app.use(cookieParser());

    // Router needs to be last
    app.use(app.router);
  });
};
<commit_msg>enable proxy knowledge<commit_after>/**
 * config/express.js
 *
 * Defines all express related configurations for the server
 */

'use strict';

var express = require('express');
var path = require('path');
// var jwt = require('express-jwt');
var modelsImport = require('../models/');
var mongoose = require('mongoose');
var cookieParser = require('cookie-parser');
var settings = require('../../settings');
var responseUtils = require('../utils/response');

module.exports = function(app) {
  var rootPath = path.normalize(__dirname + '/../..');

  mongoose.connect(settings.database);

  var Models = modelsImport(mongoose);

  // make models available in req variable
  app.use(function (req, res, next) {
    req.models = Models;
    return next();
  });

  // make error message function available in res variable
  app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');

    res.errorJson = function (err) {
      responseUtils.sendErrorJson(res, err);
    };
    return next();
  });

  app.configure('development', function(){
    app.use(require('connect-livereload')());

    app.use(express.errorHandler());
  });

  app.configure(function(){
    app.set('views', path.join(rootPath, 'views'));
    app.use(express.static(path.join(rootPath, 'public')));
    app.use('/docs', express.static(path.join(rootPath, 'docs')));
    // app.engine('ejs', engine);
    app.set('view engine', 'ejs');
    app.use(express.logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(express.methodOverride());
    app.use(cookieParser());
    app.enable('trust proxy');

    // Router needs to be last
    app.use(app.router);
  });
};
<|endoftext|>


<commit_before>/*global RuleResult, createExecutionContext */

function Rule(spec, parentAudit) {
	/*jshint evil:true */
	/*jshint maxcomplexity:11 */
	'use strict';

	this._audit = parentAudit;

	/**
	 * The code, or string ID of the rule
	 * @type {String}
	 */
	this.id = spec.id;

	/**
	 * Selector that this rule applies to
	 * @type {String}
	 */
	this.selector = spec.selector || '*';

	/**
	 * Whether to exclude hiddden elements form analysis.  Defaults to true.
	 * @type {Boolean}
	 */
	this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;

	/**
	 * Flag to enable or disable rule
	 * @type {Boolean}
	 */
	this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;

	/**
	 * Denotes if the rule should be run if Context is not an entire page AND whether
	 * the Rule should be satisified regardless of Node
	 * @type {Boolean}
	 */
	this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;

	/**
	 * Checks that any may return true to satisfy rule
	 * @type {Array}
	 */
	this.any = spec.any || [];

	/**
	 * Checks that must all return true to satisfy rule
	 * @type {Array}
	 */
	this.all = spec.all || [];

	/**
	 * Checks that none may return true to satisfy rule
	 * @type {Array}
	 */
	this.none = spec.none || [];

	/**
	 * Tags associated to this rule
	 * @type {Array}
	 */
	this.tags = spec.tags || [];

	if (spec.matches) {
		/**
		 * Optional function to test if rule should be run against a node, overrides Rule#matches
		 * @type {Function}
		 */
		this.matches = createExecutionContext(spec.matches);
	}

}

/**
 * Optionally test each node against a `matches` function to determine if the rule should run against
 * a given node.  Defaults to `true`.
 * @return {Boolean}    Whether the rule should run
 */
Rule.prototype.matches = function () {
	'use strict';

	return true;
};

/**
 * Selects `HTMLElement`s based on configured selector
 * @param  {Context} context The resolved Context object
 * @return {Array}           All matching `HTMLElement`s
 */
Rule.prototype.gather = function (context) {
	'use strict';
	var elements = axe.utils.select(this.selector, context);
	if (this.excludeHidden) {
		return elements.filter(function (element) {
			return !axe.utils.isHidden(element);
		});
	}
	return elements;
};

Rule.prototype.runChecks = function (type, node, options, resolve, reject) {
	'use strict';

	var self = this;
	var checkQueue = axe.utils.queue();
	this[type].forEach(function (c) {
		var check = self._audit.checks[c.id || c];
		var option = axe.utils.getCheckOption(check, self.id, options);
		checkQueue.defer(function (res, rej) {
			check.run(node, option, res, rej);
		});
	});

	checkQueue.then(function (results) {
		results = results.filter(function (check) {
			return check;
		});
		resolve({ type: type, results: results });
	}).catch(reject);

};

/**
 * Runs the Rule's `evaluate` function
 * @param  {Context}   context  The resolved Context object
 * @param  {Mixed}   options  Options specific to this rule
 * @param  {Function} callback Function to call when evaluate is complete; receives a RuleResult instance
 */
Rule.prototype.run = function (context, options, resolve, reject) {
	'use strict';

	var nodes = this.gather(context);
	var q = axe.utils.queue();
	var self = this;
	var ruleResult;

	ruleResult = new RuleResult(this);
	nodes.forEach(function (node) {
		if (self.matches(node)) {
			q.defer(function (resolveNode, rejectNode) {
				var checkQueue = axe.utils.queue();
				checkQueue.defer(function (res, rej) {
					self.runChecks('any', node, options, res, rej);
				});
				checkQueue.defer(function (res, rej) {
					self.runChecks('all', node, options, res, rej);
				});
				checkQueue.defer(function (res, rej) {
					self.runChecks('none', node, options, res, rej);
				});

				checkQueue.then(function (results) {
					if (results.length) {
						var hasResults = false,
							result = {
								node: new axe.utils.DqElement(node)
							};
						results.forEach(function (r) {
							var res = r.results.filter(function (result) {
								return result;
							});
							result[r.type] = res;
							if (res.length) {
								hasResults = true;
							}
						});
						if (hasResults) {
							ruleResult.nodes.push(result);
						}
					}
					resolveNode();
				}).catch(rejectNode);

			});
		}
	});

	q.then(function () {
		resolve(ruleResult);
	}).catch(reject);

};

/**
 * Iterates the rule's Checks looking for ones that have an after function
 * @private
 * @param  {Rule} rule The rule to check for after checks
 * @return {Array}      Checks that have an after function
 */
function findAfterChecks(rule) {
	'use strict';

	return axe.utils.getAllChecks(rule).map(function (c) {
		var check = rule._audit.checks[c.id || c];
		return (check && typeof check.after === 'function') ? check : null;
	}).filter(Boolean);
}

/**
 * Finds and collates all results for a given Check on a specific Rule
 * @private
 * @param  {Array} nodes RuleResult#nodes; array of 'detail' objects
 * @param  {String} checkID The ID of the Check to find
 * @return {Array}         Matching CheckResults
 */
function findCheckResults(nodes, checkID) {
	'use strict';

	var checkResults = [];
	nodes.forEach(function (nodeResult) {
		var checks = axe.utils.getAllChecks(nodeResult);
		checks.forEach(function (checkResult) {
			if (checkResult.id === checkID) {
				checkResults.push(checkResult);
			}
		});
	});
	return checkResults;
}

function filterChecks(checks) {
	'use strict';

	return checks.filter(function (check) {
		return check.filtered !== true;
	});
}

function sanitizeNodes(result) {
	'use strict';
	var checkTypes = ['any', 'all', 'none'];

	var nodes = result.nodes.filter(function (detail) {
		var length = 0;
		checkTypes.forEach(function (type) {
			detail[type] = filterChecks(detail[type]);
			length += detail[type].length;
		});
		return length > 0;
	});

	if (result.pageLevel && nodes.length) {
		nodes = [nodes.reduce(function (a, b) {
			if (a) {
				checkTypes.forEach(function (type) {
					a[type].push.apply(a[type], b[type]);
				});
				return a;
			}
		})];
	}
	return nodes;
}

/**
 * Runs all of the Rule's Check#after methods
 * @param  {RuleResult} result  The "pre-after" RuleResult
 * @param  {Mixed} options Options specific to the rule
 * @return {RuleResult}         The RuleResult as filtered by after functions
 */
Rule.prototype.after = function (result, options) {
	'use strict';

	var afterChecks = findAfterChecks(this);
	var ruleID = this.id;
	afterChecks.forEach(function (check) {
		var beforeResults = findCheckResults(result.nodes, check.id);
		var option = axe.utils.getCheckOption(check, ruleID, options);

		var afterResults = check.after(beforeResults, option);
		beforeResults.forEach(function (item) {
			if (afterResults.indexOf(item) === -1) {
				item.filtered = true;
			}
		});
	});

	result.nodes = sanitizeNodes(result);
	return result;
};

/**
 * Reconfigure a rule after it has been added
 * @param {Object} spec - the attributes to be reconfigured
 */
Rule.prototype.configure = function (spec) {
	/*jshint maxcomplexity:14 */
	/*jshint maxstatements:20 */
	/*jshint evil:true */
	'use strict';

	if (spec.hasOwnProperty('selector')) {
		this.selector = spec.selector;
	}

	if (spec.hasOwnProperty('excludeHidden')) {
		this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
	}

	if (spec.hasOwnProperty('enabled')) {
		this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
	}

	if (spec.hasOwnProperty('pageLevel')) {
		this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
	}

	if (spec.hasOwnProperty('any')) {
		this.any = spec.any;
	}

	if (spec.hasOwnProperty('all')) {
		this.all = spec.all;
	}

	if (spec.hasOwnProperty('none')) {
		this.none = spec.none;
	}

	if (spec.hasOwnProperty('tags')) {
		this.tags = spec.tags;
	}

	if (spec.hasOwnProperty('matches')) {
		if (typeof spec.matches === 'string') {
			this.matches = new Function('return ' + spec.matches + ';')();
		} else {
			this.matches = spec.matches;
		}
	}
};
<commit_msg>remove unnecessary jshint directive<commit_after>/*global RuleResult, createExecutionContext */

function Rule(spec, parentAudit) {
	/*jshint maxcomplexity:11 */
	'use strict';

	this._audit = parentAudit;

	/**
	 * The code, or string ID of the rule
	 * @type {String}
	 */
	this.id = spec.id;

	/**
	 * Selector that this rule applies to
	 * @type {String}
	 */
	this.selector = spec.selector || '*';

	/**
	 * Whether to exclude hiddden elements form analysis.  Defaults to true.
	 * @type {Boolean}
	 */
	this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;

	/**
	 * Flag to enable or disable rule
	 * @type {Boolean}
	 */
	this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;

	/**
	 * Denotes if the rule should be run if Context is not an entire page AND whether
	 * the Rule should be satisified regardless of Node
	 * @type {Boolean}
	 */
	this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;

	/**
	 * Checks that any may return true to satisfy rule
	 * @type {Array}
	 */
	this.any = spec.any || [];

	/**
	 * Checks that must all return true to satisfy rule
	 * @type {Array}
	 */
	this.all = spec.all || [];

	/**
	 * Checks that none may return true to satisfy rule
	 * @type {Array}
	 */
	this.none = spec.none || [];

	/**
	 * Tags associated to this rule
	 * @type {Array}
	 */
	this.tags = spec.tags || [];

	if (spec.matches) {
		/**
		 * Optional function to test if rule should be run against a node, overrides Rule#matches
		 * @type {Function}
		 */
		this.matches = createExecutionContext(spec.matches);
	}

}

/**
 * Optionally test each node against a `matches` function to determine if the rule should run against
 * a given node.  Defaults to `true`.
 * @return {Boolean}    Whether the rule should run
 */
Rule.prototype.matches = function () {
	'use strict';

	return true;
};

/**
 * Selects `HTMLElement`s based on configured selector
 * @param  {Context} context The resolved Context object
 * @return {Array}           All matching `HTMLElement`s
 */
Rule.prototype.gather = function (context) {
	'use strict';
	var elements = axe.utils.select(this.selector, context);
	if (this.excludeHidden) {
		return elements.filter(function (element) {
			return !axe.utils.isHidden(element);
		});
	}
	return elements;
};

Rule.prototype.runChecks = function (type, node, options, resolve, reject) {
	'use strict';

	var self = this;
	var checkQueue = axe.utils.queue();
	this[type].forEach(function (c) {
		var check = self._audit.checks[c.id || c];
		var option = axe.utils.getCheckOption(check, self.id, options);
		checkQueue.defer(function (res, rej) {
			check.run(node, option, res, rej);
		});
	});

	checkQueue.then(function (results) {
		results = results.filter(function (check) {
			return check;
		});
		resolve({ type: type, results: results });
	}).catch(reject);

};

/**
 * Runs the Rule's `evaluate` function
 * @param  {Context}   context  The resolved Context object
 * @param  {Mixed}   options  Options specific to this rule
 * @param  {Function} callback Function to call when evaluate is complete; receives a RuleResult instance
 */
Rule.prototype.run = function (context, options, resolve, reject) {
	'use strict';

	var nodes = this.gather(context);
	var q = axe.utils.queue();
	var self = this;
	var ruleResult;

	ruleResult = new RuleResult(this);
	nodes.forEach(function (node) {
		if (self.matches(node)) {
			q.defer(function (resolveNode, rejectNode) {
				var checkQueue = axe.utils.queue();
				checkQueue.defer(function (res, rej) {
					self.runChecks('any', node, options, res, rej);
				});
				checkQueue.defer(function (res, rej) {
					self.runChecks('all', node, options, res, rej);
				});
				checkQueue.defer(function (res, rej) {
					self.runChecks('none', node, options, res, rej);
				});

				checkQueue.then(function (results) {
					if (results.length) {
						var hasResults = false,
							result = {
								node: new axe.utils.DqElement(node)
							};
						results.forEach(function (r) {
							var res = r.results.filter(function (result) {
								return result;
							});
							result[r.type] = res;
							if (res.length) {
								hasResults = true;
							}
						});
						if (hasResults) {
							ruleResult.nodes.push(result);
						}
					}
					resolveNode();
				}).catch(rejectNode);

			});
		}
	});

	q.then(function () {
		resolve(ruleResult);
	}).catch(reject);

};

/**
 * Iterates the rule's Checks looking for ones that have an after function
 * @private
 * @param  {Rule} rule The rule to check for after checks
 * @return {Array}      Checks that have an after function
 */
function findAfterChecks(rule) {
	'use strict';

	return axe.utils.getAllChecks(rule).map(function (c) {
		var check = rule._audit.checks[c.id || c];
		return (check && typeof check.after === 'function') ? check : null;
	}).filter(Boolean);
}

/**
 * Finds and collates all results for a given Check on a specific Rule
 * @private
 * @param  {Array} nodes RuleResult#nodes; array of 'detail' objects
 * @param  {String} checkID The ID of the Check to find
 * @return {Array}         Matching CheckResults
 */
function findCheckResults(nodes, checkID) {
	'use strict';

	var checkResults = [];
	nodes.forEach(function (nodeResult) {
		var checks = axe.utils.getAllChecks(nodeResult);
		checks.forEach(function (checkResult) {
			if (checkResult.id === checkID) {
				checkResults.push(checkResult);
			}
		});
	});
	return checkResults;
}

function filterChecks(checks) {
	'use strict';

	return checks.filter(function (check) {
		return check.filtered !== true;
	});
}

function sanitizeNodes(result) {
	'use strict';
	var checkTypes = ['any', 'all', 'none'];

	var nodes = result.nodes.filter(function (detail) {
		var length = 0;
		checkTypes.forEach(function (type) {
			detail[type] = filterChecks(detail[type]);
			length += detail[type].length;
		});
		return length > 0;
	});

	if (result.pageLevel && nodes.length) {
		nodes = [nodes.reduce(function (a, b) {
			if (a) {
				checkTypes.forEach(function (type) {
					a[type].push.apply(a[type], b[type]);
				});
				return a;
			}
		})];
	}
	return nodes;
}

/**
 * Runs all of the Rule's Check#after methods
 * @param  {RuleResult} result  The "pre-after" RuleResult
 * @param  {Mixed} options Options specific to the rule
 * @return {RuleResult}         The RuleResult as filtered by after functions
 */
Rule.prototype.after = function (result, options) {
	'use strict';

	var afterChecks = findAfterChecks(this);
	var ruleID = this.id;
	afterChecks.forEach(function (check) {
		var beforeResults = findCheckResults(result.nodes, check.id);
		var option = axe.utils.getCheckOption(check, ruleID, options);

		var afterResults = check.after(beforeResults, option);
		beforeResults.forEach(function (item) {
			if (afterResults.indexOf(item) === -1) {
				item.filtered = true;
			}
		});
	});

	result.nodes = sanitizeNodes(result);
	return result;
};

/**
 * Reconfigure a rule after it has been added
 * @param {Object} spec - the attributes to be reconfigured
 */
Rule.prototype.configure = function (spec) {
	/*jshint maxcomplexity:14 */
	/*jshint maxstatements:20 */
	/*jshint evil:true */
	'use strict';

	if (spec.hasOwnProperty('selector')) {
		this.selector = spec.selector;
	}

	if (spec.hasOwnProperty('excludeHidden')) {
		this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
	}

	if (spec.hasOwnProperty('enabled')) {
		this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
	}

	if (spec.hasOwnProperty('pageLevel')) {
		this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
	}

	if (spec.hasOwnProperty('any')) {
		this.any = spec.any;
	}

	if (spec.hasOwnProperty('all')) {
		this.all = spec.all;
	}

	if (spec.hasOwnProperty('none')) {
		this.none = spec.none;
	}

	if (spec.hasOwnProperty('tags')) {
		this.tags = spec.tags;
	}

	if (spec.hasOwnProperty('matches')) {
		if (typeof spec.matches === 'string') {
			this.matches = new Function('return ' + spec.matches + ';')();
		} else {
			this.matches = spec.matches;
		}
	}
};
<|endoftext|>


<commit_before>/*global RuleResult, createExecutionContext, SupportError */

function Rule(spec, parentAudit) {
	/*jshint maxcomplexity:11 */
	'use strict';

	this._audit = parentAudit;

	/**
	 * The code, or string ID of the rule
	 * @type {String}
	 */
	this.id = spec.id;

	/**
	 * Selector that this rule applies to
	 * @type {String}
	 */
	this.selector = spec.selector || '*';

	/**
	 * Whether to exclude hiddden elements form analysis.  Defaults to true.
	 * @type {Boolean}
	 */
	this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;

	/**
	 * Flag to enable or disable rule
	 * @type {Boolean}
	 */
	this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;

	/**
	 * Denotes if the rule should be run if Context is not an entire page AND whether
	 * the Rule should be satisified regardless of Node
	 * @type {Boolean}
	 */
	this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;

	/**
	 * Checks that any may return true to satisfy rule
	 * @type {Array}
	 */
	this.any = spec.any || [];

	/**
	 * Checks that must all return true to satisfy rule
	 * @type {Array}
	 */
	this.all = spec.all || [];

	/**
	 * Checks that none may return true to satisfy rule
	 * @type {Array}
	 */
	this.none = spec.none || [];

	/**
	 * Tags associated to this rule
	 * @type {Array}
	 */
	this.tags = spec.tags || [];

	if (spec.matches) {
		/**
		 * Optional function to test if rule should be run against a node, overrides Rule#matches
		 * @type {Function}
		 */
		this.matches = createExecutionContext(spec.matches);
	}

}

/**
 * Optionally test each node against a `matches` function to determine if the rule should run against
 * a given node.  Defaults to `true`.
 * @return {Boolean}    Whether the rule should run
 */
Rule.prototype.matches = function () {
	'use strict';

	return true;
};

/**
 * Selects `HTMLElement`s based on configured selector
 * @param  {Context} context The resolved Context object
 * @return {Array}           All matching `HTMLElement`s
 */
Rule.prototype.gather = function (context) {
	'use strict';
	var elements = axe.utils.select(this.selector, context);
	if (this.excludeHidden) {
		return elements.filter(function (element) {
			return !axe.utils.isHidden(element);
		});
	}
	return elements;
};

Rule.prototype.runChecks = function (type, node, options, resolve, reject) {
	'use strict';

	var self = this;
	var checkQueue = axe.utils.queue();
	this[type].forEach(function (c) {
		var check = self._audit.checks[c.id || c];
		var option = axe.utils.getCheckOption(check, self.id, options);
		checkQueue.defer(function (res, rej) {
			check.run(node, option, res, rej);
		});
	});

	checkQueue.then(function (results) {
		results = results.filter(function (check) {
			return check;
		});
		resolve({ type: type, results: results });
	}).catch(reject);

};

/**
 * Runs the Rule's `evaluate` function
 * @param  {Context}   context  The resolved Context object
 * @param  {Mixed}   options  Options specific to this rule
 * @param  {Function} callback Function to call when evaluate is complete; receives a RuleResult instance
 */
Rule.prototype.run = function (context, options, resolve, reject) {
	'use strict';

	var nodes = this.gather(context);
	var q = axe.utils.queue();
	var self = this;
	var ruleResult;

	ruleResult = new RuleResult(this);
	// Matches throws an error when it lacks support for document methods
	// Wrapping the entire forEach method helps handle errors with promises in flight
	try {
		nodes.forEach(function (node) {
			if (self.matches(node)) {
				q.defer(function (resolveNode, rejectNode) {
					var checkQueue = axe.utils.queue();
					checkQueue.defer(function (res, rej) {
						self.runChecks('any', node, options, res, rej);
					});
					checkQueue.defer(function (res, rej) {
						self.runChecks('all', node, options, res, rej);
					});
					checkQueue.defer(function (res, rej) {
						self.runChecks('none', node, options, res, rej);
					});

					checkQueue.then(function (results) {
						if (results.length) {
							var hasResults = false,
								result = {
									node: new axe.utils.DqElement(node)
								};
							results.forEach(function (r) {
								var res = r.results.filter(function (result) {
									return result;
								});
								result[r.type] = res;
								if (res.length) {
									hasResults = true;
								}
							});
							if (hasResults) {
								ruleResult.nodes.push(result);
							}
						}
						resolveNode();
					}).catch(rejectNode);

				});
			}
		});

		q.then(function () {
			resolve(ruleResult);
		}).catch(reject);
	}
	catch (error) {
		reject(new SupportError({cause: error, ruleId: self.id}));
	}

};

/**
 * Iterates the rule's Checks looking for ones that have an after function
 * @private
 * @param  {Rule} rule The rule to check for after checks
 * @return {Array}      Checks that have an after function
 */
function findAfterChecks(rule) {
	'use strict';

	return axe.utils.getAllChecks(rule).map(function (c) {
		var check = rule._audit.checks[c.id || c];
		return (check && typeof check.after === 'function') ? check : null;
	}).filter(Boolean);
}

/**
 * Finds and collates all results for a given Check on a specific Rule
 * @private
 * @param  {Array} nodes RuleResult#nodes; array of 'detail' objects
 * @param  {String} checkID The ID of the Check to find
 * @return {Array}         Matching CheckResults
 */
function findCheckResults(nodes, checkID) {
	'use strict';

	var checkResults = [];
	nodes.forEach(function (nodeResult) {
		var checks = axe.utils.getAllChecks(nodeResult);
		checks.forEach(function (checkResult) {
			if (checkResult.id === checkID) {
				checkResults.push(checkResult);
			}
		});
	});
	return checkResults;
}

function filterChecks(checks) {
	'use strict';

	return checks.filter(function (check) {
		return check.filtered !== true;
	});
}

function sanitizeNodes(result) {
	'use strict';
	var checkTypes = ['any', 'all', 'none'];

	var nodes = result.nodes.filter(function (detail) {
		var length = 0;
		checkTypes.forEach(function (type) {
			detail[type] = filterChecks(detail[type]);
			length += detail[type].length;
		});
		return length > 0;
	});

	if (result.pageLevel && nodes.length) {
		nodes = [nodes.reduce(function (a, b) {
			if (a) {
				checkTypes.forEach(function (type) {
					a[type].push.apply(a[type], b[type]);
				});
				return a;
			}
		})];
	}
	return nodes;
}

/**
 * Runs all of the Rule's Check#after methods
 * @param  {RuleResult} result  The "pre-after" RuleResult
 * @param  {Mixed} options Options specific to the rule
 * @return {RuleResult}         The RuleResult as filtered by after functions
 */
Rule.prototype.after = function (result, options) {
	'use strict';

	var afterChecks = findAfterChecks(this);
	var ruleID = this.id;
	afterChecks.forEach(function (check) {
		var beforeResults = findCheckResults(result.nodes, check.id);
		var option = axe.utils.getCheckOption(check, ruleID, options);

		var afterResults = check.after(beforeResults, option);
		beforeResults.forEach(function (item) {
			if (afterResults.indexOf(item) === -1) {
				item.filtered = true;
			}
		});
	});

	result.nodes = sanitizeNodes(result);
	return result;
};

/**
 * Reconfigure a rule after it has been added
 * @param {Object} spec - the attributes to be reconfigured
 */
Rule.prototype.configure = function (spec) {
	/*jshint maxcomplexity:14 */
	/*jshint maxstatements:20 */
	/*jshint evil:true */
	'use strict';

	if (spec.hasOwnProperty('selector')) {
		this.selector = spec.selector;
	}

	if (spec.hasOwnProperty('excludeHidden')) {
		this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
	}

	if (spec.hasOwnProperty('enabled')) {
		this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
	}

	if (spec.hasOwnProperty('pageLevel')) {
		this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
	}

	if (spec.hasOwnProperty('any')) {
		this.any = spec.any;
	}

	if (spec.hasOwnProperty('all')) {
		this.all = spec.all;
	}

	if (spec.hasOwnProperty('none')) {
		this.none = spec.none;
	}

	if (spec.hasOwnProperty('tags')) {
		this.tags = spec.tags;
	}

	if (spec.hasOwnProperty('matches')) {
		if (typeof spec.matches === 'string') {
			this.matches = new Function('return ' + spec.matches + ';')();
		} else {
			this.matches = spec.matches;
		}
	}
};
<commit_msg>Refactor rule.run<commit_after>/*global RuleResult, createExecutionContext, SupportError */

function Rule(spec, parentAudit) {
	/*jshint maxcomplexity:11 */
	'use strict';

	this._audit = parentAudit;

	/**
	 * The code, or string ID of the rule
	 * @type {String}
	 */
	this.id = spec.id;

	/**
	 * Selector that this rule applies to
	 * @type {String}
	 */
	this.selector = spec.selector || '*';

	/**
	 * Whether to exclude hiddden elements form analysis.  Defaults to true.
	 * @type {Boolean}
	 */
	this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;

	/**
	 * Flag to enable or disable rule
	 * @type {Boolean}
	 */
	this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;

	/**
	 * Denotes if the rule should be run if Context is not an entire page AND whether
	 * the Rule should be satisified regardless of Node
	 * @type {Boolean}
	 */
	this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;

	/**
	 * Checks that any may return true to satisfy rule
	 * @type {Array}
	 */
	this.any = spec.any || [];

	/**
	 * Checks that must all return true to satisfy rule
	 * @type {Array}
	 */
	this.all = spec.all || [];

	/**
	 * Checks that none may return true to satisfy rule
	 * @type {Array}
	 */
	this.none = spec.none || [];

	/**
	 * Tags associated to this rule
	 * @type {Array}
	 */
	this.tags = spec.tags || [];

	if (spec.matches) {
		/**
		 * Optional function to test if rule should be run against a node, overrides Rule#matches
		 * @type {Function}
		 */
		this.matches = createExecutionContext(spec.matches);
	}

}

/**
 * Optionally test each node against a `matches` function to determine if the rule should run against
 * a given node.  Defaults to `true`.
 * @return {Boolean}    Whether the rule should run
 */
Rule.prototype.matches = function () {
	'use strict';

	return true;
};

/**
 * Selects `HTMLElement`s based on configured selector
 * @param  {Context} context The resolved Context object
 * @return {Array}           All matching `HTMLElement`s
 */
Rule.prototype.gather = function (context) {
	'use strict';
	var elements = axe.utils.select(this.selector, context);
	if (this.excludeHidden) {
		return elements.filter(function (element) {
			return !axe.utils.isHidden(element);
		});
	}
	return elements;
};

Rule.prototype.runChecks = function (type, node, options, resolve, reject) {
	'use strict';

	var self = this;
	var checkQueue = axe.utils.queue();
	this[type].forEach(function (c) {
		var check = self._audit.checks[c.id || c];
		var option = axe.utils.getCheckOption(check, self.id, options);
		checkQueue.defer(function (res, rej) {
			check.run(node, option, res, rej);
		});
	});

	checkQueue.then(function (results) {
		results = results.filter(function (check) {
			return check;
		});
		resolve({ type: type, results: results });
	}).catch(reject);

};

/**
 * Runs the Rule's `evaluate` function
 * @param  {Context}   context  The resolved Context object
 * @param  {Mixed}   options  Options specific to this rule
 * @param  {Function} callback Function to call when evaluate is complete; receives a RuleResult instance
 */
Rule.prototype.run = function (context, options, resolve, reject) {
	const q = axe.utils.queue();
	const ruleResult = new RuleResult(this);
	let nodes;

	try {
		// Matches throws an error when it lacks support for document methods
		nodes = this.gather(context)
		.filter(node => this.matches(node));
	} catch (error) {
		// Exit the rule execution if matches fails
		reject(new SupportError({cause: error, ruleId: this.id}));
		return;
	}

	nodes.forEach(node => {
		q.defer((resolveNode, rejectNode) => {
			var checkQueue = axe.utils.queue();
			checkQueue.defer((res, rej) => {
				this.runChecks('any', node, options, res, rej);
			});
			checkQueue.defer((res, rej) => {
				this.runChecks('all', node, options, res, rej);
			});
			checkQueue.defer((res, rej) => {
				this.runChecks('none', node, options, res, rej);
			});

			checkQueue.then((results) => {
				if (results.length) {
					var hasResults = false,
						result = {
							node: new axe.utils.DqElement(node)
						};
					results.forEach(r => {
						var res = r.results.filter(result => !! result);
						result[r.type] = res;
						if (res.length) {
							hasResults = true;
						}
					});
					if (hasResults) {
						ruleResult.nodes.push(result);
					}
				}
				resolveNode();
			}).catch(err => rejectNode(err));
		});
	});

	q.then(() => resolve(ruleResult))
	.catch(error => reject(error));
};

/**
 * Iterates the rule's Checks looking for ones that have an after function
 * @private
 * @param  {Rule} rule The rule to check for after checks
 * @return {Array}      Checks that have an after function
 */
function findAfterChecks(rule) {
	'use strict';

	return axe.utils.getAllChecks(rule).map(function (c) {
		var check = rule._audit.checks[c.id || c];
		return (check && typeof check.after === 'function') ? check : null;
	}).filter(Boolean);
}

/**
 * Finds and collates all results for a given Check on a specific Rule
 * @private
 * @param  {Array} nodes RuleResult#nodes; array of 'detail' objects
 * @param  {String} checkID The ID of the Check to find
 * @return {Array}         Matching CheckResults
 */
function findCheckResults(nodes, checkID) {
	'use strict';

	var checkResults = [];
	nodes.forEach(function (nodeResult) {
		var checks = axe.utils.getAllChecks(nodeResult);
		checks.forEach(function (checkResult) {
			if (checkResult.id === checkID) {
				checkResults.push(checkResult);
			}
		});
	});
	return checkResults;
}

function filterChecks(checks) {
	'use strict';

	return checks.filter(function (check) {
		return check.filtered !== true;
	});
}

function sanitizeNodes(result) {
	'use strict';
	var checkTypes = ['any', 'all', 'none'];

	var nodes = result.nodes.filter(function (detail) {
		var length = 0;
		checkTypes.forEach(function (type) {
			detail[type] = filterChecks(detail[type]);
			length += detail[type].length;
		});
		return length > 0;
	});

	if (result.pageLevel && nodes.length) {
		nodes = [nodes.reduce(function (a, b) {
			if (a) {
				checkTypes.forEach(function (type) {
					a[type].push.apply(a[type], b[type]);
				});
				return a;
			}
		})];
	}
	return nodes;
}

/**
 * Runs all of the Rule's Check#after methods
 * @param  {RuleResult} result  The "pre-after" RuleResult
 * @param  {Mixed} options Options specific to the rule
 * @return {RuleResult}         The RuleResult as filtered by after functions
 */
Rule.prototype.after = function (result, options) {
	'use strict';

	var afterChecks = findAfterChecks(this);
	var ruleID = this.id;
	afterChecks.forEach(function (check) {
		var beforeResults = findCheckResults(result.nodes, check.id);
		var option = axe.utils.getCheckOption(check, ruleID, options);

		var afterResults = check.after(beforeResults, option);
		beforeResults.forEach(function (item) {
			if (afterResults.indexOf(item) === -1) {
				item.filtered = true;
			}
		});
	});

	result.nodes = sanitizeNodes(result);
	return result;
};

/**
 * Reconfigure a rule after it has been added
 * @param {Object} spec - the attributes to be reconfigured
 */
Rule.prototype.configure = function (spec) {
	/*jshint maxcomplexity:14 */
	/*jshint maxstatements:20 */
	/*jshint evil:true */
	'use strict';

	if (spec.hasOwnProperty('selector')) {
		this.selector = spec.selector;
	}

	if (spec.hasOwnProperty('excludeHidden')) {
		this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
	}

	if (spec.hasOwnProperty('enabled')) {
		this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
	}

	if (spec.hasOwnProperty('pageLevel')) {
		this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
	}

	if (spec.hasOwnProperty('any')) {
		this.any = spec.any;
	}

	if (spec.hasOwnProperty('all')) {
		this.all = spec.all;
	}

	if (spec.hasOwnProperty('none')) {
		this.none = spec.none;
	}

	if (spec.hasOwnProperty('tags')) {
		this.tags = spec.tags;
	}

	if (spec.hasOwnProperty('matches')) {
		if (typeof spec.matches === 'string') {
			this.matches = new Function('return ' + spec.matches + ';')();
		} else {
			this.matches = spec.matches;
		}
	}
};
<|endoftext|>


<commit_before>var stream = require('stream');
var util = require('util');
var sun_calc = require('suncalc');

util.inherits(counter_device,stream);

module.exports=counter_device;

function diff(from, to){
    return (to.getHours() - from.getHours()) * 60 + to.getMinutes() - from.getMinutes();
}

function counter_device(opts, app, sd) {
    var self = this;

    this.readable = true;
    this.writeable = false;

    this.G = "daylightXChangeTimer";
    this.V = 0;
    this.D = 9001;
    this.name = "Daylight change timer"

    process.nextTick(function() {
        setInterval(function() {
            var longitude = parseFloat(opts.longitude);
            var latitude = parseFloat(opts.latitude);

            var now = new Date();
            var tomorrow = new Date();
            tomorrow.setDate(now.getDate() + 1);

            var times = sun_calc.getTimes(now, latitude, longitude);
            var times_tomorrow = sun_calc.getTimes(tomorrow, latitude, longitude);

            var sunrise_today = times.sunriseEnd;
            var sunset_today = times.sunsetStart;
            var sunrise_tomorrow = times_tomorrow.sunriseEnd;

            if(now <= sunrise_today){
                self.emit('data', diff(now, sunrise_today));
                sd.emit('data', 'night');
            } else if(now >= sunrise_today && now <= sunset_today){
                self.emit('data', diff(now, sunset_today));
                sd.emit('data', 'day');
            } else {
                self.emit('data', diff(now, sunrise_tomorrow));
                sd.emit('data', 'night');
            }

        }, 5000);
    });
};
<commit_msg>Change frequency<commit_after>var stream = require('stream');
var util = require('util');
var sun_calc = require('suncalc');

util.inherits(counter_device,stream);

module.exports=counter_device;

function diff(from, to){
    return (to.getHours() - from.getHours()) * 60 + to.getMinutes() - from.getMinutes();
}

function counter_device(opts, app, sd) {
    var self = this;

    this.readable = true;
    this.writeable = false;

    this.G = "daylightXChangeTimer";
    this.V = 0;
    this.D = 9001;
    this.name = "Daylight change timer"

    process.nextTick(function() {
        setInterval(function() {
            var longitude = parseFloat(opts.longitude);
            var latitude = parseFloat(opts.latitude);

            var now = new Date();
            var tomorrow = new Date();
            tomorrow.setDate(now.getDate() + 1);

            var times = sun_calc.getTimes(now, latitude, longitude);
            var times_tomorrow = sun_calc.getTimes(tomorrow, latitude, longitude);

            var sunrise_today = times.sunriseEnd;
            var sunset_today = times.sunsetStart;
            var sunrise_tomorrow = times_tomorrow.sunriseEnd;

            if(now <= sunrise_today){
                self.emit('data', diff(now, sunrise_today));
                sd.emit('data', 'night');
            } else if(now >= sunrise_today && now <= sunset_today){
                self.emit('data', diff(now, sunset_today));
                sd.emit('data', 'day');
            } else {
                self.emit('data', diff(now, sunrise_tomorrow));
                sd.emit('data', 'night');
            }

        }, 60000);
    });
};
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const fs = require('graceful-fs');
const loadPackageProp = require('./loadPackageProp');
const loadRc = require('./loadRc');
const loadJs = require('./loadJs');
const loadDefinedFile = require('./loadDefinedFile');

module.exports = function (options) {
  // These cache Promises that resolve with results, not the results themselves
  const fileCache = (options.cache) ? new Map() : null;
  const directoryCache = (options.cache) ? new Map() : null;
  const transform = options.transform || identityPromise;

  function clearFileCache() {
    if (fileCache) fileCache.clear();
  }

  function clearDirectoryCache() {
    if (directoryCache) directoryCache.clear();
  }

  function clearCaches() {
    clearFileCache();
    clearDirectoryCache();
  }

  function load(searchPath, configPath) {
    if (configPath) {
      const absoluteConfigPath = path.resolve(process.cwd(), configPath);
      if (fileCache && fileCache.has(absoluteConfigPath)) {
        return fileCache.get(absoluteConfigPath);
      }
      const result = loadDefinedFile(absoluteConfigPath, options)
        .then(transform);
      if (fileCache) fileCache.set(absoluteConfigPath, result);
      return result;
    }

    if (!searchPath) return Promise.resolve(null);

    const absoluteSearchPath = path.resolve(process.cwd(), searchPath);

    return isDirectory(absoluteSearchPath)
      .then((searchPathIsDirectory) => {
        const directory = (searchPathIsDirectory)
          ? absoluteSearchPath
          : path.dirname(absoluteSearchPath);
        return searchDirectory(directory);
      });
  }

  function searchDirectory(directory, splitSearchPath) {
    if (directoryCache && directoryCache.has(directory)) {
      return directoryCache.get(directory);
    }

    const result = Promise.resolve()
      .then(() => {
        if (!options.packageProp) return;
        return loadPackageProp(directory, options);
      })
      .then((result) => {
        if (result || !options.rc) return result;
        return loadRc(path.join(directory, options.rc), options);
      })
      .then((result) => {
        if (result || !options.js) return result;
        return loadJs(path.join(directory, options.js));
      })
      .then((result) => {
        if (result) return result;
        if (!splitSearchPath) splitSearchPath = directory.split(path.sep);
        if (splitSearchPath.length <= 1 || directory === options.stopDir) return null;
        splitSearchPath.pop();
        return searchDirectory(splitSearchPath.join(path.sep), splitSearchPath);
      })
      .then(transform);

    if (directoryCache) directoryCache.set(directory, result);
    return result;
  }

  return {
    load,
    clearFileCache,
    clearDirectoryCache,
    clearCaches,
  };
};

function isDirectory(filepath) {
  return new Promise((resolve, reject) => {
    fs.stat(filepath, (err, stats) => {
      if (err) return reject(err);
      return resolve(stats.isDirectory());
    });
  });
}

function identityPromise(x) {
  return Promise.resolve(x);
}
<commit_msg>Improve readability<commit_after>'use strict';

const path = require('path');
const fs = require('graceful-fs');
const loadPackageProp = require('./loadPackageProp');
const loadRc = require('./loadRc');
const loadJs = require('./loadJs');
const loadDefinedFile = require('./loadDefinedFile');

module.exports = function (options) {
  // These cache Promises that resolve with results, not the results themselves
  const fileCache = (options.cache) ? new Map() : null;
  const directoryCache = (options.cache) ? new Map() : null;
  const transform = options.transform || identityPromise;

  function clearFileCache() {
    if (fileCache) fileCache.clear();
  }

  function clearDirectoryCache() {
    if (directoryCache) directoryCache.clear();
  }

  function clearCaches() {
    clearFileCache();
    clearDirectoryCache();
  }

  function load(searchPath, configPath) {
    if (configPath) {
      const absoluteConfigPath = path.resolve(process.cwd(), configPath);
      if (fileCache && fileCache.has(absoluteConfigPath)) {
        return fileCache.get(absoluteConfigPath);
      }
      const result = loadDefinedFile(absoluteConfigPath, options)
        .then(transform);
      if (fileCache) fileCache.set(absoluteConfigPath, result);
      return result;
    }

    if (!searchPath) return Promise.resolve(null);

    const absoluteSearchPath = path.resolve(process.cwd(), searchPath);

    return isDirectory(absoluteSearchPath)
      .then((searchPathIsDirectory) => {
        const directory = (searchPathIsDirectory)
          ? absoluteSearchPath
          : path.dirname(absoluteSearchPath);
        return searchDirectory(directory);
      });
  }

  function searchDirectory(directory, splitSearchPath) {
    if (directoryCache && directoryCache.has(directory)) {
      return directoryCache.get(directory);
    }

    const result = Promise.resolve()
      .then(() => {
        if (!options.packageProp) return;
        return loadPackageProp(directory, options);
      })
      .then((result) => {
        if (result || !options.rc) return result;
        return loadRc(path.join(directory, options.rc), options);
      })
      .then((result) => {
        if (result || !options.js) return result;
        return loadJs(path.join(directory, options.js));
      })
      .then((result) => {
        if (result) return result;

        const nextDirectory = (function () {
          if (!splitSearchPath) splitSearchPath = directory.split(path.sep);
          if (splitSearchPath.length > 1) {
            splitSearchPath.pop();
            return splitSearchPath.join(path.sep);
          }
        })();

        if (!nextDirectory || directory === options.stopDir) return null;

        return searchDirectory(nextDirectory, splitSearchPath);
      })
      .then(transform);

    if (directoryCache) directoryCache.set(directory, result);
    return result;
  }

  return {
    load,
    clearFileCache,
    clearDirectoryCache,
    clearCaches,
  };
};

function isDirectory(filepath) {
  return new Promise((resolve, reject) => {
    fs.stat(filepath, (err, stats) => {
      if (err) return reject(err);
      return resolve(stats.isDirectory());
    });
  });
}

function identityPromise(x) {
  return Promise.resolve(x);
}
<|endoftext|>


<commit_before>var _ = require("underscore")._;

function testPartition(classifierConst, opts, trainOpts, trainSet, testSet) {
  var classifier = new classifierConst(opts);

  var beginTrain = Date.now();

  var trainingStats = classifier.train(trainSet, trainOpts);

  var beginTest = Date.now();

  var testStats = classifier.test(testSet);

  var endTest = Date.now();

  var stats = _(testStats).extend({
    trainTime : beginTest - beginTrain,
    testTime : endTest - beginTest,
    iterations: trainingStats.iterations,
    trainError: trainingStats.error,
    learningRate: classifier.learningRate,
    hidden: classifier.hiddenSizes
  });
  return stats;
}

module.exports = function crossValidate(classifierConst, data, opts, trainOpts, k) {
  k = k || 4;
  var size = data.length / k;

  data = _(data).sortBy(function() {
    return Math.random();
  });

  var avgs = {
    error : 0,
    trainTime : 0,
    testTime : 0,
    iterations: 0,
    trainError: 0
  };

  var stats = {
    truePos: 0,
    trueNeg: 0,
    falsePos: 0,
    falseNeg: 0,
    total: 0
  };

  var misclasses = [];

  var results = _.range(k).map(function(i) {
    var dclone = _(data).clone();
    var testSet = dclone.splice(i * size, size);
    var trainSet = dclone;

    var result = testPartition(classifierConst, opts, trainOpts, trainSet, testSet);

    _(avgs).each(function(sum, stat) {
      avgs[stat] = sum + result[stat];
    });

    _(stats).each(function(sum, stat) {
      stats[stat] = sum + result[stat];
    })

    misclasses.push(result.misclasses);
  });

  _(avgs).each(function(sum, i) {
    avgs[i] = sum / k;
  });

  stats.precision = stats.truePos / (stats.truePos + stats.falsePos);
  stats.recall = stats.truePos / (stats.truePos + stats.falseNeg);
  stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total;

  stats.testSize = size;
  stats.trainSize = data.length - size;

  return {
    avgs: avgs,
    stats: stats,
    misclasses: _(misclasses).flatten()
  };
}<commit_msg>add network and indivdual set results to cross-validation stats<commit_after>var _ = require("underscore")._;

function testPartition(classifierConst, opts, trainOpts, trainSet, testSet) {
  var classifier = new classifierConst(opts);

  var beginTrain = Date.now();

  var trainingStats = classifier.train(trainSet, trainOpts);

  var beginTest = Date.now();

  var testStats = classifier.test(testSet);

  var endTest = Date.now();

  var stats = _(testStats).extend({
    trainTime : beginTest - beginTrain,
    testTime : endTest - beginTest,
    iterations: trainingStats.iterations,
    trainError: trainingStats.error,
    learningRate: classifier.learningRate,
    hidden: classifier.hiddenSizes,
    network: classifier.toJSON()
  });

  return stats;
}

module.exports = function crossValidate(classifierConst, data, opts, trainOpts, k) {
  k = k || 4;
  var size = data.length / k;

  data = _(data).sortBy(function() {
    return Math.random();
  });

  var avgs = {
    error : 0,
    trainTime : 0,
    testTime : 0,
    iterations: 0,
    trainError: 0
  };

  var stats = {
    truePos: 0,
    trueNeg: 0,
    falsePos: 0,
    falseNeg: 0,
    total: 0
  };

  var misclasses = [];

  var results = _.range(k).map(function(i) {
    var dclone = _(data).clone();
    var testSet = dclone.splice(i * size, size);
    var trainSet = dclone;

    var result = testPartition(classifierConst, opts, trainOpts, trainSet, testSet);

    _(avgs).each(function(sum, stat) {
      avgs[stat] = sum + result[stat];
    });

    _(stats).each(function(sum, stat) {
      stats[stat] = sum + result[stat];
    })

    misclasses.push(result.misclasses);

    return result;
  });

  _(avgs).each(function(sum, i) {
    avgs[i] = sum / k;
  });

  stats.precision = stats.truePos / (stats.truePos + stats.falsePos);
  stats.recall = stats.truePos / (stats.truePos + stats.falseNeg);
  stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total;

  stats.testSize = size;
  stats.trainSize = data.length - size;

  return {
    avgs: avgs,
    stats: stats,
    sets: results,
    misclasses: _(misclasses).flatten()
  };
}<|endoftext|>


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

module.exports = function () {
    var line = '';
    var stream = through(write, flush);
    return stream;

    function write (buf) {
        for (var i = 0; i < buf.length; i++) {
            var c = typeof buf === 'string'
                ? buf.charAt(i)
                : String.fromCharCode(buf[i])
            ;
            if (c === '\n') flush();
            else line += c;
        }
    }

    function flush () {
        try { fs.writeSync(1, line + '\n'); }
        catch (e) { stream.emit('error', e) }
        line = '';
    }
};
<commit_msg>formatting<commit_after>var through = require('through');
var fs = require('fs');

module.exports = function () {
    var line = '';
    var stream = through(write, flush);
    return stream;

    function write (buf) {
        for (var i = 0; i < buf.length; i++) {
            var c = typeof buf === 'string'
                ? buf.charAt(i)
                : String.fromCharCode(buf[i])
            ;
            if (c === '\n') flush();
            else line += c;
        }
    }

    function flush () {
        try { fs.writeSync(1, line + '\n'); }
        catch (e) { stream.emit('error', e) }
        line = '';
    }
};
<|endoftext|>


<commit_before>const path = require('path')
const fs = require('fs')

const { readFile } = require('./fs.utils')
const { log } = require('./log.utils')

module.exports = exports = configFilename => {
  return (modules, options) => {
    readFile(configFilename)
      .then(data => JSON.parse(data).folder_path)
      .then(processModuleData(modules))
      .then(data => console.log(JSON.stringify(data, null, 2)))
  }
}

function processModuleData(moduleNames) {
  return folderPath => {
    return moduleNames
      .map(name => {
        const addr = path.join(folderPath, 'files', name)
        const file = fs.readFileSync(path.join(addr, 'settings.json'))

        let settings = []
        try {
          settings = JSON.parse(file)
        } catch(e) {
          log({ type: 'warn', message: `Not able to load settings file for "${name}" module.` })
        }

        return { name, folder: addr, settings }
      })
      .filter(moduleConf => moduleConf.settings.length > 0)
  }
}
<commit_msg>Format data<commit_after>const path = require('path')
const fs = require('fs')

const { readFile } = require('./fs.utils')
const { log } = require('./log.utils')

module.exports = exports = configFilename => {
  return (modules, options) => {
    readFile(configFilename)
      .then(data => JSON.parse(data).folder_path)
      .then(processModuleData(modules))
      .then(data => console.log(JSON.stringify(data, null, 2)))
  }
}

function processModuleData(moduleNames) {
  return folderPath => {
    return moduleNames
      .map(name => {
        const addr = path.join(folderPath, 'files', name)
        const file = fs.readFileSync(path.join(addr, 'settings.json'))

        let settings = []
        try {
          settings = JSON.parse(file)
        } catch(e) {
          log({ type: 'warn', message: `Not able to load settings file for "${name}" module.` })
        }

        return { name, folder: addr, settings }
      })
      .filter(moduleConf => moduleConf.settings.length > 0)
      .map(moduleConf => {
        return moduleConf.settings
          .filter(file => file.global)
          .map(file => ({
            from: path.resolve(moduleConf.folder, file.filename),
            to: path.resolve(file['target-path'].replace('~', process.env.HOME))
          }))
      })
      .reduce((files, modules) => {
        for (const file of modules) {
          files.push(file)
        }

        return files
      }, [])
  }
}
<|endoftext|>


<commit_before>/*
 * Synchronizer.js
 * Fabian Irsara
 * Copyright 2015, Licensed GPL & MIT
 */
define([
  '../sys',
  'EaselJS',
  './fs'
], function(
  sys,
  createjs,
  fs
) {
  var PROGRESS = 'progress';
  var SUCCESS = 'success';
  var ERROR = 'error';

  /**
   * Synchronizer synchronizes data from a server to the local filesystem. dispatches progress event
   *
   * @example
   * // keep data structure
   * var _syncer = new Synchronizer();
   * _syncer.remote = 'http://myremote.com/data/';
   * _syncer.local = '/Users/me/data/folder/';
   * _syncer.items = ['index.html', 'data/image.jpg'];
   * _syncer.start();
   *
   * @example
   * // custom structure
   * var _syncer = new Synchronizer();
   * _syncer.items = [{remote: 'http://myremote.com/data/index.html', local: '/Users/me/data/folder/index.html'}]
   * _syncer.start();
   *
   * @class Synchronizer
   * @memberof data
   **/
  function Synchronizer(){
    createjs.EventDispatcher.call(this);

    /**
     * Wheter items that should be synced should be overwritten if already existing on local fs
     * @memberof data.Synchronizer
     * @instance
     * @var {Boolean} overwrite
     */
    this.overwrite = false;

    /**
     * remote base path of items that should be synced

     * i.e. when setting a list of items with a relative path, remote path will be prepended
     * @memberof data.Synchronizer
     * @instance
     * @var {String} remote
     */
    this.remote = '';

    /**
     * local base path where items should be stored

     * i.e. 'storage/my/data/'
     * @memberof data.Synchronizer
     * @instance
     * @var {String} local
     */
    this.local = '';

    /**
     * if set to true cleans up defined local base folder (deletes items on local filesystem that were not defined on remote file list)

     * if it's a string cleans up defined folder instead.
     * i.e. 'storage/my/data/'
     * @memberof data.Synchronizer
     * @instance
     * @var {String|Boolean} cleanup
     */
    this.cleanup = false;

    /**
     * that should be synched

     * if a local base path was defined via this.local = 'my/path': keeps folder structure on local filesystem

     * i.e. ['item1.jpg', 'item2.jpg', ...]
     * @memberof data.Synchronizer
     * @instance
     * @var {Array} items
     */
    this.items = [];

    /**
     * success callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} success
     */
    this.success = null;

    /**
     * progress callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} progress
     */
    this.progress = null;

    /**
     * error callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} error
     */
    this.error = null;

    this._stopped = false;
    this._index = 0;
    this._storedFiles = [];
  }

  var p = sys.extend(Synchronizer, createjs.EventDispatcher);

  /**
   * initializes syncing
   * @method start
   * @memberof data.Synchronizer
   * @instance
   */
  p.start = function(){
    this._index = 0;
    this.resume();
  };

  /**
   * resumes syncing
   * @method resume
   * @memberof data.Synchronizer
   * @instance
   */
  p.resume = function(){
    this._stopped = false;
    _next.call(this);
  };

  /**
   * pauses syncing, can be resumed later on
   * @method pause
   * @memberof data.Synchronizer
   * @instance
   */
  p.pause = function(){
    this._stopped = true;
  };

  /**
   * stops syncing, resets sync index
   * @method stop
   * @memberof data.Synchronizer
   * @instance
   */
  p.stop = function(){
    this.pause();
  };

  var _next = function(){
    if (this._stopped) return;

    // get current item
    var currentItem = this.items[this._index];

    // if still has items
    if (currentItem) {
      // get that item
      _get.call(this, currentItem);
    } else {
      // otherwise: dispatch done
      _done.call(this);
    }
  };

  var _get = function(item) {
    var _this = this;

    // if current item was a string: assume remote and local path should be the same
    if (typeof item === 'string') item = {remote: item, local: item};

    // if current item was an object but has no local filepath set: set it to ''
    if (! item.local) item.local = '';

    // define download options
    var options = {};

    // if current item has an overwrite option
    if (! (item.overwrite === null || typeof item.overwrite === 'undefined')) {
      // use that definition
      options.overwrite = item.overwrite;
    } else {
      // otherwise use defined overwrite option in Synchronizer
      options.overwrite = _this.overwrite;
    }

    options.remote = _this.remote + item.remote;
    options.local = _this.local + item.local;

    // calculate current item progress
    options.progress = function(p){
      // call progress event
      _progress.call(_this, (_this._index + p) / _this.items.length);
    };

    options.error = function(err){
      _error.call(_this, err);
    };

    options.success = function(filePath){
      // increment index when finished downloading
      _this._index++;

      // store all downloaded files in an array for later use
      var filename = fs.correctLocalFilePath(filePath);
      if (_this._storedFiles.indexOf(filename) === -1) _this._storedFiles.push(filename);

      var dirname = filename;

      // store up to 10 folders backwards
      // i.e. if there are nested empty folders they will not be recognized
      for (var i = 0; i < 10; i++) {
        dirname = fs.getFolder(dirname);
        if (dirname + '/' === fs.dataPath) break;
        if (_this._storedFiles.indexOf(dirname) === -1) _this._storedFiles.push(dirname);
      }

      // call progress event
      _progress.call(_this, _this._index / _this.items.length);

      // and sync next item
      _next.call(_this);
    };

    // download current item
    fs.download(options);
  };

  var _done = function(){
    // if sync should cleanup a directory
    if (this.cleanup) {
      // get cleanup folder, assume it's the local base path folder
      var cleanup = this.local;

      // if cleanup was a string
      if (typeof this.cleanup === 'string') {
        // use that folder instead
        cleanup = this.cleanup;
      }

      _cleanup.call(this, cleanup, true);
    } else {
      // finished downloading
      _success.call(this);
    }
  };

  var _cleanup = function(folder, callCallback){
    var _this = this;

    // get all local files in that directory
    fs.readdir(folder, function(localFiles){
      // loop through local found files
      for (var i = 0, _len = localFiles.length; i < _len; i++) {
        // if it is a folder
        if (localFiles[i].indexOf('.') === -1) {
          // clean the subfolder
          _cleanup.call(_this, folder + localFiles[i] + '/');
        }

        // if local file was not in download list
        if (_this._storedFiles.indexOf(fs.correctLocalFilePath(folder + localFiles[i])) === -1) {
          // remove it as it should not be used anymore
          fs.unlink(folder + localFiles[i]);
        }
      }

      if (callCallback) {
        // finished syncing
        _success.call(_this);
      }
    });
  };

  var _progress = function(p) {
    if (this.progress) {
      this.progress(p);
    }

    var event = new createjs.Event(PROGRESS);
    event.progress = p;
    this.dispatchEvent(event);
  };

  var _error = function(err) {
    if (this.error) {
      this.error(err);
    }

    var event = new createjs.Event(ERROR);
    event.error = err;
    this.dispatchEvent(event);
  };

  var _success = function(){
    if (this.success) {
      this.success();
    }

    var event = new createjs.Event(SUCCESS);
    this.dispatchEvent(event);
  };

  return Synchronizer;
});
<commit_msg>adjust cleanup folder check<commit_after>/*
 * Synchronizer.js
 * Fabian Irsara
 * Copyright 2015, Licensed GPL & MIT
 */
define([
  '../sys',
  'EaselJS',
  './fs'
], function(
  sys,
  createjs,
  fs
) {
  var PROGRESS = 'progress';
  var SUCCESS = 'success';
  var ERROR = 'error';

  /**
   * Synchronizer synchronizes data from a server to the local filesystem. dispatches progress event
   *
   * @example
   * // keep data structure
   * var _syncer = new Synchronizer();
   * _syncer.remote = 'http://myremote.com/data/';
   * _syncer.local = '/Users/me/data/folder/';
   * _syncer.items = ['index.html', 'data/image.jpg'];
   * _syncer.start();
   *
   * @example
   * // custom structure
   * var _syncer = new Synchronizer();
   * _syncer.items = [{remote: 'http://myremote.com/data/index.html', local: '/Users/me/data/folder/index.html'}]
   * _syncer.start();
   *
   * @class Synchronizer
   * @memberof data
   **/
  function Synchronizer(){
    createjs.EventDispatcher.call(this);

    /**
     * Wheter items that should be synced should be overwritten if already existing on local fs
     * @memberof data.Synchronizer
     * @instance
     * @var {Boolean} overwrite
     */
    this.overwrite = false;

    /**
     * remote base path of items that should be synced

     * i.e. when setting a list of items with a relative path, remote path will be prepended
     * @memberof data.Synchronizer
     * @instance
     * @var {String} remote
     */
    this.remote = '';

    /**
     * local base path where items should be stored

     * i.e. 'storage/my/data/'
     * @memberof data.Synchronizer
     * @instance
     * @var {String} local
     */
    this.local = '';

    /**
     * if set to true cleans up defined local base folder (deletes items on local filesystem that were not defined on remote file list)

     * if it's a string cleans up defined folder instead.
     * i.e. 'storage/my/data/'
     * @memberof data.Synchronizer
     * @instance
     * @var {String|Boolean} cleanup
     */
    this.cleanup = false;

    /**
     * that should be synched

     * if a local base path was defined via this.local = 'my/path': keeps folder structure on local filesystem

     * i.e. ['item1.jpg', 'item2.jpg', ...]
     * @memberof data.Synchronizer
     * @instance
     * @var {Array} items
     */
    this.items = [];

    /**
     * success callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} success
     */
    this.success = null;

    /**
     * progress callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} progress
     */
    this.progress = null;

    /**
     * error callback function. alternative to event listeners
     * @memberof data.Synchronizer
     * @instance
     * @var {Function} error
     */
    this.error = null;

    this._stopped = false;
    this._index = 0;
    this._storedFiles = [];
  }

  var p = sys.extend(Synchronizer, createjs.EventDispatcher);

  /**
   * initializes syncing
   * @method start
   * @memberof data.Synchronizer
   * @instance
   */
  p.start = function(){
    this._index = 0;
    this.resume();
  };

  /**
   * resumes syncing
   * @method resume
   * @memberof data.Synchronizer
   * @instance
   */
  p.resume = function(){
    this._stopped = false;
    _next.call(this);
  };

  /**
   * pauses syncing, can be resumed later on
   * @method pause
   * @memberof data.Synchronizer
   * @instance
   */
  p.pause = function(){
    this._stopped = true;
  };

  /**
   * stops syncing, resets sync index
   * @method stop
   * @memberof data.Synchronizer
   * @instance
   */
  p.stop = function(){
    this.pause();
  };

  var _next = function(){
    if (this._stopped) return;

    // get current item
    var currentItem = this.items[this._index];

    // if still has items
    if (currentItem) {
      // get that item
      _get.call(this, currentItem);
    } else {
      // otherwise: dispatch done
      _done.call(this);
    }
  };

  var _get = function(item) {
    var _this = this;

    // if current item was a string: assume remote and local path should be the same
    if (typeof item === 'string') item = {remote: item, local: item};

    // if current item was an object but has no local filepath set: set it to ''
    if (! item.local) item.local = '';

    // define download options
    var options = {};

    // if current item has an overwrite option
    if (! (item.overwrite === null || typeof item.overwrite === 'undefined')) {
      // use that definition
      options.overwrite = item.overwrite;
    } else {
      // otherwise use defined overwrite option in Synchronizer
      options.overwrite = _this.overwrite;
    }

    options.remote = _this.remote + item.remote;
    options.local = _this.local + item.local;

    // calculate current item progress
    options.progress = function(p){
      // call progress event
      _progress.call(_this, (_this._index + p) / _this.items.length);
    };

    options.error = function(err){
      _error.call(_this, err);
    };

    options.success = function(filePath){
      // increment index when finished downloading
      _this._index++;

      // store all downloaded files in an array for later use
      var filename = fs.correctLocalFilePath(filePath);
      if (_this._storedFiles.indexOf(filename) === -1) _this._storedFiles.push(filename);

      var dirname = filename;

      // store up to 10 folders backwards
      // i.e. if there are nested empty folders they will not be recognized
      for (var i = 0; i < 10; i++) {
        dirname = fs.getFolder(dirname);
        if (dirname + '/' === fs.dataPath || dirname + '/' === '/') break;
        if (_this._storedFiles.indexOf(dirname) === -1) _this._storedFiles.push(dirname);
      }

      // call progress event
      _progress.call(_this, _this._index / _this.items.length);

      // and sync next item
      _next.call(_this);
    };

    // download current item
    fs.download(options);
  };

  var _done = function(){
    // if sync should cleanup a directory
    if (this.cleanup) {
      // get cleanup folder, assume it's the local base path folder
      var cleanup = this.local;

      // if cleanup was a string
      if (typeof this.cleanup === 'string') {
        // use that folder instead
        cleanup = this.cleanup;
      }

      _cleanup.call(this, cleanup, true);
    } else {
      // finished downloading
      _success.call(this);
    }
  };

  var _cleanup = function(folder, callCallback){
    var _this = this;

    // get all local files in that directory
    fs.readdir(folder, function(localFiles){
      // loop through local found files
      for (var i = 0, _len = localFiles.length; i < _len; i++) {
        // if it is a folder
        if (localFiles[i].indexOf('.') === -1) {
          // clean the subfolder
          _cleanup.call(_this, folder + localFiles[i] + '/');
        }

        // if local file was not in download list
        if (_this._storedFiles.indexOf(fs.correctLocalFilePath(folder + localFiles[i])) === -1) {
          // remove it as it should not be used anymore
          fs.unlink(folder + localFiles[i]);
        }
      }

      if (callCallback) {
        // finished syncing
        _success.call(_this);
      }
    });
  };

  var _progress = function(p) {
    if (this.progress) {
      this.progress(p);
    }

    var event = new createjs.Event(PROGRESS);
    event.progress = p;
    this.dispatchEvent(event);
  };

  var _error = function(err) {
    if (this.error) {
      this.error(err);
    }

    var event = new createjs.Event(ERROR);
    event.error = err;
    this.dispatchEvent(event);
  };

  var _success = function(){
    if (this.success) {
      this.success();
    }

    var event = new createjs.Event(SUCCESS);
    this.dispatchEvent(event);
  };

  return Synchronizer;
});
<|endoftext|>


<commit_before>var _ = require("underscore")._;
var assert = require("assert");
var util = require('util');
var Document = require("./document");
var Where = require("./where");
var ArgTypes = require("./arg_types");
var DA = require("deasync");

//Searching query for jsonb docs
exports.searchDoc = function(args, next){
  assert(args.keys && args.term, "Need the keys to use and the term string");

  //yuck full repetition here... fix me...
  if(!_.isArray(args.keys)){
    args.keys = [args.keys];
  }
  var tsv;
  if(args.keys.length === 1){
    tsv = util.format("(body ->> '%s')", args.keys[0]);
  }else{
    var formattedKeys = [];
    _.each(args.keys, function(key){
      formattedKeys.push(util.format("(body ->> '%s')", key));
    });
    tsv= util.format("concat(%s)", formattedKeys.join(", ' ',"));
  }
  var sql = "select * from " + this.fullname + " where " + util.format("to_tsvector(%s)", tsv);
  sql+= " @@ to_tsquery($1);";

  this.executeDocQuery(sql, [args.term], next);
};
exports.searchDocSync = DA(this.serchDoc);

exports.saveDoc = function(args, next){
  assert(_.isObject(args), "Please pass in the document for saving as an object. Include the primary key for an UPDATE.");
  //see if the args contains a PK
  var self = this;
  var sql, params = [];
  var pkName = this.primaryKeyName();
  var pkVal = args[pkName];

  //just in case
  delete args[pkName];
  //only do this after the pk is removed
  params.push(JSON.stringify(args));

  if(pkVal){
    sql = util.format("update %s set body = $1 where %s = $2 returning *;",this.fullname, pkName);
    params.push(pkVal);
  }else{
    sql = "insert into " + this.fullname + "(body) values($1) returning *;";
  }
  this.executeDocQuery(sql, params, {single : true}, next);
};
exports.saveDocSync = DA(this.saveDoc);

// Only works for jsonb column type and Postgresql 9.5
exports.updateDoc = function(id, key, val, next){
  const pkName = this.primaryKeyName();
  const params = ["{"+key+"}", val, id];
  var sql = util.format("update %s set body=jsonb_set(body, $1, $2, true) where %s = $3 returning *;", this.fullname, pkName);
  this.executeDocQuery(sql, params, {single:true}, next);
}
exports.updateDocSync = DA(this.updateDoc);

exports.findDoc = function(){
  var args = ArgTypes.findArgs(arguments);
  if(_.isFunction(args.conditions)){
    // all we're given is the callback:
    args.next = args.conditions;
  }

  // Set up the WHERE statement:
  var where = this.getWhereForDoc(args.conditions);
  var sql = util.format("select id, body from %s", this.fullname);
  sql += where.where;
  if(where.pkQuery) {
    this.executeDocQuery(sql, where.params, {single:true}, args.next);
  } else {
    this.executeDocQuery(sql, where.params, args.options, args.next);
  }
};
exports.findDocSync = DA(this.findDoc);

this.getWhereForDoc = function(conditions) {
  var where = {};
  if(_.isFunction(conditions) || conditions == "*") {
    // no crtieria provided - treat like select *
    where.where = "";
    where.params = [];
    where.pkQuery = false;
    return where;
  }

  if(_.isNumber(conditions)){
    //assume it's a search on ID
    conditions = {id : conditions};
  }

  if (_.isObject(conditions)) {
    var keys = _.keys(conditions);
    if (keys.length === 1) {
      var operator = keys[0].match("<=|>=|!=|<>|=|<|>");
      var property = keys[0].replace(operator, "").trim();
      if(property == this.primaryKeyName()) {
        // this is a query against the PK...we can use the
        // plain old table "where" builder:
        where = Where.forTable(conditions);

        // only a true pk query if testing equality
        if(operator === null || operator === "=") {
          where.pkQuery = true;
        }
      } else {
        where = Where.forDocument(conditions);
        where.pkQuery = false;
      }
    } else {
      where = Where.forDocument(conditions);
      where.pkQuery = false;
    }
  }
  return where;
};

this.executeDocQuery = function() {
  var args = ArgTypes.queryArgs(arguments);
  var doc = {};
  this.db.query(args.sql, args.params, args.options, function(err,res){
    if(err){
      args.next(err,null);
    }else{
      //only return one result if single is sent in
      if(args.options.single){
        doc = Document.formatDocument(res);
      }else{
        doc = Document.formatArray(res);
      }
      args.next(null,doc);
    }
  });
};
<commit_msg>Minor change, use const instead of var<commit_after>var _ = require("underscore")._;
var assert = require("assert");
var util = require('util');
var Document = require("./document");
var Where = require("./where");
var ArgTypes = require("./arg_types");
var DA = require("deasync");

//Searching query for jsonb docs
exports.searchDoc = function(args, next){
  assert(args.keys && args.term, "Need the keys to use and the term string");

  //yuck full repetition here... fix me...
  if(!_.isArray(args.keys)){
    args.keys = [args.keys];
  }
  var tsv;
  if(args.keys.length === 1){
    tsv = util.format("(body ->> '%s')", args.keys[0]);
  }else{
    var formattedKeys = [];
    _.each(args.keys, function(key){
      formattedKeys.push(util.format("(body ->> '%s')", key));
    });
    tsv= util.format("concat(%s)", formattedKeys.join(", ' ',"));
  }
  var sql = "select * from " + this.fullname + " where " + util.format("to_tsvector(%s)", tsv);
  sql+= " @@ to_tsquery($1);";

  this.executeDocQuery(sql, [args.term], next);
};
exports.searchDocSync = DA(this.serchDoc);

exports.saveDoc = function(args, next){
  assert(_.isObject(args), "Please pass in the document for saving as an object. Include the primary key for an UPDATE.");
  //see if the args contains a PK
  var self = this;
  var sql, params = [];
  var pkName = this.primaryKeyName();
  var pkVal = args[pkName];

  //just in case
  delete args[pkName];
  //only do this after the pk is removed
  params.push(JSON.stringify(args));

  if(pkVal){
    sql = util.format("update %s set body = $1 where %s = $2 returning *;",this.fullname, pkName);
    params.push(pkVal);
  }else{
    sql = "insert into " + this.fullname + "(body) values($1) returning *;";
  }
  this.executeDocQuery(sql, params, {single : true}, next);
};
exports.saveDocSync = DA(this.saveDoc);

// Only works for jsonb column type and Postgresql 9.5
exports.updateDoc = function(id, key, val, next){
  const pkName = this.primaryKeyName();
  const params = ["{"+key+"}", val, id];
  const sql = util.format("update %s set body=jsonb_set(body, $1, $2, true) where %s = $3 returning *;", this.fullname, pkName);
  this.executeDocQuery(sql, params, {single:true}, next);
}
exports.updateDocSync = DA(this.updateDoc);

exports.findDoc = function(){
  var args = ArgTypes.findArgs(arguments);
  if(_.isFunction(args.conditions)){
    // all we're given is the callback:
    args.next = args.conditions;
  }

  // Set up the WHERE statement:
  var where = this.getWhereForDoc(args.conditions);
  var sql = util.format("select id, body from %s", this.fullname);
  sql += where.where;
  if(where.pkQuery) {
    this.executeDocQuery(sql, where.params, {single:true}, args.next);
  } else {
    this.executeDocQuery(sql, where.params, args.options, args.next);
  }
};
exports.findDocSync = DA(this.findDoc);

this.getWhereForDoc = function(conditions) {
  var where = {};
  if(_.isFunction(conditions) || conditions == "*") {
    // no crtieria provided - treat like select *
    where.where = "";
    where.params = [];
    where.pkQuery = false;
    return where;
  }

  if(_.isNumber(conditions)){
    //assume it's a search on ID
    conditions = {id : conditions};
  }

  if (_.isObject(conditions)) {
    var keys = _.keys(conditions);
    if (keys.length === 1) {
      var operator = keys[0].match("<=|>=|!=|<>|=|<|>");
      var property = keys[0].replace(operator, "").trim();
      if(property == this.primaryKeyName()) {
        // this is a query against the PK...we can use the
        // plain old table "where" builder:
        where = Where.forTable(conditions);

        // only a true pk query if testing equality
        if(operator === null || operator === "=") {
          where.pkQuery = true;
        }
      } else {
        where = Where.forDocument(conditions);
        where.pkQuery = false;
      }
    } else {
      where = Where.forDocument(conditions);
      where.pkQuery = false;
    }
  }
  return where;
};

this.executeDocQuery = function() {
  var args = ArgTypes.queryArgs(arguments);
  var doc = {};
  this.db.query(args.sql, args.params, args.options, function(err,res){
    if(err){
      args.next(err,null);
    }else{
      //only return one result if single is sent in
      if(args.options.single){
        doc = Document.formatDocument(res);
      }else{
        doc = Document.formatArray(res);
      }
      args.next(null,doc);
    }
  });
};
<|endoftext|>


<commit_before>/*
 * Storage Class is a interface to create storage with the following contracts
 * lint comment is applied to prevent `class-method-use-this` for this case
 */

/* eslint class-methods-use-this: [
     'error', { "exceptMethods": ['ping', 'listNamespaces', 'postCode', 'putCode', 'getCode',
                                  'deleteCode', 'getCodeByCache']
   }]
*/

const ERR_UNIMPLEMENTED_METHOD = 'unimplemented method for Storage interface';

class Storage {
  constructor(name) {
    this.name = name;
  }

  ping() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  listNamespaces() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  postCode() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  putCode() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  getCode() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  deleteCode() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }

  getCodeByCache() { throw new Error(ERR_UNIMPLEMENTED_METHOD); }
}

module.exports = Storage;
<commit_msg>Simplify error raising on storage<commit_after>/*
 * Storage Class is a interface to create storage with the following contracts
 * lint comment is applied to prevent `class-method-use-this` for this case
 */

/* eslint class-methods-use-this: [
     'error', { "exceptMethods": ['ping', 'listNamespaces', 'postCode', 'putCode', 'getCode',
                                  'deleteCode', 'getCodeByCache']
   }]
*/

const ERR_UNIMPLEMENTED_METHOD = new Error('unimplemented method for Storage interface');

class Storage {
  constructor(name) {
    this.name = name;
  }

  ping() { throw ERR_UNIMPLEMENTED_METHOD; }
  listNamespaces() { throw ERR_UNIMPLEMENTED_METHOD; }
  postCode() { throw ERR_UNIMPLEMENTED_METHOD; }
  putCode() { throw ERR_UNIMPLEMENTED_METHOD; }
  getCode() { throw ERR_UNIMPLEMENTED_METHOD; }
  deleteCode() { throw ERR_UNIMPLEMENTED_METHOD; }
  getCodeByCache() { throw ERR_UNIMPLEMENTED_METHOD; }
}

module.exports = Storage;
<|endoftext|>