<commit_before>var log = new Log('fuse.handlebars');
//TODO: create a different set of helpers for init parsing

var Handlebars = require('handlebars-v2.0.0.js').Handlebars;

var getScope = function (unit,configs) {
    var jsFile = fuse.getFile(unit, '', '.js');
    var templateConfigs = configs || {};
    var script;
    var onRequestCb = function(){}; //Assume that onRequest function will not be defined by the user
    var viewModel = {};
    var cbResult;
    if (jsFile.isExists()) {
        script = require(jsFile.getPath());
        //Eagerly make the viewModel the template configs
        viewModel = templateConfigs;
        //Check if the unit author has specified an onRequest
        //callback
        if(script.hasOwnProperty('onRequest')){
            onRequestCb = script.onRequest;

            cbResult = onRequestCb(templateConfigs);
            //If the execution does not yield an object we will print
            //a warning as the unit author may have forgotten to return a data object
            if(cbResult===undefined){
                cbResult = {}; //Give an empty data object
                log.warn('[' + requestId + '] unit "' + unit + '" has a onRequest method which does not return a value.This may lead to the '
                    +'unit not been rendered correctly.');
            }
            viewModel = cbResult;
        }
    }
    else{
        //If there is no script then the view should get the configurations
        //passed in the unit call
        viewModel = templateConfigs;
    }
    viewModel.app = {
        url: '/' + fuseState.appName
    };
    viewModel.self = {
        publicURL: '/' + fuseState.appName + '/public/' + unit,
        "class": unit + '-unit'
    };
    return viewModel;
};

Handlebars.innerZones = [];
Handlebars.innerZonesFromUnit = null;

Handlebars.registerHelper('defineZone', function (zoneName, zoneContent) {
    var result = '';
    var zone = Handlebars.Utils.escapeExpression(zoneName);
    fuseState.currentZone.push(zone);
    var unitsToRender = fuseState.zones[zone] || [];

    if (Handlebars.innerZones.length > 0) {
        unitsToRender = fuseState.zones[Handlebars.innerZones[0]] || [];
    }

    // if there is no one overriding, then display inline zone
    if (zoneContent['fn'] && unitsToRender.length == 0) {
        return zoneContent.fn(this).trim();
    }

    for (var i = 0; i < unitsToRender.length; i++) {
        var unit = unitsToRender[i];
        if (Handlebars.innerZonesFromUnit == null || Handlebars.innerZonesFromUnit.unitName == unit.unitName) {
            var template = fuse.getFile(unit.originUnitName || unit.unitName, '', '.hbs');
            log.debug('[' + requestId + '] for zone "' + zone + '" including template :"' + template.getPath() + '"');
            result += Handlebars.compileFile(template)(getScope(unit.unitName));
        }
    }

    // we go to inner zones if result is empty, what we should really do it
    // if matched zone is fully made of sub-zones. this is a hack to
    // make it easy to implement.
    if (result.trim().length == 0 && zoneContent['fn']) {
        Handlebars.innerZones.push(zoneName);
        for (i = 0; i < unitsToRender.length; i++) {
            unit = unitsToRender[i];
            Handlebars.innerZonesFromUnit = unit;
            result += zoneContent.fn(this).trim();
            Handlebars.innerZonesFromUnit = null;
        }
        Handlebars.innerZones.pop();
        return result;
    }

    fuseState.currentZone.pop();
    return new Handlebars.SafeString(result);
});

Handlebars.registerHelper('zone', function (zoneName, zoneContent) {
    var currentZone = fuseState.currentZone[fuseState.currentZone.length - 1];
    if (currentZone == null) {
        return 'zone_' + zoneName + ' ';
    }

    // if it's exact zone match or if any in inner zone matches we render zone.
    // this second condition is a hack. what we should really do is to keep another stack,
    // and only match with the peek of that stack and always fill it with next in innerZone stack.
    if (zoneName == currentZone || Handlebars.innerZones.indexOf(zoneName) >= 0) {
        return zoneContent.fn(this).trim();
    } else {
        return '';
    }
});

Handlebars.registerHelper('layout', function (layoutName) {
    var currentZone = fuseState.currentZone[fuseState.currentZone.length - 1];
    if (currentZone == null) {
        return 'layout_' + layoutName;
    } else {
        return '';
    }
});

Handlebars.registerHelper('unit', function (unitName,options) {
    var unitDef = fuse.getUnitDefinition(unitName);
    var baseUnit = null;
    var templateConfigs = options.hash || {};
    for (var i = 0; i < unitDef.zones.length; i++) {
        var zone = unitDef.zones[i];
        if (zone.name == 'main') {
            baseUnit = zone.origin;
        } else {
            var golbalZone = fuseState.zones[zone.name];
            if (!golbalZone) {
                fuseState.zones[zone.name] = [{"unitName": unitName}];
            } else {
                fuseState.zones[zone.name].push({"unitName": unitName});
            }
        }
    }
    if (baseUnit == null) {
        log.error('unit does not have a main zone');
    }
    //TODO warn when unspecified decencies are included.
    fuseState.currentZone.push('main');
    var template = fuse.getFile(baseUnit, '', '.hbs');
    log.info('[' + requestId + '] including "' + baseUnit + '"');
    var result = new Handlebars.SafeString(Handlebars.compileFile(template)(getScope(baseUnit,templateConfigs)));
    fuseState.currentZone.pop();
    return result;
});

Handlebars.compileFile = function (file) {
    //TODO: remove this overloaded argument
    var f = (typeof file === 'string') ? new File(file) : file;

    if (!Handlebars.cache) {
        Handlebars.cache = {};
    }

    if (Handlebars.cache[f.getPath()] != null) {
        return Handlebars.cache[f.getPath()];
    }

    f.open('r');
    log.debug('[' + requestId + '] reading file "' + f.getPath() + '"');
    var content = f.readAll().trim();
    f.close();
    var compiled = Handlebars.compile(content);
    Handlebars.cache[f.getPath()] = compiled;
    return compiled;
};
<commit_msg>Data context of parent units are passed down to extended units<commit_after>var log = new Log('fuse.handlebars');
//TODO: create a different set of helpers for init parsing

var Handlebars = require('handlebars-v2.0.0.js').Handlebars;

var getScope = function (unit,configs) {
    var jsFile = fuse.getFile(unit, '', '.js');
    var templateConfigs = configs || {};
    var script;
    var onRequestCb = function(){}; //Assume that onRequest function will not be defined by the user
    var viewModel = {};
    var cbResult;
    if (jsFile.isExists()) {
        script = require(jsFile.getPath());
        //Eagerly make the viewModel the template configs
        viewModel = templateConfigs;
        //Check if the unit author has specified an onRequest
        //callback
        if(script.hasOwnProperty('onRequest')){
            onRequestCb = script.onRequest;

            cbResult = onRequestCb(templateConfigs);
            //If the execution does not yield an object we will print
            //a warning as the unit author may have forgotten to return a data object
            if(cbResult===undefined){
                cbResult = {}; //Give an empty data object
                log.warn('[' + requestId + '] unit "' + unit + '" has a onRequest method which does not return a value.This may lead to the '
                    +'unit not been rendered correctly.');
            }
            viewModel = cbResult;
        }
    }
    else{
        //If there is no script then the view should get the configurations
        //passed in the unit call
        viewModel = templateConfigs;
    }
    viewModel.app = {
        url: '/' + fuseState.appName
    };
    viewModel.self = {
        publicURL: '/' + fuseState.appName + '/public/' + unit,
        "class": unit + '-unit'
    };
    return viewModel;
};

Handlebars.innerZones = [];
Handlebars.innerZonesFromUnit = null;

Handlebars.registerHelper('defineZone', function (zoneName, zoneContent) {
    var result = '';
    //Child units will need to inherit the parent data context
    var parentData = (zoneContent.data)? zoneContent.data.root:{};
    var zone = Handlebars.Utils.escapeExpression(zoneName);
    fuseState.currentZone.push(zone);
    var unitsToRender = fuseState.zones[zone] || [];

    if (Handlebars.innerZones.length > 0) {
        unitsToRender = fuseState.zones[Handlebars.innerZones[0]] || [];
    }

    // if there is no one overriding, then display inline zone
    if (zoneContent['fn'] && unitsToRender.length == 0) {
        return zoneContent.fn(this).trim();
    }

    for (var i = 0; i < unitsToRender.length; i++) {
        var unit = unitsToRender[i];
        if (Handlebars.innerZonesFromUnit == null || Handlebars.innerZonesFromUnit.unitName == unit.unitName) {
            var template = fuse.getFile(unit.originUnitName || unit.unitName, '', '.hbs');
            log.debug('[' + requestId + '] for zone "' + zone + '" including template :"' + template.getPath() + '"');
            result += Handlebars.compileFile(template)(getScope(unit.unitName,parentData||{}));
        }
    }

    // we go to inner zones if result is empty, what we should really do it
    // if matched zone is fully made of sub-zones. this is a hack to
    // make it easy to implement.
    if (result.trim().length == 0 && zoneContent['fn']) {
        Handlebars.innerZones.push(zoneName);
        for (i = 0; i < unitsToRender.length; i++) {
            unit = unitsToRender[i];
            Handlebars.innerZonesFromUnit = unit;
            result += zoneContent.fn(this).trim();
            Handlebars.innerZonesFromUnit = null;
        }
        Handlebars.innerZones.pop();
        return result;
    }

    fuseState.currentZone.pop();
    return new Handlebars.SafeString(result);
});

Handlebars.registerHelper('zone', function (zoneName, zoneContent) {
    var currentZone = fuseState.currentZone[fuseState.currentZone.length - 1];
    if (currentZone == null) {
        return 'zone_' + zoneName + ' ';
    }

    // if it's exact zone match or if any in inner zone matches we render zone.
    // this second condition is a hack. what we should really do is to keep another stack,
    // and only match with the peek of that stack and always fill it with next in innerZone stack.
    if (zoneName == currentZone || Handlebars.innerZones.indexOf(zoneName) >= 0) {
        return zoneContent.fn(this).trim();
    } else {
        return '';
    }
});

Handlebars.registerHelper('layout', function (layoutName) {
    var currentZone = fuseState.currentZone[fuseState.currentZone.length - 1];
    if (currentZone == null) {
        return 'layout_' + layoutName;
    } else {
        return '';
    }
});

Handlebars.registerHelper('unit', function (unitName,options) {
    var unitDef = fuse.getUnitDefinition(unitName);
    var baseUnit = null;
    var templateConfigs = options.hash || {};
    for (var i = 0; i < unitDef.zones.length; i++) {
        var zone = unitDef.zones[i];
        if (zone.name == 'main') {
            baseUnit = zone.origin;
        } else {
            var golbalZone = fuseState.zones[zone.name];
            if (!golbalZone) {
                fuseState.zones[zone.name] = [{"unitName": unitName}];
            } else {
                fuseState.zones[zone.name].push({"unitName": unitName});
            }
        }
    }
    if (baseUnit == null) {
        log.error('unit does not have a main zone');
    }
    //TODO warn when unspecified decencies are included.
    fuseState.currentZone.push('main');
    var template = fuse.getFile(baseUnit, '', '.hbs');
    log.info('[' + requestId + '] including "' + baseUnit + '"');
    var result = new Handlebars.SafeString(Handlebars.compileFile(template)(getScope(baseUnit,templateConfigs)));
    fuseState.currentZone.pop();
    return result;
});

