<commit_before>define(function(require) {
  /*
    DEPENDENCIES
   */

  var TabDataTable = require('utils/tab-datatable');
  var VMsTableUtils = require('./utils/datatable-common');
  var SunstoneConfig = require('sunstone-config');
  var Locale = require('utils/locale');
  var StateActions = require('./utils/state-actions');
  var Sunstone = require('sunstone');
  var Vnc = require('utils/vnc');
  var Spice = require('utils/spice');
  var Notifier = require('utils/notifier');

  /*
    CONSTANTS
   */

  var RESOURCE = "VM";
  var XML_ROOT = "VM";
  var TAB_NAME = require('./tabId');

  /*
    CONSTRUCTOR
   */

  function Table(dataTableId, conf) {
    this.conf = conf || {};
    this.tabId = TAB_NAME;
    this.dataTableId = dataTableId;
    this.resource = RESOURCE;
    this.xmlRoot = XML_ROOT;

    this.dataTableOptions = {
      "bAutoWidth": false,
      "bSortClasses" : false,
      "bDeferRender": true,
      "aoColumnDefs": [
          {"bSortable": false, "aTargets": ["check", 6, 7, 11]},
          {"sWidth": "35px", "aTargets": [0]},
          {"bVisible": true, "aTargets": SunstoneConfig.tabTableColumns(TAB_NAME)},
          {"bVisible": false, "aTargets": ['_all']}
      ]
    }

    this.columns = VMsTableUtils.columns;

    this.selectOptions = {
      "id_index": 1,
      "name_index": 4,
      "select_resource": Locale.tr("Please select a VM from the list"),
      "you_selected": Locale.tr("You selected the following VM:"),
      "select_resource_multiple": Locale.tr("Please select one or more VMs from the list"),
      "you_selected_multiple": Locale.tr("You selected the following VMs:")
    };

    this.totalVms = 0;
    this.activeVms = 0;
    this.pendingVms = 0;
    this.failedVms = 0;
    this.offVms = 0;

    TabDataTable.call(this);
  };

  Table.prototype = Object.create(TabDataTable.prototype);
  Table.prototype.constructor = Table;
  Table.prototype.elementArray = _elementArray;
  Table.prototype.initialize = _initialize;
  Table.prototype.preUpdateView = _preUpdateView;
  Table.prototype.postUpdateView = _postUpdateView;

  return Table;

  /*
    FUNCTION DEFINITIONS
   */

  function _elementArray(element_json) {
    this.totalVms++;
    switch (state) {
      case "INIT":
      case "PENDING":
      case "HOLD":
        this.pendingVms++;
        break;
      case "FAILED":
        this.failedVms++;
        break;
      case "ACTIVE":
        this.activeVms++;
        break;
      case "STOPPED":
      case "SUSPENDED":
      case "POWEROFF":
        this.offVms++;
        break;
      default:
        break;
    }

    return VMsTableUtils.elementArray(element_json);
  }

  function _preUpdateView() {
    StateActions.resetStateButtons();

    this.totalVms = 0;
    this.activeVms = 0;
    this.pendingVms = 0;
    this.failedVms = 0;
    this.offVms = 0;
  }

  function _postUpdateView() {
    $(".total_vms").text(this.totalVms);
    $(".active_vms").text(this.activeVms);
    $(".pending_vms").text(this.pendingVms);
    $(".failed_vms").text(this.failedVms);
    $(".off_vms").text(this.offVms);
  }

  function _initialize(opts) {
    TabDataTable.prototype.initialize.call(this, opts);

    $('#' + this.dataTableId).on("click", '.vnc', function() {
      var vmId = $(this).attr('vm_id');

      if (!Vnc.lockStatus()) {
        Spice.lock();
        Sunstone.runAction("VM.startvnc_action", vmId);
      } else {
        Notifier.notifyError(tr("VNC Connection in progress"))
      }

      return false;
    });

    $('#' + this.dataTableId).on("click", '.spice', function() {
      var vmId = $(this).attr('vm_id');

      if (!Spice.lockStatus()) {
        Spice.lock();
        Sunstone.runAction("VM.startspice_action", vmId);
      } else {
        Notifier.notifyError(tr("SPICE Connection in progress"))
      }

      return false;
    });
  }
});
<commit_msg>Feature #3748: Fix vm datatable after rebase<commit_after>define(function(require) {
  /*
    DEPENDENCIES
   */

  var TabDataTable = require('utils/tab-datatable');
  var VMsTableUtils = require('./utils/datatable-common');
  var OpenNebulaVM = require('opennebula/vm');
  var SunstoneConfig = require('sunstone-config');
  var Locale = require('utils/locale');
  var StateActions = require('./utils/state-actions');
  var Sunstone = require('sunstone');
  var Vnc = require('utils/vnc');
  var Spice = require('utils/spice');
  var Notifier = require('utils/notifier');

  /*
    CONSTANTS
   */

  var RESOURCE = "VM";
  var XML_ROOT = "VM";
  var TAB_NAME = require('./tabId');

  /*
    CONSTRUCTOR
   */

  function Table(dataTableId, conf) {
    this.conf = conf || {};
    this.tabId = TAB_NAME;
    this.dataTableId = dataTableId;
    this.resource = RESOURCE;
    this.xmlRoot = XML_ROOT;

    this.dataTableOptions = {
      "bAutoWidth": false,
      "bSortClasses" : false,
      "bDeferRender": true,
      "aoColumnDefs": [
          {"bSortable": false, "aTargets": ["check", 6, 7, 11]},
          {"sWidth": "35px", "aTargets": [0]},
          {"bVisible": true, "aTargets": SunstoneConfig.tabTableColumns(TAB_NAME)},
          {"bVisible": false, "aTargets": ['_all']}
      ]
    }

    this.columns = VMsTableUtils.columns;

    this.selectOptions = {
      "id_index": 1,
      "name_index": 4,
      "select_resource": Locale.tr("Please select a VM from the list"),
      "you_selected": Locale.tr("You selected the following VM:"),
      "select_resource_multiple": Locale.tr("Please select one or more VMs from the list"),
      "you_selected_multiple": Locale.tr("You selected the following VMs:")
    };

    this.totalVms = 0;
    this.activeVms = 0;
    this.pendingVms = 0;
    this.failedVms = 0;
    this.offVms = 0;

    TabDataTable.call(this);
  };

  Table.prototype = Object.create(TabDataTable.prototype);
  Table.prototype.constructor = Table;
  Table.prototype.elementArray = _elementArray;
  Table.prototype.initialize = _initialize;
  Table.prototype.preUpdateView = _preUpdateView;
  Table.prototype.postUpdateView = _postUpdateView;

  return Table;

  /*
    FUNCTION DEFINITIONS
   */

  function _elementArray(element_json) {
    var element = element_json[XML_ROOT];
    var state = OpenNebulaVM.stateStr(element.STATE);

    this.totalVms++;
    switch (state) {
      case "INIT":
      case "PENDING":
      case "HOLD":
        this.pendingVms++;
        break;
      case "FAILED":
        this.failedVms++;
        break;
      case "ACTIVE":
        this.activeVms++;
        break;
      case "STOPPED":
      case "SUSPENDED":
      case "POWEROFF":
        this.offVms++;
        break;
      default:
        break;
    }

    return VMsTableUtils.elementArray(element_json);
  }

  function _preUpdateView() {
    StateActions.resetStateButtons();

    this.totalVms = 0;
    this.activeVms = 0;
    this.pendingVms = 0;
    this.failedVms = 0;
    this.offVms = 0;
  }

  function _postUpdateView() {
    $(".total_vms").text(this.totalVms);
    $(".active_vms").text(this.activeVms);
    $(".pending_vms").text(this.pendingVms);
    $(".failed_vms").text(this.failedVms);
    $(".off_vms").text(this.offVms);
  }

  function _initialize(opts) {
    TabDataTable.prototype.initialize.call(this, opts);

    $('#' + this.dataTableId).on("click", '.vnc', function() {
      var vmId = $(this).attr('vm_id');

      if (!Vnc.lockStatus()) {
        Spice.lock();
        Sunstone.runAction("VM.startvnc_action", vmId);
      } else {
        Notifier.notifyError(tr("VNC Connection in progress"))
      }

      return false;
    });

    $('#' + this.dataTableId).on("click", '.spice', function() {
      var vmId = $(this).attr('vm_id');

      if (!Spice.lockStatus()) {
        Spice.lock();
        Sunstone.runAction("VM.startspice_action", vmId);
      } else {
        Notifier.notifyError(tr("SPICE Connection in progress"))
      }

      return false;
    });
  }
});
<|endoftext|>


<commit_before>var util = Npm.require('util');
var EventEmitter = Npm.require('events').EventEmitter;
var Fibers = Npm.require('fibers');
var Future = Npm.require('fibers/future');

function SmartCollection(collectionName) {
  var self = this;
  this._collection = null;
  this.validators = createValidators();

  this.name = collectionName;
  this.versionManager = new Meteor.SmartVersionManager();

  //register collection
  Meteor.SmartInvalidator.registerCollection(collectionName, this);

  if(Meteor.SmartMongo.db) {
    createCollection();
  } else {
    Meteor.SmartMongo.once('ready', createCollection);
  }

  function createCollection() {
    self._collection = Meteor.SmartMongo.db.collection(collectionName);
    self.emit('ready');
  }

  //do both fiber and non-fiber support
  ['insert', 'update', 'remove', 'findOne', 'find'].forEach(function(writeMethod) {
    self[writeMethod] = function() {
      var future;
      if(Fibers.current) {
        future = new Future();
        Array.prototype.push.call(arguments, future.resolver());
      }

      var args = arguments;
      var rtn;
      if(self._collection) {
        rtn = applyMethod(args);
      } else {
        self.on('ready', function() {
          rtn = applyMethod(args);
        });
      }

      if(future) future.wait();

      //returning _id after inserted. only available for inserts
      if(future) {
        return future.value;
      } else {
        return rtn;
      }
    };

    //ensure called after once _collection is ready
    function applyMethod(args) {
      if(self._collection) {
        doApply();
      } else {
        self.once('ready', doApply);
      }

      function doApply() {
        self['_' + writeMethod].apply(self, args)
      }
    }
  });

  function createValidators() {
    var defaultResult = Meteor.Collection.insecure === true;
    return {
      insert: new Meteor.SmartValidator(defaultResult),
      update: new Meteor.SmartValidator(defaultResult),
      remove: new Meteor.SmartValidator(defaultResult)
    }
  }
}

util.inherits(SmartCollection, EventEmitter);

SmartCollection.prototype._find = function(selector, options, callback) {
  selector = this._normalizeSelector(selector);
  if(typeof(selector) == 'function') {
    callback = selector;
    selector = {};
    options = {};
  } else if(typeof(options) == 'function') {
    callback = options;
    options = {};
  }

  var mongoCursor = this._collection.find(selector, options);
  var cursor = new Meteor.SmartCursor(mongoCursor, this);
  if(callback) callback(null, cursor);
};