Handlebars.compileFile = function (file) {
    //TODO: remove this overloaded argument
    var f = (typeof file === 'string') ? new File(file) : file;

    if (!Handlebars.cache) {
        Handlebars.cache = {};
    }

    if (Handlebars.cache[f.getPath()] != null) {
        return Handlebars.cache[f.getPath()];
    }

    f.open('r');
    log.debug('[' + requestId + '] reading file "' + f.getPath() + '"');
    var content = f.readAll().trim();
    f.close();
    var compiled = Handlebars.compile(content);
    Handlebars.cache[f.getPath()] = compiled;
    return compiled;
};
<|endoftext|>


<commit_before>/*!
 * context
 * Version: 0.0.1
 * Date: 2016/7/29
 * https://github.com/Nuintun/fengine
 *
 * Original Author: https://github.com/tmont/html-parser
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

// lib
var util = require('./util');

// event types
var EVENTTYPES = [
  'openElement',
  'closeElement',
  'attribute',
  'comment',
  'cdata',
  'text',
  'docType',
  'xmlType',
  'closeOpenedElement'
];

/**
 * format rule
 * @param rule
 * @param porp
 */
function formatRule(rule, porp){
  switch (util.type(rule[porp])) {
    case 'string':
      rule[porp] = util.str2regex(rule[porp]);
      break;
    case 'regexp':
      if (rule[porp].global) {
        var attr = '';

        if (rule[porp].ignoreCase) {
          attr += 'i';
        }

        if (rule[porp].multiline) {
          attr += 'm';
        }

        rule[porp] = util.str2regex(rule[porp].source, attr);
      }
      break;
    default:
      throw new TypeError('rules.dataElements.' + porp + ' must be a sting or regexp.');
      break;
  }
}

/**
 * create read
 * @param raw
 * @param callbacks
 * @param rules
 * @returns {{
 *   text: string,
 *   peek: context.peek,
 *   read: context.read,
 *   readUntilNonWhitespace: context.readUntilNonWhitespace,
 *   readRule: context.readRule,
 *   peekIgnoreWhitespace: context.peekIgnoreWhitespace
 * }}
 */
module.exports.create = function (raw, callbacks, rules){
  var index = 0;
  var current = null;
  var substring = null;

  var context = {
    text: '',
    peek: function (count){
      count = count || 1;

      return this.raw.substr(this.index + 1, count);
    },
    read: function (count, peek){
      var next;

      count = count || 1;

      if (peek) {
        next = this.peek(count);
      }

      this.index += count;

      if (this.index > this.length) {
        this.index = this.length;
      }

      return next;
    },
    readUntilNonWhitespace: function (){
      var next;
      var value = '';

      while (!this.EOF) {
        next = this.read(1, true);

        value += next;

        if (!/\s$/.test(value)) {
          break;
        }
      }

      return value;
    },
    readRule: function (rule){
      var match = rule.exec(this.substring);
      var value = match ? match[0] : '';

      this.index += (match ? match.index : 0) + value.length;

      return match ? value : null;
    },
    readUntilRule: function (rule){
      var substring = this.substring;
      var match = rule.exec(substring);

      this.index += match ? match.index : 0;

      return match ? substring.substr(0, match.index) : null;
    },
    peekIgnoreWhitespace: function (count){
      count = count || 1;

      var value = '';
      var next = '';
      var offset = 0;

      do {
        next = this.raw.charAt(this.index + ++offset);

        if (!next) {
          break;
        }

        if (!/\s/.test(next)) {
          value += next;
        }
      } while (value.length < count);

      return value;
    }
  };

  // end of file
  context.__defineGetter__('EOF', function (){
    return this.index >= this.length;
  });

  // current char
  context.__defineGetter__('current', function (){
    return this.EOF ? '' : current === null ? (current = this.raw.charAt(this.index)) : current;
  });

  // raw code
  context.__defineGetter__('raw', function (){
    return raw;
  });

  // raw length
  context.__defineGetter__('length', function (){
    return this.raw.length;
  });

  // index
  context.__defineGetter__('index', function (){
    return index;
  });

  // set index
  context.__defineSetter__('index', function (value){
    index = value;
    current = null;
    substring = null;
  });

  // non parsed code
  context.__defineGetter__('substring', function (){
    return substring === null ? (substring = this.raw.substring(this.index)) : substring;
  });

  // callbacks
  context.callbacks = {};

  // format event callbacks
  EVENTTYPES.forEach(function (value){
    context.callbacks[value] = util.noop;
  });

  // merge callbacks
  util.merge(context.callbacks, callbacks || {});

  // rules
  context.rules = {
    name: /[a-zA-Z_][\w:.-]*/,
    attribute: /[a-zA-Z_][\w:.-]*/,
    dataElements: {
      cdata: {
        start: '<![CDATA[',
        end: ']]>'
      },
      comment: {
        start: '<!--',
        end: '-->'
      },
      docType: {
        start: /^<!DOCTYPE /i,
        end: '>'
      }
    }
  };

  // merge rules
  util.merge(context.rules, rules || {});

  var rule;
  var dataElements = context.rules.dataElements;

  for (var data in dataElements) {
    if (dataElements.hasOwnProperty(data)) {
      rule = dataElements[data];

      formatRule(rule, 'start');
      formatRule(rule, 'end');
    }
  }

  // return read
  return context;
};
<commit_msg>update files<commit_after>/*!
 * context
 * Version: 0.0.1
 * Date: 2016/7/29
 * https://github.com/Nuintun/fengine
 *
 * Original Author: https://github.com/tmont/html-parser
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

// lib
var util = require('./util');

// event types
var EVENTTYPES = [
  'openElement',
  'closeElement',
  'attribute',
  'comment',
  'cdata',
  'text',
  'docType',
  'xmlType',
  'closeOpenedElement'
];

/**
 * format rule
 * @param rule
 * @param porp
 */
function formatRule(rule, porp){
  switch (util.type(rule[porp])) {
    case 'string':
      rule[porp] = util.str2regex(rule[porp]);
      break;
    case 'regexp':
      if (rule[porp].global) {
        var attr = '';

        if (rule[porp].ignoreCase) {
          attr += 'i';
        }

        if (rule[porp].multiline) {
          attr += 'm';
        }

        rule[porp] = util.str2regex(rule[porp].source, attr);
      }
      break;
    default:
      throw new TypeError('rules.dataElements.' + porp + ' must be a sting or regexp.');
      break;
  }
}

/**
 * create read
 * @param raw
 * @param callbacks
 * @param rules
 * @returns {{
 *   text: string,
 *   peek: context.peek,
 *   read: context.read,
 *   readUntilNonWhitespace: context.readUntilNonWhitespace,
 *   readRule: context.readRule,
 *   peekIgnoreWhitespace: context.peekIgnoreWhitespace
 * }}
 */
module.exports.create = function (raw, callbacks, rules){
  var index = 0;
  var current = null;
  var substring = null;

  var context = {
    text: '',
    peek: function (count){
      count = count || 1;

      return this.raw.substr(this.index + 1, count);
    },
    read: function (count, peek){
      var next;

      count = count || 1;

      if (peek) {
        next = this.peek(count);
      }

      this.index += count;

      if (this.index > this.length) {
        this.index = this.length;
      }

      return next;
    },
    readUntilNonWhitespace: function (){
      var next;
      var value = '';

      while (!this.EOF) {
        next = this.read(1, true);

        value += next;

        if (!/\s$/.test(value)) {
          break;
        }
      }

      return value;
    },
    readRule: function (rule){
      var match = rule.exec(this.substring);
      var value = match ? match[0] : null;

      if (match) {
        this.index += match.index + value.length;
      }

      return value;
    },
    readUntilRule: function (rule){
      var substring = this.substring;
      var match = rule.exec(substring);

      if (match) {
        this.index += match.index;
      }

      return match ? substring.substr(0, match.index) : null;
    },
    peekIgnoreWhitespace: function (count){
      count = count || 1;

      var value = '';
      var next = '';
      var offset = 0;

      do {
        next = this.raw.charAt(this.index + ++offset);

        if (!next) {
          break;
        }

        if (!/\s/.test(next)) {
          value += next;
        }
      } while (value.length < count);

      return value;
    }
  };

  // end of file
  context.__defineGetter__('EOF', function (){
    return this.index >= this.length;
  });

  // current char
  context.__defineGetter__('current', function (){
    return this.EOF ? '' : current === null ? (current = this.raw.charAt(this.index)) : current;
  });

  // raw code
  context.__defineGetter__('raw', function (){
    return raw;
  });

  // raw length
  context.__defineGetter__('length', function (){
    return this.raw.length;
  });

  // index
  context.__defineGetter__('index', function (){
    return index;
  });

  // set index
  context.__defineSetter__('index', function (value){
    index = value;
    current = null;
    substring = null;
  });

  // non parsed code
  context.__defineGetter__('substring', function (){
    return substring === null ? (substring = this.raw.substring(this.index)) : substring;
  });

  // callbacks
  context.callbacks = {};

  // format event callbacks
  EVENTTYPES.forEach(function (value){
    context.callbacks[value] = util.noop;
  });

  // merge callbacks
  util.merge(context.callbacks, callbacks || {});

  // rules
  context.rules = {
    name: /[a-zA-Z_][\w:.-]*/,
    attribute: /[a-zA-Z_][\w:.-]*/,
    dataElements: {
      cdata: {
        start: '<![CDATA[',
        end: ']]>'
      },
      comment: {
        start: '<!--',
        end: '-->'
      },
      docType: {
        start: /^<!DOCTYPE /i,
        end: '>'
      }
    }
  };

  // merge rules
  util.merge(context.rules, rules || {});

  var rule;
  var dataElements = context.rules.dataElements;

  for (var data in dataElements) {
    if (dataElements.hasOwnProperty(data)) {
      rule = dataElements[data];

      formatRule(rule, 'start');
      formatRule(rule, 'end');
    }
  }

  // return read
  return context;
};
<|endoftext|>


<commit_before>"use strict";

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

var SettingsManager = function (data, serializer) {
    this._data = data;
    this._serializer = serializer || JSONSerializer;
};

SettingsManager.prototype.getValue = function (key, defaultValue) {
    if (typeof this._data[key] !== 'undefined')
        return this._data[key];
    else if (hasLocalStorageSupport())
        return this._serializer.deserialize(window.localStorage.getItem(key));
    else
        return defaultValue;
};