SmartCollection.prototype.allow = function(validateFunctions) {
  var self = this;
  ['insert', 'update', 'remove'].forEach(function(type) {
    var func = validateFunctions[type];
    if(func) {
      self.validators[type].register('allow', func);
    }
  });
};

SmartCollection.prototype.deny = function(validateFunctions) {
  var self = this;
  ['insert', 'update', 'remove'].forEach(function(type) {
    var func = validateFunctions[type];
    if(func) {
      self.validators[type].register('deny', func);
    }
  });
};

SmartCollection.prototype._findOne = function(selector, callback) {
  selector = this._normalizeSelector(selector);
  this._collection.findOne(selector, callback);
};

SmartCollection.prototype._insert = function _insert(document, callback) {
  var self = this;
  if(!document._id) {
    document._id = Random.id();
  }

  this._collection.insert(document, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback(null, document._id);
      Meteor.SmartInvalidator.invalidateInsert(self.name, document);
    }
  });
};

SmartCollection.prototype._update = function(selector, mod, options, callback) {
  selector = this._normalizeSelector(selector);
  var self = this;
  if(typeof(options) == 'function') {
    callback = options;
    options = {};
  }

  this._collection.update(selector, mod, options, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback();
      if(typeof(selector._id) == 'string') {
        Meteor.SmartInvalidator.invalidateUpdate(self.name, selector._id, mod);
      } else {
        Meteor.SmartInvalidator.invalidateMultiUpdate(self.name, selector, mod);
      }
    }
  });
};

SmartCollection.prototype._remove = function(selector, callback) {
  selector = this._normalizeSelector(selector);
  var self = this;
  this._collection.remove(selector, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback();
      if(typeof(selector._id) == 'string') {
        Meteor.SmartInvalidator.invalidateRemove(self.name, selector._id);
      } else {
        Meteor.SmartInvalidator.invalidateMultiRemove(self.name, selector);
      }
    }
  });
};

SmartCollection.prototype._normalizeSelector = function(selector) {
  if(selector == undefined || selector == null) {
    return {};
  } if(typeof(selector) == 'string') {
    return {_id: selector};
  } else if(typeof(selector) == 'number') {
    throw new Error('Smart Collections does not support number as the _id yet. Use a string instead');
  } else {
    return selector;
  }
};

Meteor.SmartCollection = SmartCollection;
<commit_msg>added .fineOne() support for options<commit_after>var util = Npm.require('util');
var EventEmitter = Npm.require('events').EventEmitter;
var Fibers = Npm.require('fibers');
var Future = Npm.require('fibers/future');

function SmartCollection(collectionName) {
  var self = this;
  this._collection = null;
  this.validators = createValidators();

  this.name = collectionName;
  this.versionManager = new Meteor.SmartVersionManager();

  //register collection
  Meteor.SmartInvalidator.registerCollection(collectionName, this);

  if(Meteor.SmartMongo.db) {
    createCollection();
  } else {
    Meteor.SmartMongo.once('ready', createCollection);
  }

  function createCollection() {
    self._collection = Meteor.SmartMongo.db.collection(collectionName);
    self.emit('ready');
  }

  //do both fiber and non-fiber support
  ['insert', 'update', 'remove', 'findOne', 'find'].forEach(function(writeMethod) {
    self[writeMethod] = function() {
      var future;
      if(Fibers.current) {
        future = new Future();
        Array.prototype.push.call(arguments, future.resolver());
      }

      var args = arguments;
      var rtn;
      if(self._collection) {
        rtn = applyMethod(args);
      } else {
        self.on('ready', function() {
          rtn = applyMethod(args);
        });
      }

      if(future) future.wait();

      //returning _id after inserted. only available for inserts
      if(future) {
        return future.value;
      } else {
        return rtn;
      }
    };

    //ensure called after once _collection is ready
    function applyMethod(args) {
      if(self._collection) {
        doApply();
      } else {
        self.once('ready', doApply);
      }

      function doApply() {
        self['_' + writeMethod].apply(self, args)
      }
    }
  });

  function createValidators() {
    var defaultResult = Meteor.Collection.insecure === true;
    return {
      insert: new Meteor.SmartValidator(defaultResult),
      update: new Meteor.SmartValidator(defaultResult),
      remove: new Meteor.SmartValidator(defaultResult)
    }
  }
}

util.inherits(SmartCollection, EventEmitter);

SmartCollection.prototype._find = function(selector, options, callback) {
  selector = this._normalizeSelector(selector);
  if(typeof(selector) == 'function') {
    callback = selector;
    selector = {};
    options = {};
  } else if(typeof(options) == 'function') {
    callback = options;
    options = {};
  }

  var mongoCursor = this._collection.find(selector, options);
  var cursor = new Meteor.SmartCursor(mongoCursor, this);
  if(callback) callback(null, cursor);
};

SmartCollection.prototype.allow = function(validateFunctions) {
  var self = this;
  ['insert', 'update', 'remove'].forEach(function(type) {
    var func = validateFunctions[type];
    if(func) {
      self.validators[type].register('allow', func);
    }
  });
};

SmartCollection.prototype.deny = function(validateFunctions) {
  var self = this;
  ['insert', 'update', 'remove'].forEach(function(type) {
    var func = validateFunctions[type];
    if(func) {
      self.validators[type].register('deny', func);
    }
  });
};

SmartCollection.prototype._findOne = function(selector, options, callback) {
  selector = this._normalizeSelector(selector);
  this._collection.findOne.apply(this._collection, arguments);
};

SmartCollection.prototype._insert = function _insert(document, callback) {
  var self = this;
  if(!document._id) {
    document._id = Random.id();
  }

  this._collection.insert(document, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback(null, document._id);
      Meteor.SmartInvalidator.invalidateInsert(self.name, document);
    }
  });
};

SmartCollection.prototype._update = function(selector, mod, options, callback) {
  selector = this._normalizeSelector(selector);
  var self = this;
  if(typeof(options) == 'function') {
    callback = options;
    options = {};
  }

  this._collection.update(selector, mod, options, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback();
      if(typeof(selector._id) == 'string') {
        Meteor.SmartInvalidator.invalidateUpdate(self.name, selector._id, mod);
      } else {
        Meteor.SmartInvalidator.invalidateMultiUpdate(self.name, selector, mod);
      }
    }
  });
};

SmartCollection.prototype._remove = function(selector, callback) {
  selector = this._normalizeSelector(selector);
  var self = this;
  this._collection.remove(selector, function(err) {
    if(err) {
      if(callback) callback(err);
    } else {
      if(callback) callback();
      if(typeof(selector._id) == 'string') {
        Meteor.SmartInvalidator.invalidateRemove(self.name, selector._id);
      } else {
        Meteor.SmartInvalidator.invalidateMultiRemove(self.name, selector);
      }
    }
  });
};

SmartCollection.prototype._normalizeSelector = function(selector) {
  if(selector == undefined || selector == null) {
    return {};
  } if(typeof(selector) == 'string') {
    return {_id: selector};
  } else if(typeof(selector) == 'number') {
    throw new Error('Smart Collections does not support number as the _id yet. Use a string instead');
  } else {
    return selector;
  }
};

Meteor.SmartCollection = SmartCollection;
<|endoftext|>


<commit_before>'use strict';
const assert = require('assert');
const plugins = require('../../plugins');
const config = require('../config');
const fs = require('fs');
const path = require('path');
const waterStream = require('water-stream');
const helpers = require('../../shared/helpers');

// Set the cache ttl from the configuration
waterStream.cached.config({
  stdTTL: (config.cache && config.cache.ttl) || 60 * 5 // Default is five minutes
});

const imageController = plugins.getFirst('image-controller');
if (!imageController) {
  throw new Error('Expected at least one image controller!');
}

const documentController = require('./document');

if (config.thumbnailSizes) {
  throw new Error('config.thumbnailSizes changed name to downloadOptions');
}

const THUMBNAIL_SIZE = config.thumbnailSize;

var WATERMARK_BUFFERS = {};
Object.keys(config.watermarks || {}).forEach((catalog) => {
  var path = config.watermarks[catalog];
  WATERMARK_BUFFERS[catalog] = fs.readFileSync(path);
});

const IMAGES_PATH = path.join(config.customizationPath, 'app', 'images');
const SMALL_FALLBACK_PATH = path.join(IMAGES_PATH, 'fallback-small.png');
const LARGE_FALLBACK_PATH = path.join(IMAGES_PATH, 'fallback-large.png');
assert(fs.existsSync(SMALL_FALLBACK_PATH), 'Missing a small fallback image');
assert(fs.existsSync(LARGE_FALLBACK_PATH), 'Missing a large fallback image');

function getErrorPlaceholderStream(size) {
  if (!size || size > THUMBNAIL_SIZE) {
    return fs.createReadStream(LARGE_FALLBACK_PATH);
  } else {
    return fs.createReadStream(SMALL_FALLBACK_PATH);
  }
}

const contentDispositionRegexp = /.*\.([^.]+)$/i;

exports.download = function (req, res) {
  const collection = req.params.collection;
  const id = req.params.id;
  let size = req.params.size || 'original';

  assert(size in config.downloadOptions, 'The size is must be one of ' +
    Object.keys(config.downloadOptions)
    + ' got "' + size + '"');
  const option = config.downloadOptions[size];
  var proxyRequest = imageController.proxyDownload(collection + '/' + id, size);

  res._writeHead = res.writeHead;
  res.writeHead = function (statusCode, reasonPhrase, headers) {
    if (statusCode === 200 && proxyRequest.response) {
      // Reading the file extension from the response from CIP
      var resHeaders = proxyRequest.response.headers || {};
      var contentDisposition = resHeaders['content-disposition'] || '';
      // Determine the file extension extension
      if (contentDisposition) {
        var parts = contentDisposition.match(contentDispositionRegexp);
        var extension;
        if (parts) {
          extension = '.' + parts[1];
        } else {
          extension = '.jpg'; // Default: When the CIP is not responsing
        }
        // Build the filename
        var filename = collection + '-' + id;
        if (option.filenamePrefix) {
          filename += option.filenamePrefix;
        }
        // Generating a new filename adding size if it exists
        filename += extension;
        // Write the header
        res.set('content-disposition', 'attachment; filename=' + filename);
      }
    }
    res._writeHead(statusCode, reasonPhrase, headers);
  };

  proxyRequest
    .on('error', err => {
      try {
        if (err.message === 'ESOCKETTIMEDOUT' && config.imageTimeoutRedirect) {
          // This is a timeout that occurs often when the original file is to large.
          // This redirect can cause issues as it might be run after the response
          // has been sent.
          res.redirect(config.imageTimeoutRedirect);
        } else {
          res.status(500);
          res.type('png');
          getErrorPlaceholderStream().pipe(res);
        }
      } catch (error) {
        // We are not able to send anything back if the res is closed.
        console.warn('Image proxy error: ', error);
      }

    })
    .on('response', function (response) {
      if (response.statusCode === 200) {
        proxyRequest.pipe(res);
      } else {
        res.status(response.statusCode);
        res.type('png');
        getErrorPlaceholderStream().pipe(res);
      }
    });
};

const POSITION_FUNCTIONS = {
  'middle-center': waterStream.middleCenterPosition,
  'bottom-right': waterStream.bottomRightPosition
};

exports.thumbnail = function (req, res, next) {
  var collection = req.params.collection;
  var id = req.params.id;
  var size = req.params.size ? parseInt(req.params.size, 10) : THUMBNAIL_SIZE;
  var position = req.params.position || 'middle-center';
  if (!(position in POSITION_FUNCTIONS)) {
    throw new Error('Unexpected position function: ' + position);
  }
  const positionFunction = POSITION_FUNCTIONS[position];

  function respond(watermark) {
    const proxyReq = imageController.proxyThumbnail(
      collection + '/' + id, next
    );
    proxyReq
      .on('error', err => {
        console.error(err);
        res.type('png');
        res.status(500);
        getErrorPlaceholderStream(size).pipe(res);
      })
      .on('response', function (response) {
        if (response.statusCode === 200) {
          var t = waterStream.transformation(watermark, size, positionFunction, 0.25);
          if (config.assetCacheExpiration) {
            res.header('Cache-Control', `max-age=${config.assetCacheExpiration}, public`);
          }
          proxyReq.pipe(t).pipe(res);
        } else {
          res.type('png');
          res.status(response.statusCode);
          getErrorPlaceholderStream(size).pipe(res);
        }
      });
  }

  if (config.features.watermarks) {
    documentController.get(req, 'asset').then(function (metadata) {
      const isWatermarkRequired = helpers.isWatermarkRequired(metadata);
      const isLarge = size > THUMBNAIL_SIZE;
      if (isWatermarkRequired && isLarge && collection in WATERMARK_BUFFERS) {
        respond(WATERMARK_BUFFERS[collection]);
      } else {
        respond(null);
      }
    }).then(null, (err) => {
      console.error(err);
      res.type('png');
      res.status(500);
      getErrorPlaceholderStream(size).pipe(res);
    });
  } else {
    respond(null);
  }
};
<commit_msg>Move images controller `respond` function to global scope, make parameters explicit<commit_after>'use strict';
const assert = require('assert');
const plugins = require('../../plugins');
const config = require('../config');
const fs = require('fs');
const path = require('path');
const waterStream = require('water-stream');
const helpers = require('../../shared/helpers');

// Set the cache ttl from the configuration
waterStream.cached.config({
  stdTTL: (config.cache && config.cache.ttl) || 60 * 5 // Default is five minutes
});

const imageController = plugins.getFirst('image-controller');
if (!imageController) {
  throw new Error('Expected at least one image controller!');
}

const documentController = require('./document');

if (config.thumbnailSizes) {
  throw new Error('config.thumbnailSizes changed name to downloadOptions');
}

const THUMBNAIL_SIZE = config.thumbnailSize;

var WATERMARK_BUFFERS = {};
Object.keys(config.watermarks || {}).forEach((catalog) => {
  var path = config.watermarks[catalog];
  WATERMARK_BUFFERS[catalog] = fs.readFileSync(path);
});

const IMAGES_PATH = path.join(config.customizationPath, 'app', 'images');
const SMALL_FALLBACK_PATH = path.join(IMAGES_PATH, 'fallback-small.png');
const LARGE_FALLBACK_PATH = path.join(IMAGES_PATH, 'fallback-large.png');
assert(fs.existsSync(SMALL_FALLBACK_PATH), 'Missing a small fallback image');
assert(fs.existsSync(LARGE_FALLBACK_PATH), 'Missing a large fallback image');

function getErrorPlaceholderStream(size) {
  if (!size || size > THUMBNAIL_SIZE) {
    return fs.createReadStream(LARGE_FALLBACK_PATH);
  } else {
    return fs.createReadStream(SMALL_FALLBACK_PATH);
  }
}

const contentDispositionRegexp = /.*\.([^.]+)$/i;

exports.download = function (req, res) {
  const collection = req.params.collection;
  const id = req.params.id;
  let size = req.params.size || 'original';

  assert(size in config.downloadOptions, 'The size is must be one of ' +
    Object.keys(config.downloadOptions)
    + ' got "' + size + '"');
  const option = config.downloadOptions[size];
  var proxyRequest = imageController.proxyDownload(collection + '/' + id, size);

  res._writeHead = res.writeHead;
  res.writeHead = function (statusCode, reasonPhrase, headers) {
    if (statusCode === 200 && proxyRequest.response) {
      // Reading the file extension from the response from CIP
      var resHeaders = proxyRequest.response.headers || {};
      var contentDisposition = resHeaders['content-disposition'] || '';
      // Determine the file extension extension
      if (contentDisposition) {
        var parts = contentDisposition.match(contentDispositionRegexp);
        var extension;
        if (parts) {
          extension = '.' + parts[1];
        } else {
          extension = '.jpg'; // Default: When the CIP is not responsing
        }
        // Build the filename
        var filename = collection + '-' + id;
        if (option.filenamePrefix) {
          filename += option.filenamePrefix;
        }
        // Generating a new filename adding size if it exists
        filename += extension;
        // Write the header
        res.set('content-disposition', 'attachment; filename=' + filename);
      }
    }
    res._writeHead(statusCode, reasonPhrase, headers);
  };

  proxyRequest
    .on('error', err => {
      try {
        if (err.message === 'ESOCKETTIMEDOUT' && config.imageTimeoutRedirect) {
          // This is a timeout that occurs often when the original file is to large.
          // This redirect can cause issues as it might be run after the response
          // has been sent.
          res.redirect(config.imageTimeoutRedirect);
        } else {
          res.status(500);
          res.type('png');
          getErrorPlaceholderStream().pipe(res);
        }
      } catch (error) {
        // We are not able to send anything back if the res is closed.
        console.warn('Image proxy error: ', error);
      }

    })
    .on('response', function (response) {
      if (response.statusCode === 200) {
        proxyRequest.pipe(res);
      } else {
        res.status(response.statusCode);
        res.type('png');
        getErrorPlaceholderStream().pipe(res);
      }
    });
};

const POSITION_FUNCTIONS = {
  'middle-center': waterStream.middleCenterPosition,
  'bottom-right': waterStream.bottomRightPosition
};

exports.thumbnail = function (req, res, next) {
  var collection = req.params.collection;
  var id = req.params.id;
  var size = req.params.size ? parseInt(req.params.size, 10) : THUMBNAIL_SIZE;
  var position = req.params.position || 'middle-center';
  if (!(position in POSITION_FUNCTIONS)) {
    throw new Error('Unexpected position function: ' + position);
  }
  const positionFunction = POSITION_FUNCTIONS[position];

  if (config.features.watermarks) {
    documentController.get(req, 'asset').then(function (metadata) {
      const isWatermarkRequired = helpers.isWatermarkRequired(metadata);
      const isLarge = size > THUMBNAIL_SIZE;
      if (isWatermarkRequired && isLarge && collection in WATERMARK_BUFFERS) {
        respond(res, collection, id, next, size, positionFunction, WATERMARK_BUFFERS[collection]);
      } else {
        respond(res, collection, id, next, size, positionFunction, null);
      }
    }).then(null, (err) => {
      console.error(err);
      res.type('png');
      res.status(500);
      getErrorPlaceholderStream(size).pipe(res);
    });
  } else {
    respond(res, collection, id, next, size, positionFunction, null);
  }
};

function respond(res, collection, id, next, size, positionFunction, watermark) {
  const proxyReq = imageController.proxyThumbnail(
    collection + '/' + id, next
  );
  proxyReq
    .on('error', err => {
      console.error(err);
      res.type('png');
      res.status(500);
      getErrorPlaceholderStream(size).pipe(res);
    })
    .on('response', function (response) {
      if (response.statusCode === 200) {
        var t = waterStream.transformation(watermark, size, positionFunction, 0.25);
        if (config.assetCacheExpiration) {
          res.header('Cache-Control', `max-age=${config.assetCacheExpiration}, public`);
        }
        proxyReq.pipe(t).pipe(res);
      } else {
        res.type('png');
        res.status(response.statusCode);
        getErrorPlaceholderStream(size).pipe(res);
      }
    });
}
<|endoftext|>


<commit_before>define('app/controllers/backend_add', ['app/models/backend'],
    //
    //  Backend Add Controller
    //
    //  @returns Class
    //
    function (Backend) {

        'use strict';

        return Ember.Object.extend({

            //
            //
            //  Properties
            //
            //

            callback: null,
            provider: null,

            //
            //
            //  Methods
            //
            //

            open: function (callback) {
                this._clear();
                this.view.clear();
                this.view.open();
                this.set('callback', callback);
            },

            close: function () {
                this._clear();
                this.view.close();
                this.view.clear();
            },

            add: function () {

                var provider = this.get('provider');
                var fields = getProviderFields(provider).rejectBy('name', undefined);

                var payload = {
                    title: provider.title,
                    provider: provider.provider,
                };
                fields.forEach(function (field) {
                    payload[field.name] = field.value;
                });

                var that = this;
                Mist.backendsController.addBackend({
                    payload: payload,
                    callback: function (success, backend) {
                        that._giveCallback(success, backend);
                        if (success) that.close();
                    }
                });
            },

            //
            //
            //  Pseudo-Private Methods
            //
            //

            _clear: function () {
                this.setProperties({
                    callback: null,
                    provider: null,
                });
            },

            _giveCallback: function (success, backend) {
                if (this.callback) this.callback(success, backend);
            },
        });
    }
);
<commit_msg>Show monitoring popup<commit_after>define('app/controllers/backend_add', ['app/models/backend'],
    //
    //  Backend Add Controller
    //
    //  @returns Class
    //
    function (Backend) {

        'use strict';

        return Ember.Object.extend({

            //
            //
            //  Properties
            //
            //

            callback: null,
            provider: null,

            //
            //
            //  Methods
            //
            //

            open: function (callback) {
                this._clear();
                this.view.clear();
                this.view.open();
                this.set('callback', callback);
            },

            close: function () {
                this._clear();
                this.view.close();
                this.view.clear();
            },

            add: function () {

                var provider = this.get('provider');
                var fields = getProviderFields(provider).rejectBy('name', undefined);

                var payload = {
                    title: provider.title,
                    provider: provider.provider,
                };
                fields.forEach(function (field) {
                    payload[field.name] = field.value;
                });

                var that = this;
                Mist.backendsController.addBackend({
                    payload: payload,
                    callback: function (success, backend) {
                        Ember.run.later(function () {
                            if (payload.monitoring === true)
                                that._showMonitoringPopup(backend, payload);
                            }, 200);
                        that._giveCallback(success, backend);
                        if (success) that.close();
                    }
                });
            },

            //
            //
            //  Pseudo-Private Methods
            //
            //

            _showMonitoringPopup: function (backend, payload) {
                Mist.dialogController.open({
                    type: DIALOG_TYPES.OK,
                    head: 'Install monitoring agent',
                    body: [
                        {
                            paragraph: 'Run this command on your server to install' +
                                ' the monitoring agent'
                        },
                        {
                            command: payload.windows ? backend.windows_command :
                                backend.unix_command
                        },
                    ],
                });
            },

            _clear: function () {
                this.setProperties({
                    callback: null,
                    provider: null,
                });
            },

            _giveCallback: function (success, backend) {
                if (this.callback) this.callback(success, backend);
            },
        });
    }
);
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Promise = require('bluebird');
const assert = require('hoek').assert;