SettingsManager.prototype.setValue = function (key, value) {
    if (hasLocalStorageSupport())
        window.localStorage.setItem(key, this._serializer.serialize(value));
};

function hasLocalStorageSupport() {
    try {
        return 'localStorage' in window && window['localStorage'] !== null;
    } catch (e) {
        return false;
    }
}

module.exports = SettingsManager;<commit_msg>Set empty data if SettingsManager file is void<commit_after>"use strict";

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

var SettingsManager = function (data, serializer) {
    this._data = data || {};
    this._serializer = serializer || JSONSerializer;
};

SettingsManager.prototype.getValue = function (key, defaultValue) {
    if (typeof this._data[key] !== 'undefined')
        return this._data[key];
    else if (hasLocalStorageSupport())
        return this._serializer.deserialize(window.localStorage.getItem(key));
    else
        return defaultValue;
};

SettingsManager.prototype.setValue = function (key, value) {
    if (hasLocalStorageSupport())
        window.localStorage.setItem(key, this._serializer.serialize(value));
};

function hasLocalStorageSupport() {
    try {
        return 'localStorage' in window && window['localStorage'] !== null;
    } catch (e) {
        return false;
    }
}

module.exports = SettingsManager;<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 Jan Kirchner.
 *
 * simple-mongo-timeseries
 *
 * A simple timeseries module for mongodb.
 */
var Q = require('q');
var keyBuilderFactory = require('./mongoTSKeys.js').KeyBuilderFactory();

var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'jk.smts.aggregate'});

exports = module.exports = mongoTSAggregation;

function mongoTSAggregation(config) {

    var storeAggregation = function (key, hourlyData) {

        var deferred = Q.defer();

        var updateData = {updated: new Date()};
        updateData['hours.' + hourlyData.hour] = hourlyData;

        config.getCollection().updateOne(
            {
                _id: key.buildAggregationString()
            },
            {
                $set: updateData
            },
            {
                upsert: false
            },
            function (err, results) {

                if (err) {
                    deferred.reject(new Error(err));
                } else {

                    if (results.result.n === 0) {
                        allocateAggragation(key, hourlyData).then(function (key) {
                            deferred.resolve(key);
                        });
                    } else {
                        deferred.resolve(key);
                    }
                }
            }
        );

        return deferred.promise;
    };

    var allocateAggragation = function (key, value) {

        var deferred = Q.defer();
        var hour = key.getHour();

        var updateData = {
            _id: key.buildAggregationString(),
            ts: key.getDayTimestamp(),
            updated: new Date(), hours: []
        };

        for (i = 0; i < 24; i++) {
            var allocationObj = {'hour': i, 'value': null, 'min': null, 'max': null, 'detail': []};
            for (j = 0; j < 6; j++) {
                allocationObj.detail.push({id: Number(j), value: null, min: null, max: null});
            }

            updateData.hours[i] = allocationObj;
        }

        updateData.hours[parseInt(hour)] = value;

        config.getCollection().insertOne(updateData, function (err) {
            if (err) {
                deferred.reject(new Error(err));
            } else {
                deferred.resolve(key);
            }
        });

        return deferred.promise;
    };

    var aggregateHour = function (key) {

        var deferred = Q.defer();
        var keyLength = key.getSensor().length;

        config.getCollection().aggregate(
            [
                {$match: {'_id': key.buildRegex()}},
                {
                    $project: {
                        'average': {$divide: ['$$CURRENT.total_samples', '$$CURRENT.num_samples']},
                        'min_samples': 1,
                        'max_samples': 1
                    }
                },
                {
                    $group: {
                        '_id': {$substr: ['$$CURRENT._id', 0, keyLength + 12]},
                        'average1': {$avg: '$$CURRENT.average'},
                        'min': {$min: '$$CURRENT.min_samples'},
                        'max': {$max: '$$CURRENT.max_samples'},
                        count: {$sum: 1}
                    }
                },
                {
                    $group: {
                        '_id': {$substr: ['$$CURRENT._id', 0, keyLength + 11]},
                        'value': {$avg: '$$CURRENT.average1'},
                        'min': {$min: '$$CURRENT.min'},
                        'max': {$max: '$$CURRENT.max'},
                        'detail': {
                            $push: {
                                id: {$substr: ['$$CURRENT._id', keyLength + 11, -1]},
                                value: '$$CURRENT.average1',
                                min: '$$CURRENT.min',
                                max: '$$CURRENT.max'
                            }
                        }
                    }
                }
            ]
        ).toArray(function (err, result) {

                if (err) {
                    deferred.reject(new Error(err));
                } else {

                    if (result.length === 0) {
                        deferred.resolve(keyBuilderFactory.increaseHour(key));
                    } else {

                        result.forEach(function (item) {

                            // workaround type convertion
                            item.detail = item.detail.map(function(d) {
                                d.id = parseInt(d.id);
                                return d;
                            });

                            var hourlyData = {
                                hour: parseInt(key.getHour()),
                                value: item.value,
                                min: item.min,
                                max: item.max,
                                detail: item.detail
                            };

                            storeAggregation(key, hourlyData).then(function (key) {
                                    deferred.resolve(keyBuilderFactory.increaseHour(key));
                                }
                            );
                        });
                    }
                }
            });

        return deferred.promise;
    };

    var aggregateMissingHoursUntil = function (cursor, until, deferred) {

        if (until(cursor)) {

            aggregateHour(cursor).then(
                function (resultKey) {
                    aggregateMissingHoursUntil(resultKey, until, deferred);
                }
            ).done();
        } else {
            log.info({'sensor': cursor.getSensor()},'aggregation done');
            deferred.resolve(true);
        }
    };

    var determineStart = function (keyBuilder) {
        var deferred = Q.defer();
        var regex = keyBuilder.buildRegexAllAggregations();

        config.getCollection().find({_id: regex}).sort({_id: -1}).limit(1).next(function (err, doc) {
            if (err) {
                deferred.reject(new Error(err));
            } else {

                if (doc) {
                    deferred.resolve(keyBuilderFactory.fromKeyString(doc._id));
                } else {
                    var queryFirstData = {$query: {_id: keyBuilder.buildRegexAllReadings()}, $orderby: {_id: 1}};
                    config.getCollection().findOne(queryFirstData, function (innerErr, innerDoc) {
                        if (innerErr) {
                            deferred.reject(new Error(innerErr));
                        } else {
                            if (innerDoc) {
                                deferred.resolve(keyBuilderFactory.fromKeyString(innerDoc._id));
                            } else {
                                deferred.resolve(keyBuilderFactory.fromNameAndDate(keyBuilder.getSensor(), new Date()));
                            }
                        }
                    });
                }
            }

        });

        return deferred.promise;
    };

    var determineEnd = function (keyBuilder) {
        var deferred = Q.defer();

        var queryLastData = {_id: keyBuilder.buildRegexAllReadings()};

        config.getCollection().find(queryLastData).sort({_id: -1}).limit(1).next(function (err, document) {
            if (err) {
                deferred.reject(new Error(err));
            } else {
                if (document) {
                    deferred.resolve(keyBuilderFactory.fromKeyString(document._id));
                } else {
                    deferred.resolve(keyBuilderFactory.fromNameAndDate(keyBuilder.getSensor(), new Date()));
                }
            }

        });

        return deferred.promise;
    };

    var aggregateSensor = function (sensor) {
        var deferred = Q.defer();

        var keyBuilder = keyBuilderFactory.fromNameAndDate(sensor, new Date());

        Q.all([determineStart(keyBuilder), determineEnd(keyBuilder)]).then(
            function (result) {

                var startDate = result[0].getPeriod();
                var endDate = result[1].getPeriod();

                log.info({'sensor': sensor, 'from': startDate, 'to': endDate}, 'aggregation start');

                var cursor = keyBuilderFactory.fromNameAndDate(sensor, startDate);

                var until = function (currentKey) {
                    return currentKey.getPeriod() <= endDate;
                };

                aggregateMissingHoursUntil(cursor, until, deferred);
            }
        );

        return deferred.promise;
    };

    var that = {};

    that.aggregateSensor = aggregateSensor;

    return that;

}
<commit_msg>remove necessary constructor<commit_after>/**
 * Copyright (c) 2016 Jan Kirchner.
 *
 * simple-mongo-timeseries
 *
 * A simple timeseries module for mongodb.
 */
var Q = require('q');
var keyBuilderFactory = require('./mongoTSKeys.js').KeyBuilderFactory();

var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'jk.smts.aggregate'});

exports = module.exports = mongoTSAggregation;

function mongoTSAggregation(config) {

    var storeAggregation = function (key, hourlyData) {

        var deferred = Q.defer();

        var updateData = {updated: new Date()};
        updateData['hours.' + hourlyData.hour] = hourlyData;

        config.getCollection().updateOne(
            {
                _id: key.buildAggregationString()
            },
            {
                $set: updateData
            },
            {
                upsert: false
            },
            function (err, results) {

                if (err) {
                    deferred.reject(new Error(err));
                } else {

                    if (results.result.n === 0) {
                        allocateAggragation(key, hourlyData).then(function (key) {
                            deferred.resolve(key);
                        });
                    } else {
                        deferred.resolve(key);
                    }
                }
            }
        );

        return deferred.promise;
    };

    var allocateAggragation = function (key, value) {

        var deferred = Q.defer();
        var hour = key.getHour();

        var updateData = {
            _id: key.buildAggregationString(),
            ts: key.getDayTimestamp(),
            updated: new Date(), hours: []
        };

        for (i = 0; i < 24; i++) {
            var allocationObj = {'hour': i, 'value': null, 'min': null, 'max': null, 'detail': []};
            for (j = 0; j < 6; j++) {
                allocationObj.detail.push({id: null, value: null, min: null, max: null});
            }

            updateData.hours[i] = allocationObj;
        }

        updateData.hours[parseInt(hour)] = value;

        config.getCollection().insertOne(updateData, function (err) {
            if (err) {
                deferred.reject(new Error(err));
            } else {
                deferred.resolve(key);
            }
        });

        return deferred.promise;
    };

    var aggregateHour = function (key) {

        var deferred = Q.defer();
        var keyLength = key.getSensor().length;

        config.getCollection().aggregate(
            [
                {$match: {'_id': key.buildRegex()}},
                {
                    $project: {
                        'average': {$divide: ['$$CURRENT.total_samples', '$$CURRENT.num_samples']},
                        'min_samples': 1,
                        'max_samples': 1
                    }
                },
                {
                    $group: {
                        '_id': {$substr: ['$$CURRENT._id', 0, keyLength + 12]},
                        'average1': {$avg: '$$CURRENT.average'},
                        'min': {$min: '$$CURRENT.min_samples'},
                        'max': {$max: '$$CURRENT.max_samples'},
                        count: {$sum: 1}
                    }
                },
                {
                    $group: {
                        '_id': {$substr: ['$$CURRENT._id', 0, keyLength + 11]},
                        'value': {$avg: '$$CURRENT.average1'},
                        'min': {$min: '$$CURRENT.min'},
                        'max': {$max: '$$CURRENT.max'},
                        'detail': {
                            $push: {
                                id: {$substr: ['$$CURRENT._id', keyLength + 11, -1]},
                                value: '$$CURRENT.average1',
                                min: '$$CURRENT.min',
                                max: '$$CURRENT.max'
                            }
                        }
                    }
                }
            ]
        ).toArray(function (err, result) {

                if (err) {
                    deferred.reject(new Error(err));
                } else {

                    if (result.length === 0) {
                        deferred.resolve(keyBuilderFactory.increaseHour(key));
                    } else {

                        result.forEach(function (item) {

                            // workaround type convertion
                            item.detail = item.detail.map(function(d) {
                                d.id = parseInt(d.id);
                                return d;
                            });

                            var hourlyData = {
                                hour: parseInt(key.getHour()),
                                value: item.value,
                                min: item.min,
                                max: item.max,
                                detail: item.detail
                            };

                            storeAggregation(key, hourlyData).then(function (key) {
                                    deferred.resolve(keyBuilderFactory.increaseHour(key));
                                }
                            );
                        });
                    }
                }
            });

        return deferred.promise;
    };

    var aggregateMissingHoursUntil = function (cursor, until, deferred) {

        if (until(cursor)) {

            aggregateHour(cursor).then(
                function (resultKey) {
                    aggregateMissingHoursUntil(resultKey, until, deferred);
                }
            ).done();
        } else {
            log.info({'sensor': cursor.getSensor()},'aggregation done');
            deferred.resolve(true);
        }
    };

    var determineStart = function (keyBuilder) {
        var deferred = Q.defer();
        var regex = keyBuilder.buildRegexAllAggregations();

        config.getCollection().find({_id: regex}).sort({_id: -1}).limit(1).next(function (err, doc) {
            if (err) {
                deferred.reject(new Error(err));
            } else {

                if (doc) {
                    deferred.resolve(keyBuilderFactory.fromKeyString(doc._id));
                } else {
                    var queryFirstData = {$query: {_id: keyBuilder.buildRegexAllReadings()}, $orderby: {_id: 1}};
                    config.getCollection().findOne(queryFirstData, function (innerErr, innerDoc) {
                        if (innerErr) {
                            deferred.reject(new Error(innerErr));
                        } else {
                            if (innerDoc) {
                                deferred.resolve(keyBuilderFactory.fromKeyString(innerDoc._id));
                            } else {
                                deferred.resolve(keyBuilderFactory.fromNameAndDate(keyBuilder.getSensor(), new Date()));
                            }
                        }
                    });
                }
            }

        });

        return deferred.promise;
    };

    var determineEnd = function (keyBuilder) {
        var deferred = Q.defer();

        var queryLastData = {_id: keyBuilder.buildRegexAllReadings()};

        config.getCollection().find(queryLastData).sort({_id: -1}).limit(1).next(function (err, document) {
            if (err) {
                deferred.reject(new Error(err));
            } else {
                if (document) {
                    deferred.resolve(keyBuilderFactory.fromKeyString(document._id));
                } else {
                    deferred.resolve(keyBuilderFactory.fromNameAndDate(keyBuilder.getSensor(), new Date()));
                }
            }

        });

        return deferred.promise;
    };

    var aggregateSensor = function (sensor) {
        var deferred = Q.defer();

        var keyBuilder = keyBuilderFactory.fromNameAndDate(sensor, new Date());

        Q.all([determineStart(keyBuilder), determineEnd(keyBuilder)]).then(
            function (result) {

                var startDate = result[0].getPeriod();
                var endDate = result[1].getPeriod();

                log.info({'sensor': sensor, 'from': startDate, 'to': endDate}, 'aggregation start');

                var cursor = keyBuilderFactory.fromNameAndDate(sensor, startDate);

                var until = function (currentKey) {
                    return currentKey.getPeriod() <= endDate;
                };

                aggregateMissingHoursUntil(cursor, until, deferred);
            }
        );

        return deferred.promise;
    };

    var that = {};

    that.aggregateSensor = aggregateSensor;

    return that;

}
<|endoftext|>


<commit_before>var net = require('net'),
  debug = require('util').debug,
  inspect = require('util').inspect,
  EventEmitter = require("events").EventEmitter,
  BinaryParser = require('./bson/binary_parser').BinaryParser,
  inherits = require('util').inherits,
  Server = require('./connections/server').Server;

var Connection = exports.Connection = function(host, port, autoReconnect, options) {
  this.options = options == null ? {} : options;
  this.host = host;
  this.port = port;
  this.autoReconnect = autoReconnect;
  this.drained = true;
  // Fetch the poolsize
  this.poolSize = this.options["poolSize"] == null ? 1 : this.options["poolSize"];
  // Reconnect buffer for messages
  this.messages = [];

  // Status messages
  this.sizeOfMessage = 0;
  this.bytesRead = 0;
  this.buffer = '';
  this.stubBuffer = '';
  this.connected = false;

  // Connection pool variables
  this.pool = [];
  this.poolByReference = {};
  this.poolIndex = 0;
};

inherits(Connection, EventEmitter);

var getConnection = function(self) {
  return self.pool[self.poolIndex++ % self.pool.length];
}

// Setup the connection pool
var setupConnectionPool = function(self, poolSize, reconnect) {
  // Pool off connections and status variables
  var connectionPool = [];
  var connectedTo = 0;
  var errors = 0;
  var connectionError = null;

  //
  // Listener that handles callbacks for the connection
  // Uses the internal object states to keep individual tcp connections seperate
  var receiveListener = function(result, fd) {
    fd = fd == null ? this.fd : fd;

    // Fetch the pool reference
    var conObj = self.poolByReference[fd];

    // if(conObj == null) {
    //   debug("================================================================ failed to find connection :: " + this.fd)
    //   debug(inspect(self.poolByReference))
    // }

    // Check if we have an unfinished message
    if(conObj != null && conObj.bytesRead > 0 && conObj.sizeOfMessage > 0) {
      // Calculate remaing bytes to fetch
      var remainingBytes = conObj.sizeOfMessage - conObj.bytesRead;
      // Check if we have multiple packet messages and save the pieces otherwise emit the message
      if(remainingBytes > result.length) {
        conObj.buffer = conObj.buffer + result; conObj.bytesRead = conObj.bytesRead + result.length;
      } else {
        // Cut off the remaining message
        conObj.buffer = conObj.buffer + result.substr(0, remainingBytes);
        // Emit the message
        self.emit("data", conObj.buffer);
        // Reset the variables
        conObj.buffer = ''; conObj.bytesRead = 0; conObj.sizeOfMessage = 0;
        // If message is longer than the current one, keep parsing
        if(remainingBytes < result.length) {
          // debug("--------------------------------------- remainingBytes < result.length :: " + this.fd)
          // receiveListener.call(this, result.substr(remainingBytes, (result.length - remainingBytes)));
          receiveListener(result.substr(remainingBytes, (result.length - remainingBytes)), fd);
        }
      }
    } else if(conObj != null){
      if(conObj.stubBuffer.length > 0) {
        result = conObj.stubBuffer + result;
        conObj.stubBuffer = '';
      }

      if(result.length > 4) {
        var sizeOfMessage = BinaryParser.toInt(result.substr(0, 4));
        // We got a partial message, store the result and wait for more
        if(sizeOfMessage > result.length) {
          conObj.buffer = conObj.buffer + result; conObj.bytesRead = result.length; conObj.sizeOfMessage = sizeOfMessage;
        } else if(sizeOfMessage == result.length) {
          self.emit("data", result);
        } else if(sizeOfMessage < result.length) {
          self.emit("data", result.substr(0, sizeOfMessage));
          // debug("--------------------------------------- sizeOfMessage < result.length :: " + this.fd)
          // receiveListener.call(this, result.substr(sizeOfMessage, (result.length - sizeOfMessage)));
          receiveListener(result.substr(sizeOfMessage, (result.length - sizeOfMessage)), fd);
        }
      } else {
        conObj.stubBuffer = result;
      }
    }
  };

  // Fill the pool
  for(var i = 0; i < poolSize; i++) {
    // Create the associated connection
    var connection = net.createConnection(self.port, self.host);
    // Set up the net client
    connection.setEncoding("binary");
    // Add connnect listener
    connection.addListener("connect", function() {
      this.setEncoding("binary");
      this.setTimeout(0);
      this.setNoDelay();
      // Update number of connected to server
      connectedTo = connectedTo + 1;
    });

    connection.addListener("error", function(err) {
      // Update number of errors
      errors = errors + 1;
      connectionError = err;
    });

    connection.addListener("timeout", function(err) {
      // Update number of errors
      errors = errors + 1;
      connectionError = err;
    });

    // Add a close listener
    connection.addListener("close", function() {
      self.emit("close");
    });

    // Add connection to the pool array
    connectionPool.push({"connection": connection,
      "sizeOfMessage": 0,
      "bytesRead": 0,
      "buffer": '',
      "stubBuffer": ''});
    // Add the listener to the connection
    connection.addListener("data", receiveListener);
  }

  // Function that wait for connection to finish up
  var waitForConnections = function() {
    // Emit a connect message once all connections are up
    if(connectedTo == connectionPool.length) {
      if(reconnect == null || !reconnect) {
        self.connected = true;
        self.poolByReference = {};

         // Save the connections by the fd reference
        self.pool.forEach(function(con) {
          self.poolByReference[con.connection.fd] = con;
        });

        self.emit("connect");
      } else {
        self.connected = false;
        self.emit("reconnect");
      }
    } else if(errors + connectedTo == connectionPool.length) {
      if(reconnect == null || !reconnect) {
        self.connected = false;
        self.emit("error", connectionError);
      } else {
        self.connected = false;
        self.emit("reconnect");
      }
    } else {
      process.nextTick(waitForConnections);
    }
  }

  // Wait until we are done connected to all pool entries before emitting connect signal
  process.nextTick(waitForConnections);

  // Return the pool
  return connectionPool;
}

// Functions to open the connection
Connection.prototype.open = function() {
  var self = this;
  // Create the pool with connections
  this.pool = setupConnectionPool(this, this.poolSize);
}

Connection.prototype.close = function() {
  this.connected = false;
  // Close all entries in the pool
  for(var i = 0; i < this.pool.length; i++) {
    this.pool[i].connection.end();
  }
};