class Deployer {
  constructor(namespace, kubectl) {
    this.namespace = namespace;
    this.kubectl = kubectl;
  }

  deployResource(path, options) {
    let requirements = Promise.resolve();
    const resource = this.namespace.getResource(path);

    assert(resource, "Resource not defined");

    const dependencies = _.get(resource.value, ["metadata", "annotations", "x-truder.net/dependencies"]);
    if (dependencies) {
      requirements = Promise.map(dependencies.split(','), dep => {
        return this.deployResource(dep, options);
      });
    }

    return requirements.then(() => {
      if (options.rollingUpdate && resource.type === 'replicationcontrollers') {
        return this.kubectl.rollingUpdate(resource.namespace, options.rollingUpdate, resource.value);
      }

      return this.kubectl.deploy(resource.namespace, resource.kind, resource.name, resource.value);
    }).then(() => {
      if (options.restart && resource.type === 'replicationcontrollers') {
        return this.kubectl.deleteByLabels(resource.name, 'pod', resource.value.spec.selector);
      }
    });
  }

  deploy(include, options) {
    let resources;

    if (_.isEmpty(include)) {
      resources = this.namespace.resources;
    } else {
      resources = _.isArray(include) ? include : [include];
    }

    return Promise.mapSeries(resources, path => this.deployResource(path, options));
  }
}

module.exports = Deployer;
<commit_msg>more descriptive error for resource not found<commit_after>'use strict';

const _ = require('lodash');
const Promise = require('bluebird');
const assert = require('hoek').assert;

class Deployer {
  constructor(namespace, kubectl) {
    this.namespace = namespace;
    this.kubectl = kubectl;
  }

  deployResource(path, options) {
    let requirements = Promise.resolve();
    const resource = this.namespace.getResource(path);

    assert(resource, `Resource not defined: ${path}`);

    const dependencies = _.get(resource.value, ["metadata", "annotations", "x-truder.net/dependencies"]);
    if (dependencies) {
      requirements = Promise.map(dependencies.split(','), dep => {
        return this.deployResource(dep, options);
      });
    }

    return requirements.then(() => {
      if (options.rollingUpdate && resource.type === 'replicationcontrollers') {
        return this.kubectl.rollingUpdate(resource.namespace, options.rollingUpdate, resource.value);
      }

      return this.kubectl.deploy(resource.namespace, resource.kind, resource.name, resource.value);
    }).then(() => {
      if (options.restart && resource.type === 'replicationcontrollers') {
        return this.kubectl.deleteByLabels(resource.name, 'pod', resource.value.spec.selector);
      }
    });
  }

  deploy(include, options) {
    let resources;

    if (_.isEmpty(include)) {
      resources = this.namespace.resources;
    } else {
      resources = _.isArray(include) ? include : [include];
    }

    return Promise.mapSeries(resources, path => this.deployResource(path, options));
  }
}

module.exports = Deployer;
<|endoftext|>


<commit_before>'use strict';
const assert = require('assert');
const plugins = require('../../plugins');
const config = require('../config');
const fs = require('fs');
const path = require('path');

const imageController = plugins.getFirst('image-controller');
if (!imageController) {
  throw new Error('Expected at least one image controller!');
}

/**
 * A simplified controller that does not assume we're streaming an image but supports HTTP 206
 *
 * @param req
 * @param res
 * @param next
 */
exports.stream = function (req, res, next) {
  const collection = req.params.collection;
  const id = req.params.id;

  let size = 'original';
  const option = config.downloadOptions[size];

  // The request against the backend system.
  var proxyRequest;
  const range = req.headers.range;
  if (range) {
    proxyRequest = imageController.proxyDownload(collection + '/' + id, size, range);
  } else {
    proxyRequest = imageController.proxyDownload(collection + '/' + id, size);
  }

  proxyRequest
    .on('error', function (error) {
      // We can't assume that it's ok to reply with eg. an error-image, so we
      // just close the connection.
      res.end();
    })
    .on('response', function (response) {
      // Handle normal GET as well as partials.
      if (response.statusCode === 200 || response.statusCode === 206) {
        proxyRequest.pipe(res);
      } else {
        res.status(500).send('Error occured while processing request.');
      }
    });
};
<commit_msg>add logging to downloading error<commit_after>'use strict';
const assert = require('assert');
const plugins = require('../../plugins');
const config = require('../config');
const fs = require('fs');
const path = require('path');

const imageController = plugins.getFirst('image-controller');
if (!imageController) {
  throw new Error('Expected at least one image controller!');
}

/**
 * A simplified controller that does not assume we're streaming an image but supports HTTP 206
 *
 * @param req
 * @param res
 * @param next
 */
exports.stream = function (req, res, next) {
  const collection = req.params.collection;
  const id = req.params.id;

  let size = 'original';
  const option = config.downloadOptions[size];

  // The request against the backend system.
  var proxyRequest;
  const range = req.headers.range;
  if (range) {
    proxyRequest = imageController.proxyDownload(collection + '/' + id, size, range);
  } else {
    proxyRequest = imageController.proxyDownload(collection + '/' + id, size);
  }

  proxyRequest
    .on('error', function (error) {
      // We can't assume that it's ok to reply with eg. an error-image, so we
      // just close the connection.
      res.end();
    })
    .on('response', function (response) {
      // Handle normal GET as well as partials.
      if (response.statusCode === 200 || response.statusCode === 206) {
        proxyRequest.pipe(res);
      } else {
        console.error("failed to download image ", response);
        res.status(500).send('Error occured while processing request.');
      }
    });
};
<|endoftext|>


<commit_before>const chai = require('chai');
const assert = chai.assert;

var isColliding = require('../app/lib/collision/is-colliding');
const Skier = require('../app/lib/skier');
const Tree = require('../app/lib/tree');

describe('isColliding', function() {
  beforeEach(function () {
    this.canvas = document.createElement('canvas');
    this.canvas.width = 600;
    this.canvas.height = 500;
    this.context = this.canvas.getContext('2d');
  });

  it('should report if there is a collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 50;

    assert.strictEqual(skier.crashed, false);

    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, true);
  });

  it('should decrement the skier\'s lives by one on collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 50;
    var originalLives = skier.lives;
    isColliding.isColliding(skier, obstacle);

    assert.isBelow(skier.lives, originalLives);
  });

  it('should report if there is no collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 30;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);
  });

  it('should report based on the skiers width', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = skier.y - skier.width - 5;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);

    obstacle.y = skier.y - skier.width;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);

    obstacle.y = skier.y - skier.width + 2;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, true);
  });

  it('should add obstacles to collisionObstacles after collision', function () {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    var collisionObstacles = [];
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 50;
    isColliding.crashed(skier, obstacle, collisionObstacles);

    assert.deepEqual(collisionObstacles[0], obstacle);
  });
});
<commit_msg>Add test for jumping function inside of isColliding<commit_after>const chai = require('chai');
const assert = chai.assert;

var isColliding = require('../app/lib/collision/is-colliding');
const Skier = require('../app/lib/skier');
const Tree = require('../app/lib/tree');
const Jump = require('../app/lib/jump');

describe('isColliding', function() {
  beforeEach(function () {
    this.canvas = document.createElement('canvas');
    this.canvas.width = 600;
    this.canvas.height = 500;
    this.context = this.canvas.getContext('2d');
  });

  it('should report if there is a collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 50;

    assert.strictEqual(skier.crashed, false);

    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, true);
  });

  it('should decrement the skier\'s lives by one on collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 50;
    var originalLives = skier.lives;
    isColliding.isColliding(skier, obstacle);

    assert.isBelow(skier.lives, originalLives);
  });

  it('should report if there is no collision', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = 30;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);
  });

  it('should report based on the skiers width', function() {
    var skier = new Skier({ canvas: this.canvas, context: this.context });
    var obstacle = new Tree({ canvas: this.canvas, context: this.context });
    skier.x = 50; skier.y = 50;
    obstacle.x = 50; obstacle.y = skier.y - skier.width - 5;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);

    obstacle.y = skier.y - skier.width;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, false);

    obstacle.y = skier.y - skier.width + 2;
    isColliding.isColliding(skier, obstacle);

    assert.strictEqual(skier.crashed, true);
  });
  describe('crashed', function() {
    it('should add obstacles to collisionObstacles after collision', function () {
      var skier = new Skier({ canvas: this.canvas, context: this.context });
      var obstacle = new Tree({ canvas: this.canvas, context: this.context });
      var collisionObstacles = [];
      skier.x = 50; skier.y = 50;
      obstacle.x = 50; obstacle.y = 50;
      isColliding.crashed(skier, obstacle, collisionObstacles);

      assert.deepEqual(collisionObstacles[0], obstacle);
    });

    it('should not be able to collide with obstacles in collisionObstacles', function() {
      var skier = new Skier({ canvas: this.canvas, context: this.context });
      var obstacle = new Tree({ canvas: this.canvas, context: this.context });
      var collisionObstacles = [];
      skier.x = 50; skier.y = 50;
      obstacle.x = 50; obstacle.y = 50;
      collisionObstacles.push(obstacle);
      var originalLives = skier.lives;
      isColliding.crashed(skier, obstacle, collisionObstacles);

      assert.strictEqual(originalLives, skier.lives);
    });
  });

  describe('jump', function() {
    it('should set jumping to true if obstacle is a jump', function() {
      var skier = new Skier({ canvas: this.canvas, context: this.context });
      var obstacle = new Jump({ canvas: this.canvas, context: this.context });
      skier.x = 50; skier.y = 50;
      obstacle.x = 50; obstacle.y = 50;
      isColliding.isColliding(skier, obstacle);

      assert.strictEqual(skier.jumping, true);
    });
  });
});
<|endoftext|>