Connection.prototype.send = function(command, rawConnection) {
  var self = this;
  // If we are executing the commnand on the entire pool
  var connection = null;
  // If we are forcing the use of a connection
  if(rawConnection != null) {
    connection = rawConnection;
  } else {
    connection = getConnection(self).connection;
  }

  // Check if the connection is closed
  try {
    if (connection.readyState != "open") {
      throw 'notConnected';
    }

    // Send the command, if it's an array of commands execute them all on the same connection
    if(Array.isArray(command)) {
      for(var i = 0; i < command.length; i++) {
        connection.write((typeof command[i] == 'string') ? command[i] : command[i].toBinary(), "binary");
      }
    } else {
      connection.write((typeof command == 'string') ? command : command.toBinary(), "binary");
    }
  } catch(err) {
    // Check if the connection is closed
    if(connection.readyState != "open" && self.autoReconnect) {
      // Add the message to the queue of messages to send
      self.messages.push(command);
      // Initiate reconnect if no current running
      if(self.currently_reconnecting == null || self.currently_reconnecting == false) {
        self.currently_reconnecting = true;

        // Create the pool with connections
        self.pool = setupConnectionPool(self, self.poolSize, true);
        self.poolByReference = {};
        // Save the connections by the fd reference
        self.pool.forEach(function(con) {
          self.poolByReference[con.connection.fd] = con;
        })

        // Wait for a reconnect and send all the messages
        self.on("reconnect", function() {
          self.currently_reconnecting = false;
          // Fire the message again
          while(self.messages.length > 0) {
            // Fetch a connection and resend messages
            connection = getConnection(self).connection;
            // Fetch the a message
            var command = self.messages.shift();
            // Fire
            if(Array.isArray(command)) {
              for(var i = 0; i < command.length; i++) {
                connection.write((typeof command[i] == 'string') ? command[i] : command[i].toBinary(), "binary");
              }
            } else {
              connection.write((typeof command == 'string') ? command : command.toBinary(), "binary");
            }
          }
        })
      }
    } else {
      // Set connected to false
      self.connected = false;
      // Throw error
      throw err;
    }
  }
};

/**
* Wrtie command without an attempt of reconnect
* @param command
*/
Connection.prototype.sendwithoutReconnect = function(command) {
  var self = this;
  var connection = this.connection;

  // Check if the connection is closed
  if (connection.readyState != "open") {
    throw new Error( 'Connection closed!' );
  }
  try {
    connection.write(command.toBinary(), "binary");
  } catch(err) {
    // no need to reconnect since called by latest master
    // and already went through send() function
    throw err;
  };
};

// Some basic defaults
Connection.DEFAULT_PORT = 27017;<commit_msg>Cleanup of sending code<commit_after>var net = require('net'),
  debug = require('util').debug,
  inspect = require('util').inspect,
  EventEmitter = require("events").EventEmitter,
  BinaryParser = require('./bson/binary_parser').BinaryParser,
  inherits = require('util').inherits,
  Server = require('./connections/server').Server;

var Connection = exports.Connection = function(host, port, autoReconnect, options) {
  this.options = options == null ? {} : options;
  this.host = host;
  this.port = port;
  this.autoReconnect = autoReconnect;
  this.drained = true;
  // Fetch the poolsize
  this.poolSize = this.options["poolSize"] == null ? 1 : this.options["poolSize"];
  // Reconnect buffer for messages
  this.messages = [];

  // Status messages
  this.sizeOfMessage = 0;
  this.bytesRead = 0;
  this.buffer = '';
  this.stubBuffer = '';
  this.connected = false;

  // Connection pool variables
  this.pool = [];
  this.poolByReference = {};
  this.poolIndex = 0;
};

inherits(Connection, EventEmitter);

var getConnection = function(self) {
  return self.pool[self.poolIndex++ % self.pool.length];
}

// Setup the connection pool
var setupConnectionPool = function(self, poolSize, reconnect) {
  // Pool off connections and status variables
  var connectionPool = [];
  var connectedTo = 0;
  var errors = 0;
  var connectionError = null;

  //
  // Listener that handles callbacks for the connection
  // Uses the internal object states to keep individual tcp connections seperate
  var receiveListener = function(result, fd) {
    fd = fd == null ? this.fd : fd;

    // Fetch the pool reference
    var conObj = self.poolByReference[fd];

    // if(conObj == null) {
    //   debug("================================================================ failed to find connection :: " + this.fd)
    //   debug(inspect(self.poolByReference))
    // }

    // Check if we have an unfinished message
    if(conObj != null && conObj.bytesRead > 0 && conObj.sizeOfMessage > 0) {
      // Calculate remaing bytes to fetch
      var remainingBytes = conObj.sizeOfMessage - conObj.bytesRead;
      // Check if we have multiple packet messages and save the pieces otherwise emit the message
      if(remainingBytes > result.length) {
        conObj.buffer = conObj.buffer + result; conObj.bytesRead = conObj.bytesRead + result.length;
      } else {
        // Cut off the remaining message
        conObj.buffer = conObj.buffer + result.substr(0, remainingBytes);
        // Emit the message
        self.emit("data", conObj.buffer);
        // Reset the variables
        conObj.buffer = ''; conObj.bytesRead = 0; conObj.sizeOfMessage = 0;
        // If message is longer than the current one, keep parsing
        if(remainingBytes < result.length) {
          // debug("--------------------------------------- remainingBytes < result.length :: " + this.fd)
          // receiveListener.call(this, result.substr(remainingBytes, (result.length - remainingBytes)));
          receiveListener(result.substr(remainingBytes, (result.length - remainingBytes)), fd);
        }
      }
    } else if(conObj != null){
      if(conObj.stubBuffer.length > 0) {
        result = conObj.stubBuffer + result;
        conObj.stubBuffer = '';
      }

      if(result.length > 4) {
        var sizeOfMessage = BinaryParser.toInt(result.substr(0, 4));
        // We got a partial message, store the result and wait for more
        if(sizeOfMessage > result.length) {
          conObj.buffer = conObj.buffer + result; conObj.bytesRead = result.length; conObj.sizeOfMessage = sizeOfMessage;
        } else if(sizeOfMessage == result.length) {
          self.emit("data", result);
        } else if(sizeOfMessage < result.length) {
          self.emit("data", result.substr(0, sizeOfMessage));
          // debug("--------------------------------------- sizeOfMessage < result.length :: " + this.fd)
          // receiveListener.call(this, result.substr(sizeOfMessage, (result.length - sizeOfMessage)));
          receiveListener(result.substr(sizeOfMessage, (result.length - sizeOfMessage)), fd);
        }
      } else {
        conObj.stubBuffer = result;
      }
    }
  };

  // Fill the pool
  for(var i = 0; i < poolSize; i++) {
    // Create the associated connection
    var connection = net.createConnection(self.port, self.host);
    // Set up the net client
    connection.setEncoding("binary");
    // Add connnect listener
    connection.addListener("connect", function() {
      this.setEncoding("binary");
      this.setTimeout(0);
      this.setNoDelay();
      // Update number of connected to server
      connectedTo = connectedTo + 1;
    });

    connection.addListener("error", function(err) {
      // Update number of errors
      errors = errors + 1;
      connectionError = err;
    });

    connection.addListener("timeout", function(err) {
      // Update number of errors
      errors = errors + 1;
      connectionError = err;
    });

    // Add a close listener
    connection.addListener("close", function() {
      self.emit("close");
    });

    // Add connection to the pool array
    connectionPool.push({"connection": connection,
      "sizeOfMessage": 0,
      "bytesRead": 0,
      "buffer": '',
      "stubBuffer": ''});
    // Add the listener to the connection
    connection.addListener("data", receiveListener);
  }

  // Function that wait for connection to finish up
  var waitForConnections = function() {
    // Emit a connect message once all connections are up
    if(connectedTo == connectionPool.length) {
      if(reconnect == null || !reconnect) {
        self.connected = true;
        self.poolByReference = {};

         // Save the connections by the fd reference
        self.pool.forEach(function(con) {
          self.poolByReference[con.connection.fd] = con;
        });

        self.emit("connect");
      } else {
        self.connected = false;
        self.emit("reconnect");
      }
    } else if(errors + connectedTo == connectionPool.length) {
      if(reconnect == null || !reconnect) {
        self.connected = false;
        self.emit("error", connectionError);
      } else {
        self.connected = false;
        self.emit("reconnect");
      }
    } else {
      process.nextTick(waitForConnections);
    }
  }

  // Wait until we are done connected to all pool entries before emitting connect signal
  process.nextTick(waitForConnections);

  // Return the pool
  return connectionPool;
}

// Functions to open the connection
Connection.prototype.open = function() {
  var self = this;
  // Create the pool with connections
  this.pool = setupConnectionPool(this, this.poolSize);
}

Connection.prototype.close = function() {
  this.connected = false;
  // Close all entries in the pool
  for(var i = 0; i < this.pool.length; i++) {
    this.pool[i].connection.end();
  }
};

Connection.prototype.send = function(command, rawConnection) {
  var self = this;
  // If we are executing the commnand on the entire pool
  var connection = null;
  // If we are forcing the use of a connection
  if(rawConnection != null) {
    connection = rawConnection;
  } else {
    connection = getConnection(self).connection;
  }

  // Check if the connection is closed
  try {
    if (connection.readyState != "open") {
      throw 'notConnected';
    }

    // Send the command, if it's an array of commands execute them all on the same connection
    if(Array.isArray(command)) {
      for(var i = 0; i < command.length; i++) {
        connection.write(command[i].toBinary(), "binary");
      }
    } else {
      connection.write(command.toBinary(), "binary");
    }
  } catch(err) {
    // Check if the connection is closed
    if(connection.readyState != "open" && self.autoReconnect) {
      // Add the message to the queue of messages to send
      self.messages.push(command);
      // Initiate reconnect if no current running
      if(self.currently_reconnecting == null || self.currently_reconnecting == false) {
        self.currently_reconnecting = true;

        // Create the pool with connections
        self.pool = setupConnectionPool(self, self.poolSize, true);
        self.poolByReference = {};
        // Save the connections by the fd reference
        self.pool.forEach(function(con) {
          self.poolByReference[con.connection.fd] = con;
        })

        // Wait for a reconnect and send all the messages
        self.on("reconnect", function() {
          self.currently_reconnecting = false;
          // Fire the message again
          while(self.messages.length > 0) {
            // Fetch a connection and resend messages
            connection = getConnection(self).connection;
            // Fetch the a message
            var command = self.messages.shift();
            // Fire
            if(Array.isArray(command)) {
              for(var i = 0; i < command.length; i++) {
                connection.write(command[i].toBinary(), "binary");
              }
            } else {
              connection.write(command.toBinary(), "binary");
            }
          }
        })
      }
    } else {
      // Set connected to false
      self.connected = false;
      // Throw error
      throw err;
    }
  }
};

/**
* Wrtie command without an attempt of reconnect
* @param command
*/
Connection.prototype.sendwithoutReconnect = function(command) {
  var self = this;
  var connection = this.connection;

  // Check if the connection is closed
  if (connection.readyState != "open") {
    throw new Error( 'Connection closed!' );
  }
  try {
    connection.write(command.toBinary(), "binary");
  } catch(err) {
    // no need to reconnect since called by latest master
    // and already went through send() function
    throw err;
  };
};

// Some basic defaults
Connection.DEFAULT_PORT = 27017;<|endoftext|>


<commit_before>'use strict';

var Node = require('../node');

var TYPE = 'closest';