<commit_before>$(document).ready(function(){
	if($('#content .container').hasClass('home'))
		twitterIni();
	$.cookie.defaults.path = '/';
	$('.jscrollpane').jScrollPane();
	$('.custom-select').customSelect();
	$('.calificacion-form').validate();
	$('.reporte-form').validate();
	$('.petition-form').validate();
	$('.contacto-form').validate();
	$('form.newsletter').validate();

	$('#ver-en-mapa').click(function(e){
		e.preventDefault();
		$('#general-search').attr('action',$(this).attr('href'));
		$('#general-search').submit();
	});

	$('.compara-tabs a').click(function(e){
		e.preventDefault();
		var index = $(this).index();
		$('.compara-tabs a.on').removeClass('on');
		$(this).addClass('on');
		$('.compara-tab-container .tab.on').removeClass('on');
		$('.compara-tab-container .tab').eq(index).addClass('on');
	})

	$('.compara-escuela').on('click',function(e){
		e.preventDefault();
		var tr = $(this).parent().parent().toggleClass('on');
		var cct = $(this).attr('href');
		toggle_escuela(cct);
	});

	$('#content .perfil .tabs li a').click(function(e){
		e.preventDefault();
		var index = 4 - $(this).parent().index();
		$('#content .perfil .tabs li.on').removeClass('on');
		$(this).parent().addClass('on');
		$('#content .perfil .tab-container .tab.on').removeClass('on');
		$('#content .perfil .tab-container .tab').eq(index).addClass('on').jScrollPane();
		if($(this).html() == 'Resultados Educativos' ) drawCharts();
	})
	$('#rank-bar').mousemove(function(e){
		set_rank_bar(e.pageX - $(this).offset().left);
	});
	$('#rank-bar').click(function(e){
		var rank = set_rank_bar(e.pageX - $(this).offset().left);
		$('#rank-value').val(rank);
	});
	$('#rank-bar').mouseout(function(e){
		var max = $('.container').hasClass('B')?173:336;
		var x = e.pageX - $(this).offset().left;
		var y = e.pageY - $(this).offset().top;
		if((y >= 10 || y < 0) || (x < 0 || x > max)){
			var val = $('#rank-value').val();
			if(val != ''){
				set_rank_bar(Math.round(val/100*max));
			}else{
				$('#rank-bar .bar').hide();
				$('#rank-label').hide();
			}
		}
	});

	if($("#name-input") .length)
	$( "#name-input" ).autocomplete({
  		source: function(request,response){
  			$.post("/main/get_escuelas/",{
  				term : request.term,
  				entidad : $("#state-input").val(),
  				municipio : $("#municipio-input").val(),
  				localidad : $("#localidad-input").val(),
  				nivel : $("#nivel-input").val(),
  				json : true
  			},response,'json');
  		},
  		minLength: 3,
		select: function( event, ui ) {
			window.location = "/escuelas/index/"+ui.item.cct;
			return false;
		}
	}).data( "ui-autocomplete" )._renderItem = function( ul, item ){
      return $("
").append(""+item.label+""+item.address+"").appendTo(ul);
    };

	$('#map-button').click(function(e){
		e.preventDefault();
		$('#general-search').attr('action','/mapa/');
		$('#general-search').submit();

	});
	$('#state-input').change(function(e){
		$("#localidad-input").prop('disabled', true).next().addClass('customSelectDisabled');
		load_location_options(
			$("#municipio-input"),
			'load_municipios',
			{entidad:$(this).val(),json:true},
			"Municipio"
		);
	});

	$('#municipio-input').change(function(){
		if($(this).val() != "" || ($("#state-input option:selected").val() != "" && $("#state-input option:selected").val() != 7 && $("#state-input option:selected").val() != 20 && $("#state-input option:selected").val() != 30)){
			load_location_options(
				$("#localidad-input"),
				'load_localidades',
				{municipio:$(this).val(),entidad:$("#state-input option:selected").val(),json:true},
				"Localidad"
			);
		}else{
			$("#localidad-input").prop('disabled', true).next().addClass('customSelectDisabled');
			$("#localidad-input").html('<option value="">Localidad</option>');
		}
	});

	$('#content .home .circle a.line').hover(function(){
		var x=[27,23,19];
		var i=$(this).index();
		var xP=$(this).position().left;
		$(this).parent().find('.line1').css({'left':xP+x[i-1] + 'px','display':'block'});
		$(this).parent().find('.line2').css({'left':89+xP+x[i-1]+'px','display':'block'});
	},function(){
			$(this).parent().find('.line1').css('display','none');
			$(this).parent().find('.line2').css('display','none');
	});

	$('#content .share-bt a.button-frame').click(function(e){
		e.preventDefault();
		$('#content .share-bt .social').toggleClass('on');
	});

	$('.wrap_cal span').click(function(){
		var span =  $(this).parent().find('span');
		if($(this).hasClass('on') && $(this).index()==0){
			span.removeClass('on');
		}else{
			span.removeClass('on');
			for(var i=0;i<=$(this).index();i++){
				$(span[i]).addClass('on');
			}
		}
		var promedio = $('.wrap_cal span.on').size() / $('.wrap_cal').size();
		promedio = promedio.toString().length>3?promedio.toFixed(1):promedio;
		$('.promedio span').html(promedio);
		$('#rank-value').val(promedio);
	});

	$('.menu a.logo + a + a').click(function(e){
		e.preventDefault();
		var cookie = $.cookie('escuelas'),
		    url = '/compara/escuelas/'+ (cookie != undefined ? cookie:'');
		location.href = url;
	});

	$('.search-estado select.custom-select').change(function(){
		var id;
		if((id = $(this).val())!=''){
			location.href = '/resultados-nacionales/entidad/'+id;
		}
	});

	$('.peticion h1').click(function(){
		$('.wrap_peticion, .social.on').removeClass('on');
		$(this).next().addClass('on');
	});

	if($('#content .container').hasClass('perfil')){
		$('.menu a.logo + a + a + a').click(function(e){
			e.preventDefault();
			location.href = $('.califica a.title').attr('href');
		});

		$('.tabs a.result').click(function(){
		var texts = $('text[text-anchor="start"]'),
		    text;
		for(var i=0;i<texts.length;i++){
			text = $(texts[i]);
			text.text(text.text()+' grado');
		}
		});

	}

	if($('.container').hasClass('perfil')){
		var cct = $('span.CCT').html();
		var escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [];
		if(escuelas.indexOf(cct)==-1){
			escuelas.push(cct);
			escuelas.sort();
			$.cookie('escuelas',escuelas.join('-'));
			$('a[href="'+cct+'"]').parent().parent().addClass('on');
		}
		/*if(!($.cookie('escuelas')) || $.cookie('escuelas').split('-').indexOf(cct)==-1){
			$('a[href="'+cct+'"]').trigger('click');
			if(!$('a[href="'+cct+'"]').size()){
				toggle_escuela(cct);
			}
		}*/

	}

	if($('.container').hasClass('comparar')){
		$('#general-search').submit(function(e){
			e.preventDefault();
			var url='';
			$(this).find('[name]').each(function(i,val){
				url +='&'+$(val).attr('name')+'='+$(val).val();
			});
			window.location = $(this).attr('action')+url;
		});
	}

	if($('.container').hasClass('resultados')){
		$(window).unload(function(){
			add_escuelas_cookie();
		});
	}

	$('#compara-main-button').click(function(e){
		e.preventDefault();
		add_escuelas_cookie();
		$(window).off();
		location.href = '/compara/escuelas/' + $.cookie('escuelas');
	});

	$('#content .comparar.resultados table tr.on .compara-escuela').click(function(e){
		e.preventDefault();
		var cct = $(this).attr('href'),
		url=document.URL.replace(new RegExp('-*'+cct),''),
		escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [];
		escuelas.pop(escuelas.indexOf(cct));
		$.cookie('escuelas',escuelas.join('-'));
		if(document.URL != url)
			location.href = url;

		console.log(true,cct);

	});

});

function load_location_options(input,directive,options,name){
	input.prop('disabled', true);
	input.next().addClass('customSelectDisabled');
	$.post('/main/'+directive,options,function(data){
		input.html('<option value="">'+name+'</option>');
		for(x in data){
			var item = data[x];
			input.append('<option value="'+item.id+'">'+item.nombre+'</option>');
		}
		input.prop('disabled', false);
		input.next().removeClass('customSelectDisabled');
		input.trigger('change');
	},'json');
}
function set_rank_bar(x){
	var max = $('.container').hasClass('B')?173:336;
	var rank = Math.round(x/max * 100);
	var offset = x - 12;
	$('#rank-bar .bar').css('width',x+'px').show();
	$('#rank-label').html(rank+'%').css('left',offset+'px').show();
	return rank;
}
function toggle_escuela(cct){
	var escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [],
	index;
	if((index = escuelas.indexOf(cct)) != -1){
		escuelas.pop(index);
		escuelas.sort();
		$.cookie('escuelas',escuelas.join('-'));
	}
	//$('#compara-main-button').attr('href','/compara/escuelas/'+escuelas.join('-') || '');
	/*
	if(typeof($.cookie('escuelas')) == 'undefined'){
		$.cookie('escuelas',[cct]);
	}else{
		var escuelas = $.cookie('escuelas').split('-');
		var index = escuelas.indexOf(cct);
		if(index != -1){
			escuelas.pop(index);
		}else{
			escuelas.push(cct);
		}
		//escuelas.sort();
		$.cookie('escuelas',escuelas.join('-'));
		if( $('.container.resultados').hasClass('comparar')){
			var url=document.URL.replace(new RegExp('-*'+cct),'');
			if(document.URL != url)
				location.href = url;
		}
	}
	*/
}
function twitterIni(){
    var username =  "mejoratuescuela",
	page_proxy = '/home/twitter';
	$("#tweets .tweet p").html("cargando tweets...");
	$.getJSON(page_proxy, function(data){
		$("#tweets .tweet").css('display','none');
		$("#tweets").append('

');
		for(d in data){
			var x = data[d];
			$("#tweets ul").append('

@'+username+' '+x.text+'

');
	    	}
	    })
}

function add_escuelas_cookie(selector_table){
	console.log(true);
	selector_table = $('.resultados.container table');
	var on = selector_table.find('tr.on'),
	cookie = $.cookie('escuelas'),
	escuelas = cookie && cookie.split('-') || [];
	for(var i=0;i<on.length;i++){
		var val = $(on[i]),
		cct = val.find('.compara-escuela').attr('href');
		if(escuelas.indexOf(cct)==-1)
			escuelas.push(cct);
	}
	escuelas.sort();
	console.log(escuelas);
	if(escuelas.length){
		$.cookie('escuelas',escuelas.join('-'));
	}

}
<commit_msg>listo cookie escuelas<commit_after>$(document).ready(function(){
	if($('#content .container').hasClass('home'))
		twitterIni();
	$.cookie.defaults.path = '/';
	$('.jscrollpane').jScrollPane();
	$('.custom-select').customSelect();
	$('.calificacion-form').validate();
	$('.reporte-form').validate();
	$('.petition-form').validate();
	$('.contacto-form').validate();
	$('form.newsletter').validate();

	$('#ver-en-mapa').click(function(e){
		e.preventDefault();
		$('#general-search').attr('action',$(this).attr('href'));
		$('#general-search').submit();
	});

	$('.compara-tabs a').click(function(e){
		e.preventDefault();
		var index = $(this).index();
		$('.compara-tabs a.on').removeClass('on');
		$(this).addClass('on');
		$('.compara-tab-container .tab.on').removeClass('on');
		$('.compara-tab-container .tab').eq(index).addClass('on');
	})

	$('.compara-escuela').on('click',function(e){
		e.preventDefault();
		var tr = $(this).parent().parent().toggleClass('on');
		var cct = $(this).attr('href');
		toggle_escuela(cct);
	});

	$('#content .perfil .tabs li a').click(function(e){
		e.preventDefault();
		var index = 4 - $(this).parent().index();
		$('#content .perfil .tabs li.on').removeClass('on');
		$(this).parent().addClass('on');
		$('#content .perfil .tab-container .tab.on').removeClass('on');
		$('#content .perfil .tab-container .tab').eq(index).addClass('on').jScrollPane();
		if($(this).html() == 'Resultados Educativos' ) drawCharts();
	})
	$('#rank-bar').mousemove(function(e){
		set_rank_bar(e.pageX - $(this).offset().left);
	});
	$('#rank-bar').click(function(e){
		var rank = set_rank_bar(e.pageX - $(this).offset().left);
		$('#rank-value').val(rank);
	});
	$('#rank-bar').mouseout(function(e){
		var max = $('.container').hasClass('B')?173:336;
		var x = e.pageX - $(this).offset().left;
		var y = e.pageY - $(this).offset().top;
		if((y >= 10 || y < 0) || (x < 0 || x > max)){
			var val = $('#rank-value').val();
			if(val != ''){
				set_rank_bar(Math.round(val/100*max));
			}else{
				$('#rank-bar .bar').hide();
				$('#rank-label').hide();
			}
		}
	});

	if($("#name-input") .length)
	$( "#name-input" ).autocomplete({
  		source: function(request,response){
  			$.post("/main/get_escuelas/",{
  				term : request.term,
  				entidad : $("#state-input").val(),
  				municipio : $("#municipio-input").val(),
  				localidad : $("#localidad-input").val(),
  				nivel : $("#nivel-input").val(),
  				json : true
  			},response,'json');
  		},
  		minLength: 3,
		select: function( event, ui ) {
			window.location = "/escuelas/index/"+ui.item.cct;
			return false;
		}
	}).data( "ui-autocomplete" )._renderItem = function( ul, item ){
      return $("
").append(""+item.label+""+item.address+"").appendTo(ul);
    };

	$('#map-button').click(function(e){
		e.preventDefault();
		$('#general-search').attr('action','/mapa/');
		$('#general-search').submit();

	});
	$('#state-input').change(function(e){
		$("#localidad-input").prop('disabled', true).next().addClass('customSelectDisabled');
		load_location_options(
			$("#municipio-input"),
			'load_municipios',
			{entidad:$(this).val(),json:true},
			"Municipio"
		);
	});

	$('#municipio-input').change(function(){
		if($(this).val() != "" || ($("#state-input option:selected").val() != "" && $("#state-input option:selected").val() != 7 && $("#state-input option:selected").val() != 20 && $("#state-input option:selected").val() != 30)){
			load_location_options(
				$("#localidad-input"),
				'load_localidades',
				{municipio:$(this).val(),entidad:$("#state-input option:selected").val(),json:true},
				"Localidad"
			);
		}else{
			$("#localidad-input").prop('disabled', true).next().addClass('customSelectDisabled');
			$("#localidad-input").html('<option value="">Localidad</option>');
		}
	});

	$('#content .home .circle a.line').hover(function(){
		var x=[27,23,19];
		var i=$(this).index();
		var xP=$(this).position().left;
		$(this).parent().find('.line1').css({'left':xP+x[i-1] + 'px','display':'block'});
		$(this).parent().find('.line2').css({'left':89+xP+x[i-1]+'px','display':'block'});
	},function(){
			$(this).parent().find('.line1').css('display','none');
			$(this).parent().find('.line2').css('display','none');
	});

	$('#content .share-bt a.button-frame').click(function(e){
		e.preventDefault();
		$('#content .share-bt .social').toggleClass('on');
	});

	$('.wrap_cal span').click(function(){
		var span =  $(this).parent().find('span');
		if($(this).hasClass('on') && $(this).index()==0){
			span.removeClass('on');
		}else{
			span.removeClass('on');
			for(var i=0;i<=$(this).index();i++){
				$(span[i]).addClass('on');
			}
		}
		var promedio = $('.wrap_cal span.on').size() / $('.wrap_cal').size();
		promedio = promedio.toString().length>3?promedio.toFixed(1):promedio;
		$('.promedio span').html(promedio);
		$('#rank-value').val(promedio);
	});

	$('.menu a.logo + a + a').click(function(e){
		e.preventDefault();
		var cookie = $.cookie('escuelas'),
		    url = '/compara/escuelas/'+ (cookie != undefined ? cookie:'');
		location.href = url;
	});

	$('.search-estado select.custom-select').change(function(){
		var id;
		if((id = $(this).val())!=''){
			location.href = '/resultados-nacionales/entidad/'+id;
		}
	});

	$('.peticion h1').click(function(){
		$('.wrap_peticion, .social.on').removeClass('on');
		$(this).next().addClass('on');
	});

	if($('#content .container').hasClass('perfil')){
		$('.menu a.logo + a + a + a').click(function(e){
			e.preventDefault();
			location.href = $('.califica a.title').attr('href');
		});

		$('.tabs a.result').click(function(){
		var texts = $('text[text-anchor="start"]'),
		    text;
		for(var i=0;i<texts.length;i++){
			text = $(texts[i]);
			text.text(text.text()+' grado');
		}
		});

	}

	if($('.container').hasClass('perfil')){
		var cct = $('span.CCT').html();
		var escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [];
		if(escuelas.indexOf(cct)==-1){
			escuelas.push(cct);
			escuelas.sort();
			$.cookie('escuelas',escuelas.join('-'));
			$('a[href="'+cct+'"]').parent().parent().addClass('on');
		}
		/*if(!($.cookie('escuelas')) || $.cookie('escuelas').split('-').indexOf(cct)==-1){
			$('a[href="'+cct+'"]').trigger('click');
			if(!$('a[href="'+cct+'"]').size()){
				toggle_escuela(cct);
			}
		}*/

	}

	if($('.container').hasClass('comparar')){
		$('#general-search').submit(function(e){
			e.preventDefault();
			var url='';
			$(this).find('[name]').each(function(i,val){
				url +='&'+$(val).attr('name')+'='+$(val).val();
			});
			window.location = $(this).attr('action')+url;
		});
	}

	if($('.container').hasClass('resultados')){
		$(window).unload(function(){
			add_escuelas_cookie();
		});
	}

	$('#compara-main-button').click(function(e){
		e.preventDefault();
		add_escuelas_cookie();
		$(window).off();
		location.href = '/compara/escuelas/' + $.cookie('escuelas');
	});

	$('#content .comparar.resultados table tr.on .compara-escuela').click(function(e){
		e.preventDefault();
		var cct = $(this).attr('href'),
		url=document.URL.replace(new RegExp('-*'+cct),''),
		escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [];
		escuelas.splice(escuelas.indexOf(cct),1);
		$.cookie('escuelas',escuelas.join('-'));
		if(document.URL != url)
			location.href = url;

	});

});

function load_location_options(input,directive,options,name){
	input.prop('disabled', true);
	input.next().addClass('customSelectDisabled');
	$.post('/main/'+directive,options,function(data){
		input.html('<option value="">'+name+'</option>');
		for(x in data){
			var item = data[x];
			input.append('<option value="'+item.id+'">'+item.nombre+'</option>');
		}
		input.prop('disabled', false);
		input.next().removeClass('customSelectDisabled');
		input.trigger('change');
	},'json');
}
function set_rank_bar(x){
	var max = $('.container').hasClass('B')?173:336;
	var rank = Math.round(x/max * 100);
	var offset = x - 12;
	$('#rank-bar .bar').css('width',x+'px').show();
	$('#rank-label').html(rank+'%').css('left',offset+'px').show();
	return rank;
}
function toggle_escuela(cct){
	var escuelas = $.cookie('escuelas') && $.cookie('escuelas').split('-') || [],
	index;
	if((index = escuelas.indexOf(cct)) != -1){
		escuelas.splice(index,1);
		escuelas.sort();
		$.cookie('escuelas',escuelas.join('-'));
	}
	//$('#compara-main-button').attr('href','/compara/escuelas/'+escuelas.join('-') || '');
	/*
	if(typeof($.cookie('escuelas')) == 'undefined'){
		$.cookie('escuelas',[cct]);
	}else{
		var escuelas = $.cookie('escuelas').split('-');
		var index = escuelas.indexOf(cct);
		if(index != -1){
			escuelas.pop(index);
		}else{
			escuelas.push(cct);
		}
		//escuelas.sort();
		$.cookie('escuelas',escuelas.join('-'));
		if( $('.container.resultados').hasClass('comparar')){
			var url=document.URL.replace(new RegExp('-*'+cct),'');
			if(document.URL != url)
				location.href = url;
		}
	}
	*/
}
function twitterIni(){
    var username =  "mejoratuescuela",
	page_proxy = '/home/twitter';
	$("#tweets .tweet p").html("cargando tweets...");
	$.getJSON(page_proxy, function(data){
		$("#tweets .tweet").css('display','none');
		$("#tweets").append('

');
		for(d in data){
			var x = data[d];
			$("#tweets ul").append('

@'+username+' '+x.text+'

');
	    	}
	    })
}

function add_escuelas_cookie(){
	var selector_table = $('.resultados.container table'),
	on = selector_table.find('tr.on'),
	cookie = $.cookie('escuelas'),
	escuelas = cookie && cookie.split('-') || [];
	for(var i=0;i<on.length;i++){
		var val = $(on[i]),
		cct = val.find('.compara-escuela').attr('href');
		if(escuelas.indexOf(cct)==-1)
			escuelas.push(cct);
	}
	escuelas.sort();
	if(escuelas.length){
		$.cookie('escuelas',escuelas.join('-'));
	}

}
<|endoftext|>


<commit_before>/* globals it, describe, require */
"use strict";

var js2xmlparser = require("../lib/js2xmlparser"),
    should       = require("should");

describe("the XML parser", function () {

  describe("when prettyPrinting is disabled", function () {
    var opts = {
          prettyPrinting: {
            enabled : false
          }
    };

    it("should correctly serialize a simple object", function () {
      var res = js2xmlparser("root", {"hello":"world"}, opts);
      res.should.eql("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><hello>world</hello></root>");
    });

    it("should correctly serialize an empty object", function () {
      var res = js2xmlparser("root", {}, opts);
      res.should.eql("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root/>");
    });

    it("should correctly serialize an empty object", function () {
      var res;
      try {
        res = js2xmlparser(undefined, {}, opts);
      } catch (e) {
        e.should.match(/root element must be a string/);
      }
      should.not.exist(res);
    });
  });
});<commit_msg>Fix test description<commit_after>/* globals it, describe, require */
"use strict";

var js2xmlparser = require("../lib/js2xmlparser"),
    should       = require("should");

describe("the XML parser", function () {

  describe("when prettyPrinting is disabled", function () {
    var opts = {
          prettyPrinting: {
            enabled : false
          }
    };

    it("should correctly serialize a simple object", function () {
      var res = js2xmlparser("root", {"hello":"world"}, opts);
      res.should.eql("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><hello>world</hello></root>");
    });

    it("should correctly serialize an empty object", function () {
      var res = js2xmlparser("root", {}, opts);
      res.should.eql("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root/>");
    });

    it("should raise an error when no root is provided", function () {
      var res;
      try {
        res = js2xmlparser(undefined, {}, opts);
      } catch (e) {
        e.should.match(/root element must be a string/);
      }
      should.not.exist(res);
    });
  });
});<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var tape = require('tape');
var parallel = require('run-parallel');
var NullStatsd = require('uber-statsd-client/null');
var debugLogtron = require('debug-logtron');
var inherits = require('util').inherits;
var tapeCluster = require('tape-cluster');

var allocCluster = require('./alloc-cluster.js');
var EventEmitter = require('../../lib/event_emitter.js');
var EndpointHandler = require('../../endpoint-handler.js');
var ServiceProxy = require('../../hyperbahn/service_proxy.js');
var HyperbahnHandler = require('../../hyperbahn/handler.js');

function noop() {}

// e.g., topology = {'alice': ['127.0.0.1:4040'], 'bob': ['127.0.0.1:4041']}, '127.0.0.1:4040'
function FakeEgressNodes(topology, hostPort) {
    var self = this;
    EventEmitter.call(self);
    self.hostPort = hostPort;
    self.topology = topology;
    self.membershipChangedEvent = self.defineEvent('membershipChanged');
}

inherits(FakeEgressNodes, EventEmitter);

FakeEgressNodes.prototype.isExitFor = function isExitFor(serviceName) {
    var self = this;
    return self.topology[serviceName].indexOf(self.hostPort) >= 0;
};

FakeEgressNodes.prototype.exitsFor = function exitsFor(serviceName) {
    var self = this;
    var hostPorts = self.topology[serviceName];
    var result = Object.create(null);
    hostPorts.forEach(function (hostPort, index) {
        result[hostPort] = serviceName + "~" + index;
    });
    return result;
};

function RelayNetwork(options) {
    if (!(this instanceof RelayNetwork)) {
        return new RelayNetwork(options);
    }

    var self = this;

    self.numRelays = options.numRelays || 3;
    self.numInstancesPerService = options.numInstancesPerService || 3;
    self.serviceNames = options.serviceNames || ['alice', 'bob', 'charlie'];
    self.kValue = options.kValue || 2;
    self.createCircuits = options.createCircuits || noop;
    self.clusterOptions = options.cluster || {};

    self.numPeers = self.numRelays + self.serviceNames.length * self.numInstancesPerService;
    self.clusterOptions.numPeers = self.numPeers;
    self.cluster = null;
    self.topology = null;
    self.relayChannels = null;
    self.serviceChannels = null;
    self.serviceChannelsByName = null;

    var relayIndexes = [];
    for (var relayIndex = 0; relayIndex < self.numRelays; relayIndex++) {
        relayIndexes.push(relayIndex);
    }
    self.relayIndexes = relayIndexes;

    var instanceIndexes = [];
    for (var instanceIndex = 0; instanceIndex < self.numInstancesPerService; instanceIndex++) {
        instanceIndexes.push(instanceIndex);
    }
    self.instanceIndexes = instanceIndexes;
}

RelayNetwork.test = tapeCluster(tape, RelayNetwork);

RelayNetwork.prototype.bootstrap = function bootstrap(cb) {
    var self = this;

    allocCluster(self.clusterOptions).ready(clusterReady);

    function clusterReady(cluster) {
        self.setCluster(cluster);
        self.connect(cb);
    }
};

RelayNetwork.prototype.close = function close(cb) {
    var self = this;

    self.cluster.destroy();
    cb();
};

RelayNetwork.prototype.setCluster = function setCluster(cluster) {
    var self = this;
    self.cluster = cluster;

    // consume channels for the following services
    var nextChannelIndex = 0;

    self.relayChannels = self.relayIndexes.map(function () {
        return cluster.channels[nextChannelIndex++];
    });

    self.serviceChannels = [];
    self.serviceChannelsByName = {};
    self.serviceNames.forEach(function (serviceName) {
        var channels = self.instanceIndexes.map(function (instanceIndex) {
            return cluster.channels[nextChannelIndex++];
        });
        self.serviceChannels.push(channels);
        self.serviceChannelsByName[serviceName] = channels;
    });

    // Create a relay topology for egress nodes.
    self.topology = {};
    self.serviceChannels.forEach(function (channels, index) {
        var serviceName = self.serviceNames[index];
        var relayHostPorts = [];
        for (var kIndex = 0; kIndex < self.kValue; kIndex++) {
            var hostPort = self.relayChannels[
                (index + kIndex) %
                self.relayChannels.length
            ].hostPort;

            if (relayHostPorts.indexOf(hostPort) === -1) {
                relayHostPorts.push(hostPort);
            }
        }
        self.topology[serviceName] = relayHostPorts;
    });

    self.egressNodesForRelay = self.relayChannels.map(function eachRelay(relayChannel, index) {
        return new FakeEgressNodes(self.topology, relayChannel.hostPort);
    });

    // Set up relays
    self.relayChannels.forEach(function (relayChannel, index) {
        var egressNodes = self.egressNodesForRelay[index];
        var statsd = new NullStatsd();

        relayChannel.handler = new ServiceProxy({
            channel: relayChannel,
            logger: debugLogtron('serviceproxy' + index, {enabled: true}),
            statsd: statsd,
            egressNodes: egressNodes,
            circuits: self.createCircuits({
                timers: relayChannel.timers,
                random: null,
                period: null,
                maxErrorRate: null,
                minRequests: null,
                probation: null
            })
        });

        var hyperbahnChannel = relayChannel.makeSubChannel({
            serviceName: 'hyperbahn'
        });
        var hyperbahnHandler = HyperbahnHandler({
            channel: hyperbahnChannel,
            egressNodes: egressNodes,
            callerName: 'autobahn'
        });
        hyperbahnHandler.advertise =
        function advertise(serviceObj) {
            var peer = relayChannel.handler.getServicePeer(
                serviceObj.serviceName, serviceObj.hostPort
            );
            peer.connect();
        };
        hyperbahnChannel.handler = hyperbahnHandler;

        // In response to artificial advertisement
        self.serviceNames.forEach(function eachServiceName(serviceName, index) {
            if (egressNodes.isExitFor(serviceName)) {
                self.serviceChannels[index].forEach(function (serviceChannel) {
                    relayChannel.handler.getServicePeer(serviceName, serviceChannel.hostPort);
                });
            }
        });
    });

    // Create and connect service channels
    self.subChannels = [];
    self.subChannelsByName = {};
    self.serviceChannels.forEach(function (channels, serviceIndex) {
        var serviceName = self.serviceNames[serviceIndex];
        var subChannels = channels.map(function (channel, channelIndex) {
            var subChannel = channel.makeSubChannel({
                serviceName: serviceName,
                requestDefaults: {
                    headers: {
                        cn: serviceName
                    },
                    hasNoParent: true
                },
                peers: self.topology[serviceName] // TODO this really ought to be linked directly to the root peers
            });

            // Set up server
            var endpointHandler = new EndpointHandler(serviceName);
            subChannel.handler = endpointHandler;

            return subChannel;
        });
        self.subChannels.push(subChannels);
        self.subChannelsByName[serviceName] = subChannels;
    });

};

RelayNetwork.prototype.forEachSubChannel = function (callback) {
    var self = this;
    self.subChannels.forEach(function (subChannels, serviceIndex) {
        var serviceName = self.serviceNames[serviceIndex];
        subChannels.forEach(function (subChannel, instanceIndex) {
            callback(subChannel, serviceName, instanceIndex);
        });
    });
};

RelayNetwork.prototype.connect = function connect(callback) {
    var self = this;

    function connectRelays(callback) {
        return self.cluster.connectChannels(
            self.relayChannels,
            callback
        );
    }

    function connectServices(callback) {
        self.connectServices(callback);
    }

    return parallel([connectRelays, connectServices], callback);
};

RelayNetwork.prototype.connectServices = function connectServices(callback) {
    var self = this;

    var plans = [];

    self.relayChannels.forEach(function (relayChannel, relayIndex) {
        self.serviceNames.forEach(function (serviceName) {
            if (self.egressNodesForRelay[relayIndex].isExitFor(serviceName)) {
                plans.push(planToConnect(
                    relayChannel,
                    self.serviceChannelsByName[serviceName]
                ));
            }
        });
    });

    function planToConnect(channel, channels) {
        return function connect(callback) {
            return self.cluster.connectChannelToChannels(channel, channels, callback);
        };
    }

    return parallel(plans, callback);
};

module.exports = RelayNetwork;
<commit_msg>test/relay_network: add support for dynamic service names<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var tape = require('tape');
var parallel = require('run-parallel');
var NullStatsd = require('uber-statsd-client/null');
var debugLogtron = require('debug-logtron');
var inherits = require('util').inherits;
var tapeCluster = require('tape-cluster');

var allocCluster = require('./alloc-cluster.js');
var EventEmitter = require('../../lib/event_emitter.js');
var EndpointHandler = require('../../endpoint-handler.js');
var ServiceProxy = require('../../hyperbahn/service_proxy.js');
var HyperbahnHandler = require('../../hyperbahn/handler.js');

function noop() {}

// e.g., topology = {'alice': ['127.0.0.1:4040'], 'bob': ['127.0.0.1:4041']}, '127.0.0.1:4040'
function FakeEgressNodes(options) {
    if (!(this instanceof FakeEgressNodes)) {
        return new FakeEgressNodes(options);
    }

    var self = this;

    EventEmitter.call(self);

    self.hostPort = options.hostPort;

    // Everyone must mutate this
    self.topology = options.topology;
    self.kValue = options.kValue;
    self.relayChannels = options.relayChannels;

    self.membershipChangedEvent = self.defineEvent('membershipChanged');
}

inherits(FakeEgressNodes, EventEmitter);

FakeEgressNodes.prototype.isExitFor = function isExitFor(serviceName) {
    var self = this;

    return self.topology[serviceName].indexOf(self.hostPort) >= 0;
};

FakeEgressNodes.prototype.getRandomNodes =
function getRandomNodes(serviceName) {
    var self = this;

    var hosts = [];

    for (var i = 0; i < self.kValue; i++) {
        var n = Math.floor(Math.random() * self.relayChannels.length);

        var node = self.relayChannels[n].hostPort;
        if (hosts.indexOf(node) === -1) {
            hosts.push(node);
        }
    }

    self.topology[serviceName] = hosts;

    return hosts;
};

FakeEgressNodes.prototype.exitsFor = function exitsFor(serviceName) {
    var self = this;

    var hostPorts = self.topology[serviceName];

    // A random service; pick k random things
    if (!hostPorts) {
        hostPorts = self.getRandomNodes(serviceName);
    }

    var result = Object.create(null);
    hostPorts.forEach(function buildResult(hostPort, index) {
        result[hostPort] = serviceName + '~' + index;
    });
    return result;
};

function RelayNetwork(options) {
    if (!(this instanceof RelayNetwork)) {
        return new RelayNetwork(options);
    }

    var self = this;

    self.numRelays = options.numRelays || 3;
    self.numInstancesPerService = options.numInstancesPerService || 3;
    self.serviceNames = options.serviceNames || ['alice', 'bob', 'charlie'];
    self.kValue = options.kValue || 2;
    self.createCircuits = options.createCircuits || noop;
    self.clusterOptions = options.cluster || {};

    self.numPeers = self.numRelays + self.serviceNames.length * self.numInstancesPerService;
    self.clusterOptions.numPeers = self.numPeers;
    self.cluster = null;

    // The topology gets mutate by all the fake egress nodes to get consensus
    self.topology = null;
    self.relayChannels = null;
    self.serviceChannels = null;
    self.serviceChannelsByName = null;

    var relayIndexes = [];
    for (var relayIndex = 0; relayIndex < self.numRelays; relayIndex++) {
        relayIndexes.push(relayIndex);
    }
    self.relayIndexes = relayIndexes;

    var instanceIndexes = [];
    for (var instanceIndex = 0; instanceIndex < self.numInstancesPerService; instanceIndex++) {
        instanceIndexes.push(instanceIndex);
    }
    self.instanceIndexes = instanceIndexes;
}

RelayNetwork.test = tapeCluster(tape, RelayNetwork);

RelayNetwork.prototype.bootstrap = function bootstrap(cb) {
    var self = this;

    allocCluster(self.clusterOptions).ready(clusterReady);

    function clusterReady(cluster) {
        self.setCluster(cluster);
        self.connect(cb);
    }
};

RelayNetwork.prototype.close = function close(cb) {
    var self = this;

    self.cluster.destroy();
    cb();
};

RelayNetwork.prototype.setCluster = function setCluster(cluster) {
    var self = this;
    self.cluster = cluster;

    // consume channels for the following services
    var nextChannelIndex = 0;

    self.relayChannels = self.relayIndexes.map(function () {
        return cluster.channels[nextChannelIndex++];
    });

    self.serviceChannels = [];
    self.serviceChannelsByName = {};
    self.serviceNames.forEach(function (serviceName) {
        var channels = self.instanceIndexes.map(function (instanceIndex) {
            return cluster.channels[nextChannelIndex++];
        });
        self.serviceChannels.push(channels);
        self.serviceChannelsByName[serviceName] = channels;
    });

    // Create a relay topology for egress nodes.
    self.topology = {};
    self.serviceChannels.forEach(function (channels, index) {
        var serviceName = self.serviceNames[index];
        var relayHostPorts = [];
        for (var kIndex = 0; kIndex < self.kValue; kIndex++) {
            var hostPort = self.relayChannels[
                (index + kIndex) %
                self.relayChannels.length
            ].hostPort;

            if (relayHostPorts.indexOf(hostPort) === -1) {
                relayHostPorts.push(hostPort);
            }
        }
        self.topology[serviceName] = relayHostPorts;
    });

    self.egressNodesForRelay = self.relayChannels.map(function eachRelay(relayChannel, index) {
        return new FakeEgressNodes({
            topology: self.topology,
            hostPort: relayChannel.hostPort,
            relayChannels: self.relayChannels,
            kValue: self.kValue
        });
    });

    // Set up relays
    self.relayChannels.forEach(function (relayChannel, index) {
        var egressNodes = self.egressNodesForRelay[index];
        var statsd = new NullStatsd();

        relayChannel.handler = new ServiceProxy({
            channel: relayChannel,
            logger: debugLogtron('serviceproxy' + index, {enabled: true}),
            statsd: statsd,
            egressNodes: egressNodes,
            circuits: self.createCircuits({
                timers: relayChannel.timers,
                random: null,
                period: null,
                maxErrorRate: null,
                minRequests: null,
                probation: null
            })
        });

        var hyperbahnChannel = relayChannel.makeSubChannel({
            serviceName: 'hyperbahn'
        });
        var hyperbahnHandler = HyperbahnHandler({
            channel: hyperbahnChannel,
            egressNodes: egressNodes,
            callerName: 'autobahn'
        });
        hyperbahnHandler.advertise =
        function advertise(serviceObj) {
            var peer = relayChannel.handler.getServicePeer(
                serviceObj.serviceName, serviceObj.hostPort
            );
            peer.connect();
        };
        hyperbahnChannel.handler = hyperbahnHandler;

        // In response to artificial advertisement
        self.serviceNames.forEach(function eachServiceName(serviceName, index) {
            if (egressNodes.isExitFor(serviceName)) {
                self.serviceChannels[index].forEach(function (serviceChannel) {
                    relayChannel.handler.getServicePeer(serviceName, serviceChannel.hostPort);
                });
            }
        });
    });

    // Create and connect service channels
    self.subChannels = [];
    self.subChannelsByName = {};
    self.serviceChannels.forEach(function (channels, serviceIndex) {
        var serviceName = self.serviceNames[serviceIndex];
        var subChannels = channels.map(function (channel, channelIndex) {
            var subChannel = channel.makeSubChannel({
                serviceName: serviceName,
                requestDefaults: {
                    headers: {
                        cn: serviceName
                    },
                    hasNoParent: true
                },
                peers: self.topology[serviceName] // TODO this really ought to be linked directly to the root peers
            });

            // Set up server
            var endpointHandler = new EndpointHandler(serviceName);
            subChannel.handler = endpointHandler;

            return subChannel;
        });
        self.subChannels.push(subChannels);
        self.subChannelsByName[serviceName] = subChannels;
    });

};

RelayNetwork.prototype.forEachSubChannel = function (callback) {
    var self = this;
    self.subChannels.forEach(function (subChannels, serviceIndex) {
        var serviceName = self.serviceNames[serviceIndex];
        subChannels.forEach(function (subChannel, instanceIndex) {
            callback(subChannel, serviceName, instanceIndex);
        });
    });
};

RelayNetwork.prototype.connect = function connect(callback) {
    var self = this;

    function connectRelays(callback) {
        return self.cluster.connectChannels(
            self.relayChannels,
            callback
        );
    }

    function connectServices(callback) {
        self.connectServices(callback);
    }

    return parallel([connectRelays, connectServices], callback);
};

RelayNetwork.prototype.connectServices = function connectServices(callback) {
    var self = this;

    var plans = [];

    self.relayChannels.forEach(function (relayChannel, relayIndex) {
        self.serviceNames.forEach(function (serviceName) {
            if (self.egressNodesForRelay[relayIndex].isExitFor(serviceName)) {
                plans.push(planToConnect(
                    relayChannel,
                    self.serviceChannelsByName[serviceName]
                ));
            }
        });
    });

    function planToConnect(channel, channels) {
        return function connect(callback) {
            return self.cluster.connectChannelToChannels(channel, channels, callback);
        };
    }

    return parallel(plans, callback);
};

module.exports = RelayNetwork;
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import R from 'ramda';
import {
  Link,
} from 'react-router-dom';

import block from '../../../helpers/bem-cn';

import Correct from './Correct';
import Icon from '../../Icon/Icon';
import Pagination from '../../Pagination/Pagination';
import HealthCheckModal from '../../modals/HealthCheckModal/HealthCheckModal';

import './HealthCheckList.css';

const b = block('j-healthcheck');
const bList = block(b('list')());
const bItem = block(b('list-item')());

const propTypes = {
    clearHealthCheckDetails: PropTypes.func.isRequired,
    currentPageIndex: PropTypes.number.isRequired,
    fetchHealthCheckList: PropTypes.func.isRequired,
    fetchHealthCheckItem: PropTypes.func.isRequired,
    healthcheckList: PropTypes.arrayOf(PropTypes.object).isRequired,
    setCurrentPageIndex: PropTypes.func.isRequired,
};

class HealthCheckList extends PureComponent {
    componentDidMount() {
        this.props.fetchHealthCheckList();
    }

    handleShowDetailes = name => {
        this.props.fetchHealthCheckItem(name);
    }

    renderHealthcheckInfo = list => {
        const {
            clearHealthCheckDetails,
            problemToDisplay,
            status,
        } = this.props;

        if (status) {
            return (

                    <Correct className={b('correct')()} />

            );
        }

        return (

                {
                    list.map(item => {
                        return (

{item.name}

{item.message}

 this.handleShowDetailes(item.name)}>Show Details

                                <Link to={`/${item.name}`}>
                                    <Icon type="edit" />
                                </Link>

                        );
                    })
                }

                <HealthCheckModal
                    className={b('modal')()}
                    isOpen={!R.isEmpty(problemToDisplay)}
                    closeModal={clearHealthCheckDetails}
                    message={problemToDisplay.status}
                    statusText={problemToDisplay.name}
                    problems={problemToDisplay.list}
                />

        );
    }

    render() {
        return (
            <Pagination
                list={this.props.healthcheckList}
                itemsPerPage={3}
                currentPageIndex={this.props.currentPageIndex}
                changePageIndex={this.props.setCurrentPageIndex}
                maximumVisiblePaginators={3}
                renderChildren={this.renderHealthcheckInfo}
            />
        );
    }
};

HealthCheckList.propTypes = propTypes;

export default HealthCheckList;
<commit_msg>fi CS<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import R from 'ramda';
import { Link } from 'react-router-dom';

import block from '../../../helpers/bem-cn';

import Correct from './Correct';
import Icon from '../../Icon/Icon';
import Pagination from '../../Pagination/Pagination';
import HealthCheckModal from '../../modals/HealthCheckModal/HealthCheckModal';

import './HealthCheckList.css';

const b = block('j-healthcheck');
const bList = block(b('list')());
const bItem = block(b('list-item')());

const propTypes = {
    clearHealthCheckDetails: PropTypes.func.isRequired,
    currentPageIndex: PropTypes.number.isRequired,
    fetchHealthCheckList: PropTypes.func.isRequired,
    fetchHealthCheckItem: PropTypes.func.isRequired,
    healthcheckList: PropTypes.arrayOf(PropTypes.object).isRequired,
    setCurrentPageIndex: PropTypes.func.isRequired,
};

class HealthCheckList extends PureComponent {
    componentDidMount() {
        this.props.fetchHealthCheckList();
    }

    handleShowDetailes = name => {
        this.props.fetchHealthCheckItem(name);
    }

    renderHealthcheckInfo = list => {
        const {
            clearHealthCheckDetails,
            problemToDisplay,
            status,
        } = this.props;

        if (status) {
            return (

                    <Correct className={b('correct')()} />

            );
        }

        return (

                {
                    list.map(item => {
                        return (

{item.name}

{item.message}

 this.handleShowDetailes(item.name)}>Show Details

                                <Link to={`/${item.name}`}>
                                    <Icon type="edit" />
                                </Link>

                        );
                    })
                }

                <HealthCheckModal
                    className={b('modal')()}
                    isOpen={!R.isEmpty(problemToDisplay)}
                    closeModal={clearHealthCheckDetails}
                    message={problemToDisplay.status}
                    statusText={problemToDisplay.name}
                    problems={problemToDisplay.list}
                />

        );
    }

    render() {
        return (
            <Pagination
                list={this.props.healthcheckList}
                itemsPerPage={3}
                currentPageIndex={this.props.currentPageIndex}
                changePageIndex={this.props.setCurrentPageIndex}
                maximumVisiblePaginators={3}
                renderChildren={this.renderHealthcheckInfo}
            />
        );
    }
};

HealthCheckList.propTypes = propTypes;

export default HealthCheckList;
<|endoftext|>