var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    target: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    responses: Node.PARAM.NULLABLE(Node.PARAM.NUMBER(), 1)
};

var Closest = Node.create(TYPE, PARAMS, {cache: true, version: 1});

module.exports = Closest;

var closestTemplate = Node.template([
    'WITH',
    ' source as({{=it.squery}}),',
    ' target as({{=it.tquery}})',
    'SELECT',
    ' s.*,',
    ' t.cartodb_id as closest_id,',
    ' ST_Distance(geography(t.the_geom),',
    ' geography(s.the_geom)) as closest_dist',
    'FROM',
    '(',
        'SELECT DISTINCT ON (the_geom) *',
        ' FROM source',
    ') AS s',
    'CROSS JOIN LATERAL',
    '(',
        'SELECT cartodb_id, the_geom',
        ' FROM target',
        ' ORDER BY s.the_geom <-> the_geom',
        ' LIMIT {{=it.responses}}'
    ') AS t'
].join('\n');

Closest.prototype.sql = function(){
    return closestTemplate({
        squery: this.source.getQuery(),
        tquery: this.target.getQuery(),
        responses: this.responses
    });
};
<commit_msg>Add multiple results option<commit_after>'use strict';

var Node = require('../node');

var TYPE = 'closest';

var PARAMS = {
    source: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    target: Node.PARAM.NODE(Node.GEOMETRY.ANY),
    responses: Node.PARAM.NULLABLE(Node.PARAM.NUMBER(), 1)
};

var Closest = Node.create(TYPE, PARAMS, {cache: true, version: 1});

module.exports = Closest;

var closestTemplate = Node.template([
    'WITH',
    ' source as({{=it.squery}}),',
    ' target as({{=it.tquery}})',
    'SELECT',
    ' s.*,',
    ' t.cartodb_id as closest_id,',
    ' ST_Distance(geography(t.the_geom),',
    ' geography(s.the_geom)) as closest_dist',
    'FROM',
    '(',
        'SELECT DISTINCT ON (the_geom) *',
        ' FROM source',
    ') AS s',
    'CROSS JOIN LATERAL',
    '(',
        'SELECT cartodb_id, the_geom',
        ' FROM target',
        ' ORDER BY s.the_geom <-> the_geom',
        ' LIMIT {{=it.responses}}',
    ') AS t'
].join('\n');

Closest.prototype.sql = function(){
    return closestTemplate({
        squery: this.source.getQuery(),
        tquery: this.target.getQuery(),
        responses: this.responses
    });
};
<|endoftext|>


<commit_before>/*!
 * Pencil
 * Copyright(c) 2012 Gabriele Di Stefano <gabriele.ds@gmail.com>
 * MIT Licensed
 */

var	Pencil = require('./../../pencil')
	;

/**
 * Block
 */
var Block = module.exports = Pencil.jade.nodes.Block;<commit_msg>Update master<commit_after>/*!
 * Pencil
 * Copyright(c) 2012 Gabriele Di Stefano <gabriele.ds@gmail.com>
 * MIT Licensed
 */

var  Pencil = require('./../../pencil')
  ;

/**
 * Block
 */
var Block = module.exports = Pencil.jade.nodes.Block;<|endoftext|>


<commit_before>
(function(exports) {
	var phantomizer_helper = function(){

        var html_utils = require("./html_utils").html_utils;

        var get_r_config = function(rjs_base_url, requirejs_paths){
            var r_config = "";
            r_config += ""
            return r_config;
        }
        /**
         * Inject requireJS
         *
         * @param rjs_base_url
         * @param rjs_url
         * @param buf
         * @param main_url
         * @returns {*}
         */
        this.inject_requirejs = function(rjs_base_url, rjs_url, requirejs_paths, buf, main_url){
            var ncontent = "";
            if( rjs_url.substring ) rjs_url = [rjs_url];
            for(var n in rjs_url ){
                if( buf.match(rjs_base_url+rjs_url[n]) != null ){
                    var rjs_node = html_utils.find_rjs_nodes(buf, rjs_url[n], rjs_base_url)[0];
                    ncontent = "";
                    var r_config = get_r_config(rjs_base_url, requirejs_paths);
                    ncontent += r_config
                    ncontent += rjs_node.node+"";
                    if( main_url ){
                        ncontent += ""
                    }
                    buf = buf.replace(r_config,'');
                    buf = buf.replace(rjs_node.node, ncontent)
                    return buf;
                }
            }

            if( rjs_url.length > 0 ){
                if( main_url != null ){
                    ncontent = ""
                }else{
                    ncontent = ""
                }
                var r_config = get_r_config(rjs_base_url, requirejs_paths);
                buf = buf.replace(r_config,'');
                buf = buf.replace("", r_config+ncontent+"")
            }
            return buf
        };
        /**
         * Inject scripts before requirejs
         *
         * @param rjs_base_url
         * @param rjs_url
         * @param buf
         * @param injected
         * @returns {*}
         */
        this.inject_after_requirejs = function(rjs_base_url, rjs_url, requirejs_paths, buf, injected){
            if( rjs_url.substring ) rjs_url = [rjs_url];
            for(var n in rjs_url ){
                if( buf.match(rjs_base_url+rjs_url[n]) != null ){
                    var rjs_node = html_utils.find_rjs_nodes(buf, rjs_url[n], rjs_base_url)[0];
                    var content = "";
                    var r_config = get_r_config(rjs_base_url, requirejs_paths);
                    if( rjs_node.main ){
                        content += ""
                        if( injected ){
                            content += ""
                        }else{
                            content += ""
                        }
                    }else{
                        content += rjs_node.node+"";
                        if( injected ){
                            content += ""
                        }
                    }
                    buf = buf.replace(r_config,'');
                    buf = buf.replace(rjs_node.node, r_config+content)
                    return buf;
                }
            }
            return buf;
        }
        /**
         * Inject is_phantom variable to inject build status into DOM
         *
         * @param buf
         * @returns {XML|string}
         */
        this.inject_phantom = function(buf){
            var ncontent = ""
            ncontent += ""
            buf = buf.replace("", ""+ncontent)
            return buf
        };
        this.apply_scripts = function(scripts, base_url, html_content){
            if( scripts.append ){
                for( var target_merge in scripts.append ){
                    var asset_deps = scripts.append[target_merge];
                    html_content = html_utils.strip_scripts(asset_deps, html_content, base_url);
                    html_content = html_utils.append_script(target_merge, html_content );
                }
            }
            if( scripts.prepend ){
                for( var target_merge in scripts.prepend ){
                    var asset_deps = scripts.prepend[target_merge];
                    html_content = html_utils.strip_scripts(asset_deps, html_content, base_url);
                    var anchor = html_utils.script_anchor(html_content, base_url);
                    html_content = html_utils.prepend_script(target_merge, html_content, anchor);
                }
            }
            if( scripts.strip ){
                html_content = html_utils.strip_scripts(scripts.strip, html_content, base_url );
                //grunt.verbose.ok("scripts striped");
            }
            return html_content;
        }
        this.apply_styles = function(styles, base_url, html_content){
            if( styles.append ){
                for( var target_merge in styles.append ){
                    var asset_deps = styles.append[target_merge];
                    html_content = html_utils.strip_css(asset_deps, html_content, base_url);
                    html_content = html_utils.append_css(target_merge, html_content );
                   //grunt.verbose.ok("css injected "+target_merge+", append");
                }
            }
            if( styles.prepend ){
                for( var target_merge in styles.prepend ){
                    var asset_deps = styles.prepend[target_merge];
                    html_content = html_utils.strip_css(asset_deps, html_content, base_url);
                    var anchor = html_utils.css_anchor(html_content, base_url);
                    html_content = html_utils.prepend_css(target_merge, html_content, anchor);
                    //grunt.verbose.ok("css injected "+target_merge+", prepend");
                }
            }
            if( styles.strip ){
                html_content = html_utils.strip_css(styles.strip, html_content, base_url );
                //grunt.verbose.ok("css striped");
            }
            return html_content;
        }
	};

  // Expose the constructor function.
  exports.phantomizer_helper = new phantomizer_helper();
}(typeof exports === 'object' && exports || this));

<commit_msg>Imrpoved requires js insertion to prevent useless insertion<commit_after>
(function(exports) {
	var phantomizer_helper = function(){

        var html_utils = require("./html_utils").html_utils;

        this.get_r_config=function(rjs_base_url, requirejs_paths){
            var r_config = "";
            r_config += ""
            return r_config;
        }
        /**
         * Inject requireJS
         *
         * @param rjs_base_url
         * @param rjs_url
         * @param buf
         * @param main_url
         * @returns {*}
         */
        this.inject_requirejs = function(rjs_base_url, rjs_url, requirejs_paths, buf, main_url){
            var ncontent = "";
            if( rjs_url.substring ) rjs_url = [rjs_url];
            for(var n in rjs_url ){
                if( buf.match(rjs_base_url+rjs_url[n]) != null ){
                    var rjs_node = html_utils.find_rjs_nodes(buf, rjs_url[n], rjs_base_url)[0];
                    ncontent = "";
                    var r_config = this.get_r_config(rjs_base_url, requirejs_paths);
                    ncontent += r_config
                    ncontent += rjs_node.node+"";
                    if( main_url ){
                        ncontent += ""
                    }
                    buf = buf.replace(r_config,'');
                    buf = buf.replace(rjs_node.node, ncontent)
                    return buf;
                }
            }

            if( rjs_url.length > 0 ){
                if( main_url != null ){
                    ncontent = ""
                    var r_config = this.get_r_config(rjs_base_url, requirejs_paths);
                    buf = buf.replace(r_config,'');
                    buf = buf.replace("", r_config+ncontent+"")
                }
            }
            return buf
        };
        /**
         * Inject scripts before requirejs
         *
         * @param rjs_base_url
         * @param rjs_url
         * @param buf
         * @param injected
         * @returns {*}
         */
        this.inject_after_requirejs = function(rjs_base_url, rjs_url, requirejs_paths, buf, injected){
            var content = "";
            if( rjs_url.substring ) rjs_url = [rjs_url];
            for(var n in rjs_url ){
                if( buf.match(rjs_base_url+rjs_url[n]) != null ){
                    var rjs_node = html_utils.find_rjs_nodes(buf, rjs_url[n], rjs_base_url)[0];
                    content = "";
                    var r_config = this.get_r_config(rjs_base_url, requirejs_paths);
                    if( rjs_node.main ){
                        content += ""
                        if( injected ){
                            content += ""
                        }else{
                            content += ""
                        }
                    }else{
                        content += rjs_node.node+"";
                        if( injected ){
                            content += ""
                        }
                    }
                    buf = buf.replace(r_config,'');
                    buf = buf.replace(rjs_node.node, r_config+content)
                    return buf;
                }
            }
            if( rjs_url.length > 0 ){
                if( injected != null ){
                    content = ""
                    var r_config = this.get_r_config(rjs_base_url, requirejs_paths);
                    buf = buf.replace(r_config,'');
                    buf = buf.replace("", r_config+content+"")
                }
            }
            return buf;
        }
        /**
         * Inject is_phantom variable to inject build status into DOM
         *
         * @param buf
         * @returns {XML|string}
         */
        this.inject_phantom = function(buf){
            var ncontent = ""
            ncontent += ""
            buf = buf.replace("", ""+ncontent)
            return buf
        };
        this.apply_scripts = function(scripts, base_url, html_content){
            if( scripts.append ){
                for( var target_merge in scripts.append ){
                    var asset_deps = scripts.append[target_merge];
                    html_content = html_utils.strip_scripts(asset_deps, html_content, base_url);
                    html_content = html_utils.append_script(target_merge, html_content );
                }
            }
            if( scripts.prepend ){
                for( var target_merge in scripts.prepend ){
                    var asset_deps = scripts.prepend[target_merge];
                    html_content = html_utils.strip_scripts(asset_deps, html_content, base_url);
                    var anchor = html_utils.script_anchor(html_content, base_url);
                    html_content = html_utils.prepend_script(target_merge, html_content, anchor);
                }
            }
            if( scripts.strip ){
                html_content = html_utils.strip_scripts(scripts.strip, html_content, base_url );
                //grunt.verbose.ok("scripts striped");
            }
            return html_content;
        }
        this.apply_styles = function(styles, base_url, html_content){
            if( styles.append ){
                for( var target_merge in styles.append ){
                    var asset_deps = styles.append[target_merge];
                    html_content = html_utils.strip_css(asset_deps, html_content, base_url);
                    html_content = html_utils.append_css(target_merge, html_content );
                   //grunt.verbose.ok("css injected "+target_merge+", append");
                }
            }
            if( styles.prepend ){
                for( var target_merge in styles.prepend ){
                    var asset_deps = styles.prepend[target_merge];
                    html_content = html_utils.strip_css(asset_deps, html_content, base_url);
                    var anchor = html_utils.css_anchor(html_content, base_url);
                    html_content = html_utils.prepend_css(target_merge, html_content, anchor);
                    //grunt.verbose.ok("css injected "+target_merge+", prepend");
                }
            }
            if( styles.strip ){
                html_content = html_utils.strip_css(styles.strip, html_content, base_url );
                //grunt.verbose.ok("css striped");
            }
            return html_content;
        }
	};

  // Expose the constructor function.
  exports.phantomizer_helper = new phantomizer_helper();
}(typeof exports === 'object' && exports || this));

<|endoftext|>


<commit_before>'use strict';

let cheerio;
const escape = require('lodash/escape');

function tocHelper(str, options = {}) {
  if (!cheerio) cheerio = require('cheerio');

  const $ = cheerio.load(str);
  const headingsMaxDepth = options.hasOwnProperty('max_depth') ? options.max_depth : 6;
  const headingsSelector = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].slice(0, headingsMaxDepth).join(',');
  const headings = $(headingsSelector);

  if (!headings.length) return '';

  const className = options.class || 'toc';
  const listNumber = options.hasOwnProperty('list_number') ? options.list_number : true;
  let result = `<ol class="${className}">`;
  const lastNumber = [0, 0, 0, 0, 0, 0];
  let firstLevel = 0;
  let lastLevel = 0;

  headings.each(function() {
    const level = +this.name[1];
    const id = $(this).attr('id');
    const text = escape($(this).text());

    lastNumber[level - 1]++;

    for (let i = level; i <= 5; i++) {
      lastNumber[i] = 0;
    }

    if (firstLevel) {
      for (let i = level; i < lastLevel; i++) {
        result += '

';
      }

      if (level > lastLevel) {
        result += `<ol class="${className}-child">`;
      } else {
        result += '
';
      }
    } else {
      firstLevel = level;
    }

    result += `<li class="${className}-item ${className}-level-${level}">`;
    result += `<a class="${className}-link" href="#${id}">`;

    if (listNumber) {
      result += `<span class="${className}-number">`;

      for (let i = firstLevel - 1; i < level; i++) {
        result += `${lastNumber[i]}.`;
      }

      result += ' ';
    }

    result += `<span class="${className}-text">${text}</span></a>`;

    lastLevel = level;
  });

  for (let i = firstLevel - 1; i < lastLevel; i++) {
    result += '

';
  }

  return result;
}

module.exports = tocHelper;
<commit_msg>feat(toc): seek anchor id from parent nodes when target is not available<commit_after>'use strict';

let cheerio;
const escape = require('lodash/escape');

function tocHelper(str, options = {}) {
  if (!cheerio) cheerio = require('cheerio');

  const $ = cheerio.load(str);
  const headingsMaxDepth = options.hasOwnProperty('max_depth') ? options.max_depth : 6;
  const headingsSelector = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].slice(0, headingsMaxDepth).join(',');
  const headings = $(headingsSelector);

  if (!headings.length) return '';

  const className = options.class || 'toc';
  const listNumber = options.hasOwnProperty('list_number') ? options.list_number : true;
  let result = `<ol class="${className}">`;
  const lastNumber = [0, 0, 0, 0, 0, 0];
  let firstLevel = 0;
  let lastLevel = 0;

  headings.each(function() {
    function getId(ele) {
      const id = $(ele).attr('id');
      return id ||
        ($(ele).parent().is('html') ? null :
          getId($(ele).parent()));
    }
    const level = +this.name[1];
    const id = getId(this);
    const text = escape($(this).text());

    lastNumber[level - 1]++;

    for (let i = level; i <= 5; i++) {
      lastNumber[i] = 0;
    }

    if (firstLevel) {
      for (let i = level; i < lastLevel; i++) {
        result += '

';
      }

      if (level > lastLevel) {
        result += `<ol class="${className}-child">`;
      } else {
        result += '
';
      }
    } else {
      firstLevel = level;
    }

    result += `<li class="${className}-item ${className}-level-${level}">`;
    result += `<a class="${className}-link" href="#${id}">`;

    if (listNumber) {
      result += `<span class="${className}-number">`;

      for (let i = firstLevel - 1; i < level; i++) {
        result += `${lastNumber[i]}.`;
      }

      result += ' ';
    }

    result += `<span class="${className}-text">${text}</span></a>`;

    lastLevel = level;
  });

  for (let i = firstLevel - 1; i < lastLevel; i++) {
    result += '

';
  }

  return result;
}

module.exports = tocHelper;
<|endoftext|>


<commit_before>module.exports = inject;

function inject(bot) {
  bot.scoreboard = {};

  bot._client.on('scoreboard_objective', function(packet) {

    if(!bot.scoreboard[
      packet["name"]
      ]){
      bot.scoreboard[packet["name"]]
                    = {};

    }

    bot.scoreboard[packet["name"]]={"name": packet["name"],
                                    "displayText": packet["displayText"]};
    bot.scoreboard[packet["name"]]["items"]= {};

    bot.emit('scoreboardObjective', packet["name"], packet["displayText"]);

  });

  bot._client.on('scoreboard_score', function(packet) {
    if(bot.scoreboard[packet["scoreName"]]){

        if(!bot.scoreboard[packet["scoreName"]]
                          ["items"]
                          ){

          bot.scoreboard[packet["scoreName"]]
                        ["items"]
                        = {};
        }

        if(!bot.scoreboard[packet["scoreName"]]
                         ["items"]
                         [packet["itemName"]]
                         ){

          bot.scoreboard[packet["scoreName"]]
                        ["items"]
                        [packet["itemName"]]
                        = {};
        }

        bot.scoreboard[packet["scoreName"]]
                      ["items"]
                      [packet["itemName"]]
                      = packet["value"];
    }

    bot.emit('scoreboardScore', packet["itemName"], packet["action"], packet["scoreName"], packet["value"]);

  });

  bot._client.on('scoreboard_display_objective', function(packet) {
    if(bot.scoreboard[packet["name"]]){

      bot.scoreboard[packet["name"]]
      if(!bot.scoreboard[packet["name"]]
                      ["position"]
                      ){

      bot.scoreboard[packet["name"]]
                    ["position"]
                    = {};
      }

      bot.scoreboard[packet["name"]]
                    ["position"]
                    = packet["position"];
    }

    bot.emit('scoreboardDisplayObjective', packet["name"], packet["position"]);

  });

}

<commit_msg>Final cleanup (I hope)<commit_after>module.exports = inject;

function inject(bot) {
  bot.scoreboard = {};

  bot._client.on('scoreboard_objective', function(packet) {

    if(!bot.scoreboard[
      packet["name"]
      ]){
      bot.scoreboard[packet["name"]]
                    = {};

    }

    bot.scoreboard[packet["name"]]={"name": packet["name"],
                                    "displayText": packet["displayText"]};
    bot.scoreboard[packet["name"]]["items"]= {};

    bot.emit('scoreboardObjective', packet["name"], packet["displayText"]);

  });

  bot._client.on('scoreboard_score', function(packet) {
    if(bot.scoreboard[packet["scoreName"]]){

        if(!bot.scoreboard[packet["scoreName"]]
                          ["items"]
                          ){

          bot.scoreboard[packet["scoreName"]]
                        ["items"]
                        = {};
        }

        if(!bot.scoreboard[packet["scoreName"]]
                         ["items"]
                         [packet["itemName"]]
                         ){

          bot.scoreboard[packet["scoreName"]]
                        ["items"]
                        [packet["itemName"]]
                        = {};
        }

        bot.scoreboard[packet["scoreName"]]
                      ["items"]
                      [packet["itemName"]]
                      = packet["value"];
    }

    bot.emit('scoreboardScore', packet["scoreName"], packet["itemName"], packet["value"]);

  });

  bot._client.on('scoreboard_display_objective', function(packet) {
    if(bot.scoreboard[packet["name"]]){

      bot.scoreboard[packet["name"]]
      if(!bot.scoreboard[packet["name"]]
                      ["position"]
                      ){

      bot.scoreboard[packet["name"]]
                    ["position"]
                    = {};
      }

      bot.scoreboard[packet["name"]]
                    ["position"]
                    = packet["position"];
    }

    bot.emit('scoreboardDisplayObjective', packet["name"], packet["position"]);

  });

}
<|endoftext|>


<commit_before>
var Plugger = require('plugger')
  , methods = require('methods')
  , debug = require('debug')('pnp-express-router')
  , path = require('path')
  ;

/**
 * Cache
 */
var slice = Array.prototype.slice;

/**
 * Methods that exist in router files
 */
var DEF_ROUTE_OPTIONS = {
    types: [
        'params'
      , 'external'
      , 'validate'
      , 'validated'
      , 'check'
      , 'checked'
      , 'authenticate'
      , 'authenticated'
    ]
  , middlewares: {

    }
};

/**
 * Protocol to be followed by all routes
 */
var DEF_PROTOCOL = {
    main: false
  , id: 'name'
  , orderBy: 'priority'
  , contract: {
        name: 'string'
      , priority: 'number'
    }
};

/**
 *
 * @param config {Object}     node-convict configuration
 * @param app {Object}        express app
 * @param options {Object}    options including 'isSubApp' and 'plugins'
 * @param callback            feedback on plugin invocation
 * @returns {RouteLoader}
 * @constructor
 */
function RouteLoader(config, app, options, callback) {
    if (!(this instanceof RouteLoader)) {
        return new RouteLoader(config, app, options);
    }

    options = options || {};
    options.plugins = options.plugins || [];
    options.protocol = options.protocol || DEF_PROTOCOL;
    options.routeOptions = options.routeOptions || DEF_ROUTE_OPTIONS;

    this._routeTypes = options.routeOptions.types || DEF_ROUTE_OPTIONS.types;
    this._middlewares = options.routeOptions.middlewares || DEF_ROUTE_OPTIONS.middlewares;

    this._options = options;
    this._config = config;
    this._app = app;
    this._routes = [];
    this.plugger = null;

    if (!this._routeTypes.length || !this._config || !this._app) {
        throw new Error('Invalid arguments');
    }

    return this;
}

/**
 * Allows adding a route before init
 * @param plugin
 */
RouteLoader.prototype.addRoute = function (plugin) {
    if (typeof plugin !== 'object' || !plugin.path) {
        throw new Error('Invalid arguments');
    }

    if (this.plugger != null) {
        throw new Error('Routes already initialized');
    }

    this._options.plugins.push(plugin);
}

/**
 * Initializes detected routes and invokes hooks
 */
RouteLoader.prototype.init = function () {
    var args = slice.call(arguments)
      , self = this
      , options = this._options
      , routeTypes = this._routeTypes
      , priority = 1
      , plugger
      , pluginOpts
      ;

    pluginOpts = {
        protocol: options.protocol
        , filter: function (plugin) {
            for (var i = 0, l = routeTypes.length; i < l; i++) {
                if (typeof plugin[routeTypes[i]] === 'function') {
                    debug('accepted route: ' + plugin[options.protocol.id]);
                    return true;
                }
            }

            debug('ignored route: ' + plugin[options.protocol.id]);
            return false;
        }
    };

    this.plugger = plugger = new Plugger(options.plugins, pluginOpts, function (err) {
        if (typeof callback === 'function') {
            callback(err);
        }

        debug('complete', err || true);
    });

    plugger.forEach(function (plugin) {
        routeTypes.forEach(function (routeType) {
            if (typeof plugin[routeType] === 'function') {

                plugger.hook(routeType, { priority: priority }, function () {
                    plugin[routeType].apply(plugin, self._buildPluginArgs(routeType, plugin, slice.call(arguments)));
                });

                priority++;
            }
        });
    });

    // let plugins register their hooks
    plugger.init();
    plugger.seal();

    routeTypes.forEach(function (routeType) {

        // pass on arguments, if any, to every 'routeType' hook
        var fnArgs = (args.length > 0)
            ? args.slice(0)
            : [];

        fnArgs.unshift(routeType);
        self._dispatchEvent.apply(self, fnArgs);
    });
};

/**
 * Returns registered routes
 * @returns {Array}
 */
RouteLoader.prototype.getRoutes = function () {
    return this._routes || [];
};

/**
 * Prints all registered routes
 */
RouteLoader.prototype.debug = function () {
    console.log('\n---------------');

    this._routes.forEach(function (route) {
        console.log('[ROUTE] ' + route.method + ' '  + route.path + ' | ' + route.plugin + '.' + route.routeType);
    });

    console.log('---------------\n');
};

/**
 * Invoke registered hooks for the specified event
 * @returns {boolean}
 * @private
 */
RouteLoader.prototype._dispatchEvent = function () {
    if (arguments.length === 0) {
        debug('_dispatchEvent: invalid args');
        return false;
    }

    var args = slice.call(arguments) || []
      , plugger = this.plugger
      ;

    debug('invoking ' + args[0]);
    plugger.invoke.apply(plugger, args);
    return true;
};

RouteLoader.prototype._buildPluginArgs = function (routeType, plugin, pluginArgs) {

    var routes = this._routes
      , middleware = this._middlewares[routeType] || false
      , app = this._app
      , config = this._config
      , id = this._options.protocol.id
      , routerApp = {}
      , appFns = methods
      ;

    appFns.push('param', 'use');

    appFns.forEach(function (fn) {
        routerApp[fn] = function () {
            if (!arguments.length) {
                return;
            }

            var args = slice.call(arguments)
              , path
              ;

            if (typeof middleware === 'function') {
                // attach middleware
                path = args.shift();
                args.unshift(middleware);
                args.unshift(path);

                debug('attached middleware for path: ' + path);
            }

            // call actual app
            app[fn].apply(app, args);

            // record registered routes
            routes.push({
                plugin: plugin[id]
              , routeType: routeType
              , method: fn.toUpperCase()
              , path: args[0]
            });
        };
    });

    routerApp = (Object.keys(routerApp).length > 0)
        ? routerApp
        : app;

    pluginArgs.unshift(routerApp);
    pluginArgs.unshift(config);

    return pluginArgs;
};

module.exports = exports = RouteLoader;<commit_msg>Added missing proxy methods<commit_after>
var Plugger = require('plugger')
  , methods = require('methods')
  , debug = require('debug')('pnp-express-router')
  , path = require('path')
  ;

/**
 * Cache
 */
var slice = Array.prototype.slice;

/**
 * Methods that exist in router files
 */
var DEF_ROUTE_OPTIONS = {
    types: [
        'params'
      , 'external'
      , 'validate'
      , 'validated'
      , 'check'
      , 'checked'
      , 'authenticate'
      , 'authenticated'
    ]
  , middlewares: {

    }
};

/**
 * Protocol to be followed by all routes
 */
var DEF_PROTOCOL = {
    main: false
  , id: 'name'
  , orderBy: 'priority'
  , contract: {
        name: 'string'
      , priority: 'number'
    }
};

/**
 *
 * @param config {Object}     node-convict configuration
 * @param app {Object}        express app
 * @param options {Object}    options including 'isSubApp' and 'plugins'
 * @param callback            feedback on plugin invocation
 * @returns {RouteLoader}
 * @constructor
 */
function RouteLoader(config, app, options, callback) {
    if (!(this instanceof RouteLoader)) {
        return new RouteLoader(config, app, options);
    }

    options = options || {};
    options.plugins = options.plugins || [];
    options.protocol = options.protocol || DEF_PROTOCOL;
    options.routeOptions = options.routeOptions || DEF_ROUTE_OPTIONS;

    this._routeTypes = options.routeOptions.types || DEF_ROUTE_OPTIONS.types;
    this._middlewares = options.routeOptions.middlewares || DEF_ROUTE_OPTIONS.middlewares;

    this._options = options;
    this._config = config;
    this._app = app;
    this._routes = [];
    this.plugger = null;

    if (!this._routeTypes.length || !this._config || !this._app) {
        throw new Error('Invalid arguments');
    }

    return this;
}

/**
 * Allows adding a route before init
 * @param plugin
 */
RouteLoader.prototype.addRoute = function (plugin) {
    if (typeof plugin !== 'object' || !plugin.path) {
        throw new Error('Invalid arguments');
    }

    if (this.plugger != null) {
        throw new Error('Routes already initialized');
    }

    this._options.plugins.push(plugin);
}

/**
 * Initializes detected routes and invokes hooks
 */
RouteLoader.prototype.init = function () {
    var args = slice.call(arguments)
      , self = this
      , options = this._options
      , routeTypes = this._routeTypes
      , priority = 1
      , plugger
      , pluginOpts
      ;

    pluginOpts = {
        protocol: options.protocol
        , filter: function (plugin) {
            for (var i = 0, l = routeTypes.length; i < l; i++) {
                if (typeof plugin[routeTypes[i]] === 'function') {
                    debug('accepted route: ' + plugin[options.protocol.id]);
                    return true;
                }
            }

            debug('ignored route: ' + plugin[options.protocol.id]);
            return false;
        }
    };

    this.plugger = plugger = new Plugger(options.plugins, pluginOpts, function (err) {
        if (typeof callback === 'function') {
            callback(err);
        }

        debug('complete', err || true);
    });

    plugger.forEach(function (plugin) {
        routeTypes.forEach(function (routeType) {
            if (typeof plugin[routeType] === 'function') {

                plugger.hook(routeType, { priority: priority }, function () {
                    plugin[routeType].apply(plugin, self._buildPluginArgs(routeType, plugin, slice.call(arguments)));
                });

                priority++;
            }
        });
    });

    // let plugins register their hooks
    plugger.init();
    plugger.seal();

    routeTypes.forEach(function (routeType) {

        // pass on arguments, if any, to every 'routeType' hook
        var fnArgs = (args.length > 0)
            ? args.slice(0)
            : [];

        fnArgs.unshift(routeType);
        self._dispatchEvent.apply(self, fnArgs);
    });
};

/**
 * Returns registered routes
 * @returns {Array}
 */
RouteLoader.prototype.getRoutes = function () {
    return this._routes || [];
};

/**
 * Prints all registered routes
 */
RouteLoader.prototype.debug = function () {
    console.log('\n---------------');

    this._routes.forEach(function (route) {
        console.log('[ROUTE] ' + route.method + ' '  + route.path + ' | ' + route.plugin + '.' + route.routeType);
    });

    console.log('---------------\n');
};

/**
 * Invoke registered hooks for the specified event
 * @returns {boolean}
 * @private
 */
RouteLoader.prototype._dispatchEvent = function () {
    if (arguments.length === 0) {
        debug('_dispatchEvent: invalid args');
        return false;
    }

    var args = slice.call(arguments) || []
      , plugger = this.plugger
      ;

    debug('invoking ' + args[0]);
    plugger.invoke.apply(plugger, args);
    return true;
};

RouteLoader.prototype._buildPluginArgs = function (routeType, plugin, pluginArgs) {

    var routes = this._routes
      , middleware = this._middlewares[routeType] || false
      , app = this._app
      , config = this._config
      , id = this._options.protocol.id
      , routerApp = {}
      , appFns = methods
      ;

    appFns.push('del', 'all', 'param', 'use');

    appFns.forEach(function (fn) {
        routerApp[fn] = function () {
            if (!arguments.length) {
                return;
            }

            var args = slice.call(arguments)
              , path
              ;

            if (typeof middleware === 'function') {
                // attach middleware
                path = args.shift();
                args.unshift(middleware);
                args.unshift(path);

                debug('attached middleware for path: ' + path);
            }

            // call actual app
            app[fn].apply(app, args);

            // record registered routes
            routes.push({
                plugin: plugin[id]
              , routeType: routeType
              , method: fn.toUpperCase()
              , path: args[0]
            });
        };
    });

    routerApp = (Object.keys(routerApp).length > 0)
        ? routerApp
        : app;

    pluginArgs.unshift(routerApp);
    pluginArgs.unshift(config);

    return pluginArgs;
};

module.exports = exports = RouteLoader;<|endoftext|>