<commit_before>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

'use strict';
require('lib/promise');

var _ = require('underscore');
var debug = require('debug')('wall:module_state_machine');
var random = require('random-js')();

var stateMachine = require('lib/state_machine');
var time = require('server/util/time');
var library = require('server/modules/module_library');
var ServerStateMachine = require('server/modules/server_state_machine');
var geometry = require('lib/geometry');

function isDisplayInPoly(rect, poly) {
  // find the center point of this display:
  var cx = rect.w / 2 + rect.x;
  var cy = rect.h / 2 + rect.y;

  return geometry.isInside(poly, cx, cy);
}

// Takes a map of client ids -> client state machines. Not owned or changed
// by this class, only read.
class ModuleStateMachine extends stateMachine.Machine {
  constructor(allClients, geo) {
    super(debug, new IdleState);

    // The geo that contains this module sm.
    this.geo_ = geo;

    // Map of ID to ClientControlStateMachine for all clients.
    this.allClients_ = allClients;

    // Server module controller by the module state machine.
    this.context_.server = new ServerStateMachine(geo);

    // Clients controlled by the module state machine.
    this.context_.clients = _.pick(allClients, (client) =>
        isDisplayInPoly(client.getClientInfo().rect, geo));

    _.each(this.context_.clients, (clientSM) => clientSM.setGeo(geo));

    this.context_.playlist = null;
    this.context_.moduleDuration = null;

    this.reloadHandler = (moduleDef) => {
      this.playModule(moduleDef.name);
    };
    library.on('reloaded', this.reloadHandler);
  }
  newClient(client) {
    if (!isDisplayInPoly(client.rect, this.geo_)) {
      return false;
    }

    this.context_.clients[client.socket.id] = this.allClients_[client.socket.id];
    this.context_.clients[client.socket.id].setGeo(this.geo_);
    this.current_.newClient(client);
    return true;
  }
  dropClient(id) {
    if (!(id in this.context_.clients)) {
      return false;
    }

    delete this.context_.clients[id];

    return true;
  }
  loadPlaylist(layout, deadline) {
    debug('switch to layout', layout);
    this.context_.playlist = layout.modules.slice(0);
    random.shuffle(this.context_.playlist);
    this.context_.moduleDuration = layout.moduleDuration;
    this.current_.loadPlaylist(deadline);
  }
  fadeToBlack(deadline) {
    library.removeListener('reloaded', this.reloadHandler);

    this.context_.playlist = [library.modules['_faded_out']];  // jshint ignore:line
    this.context_.moduleDuration = deadline;
    this.current_.loadPlaylist(deadline);

    // Return a promise that will be resolved when the state machine is
    // idling (technically, in Display state with a black-screen module).
    return this.context_.server.monitorState(function(state) {
      return state.name_ == 'DisplayState';
    }).then(() => this.stop());
  }
  playModule(moduleName) {
    return this.current_.playModule(moduleName);
  }
  getGeo() {
    return this.geo_;
  }
  getDeadlineOfNextTransition() {
    return this.current_.getDeadline();
  }
  stop() {
    this.context_.server.stop();
  }
}

class IdleState extends stateMachine.State {
  constructor() {
    super('IdleState');
  }
  enter_() {}
  loadPlaylist(deadline) {
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {}
  playModule(moduleName) {
    return false;
  }
  getDeadline() {
    return Infinity;
  }
}

class LoadingState extends stateMachine.State {
  constructor(deadline) {
    super('LoadingState');

    this.indexOfModuleToPlayWhenLoaded_ = 0;

    // The time at which we should swap to the new playlist.
    this.deadline_ = deadline;
  }
  enter_() {
    // Load the playlist.
    var modulePromises = this.context_.playlist.map((m) => m.loadPromise);
    Promise.allSettled(modulePromises).done((results) => {
      // Check to see if any modules were rejected. If so, remove them from the
      // playlist.
      this.context_.playlist = this.context_.playlist.filter((module, index) => {
        if (results[index].status != 'resolved') {
          debug('Removing ' + module + ' from the playlist!');
        }
        return results[index].status == 'resolved';
      });
      this.transition_(new TransitionState(this.deadline_, this.indexOfModuleToPlayWhenLoaded_));
    });
  }
  loadPlaylist(deadline) {
    // Stop any prior async work from continuing.
    // The fact that we still be in the 'map' above is no big deal, we'll just
    // extra disk i/o.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {}
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Will play module ' + moduleName + ' when loading is complete.');
      this.indexOfModuleToPlayWhenLoaded_ = index;
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

class TransitionState extends stateMachine.State {
  constructor(deadline, opt_index) {
    super('TransitionState');

    // If no next item passed, choose the first one.
    this.index_ = opt_index || 0;

    this.deadline_ = deadline;

    // The current moduleDef we are attempting to show or showing.
    this.moduleDef_ = null;
  }
  enter_() {
    // Check for wrapping.
    this.index_ = this.index_ % this.context_.playlist.length;

    // We'll attempt to transition the clients to this module.
    this.moduleDef_ = this.context_.playlist[this.index_];

    // Tell the server to transition.
    this.context_.server.nextModule(this.moduleDef_, this.deadline_);
    this.context_.server
        .monitorState((state) => {
          return state.name_ == 'ErrorState' || state.name_ == 'TransitionState';
        }).then(() => {
          if (this.context_.server.getState() == 'ErrorState') {
            debug('Advancing to next module soon due to error state');
            // Wait a bit so that if we only have one module (as in
            // development mode) we don't throw errors in a tight loop.
            this.deadline_ = time.inFuture(2000);
            Promise.delay(2000).then(() => this.transition_(
                new TransitionState(time.inFuture(5000), this.index_ + 1)));
          }
        });

    // Tell each client to do the module.
    _.each(this.context_.clients, function(clientState) {
      clientState.nextModule(this.moduleDef_, this.deadline_);
    }, this);

    // When the deadline arrives, enter display state.
    debug('Waiting until', this.deadline_);
    Promise.delay(time.until(this.deadline_)).done(() => {
      let originalIndex = _(this.context_.playlist).findIndex(this.moduleDef_);
      let duration = this.index_ != originalIndex ? 1 : undefined;
      this.transition_(new DisplayState(
          this.moduleDef_, this.deadline_, this.index_, duration));
    });
  }
  loadPlaylist(deadline) {
    // We changed the layout... immediately load the new playlist.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {
    // Tell the new guy to load the next module NOW.
    this.context_.clients[client.socket.id].nextModule(
        this.moduleDef_, this.deadline_);
  }
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Will play module ' + moduleName + ' just as soon as current transition completes!');
      this.index_ = index;
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

class DisplayState extends stateMachine.State {
  constructor(moduleDef, deadline, index, opt_duration) {
    super('DisplayState');

    // The module to tell late clients to transition to.
    this.lateClientModuleDef_ = moduleDef;
    this.lateClientDeadline_ = deadline;

    // What to play from the playlist.
    this.index_ = index;

    // How long to play the module.
    this.duration_ = opt_duration || 0;
  }
  enter_() {
    if (this.context_.playlist.length > 1) {
      // Hold for a while, then transition to the next module.

      // Pad the module duration by 20% so that individual wall partitions
      // transition at slightly different times.
      this.duration_ = this.duration_ || this.context_.moduleDuration +
          Math.random() * this.context_.moduleDuration / 5 * 1000;
      this.deadline_ = time.inFuture(this.duration_);

      debug('Displaying ', this.lateClientModuleDef_.name, 'until', this.deadline_ , this.duration_);
      Promise.delay(time.until(this.deadline_)).done(() => {
        this.transition_(new TransitionState(
            this.deadline_, this.index_ + 1));
      });
    } else {
      debug('Displaying ', this.lateClientModuleDef_.name);
      this.deadline_ = Infinity;
    }
  }
  loadPlaylist(deadline) {
    // We changed the layout... immediately load the new playlist.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {
    // Tell the new guy to load the next module NOW.
    this.context_.clients[client.socket.id].nextModule(
        this.lateClientModuleDef_, this.lateClientDeadline_);
  }
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Found requested module ' + moduleName, index);
      this.index_ = index;
      // Transition immediately.
      this.transition_(new TransitionState(time.now(), index));
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

module.exports = ModuleStateMachine;
<commit_msg>Fix module durations after moduledef refactoring.<commit_after>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

'use strict';
require('lib/promise');

var _ = require('underscore');
var debug = require('debug')('wall:module_state_machine');
var random = require('random-js')();

var stateMachine = require('lib/state_machine');
var time = require('server/util/time');
var library = require('server/modules/module_library');
var ServerStateMachine = require('server/modules/server_state_machine');
var geometry = require('lib/geometry');

function isDisplayInPoly(rect, poly) {
  // find the center point of this display:
  var cx = rect.w / 2 + rect.x;
  var cy = rect.h / 2 + rect.y;

  return geometry.isInside(poly, cx, cy);
}

// Takes a map of client ids -> client state machines. Not owned or changed
// by this class, only read.
class ModuleStateMachine extends stateMachine.Machine {
  constructor(allClients, geo) {
    super(debug, new IdleState);

    // The geo that contains this module sm.
    this.geo_ = geo;

    // Map of ID to ClientControlStateMachine for all clients.
    this.allClients_ = allClients;

    // Server module controller by the module state machine.
    this.context_.server = new ServerStateMachine(geo);

    // Clients controlled by the module state machine.
    this.context_.clients = _.pick(allClients, (client) =>
        isDisplayInPoly(client.getClientInfo().rect, geo));

    _.each(this.context_.clients, (clientSM) => clientSM.setGeo(geo));

    this.context_.playlist = null;
    this.context_.moduleDuration = null;

    this.reloadHandler = (moduleDef) => {
      this.playModule(moduleDef.name);
    };
    library.on('reloaded', this.reloadHandler);
  }
  newClient(client) {
    if (!isDisplayInPoly(client.rect, this.geo_)) {
      return false;
    }

    this.context_.clients[client.socket.id] = this.allClients_[client.socket.id];
    this.context_.clients[client.socket.id].setGeo(this.geo_);
    this.current_.newClient(client);
    return true;
  }
  dropClient(id) {
    if (!(id in this.context_.clients)) {
      return false;
    }

    delete this.context_.clients[id];

    return true;
  }
  loadPlaylist(layout, deadline) {
    debug('switch to layout', layout);
    this.context_.playlist = layout.modules.slice(0);
    random.shuffle(this.context_.playlist);
    this.context_.moduleDuration = layout.moduleDuration;
    this.current_.loadPlaylist(deadline);
  }
  fadeToBlack(deadline) {
    library.removeListener('reloaded', this.reloadHandler);

    this.context_.playlist = [library.modules['_faded_out']];  // jshint ignore:line
    this.context_.moduleDuration = deadline;
    this.current_.loadPlaylist(deadline);

    // Return a promise that will be resolved when the state machine is
    // idling (technically, in Display state with a black-screen module).
    return this.context_.server.monitorState(function(state) {
      return state.name_ == 'DisplayState';
    }).then(() => this.stop());
  }
  playModule(moduleName) {
    return this.current_.playModule(moduleName);
  }
  getGeo() {
    return this.geo_;
  }
  getDeadlineOfNextTransition() {
    return this.current_.getDeadline();
  }
  stop() {
    this.context_.server.stop();
  }
}

class IdleState extends stateMachine.State {
  constructor() {
    super('IdleState');
  }
  enter_() {}
  loadPlaylist(deadline) {
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {}
  playModule(moduleName) {
    return false;
  }
  getDeadline() {
    return Infinity;
  }
}

class LoadingState extends stateMachine.State {
  constructor(deadline) {
    super('LoadingState');

    this.indexOfModuleToPlayWhenLoaded_ = 0;

    // The time at which we should swap to the new playlist.
    this.deadline_ = deadline;
  }
  enter_() {
    // Load the playlist.
    var modulePromises = this.context_.playlist.map((m) => m.loadPromise);
    Promise.allSettled(modulePromises).done((results) => {
      // Check to see if any modules were rejected. If so, remove them from the
      // playlist.
      this.context_.playlist = this.context_.playlist.filter((module, index) => {
        if (results[index].status != 'resolved') {
          debug('Removing ' + module + ' from the playlist!');
        }
        return results[index].status == 'resolved';
      });
      this.transition_(new TransitionState(this.deadline_, this.indexOfModuleToPlayWhenLoaded_));
    });
  }
  loadPlaylist(deadline) {
    // Stop any prior async work from continuing.
    // The fact that we still be in the 'map' above is no big deal, we'll just
    // extra disk i/o.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {}
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Will play module ' + moduleName + ' when loading is complete.');
      this.indexOfModuleToPlayWhenLoaded_ = index;
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

class TransitionState extends stateMachine.State {
  constructor(deadline, opt_index) {
    super('TransitionState');

    // If no next item passed, choose the first one.
    this.index_ = opt_index || 0;

    this.deadline_ = deadline;

    // The current moduleDef we are attempting to show or showing.
    this.moduleDef_ = null;
  }
  enter_() {
    // Check for wrapping.
    this.index_ = this.index_ % this.context_.playlist.length;

    // We'll attempt to transition the clients to this module.
    this.moduleDef_ = this.context_.playlist[this.index_];

    // Tell the server to transition.
    this.context_.server.nextModule(this.moduleDef_, this.deadline_);
    this.context_.server
        .monitorState((state) => {
          return state.name_ == 'ErrorState' || state.name_ == 'TransitionState';
        }).then(() => {
          if (this.context_.server.getState() == 'ErrorState') {
            debug('Advancing to next module soon due to error state');
            // Wait a bit so that if we only have one module (as in
            // development mode) we don't throw errors in a tight loop.
            this.deadline_ = time.inFuture(2000);
            Promise.delay(2000).then(() => this.transition_(
                new TransitionState(time.inFuture(5000), this.index_ + 1)));
          }
        });

    // Tell each client to do the module.
    _.each(this.context_.clients, function(clientState) {
      clientState.nextModule(this.moduleDef_, this.deadline_);
    }, this);

    // When the deadline arrives, enter display state.
    debug('Waiting until', this.deadline_);
    Promise.delay(time.until(this.deadline_)).done(() => {
      let originalIndex = _(this.context_.playlist).findIndex(this.moduleDef_);
      let duration = this.index_ != originalIndex ? 1 : undefined;
      this.transition_(new DisplayState(
          this.moduleDef_, this.deadline_, this.index_, duration));
    });
  }
  loadPlaylist(deadline) {
    // We changed the layout... immediately load the new playlist.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {
    // Tell the new guy to load the next module NOW.
    this.context_.clients[client.socket.id].nextModule(
        this.moduleDef_, this.deadline_);
  }
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Will play module ' + moduleName + ' just as soon as current transition completes!');
      this.index_ = index;
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

class DisplayState extends stateMachine.State {
  constructor(moduleDef, deadline, index, opt_duration) {
    super('DisplayState');

    // The module to tell late clients to transition to.
    this.lateClientModuleDef_ = moduleDef;
    this.lateClientDeadline_ = deadline;

    // What to play from the playlist.
    this.index_ = index;

    // How long to play the module.
    this.duration_ = opt_duration || 0;
  }
  enter_() {
    if (this.context_.playlist.length > 1) {
      // Hold for a while, then transition to the next module.

      // Pad the module duration by 20% so that individual wall partitions
      // transition at slightly different times.
      this.duration_ = this.duration_ || (this.context_.moduleDuration +
          Math.random() * this.context_.moduleDuration / 5) * 1000;
      this.deadline_ = time.inFuture(this.duration_);

      debug('Displaying ', this.lateClientModuleDef_.name, 'until', this.deadline_ , this.duration_);
      Promise.delay(time.until(this.deadline_)).done(() => {
        this.transition_(new TransitionState(
            this.deadline_, this.index_ + 1));
      });
    } else {
      debug('Displaying ', this.lateClientModuleDef_.name);
      this.deadline_ = Infinity;
    }
  }
  loadPlaylist(deadline) {
    // We changed the layout... immediately load the new playlist.
    this.transition_(new LoadingState(deadline));
  }
  newClient(client) {
    // Tell the new guy to load the next module NOW.
    this.context_.clients[client.socket.id].nextModule(
        this.lateClientModuleDef_, this.lateClientDeadline_);
  }
  playModule(moduleName) {
    var index = _.findIndex(this.context_.playlist, (d) => d.name == moduleName);
    if (index != -1) {
      debug('Found requested module ' + moduleName, index);
      this.index_ = index;
      // Transition immediately.
      this.transition_(new TransitionState(time.now(), index));
      return true;
    }
    debug('Could not find requested module ' + moduleName);
    return false;
  }
  getDeadline() {
    return this.deadline_;
  }
}

module.exports = ModuleStateMachine;
<|endoftext|>


<commit_before><commit_msg>Tests dirnames function properly<commit_after><|endoftext|>


<commit_before>'use strict';
const beaconRate = 5000;
const ignorePressureChangeThreshold = 100000;
class RovBeacon{
    constructor(name,deps){
     this.state={
         name: require('os').hostname(),
         //model:'trident',  //TODO: Add model detection
         battery:.7
     };
     this.beacon = null;
     this.bus = deps.globalEventLoop;

     this._lastIntPressureReading = {time:0,p:0,t:0};
    }

    start() {
     this.beacon = require('./beacon.js')({beaconRate});
     this.beacon.broadcast(this._genBeaconMessage.bind(this));
     this._listenForStateChanges();
    }

    stop(){
     this.beacon.stop();
     this._stopListenForStateChanges()
    }

    _genBeaconMessage(){
        this.state.exp=beaconRate*2; //Set the expeiration for this to 2X the broadcast rate.
        return this.state;
    }

    _listenForStateChanges(){
      this.bus.on('mcu.status',this._processMCUStatus.bind(this))
    }

    _stopListenForStateChanges(){
      this.bus.off('mcu.status',this._processMCUStatus.bind(this))
    }

    _computerPressureTrend(currentpressure,currenttemp){
        //TODO: Do we need to enhance for temperature compensation?
        if (this._lastIntPressureReading.p> (currentpressure+ignorePressureChangeThreshold)) {
            return this._lastIntPressureReading.p-currentpressure;
        }
        if (this._lastIntPressureReading.p< ( currentpressure-ignorePressureChangeThreshold)){
            return this._lastIntPressureReading.p-currentpressure;
        }
        return 0
    }

    _processMCUStatus(status){
        for (var data in status) {
            switch (data) {
                case 'baro_p' :
                    //TODO: Confirm the value units of baro_p
                    //https://gitlab.com/openrov/RIOT/blob/openrov/apps/trident/CMPL3115A2.cpp#L98
                    this.state.intPressure_mb=status["baro_p"];
                    //TODO: Does this need to be smoothed over time?
                    this.state.intPressureRate=this._computerPressureTrend(this.state.intPressure_mb,status['baro_t']);
                    this._lastIntPressureReading = {time: Date.now(), p:this.state.intPressure_mb, t:status['baro_t']};
                break;
                case 'vout' :
                  this.state.battery = status['vout'];
                break;
                case 'batt_v': //Ma
                 this.state.battery = status['batt_v'] / 1000.0;
                break;
            }
        }
    }

}

module.exports = function (name, deps) {
  return new RovBeacon(name, deps);
};<commit_msg>Added imageVersion to udpBeacon<commit_after>'use strict';
const beaconRate = 5000;
const ignorePressureChangeThreshold = 100000;
const RESIN_APP_RELEASE = process.env.RESIN_APP_RELEASE;
class RovBeacon{
    constructor(name,deps){
     this.state={
         name: require('os').hostname(),
         //model:'trident',  //TODO: Add model detection
         battery:.7,
         imageVersion:RESIN_APP_RELEASE
     };
     this.beacon = null;
     this.bus = deps.globalEventLoop;

     this._lastIntPressureReading = {time:0,p:0,t:0};
    }

    start() {
     this.beacon = require('./beacon.js')({beaconRate});
     this.beacon.broadcast(this._genBeaconMessage.bind(this));
     this._listenForStateChanges();
    }

    stop(){
     this.beacon.stop();
     this._stopListenForStateChanges()
    }

    _genBeaconMessage(){
        this.state.exp=beaconRate*2; //Set the expeiration for this to 2X the broadcast rate.
        return this.state;
    }

    _listenForStateChanges(){
      this.bus.on('mcu.status',this._processMCUStatus.bind(this))
    }

    _stopListenForStateChanges(){
      this.bus.off('mcu.status',this._processMCUStatus.bind(this))
    }

    _computerPressureTrend(currentpressure,currenttemp){
        //TODO: Do we need to enhance for temperature compensation?
        if (this._lastIntPressureReading.p> (currentpressure+ignorePressureChangeThreshold)) {
            return this._lastIntPressureReading.p-currentpressure;
        }
        if (this._lastIntPressureReading.p< ( currentpressure-ignorePressureChangeThreshold)){
            return this._lastIntPressureReading.p-currentpressure;
        }
        return 0
    }

    _processMCUStatus(status){
        for (var data in status) {
            switch (data) {
                case 'baro_p' :
                    //TODO: Confirm the value units of baro_p
                    //https://gitlab.com/openrov/RIOT/blob/openrov/apps/trident/CMPL3115A2.cpp#L98
                    this.state.intPressure_mb=status["baro_p"];
                    //TODO: Does this need to be smoothed over time?
                    this.state.intPressureRate=this._computerPressureTrend(this.state.intPressure_mb,status['baro_t']);
                    this._lastIntPressureReading = {time: Date.now(), p:this.state.intPressure_mb, t:status['baro_t']};
                break;
                case 'vout' :
                  this.state.battery = status['vout'];
                break;
                case 'batt_v': //Ma
                 this.state.battery = status['batt_v'] / 1000.0;
                break;
            }
        }
    }

}

module.exports = function (name, deps) {
  return new RovBeacon(name, deps);
};<|endoftext|>


<commit_before>const {join} = require('path');

const grpc = require('grpc');
const {loadSync} = require('@grpc/proto-loader');

const expectedSslConfiguration = require('./conf/lnd').grpc_ssl_cipher_suites;

const confDir = 'conf';
const defaultServiceType = 'Lightning';
const {GRPC_SSL_CIPHER_SUITES} = process.env;
const protoFile = 'grpc.proto';
const unlockerServiceType = 'WalletUnlocker';

/** GRPC interface to the Lightning Network Daemon (lnd).

  {
    cert: <Base64 Serialized LND TLS Cert>
    macaroon: <Base64 Serialized Macaroon String>
    [service]: <Service Name String> // "WalletUnlocker"|"Lightning" (default)
    socket: <Host:Port String>
  }

  @throws
  <ExpectedBase64EncodedGrpcMacaroonFile Error>
  <ExpectedBase64EncodedTlsCertFileString Error>
  <ExpectedGrpcIpOrDomainWithPortString Error>
  <ExpectedGrpcSslCipherSuitesEnvVar Error>
  <UnexpectedLightningDaemonServiceType Error>

  @returns
  <LND GRPC Api Object>
*/
module.exports = ({cert, macaroon, service, socket}) => {
  if (!cert) {
    throw new Error('ExpectedBase64EncodedTlsCertFileString');
  }

  if (!macaroon && service !== unlockerServiceType) {
    throw new Error('ExpectedBase64EncodedGrpcMacaroonFile');
  }

  if (!socket) {
    throw new Error('ExpectedGrpcIpOrDomainWithPortString');
  }

  const packageDefinition = loadSync(join(__dirname, confDir, protoFile), {
    defaults: true,
    enums: String,
    keepCase: true,
    longs: String,
    oneofs: true,
  });

  const rpc = grpc.loadPackageDefinition(packageDefinition);

  // Exit early when GRPC_SSL_CIPHER_SUITES cipher suite is not correct
  if (GRPC_SSL_CIPHER_SUITES !== expectedSslConfiguration) {
    throw new Error('ExpectedGrpcSslCipherSuitesEnvVar');
  }

  const certData = Buffer.from(cert, 'base64');
  let credentials;
  const serviceType = service || defaultServiceType;

  const ssl = grpc.credentials.createSsl(certData);

  switch (serviceType) {
  case defaultServiceType:
    const macaroonData = Buffer.from(macaroon, 'base64').toString('hex');

    const macCreds = grpc.credentials.createFromMetadataGenerator((_, cbk) => {
      const metadata = new grpc.Metadata();

      metadata.add('macaroon', macaroonData);

      return cbk(null, metadata);
    });

    credentials = grpc.credentials.combineChannelCredentials(ssl, macCreds);
    break;

  case unlockerServiceType:
    credentials = ssl;
    break;

  default:
    throw new Error('UnexpectedLightningDaemonServiceType');
  }

  return new rpc.lnrpc[serviceType](socket, credentials);
};

<commit_msg>Can use ln-service with trusted certificates (Fix #70)<commit_after>const {join} = require('path');

const grpc = require('grpc');
const {loadSync} = require('@grpc/proto-loader');

const expectedSslConfiguration = require('./conf/lnd').grpc_ssl_cipher_suites;

const confDir = 'conf';
const defaultServiceType = 'Lightning';
const {GRPC_SSL_CIPHER_SUITES} = process.env;
const protoFile = 'grpc.proto';
const unlockerServiceType = 'WalletUnlocker';

/** GRPC interface to the Lightning Network Daemon (lnd).

  {
    cert: <Base64 Serialized LND TLS Cert>
    macaroon: <Base64 Serialized Macaroon String>
    [service]: <Service Name String> // "WalletUnlocker"|"Lightning" (default)
    socket: <Host:Port String>
  }

  @throws
  <ExpectedBase64EncodedGrpcMacaroonFile Error>
  <ExpectedBase64EncodedTlsCertFileString Error>
  <ExpectedGrpcIpOrDomainWithPortString Error>
  <ExpectedGrpcSslCipherSuitesEnvVar Error>
  <UnexpectedLightningDaemonServiceType Error>

  @returns
  <LND GRPC Api Object>
*/
module.exports = ({cert, macaroon, service, socket}) => {
  if (!macaroon && service !== unlockerServiceType) {
    throw new Error('ExpectedBase64EncodedGrpcMacaroonFile');
  }

  if (!socket) {
    throw new Error('ExpectedGrpcIpOrDomainWithPortString');
  }

  const packageDefinition = loadSync(join(__dirname, confDir, protoFile), {
    defaults: true,
    enums: String,
    keepCase: true,
    longs: String,
    oneofs: true,
  });

  const rpc = grpc.loadPackageDefinition(packageDefinition);

  // Exit early when GRPC_SSL_CIPHER_SUITES cipher suite is not correct
  if (GRPC_SSL_CIPHER_SUITES !== expectedSslConfiguration) {
    throw new Error('ExpectedGrpcSslCipherSuitesEnvVar');
  }

  let credentials;
  const serviceType = service || defaultServiceType;

  const certData = cert ? Buffer.from(cert, 'base64') : null;
  const ssl = certData ? grpc.credentials.createSsl(certData) : grpc.credentials.createSsl();

  switch (serviceType) {
  case defaultServiceType:
    const macaroonData = Buffer.from(macaroon, 'base64').toString('hex');

    const macCreds = grpc.credentials.createFromMetadataGenerator((_, cbk) => {
      const metadata = new grpc.Metadata();

      metadata.add('macaroon', macaroonData);

      return cbk(null, metadata);
    });

    credentials = grpc.credentials.combineChannelCredentials(ssl, macCreds);
    break;

  case unlockerServiceType:
    credentials = ssl;
    break;

  default:
    throw new Error('UnexpectedLightningDaemonServiceType');
  }

  return new rpc.lnrpc[serviceType](socket, credentials);
};

<|endoftext|>


<commit_before>// GPS successfully occured function
var onSuccess = function(location) {

  var date = new Date();
  var currtime = date.getFullYear() + '-' + (date.getMonth()+1) + '-' + date.getDate() + ' ' + date.toLocaleTimeString();

  //Compose packet (in the event offine is needed)
  var packet = {"packet":{
      "position": {
        "longitude": location.coords.longitude, "latitude": location.coords.latitude, "accuracy": location.coords.accuracy,
        "datestamp": currtime}, "pest": window.sessionStorage.currentPest,
      "auth":
      {"uid": window.sessionStorage.userID, "accessToken": window.sessionStorage.accessToken}
      }};

  if (checkConnection()){
    //is connected
    sendJSON(packet);
  } else {
    //not connected
    alert(JSON.stringify(packet));
    window.localStorage.packet = JSON.stringify(packet);
    alert("You are currently offine\nYour report will be sent when you are online");
    ajaxSuccess();
  }
};

// ajax posting method
function sendJSON(packet){
  // Post packet to sever
  var jsonUrl = "http://judas.herokuapp.com/pestspotted";
  $.ajax({
    type: "POST",
    url: jsonUrl,
    data: packet,
    success: ajaxSuccess,
    error: function(jqXHR, textStatus, errorThrown){
      $.mobile.loading("hide");
      alert(JSON.stringify(jqXHR) + "error: " + errorThrown + "status: "+ textStatus);
    }
  });
};

// Returns true if connection detected
function checkConnection()
{
     if( !navigator.network )
     {
         // set the parent windows navigator network object to the child window
         navigator.network = window.top.navigator.network;
     }
    // return the type of connection found
   return ( (navigator.network.connection.type === "none" || navigator.network.connection.type === null ||
          navigator.network.connection.type === "unknown" ) ? false : true );
}

function ajaxSuccess(data, textStatus, jqHXR){
      $.mobile.loading("hide");
      var timeoutVal = 2000;
      switch (window.sessionStorage.currentPage) {
        case 'main':
          $( "#thanks-popup-main" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-main").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'cat':
          $( "#thanks-popup-cat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
          $("#thanks-popup-cat").popup('close', {transition: 'fade'});
          }, timeoutVal);
          break;
        case 'possum':
          $( "#thanks-popup-possum" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-possum").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'stoat':
          $( "#thanks-popup-stoat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-stoat").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'rat':
          $( "#thanks-popup-rat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-rat").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
      }
};

// onError Callback receives a PositionError object
function onError(error) {
  $.mobile.loading("hide");
  alert("GPS error\nPlease ensure that you have your location enabled under settings.");
};

function reportLoginFailure(){
  alert("Report Failed\nYou are not logged in");
  $.mobile.changePage($("#login"));
  $.mobile.loading("hide");
};

// This script contains the more technical networking related functions

function bindsendreport(){
  //Button for reporting pests
  $( ".send-report" ).bind( "click", function(event, ui) {

    //Get the current page
    var currentPage = $.mobile.activePage.attr('id');
    currentPage = currentPage.substring(0, currentPage.indexOf("page"));
    window.sessionStorage.currentPage = currentPage;

    if (window.sessionStorage.currentPest === undefined){
      alert("Please select a pest before reporting");
    } else {
      //show loader
      $.mobile.loading( "show", {
        text: "Sending...",
        textVisible: true,
        theme: "a",
        html: ""
      });

      if (window.sessionStorage.loginstatus === "facebook"){
        //Check user is logged into Facebook
        FB.getLoginStatus(function(response){
            if (response.status === 'connected') {
              window.sessionStorage.accessToken = response.authResponse.accessToken;

              // UID not returned in login check so make api call for email
              FB.api('/me?fields=email,id', function(response){
                window.sessionStorage.userID = response.id;
                if (response.id != undefined) {
                  navigator.geolocation.getCurrentPosition(onSuccess, onError);
                } else {
                  alert("Could not retreive your ID");
                }
              });

            } else {
                reportLoginFailure();
            }
        });
      } else if (window.sessionStorage.loginstatus === "phone"){
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
      } else {
        reportLoginFailure();
      }

    }
    switch (currentPage) {
      case 'main':
        $('#popup-report-main').popup('close');
        break;
      case 'rat':
        $('#popup-report-rat').popup('close');
        break;
      case 'stoat':
        $('#popup-report-stoat').popup('close');
        break;
      case 'cat':
        $('#popup-report-cat').popup('close');
        break;
      case 'possum':
        $('#popup-report-possum').popup('close');
        break;
    }

  });
};

function bindphonelogin() {
  $("#phone-login").on("click", function(){
    window.sessionStorage.userID = device.name + device.uuid;
    window.sessionStorage.accessToken = "#PHONE";
    window.sessionStorage.loginstatus = "phone";
    $.mobile.changePage($("#mainpage"));
  });
/*
  accessToken
  userID*/
};

function getFacebookID(){
  // UID not returned in login check so make api call for email
  FB.api('/me?fields=email,id', function(response){
    window.sessionStorage.userID = response.id;
    if (response.id === undefined) {
      alert("Could not retreive your ID");
    }
  });
};

function initbuttons(){
    $.ajaxSetup ({
      cache: false
    });
    bindlogin();
    bindlogout();
    bindreportpage();
    bindloginmenu();
    bindswipe();
    bindmenupest();
	  bindsendreport();
    bindrecordcurrentpest();
    bindphotopopup();
    bindphonelogin();
};

// deviceready event listener, loads FB connect and checks if signed in
if (typeof CDV === 'undefined') {
        alert('CDV variable does not exist. Check that you have included cdv-plugin-fb-connect.js correctly');
    }
if (typeof FB === 'undefined') {
    alert('FB variable does not exist. Check that you have included the Facebook JS SDK file.');
}

document.addEventListener('deviceready', function() {

    try {
        // Initialise FB SDK with app id
        FB.init({
            appId: "628299267250368",
            nativeInterface: CDV.FB,
            useCachedDialogs: false
        });

        if(window.sessionStorage.loginstatus === "phone"){
          $.mobile.changePage($("#mainpage"));
        } else {
          // check if user is already signed in, if so forward to report screen
          FB.getLoginStatus(function(response){
            if (response.status === 'connected') {
              window.sessionStorage.loginstatus = "facebook";
              getFacebookID();
              $.mobile.changePage($("#mainpage"));
            }
          });
        }

    } catch (e) {
        alert(e);
    }

}, false);

//include in device ready once debuging is done
$(document).ready(function(){

    $.mobile.buttonMarkup.hoverdelay = 200;
    $.mobile.defaultPageTransition = 'none';

    initbuttons();
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#catpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/Matt/cat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#possumpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/possum";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-possum").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#ratpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/rat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#stoatpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/stoat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
       }
      }, 'json');
  }
});

// Event timer to check for offline objects
setInterval(
     function(){
        // Check to see if connection is restored
        if (checkConnection()){
          if (window.localStorage.packet != undefined){
            var stringPacket = window.localStorage.packet;
            window.localStorage.packet = undefined;
            var packet = JSON.parse(stringPacket);
            sendJSON(packet);
          }
        }
     },
     30000  //every 30 seconds
);<commit_msg>final working push<commit_after>// GPS successfully occured function
var onSuccess = function(location) {

  var date = new Date();
  var currtime = date.getFullYear() + '-' + (date.getMonth()+1) + '-' + date.getDate() + ' ' + date.toLocaleTimeString();

  //Compose packet (in the event offine is needed)
  var packet = {"packet":{
      "position": {
        "longitude": location.coords.longitude, "latitude": location.coords.latitude, "accuracy": location.coords.accuracy,
        "datestamp": currtime}, "pest": window.sessionStorage.currentPest,
      "auth":
      {"uid": window.sessionStorage.userID, "accessToken": window.sessionStorage.accessToken}
      }};

  if (checkConnection()){
    //is connected
    sendJSON(packet);
  } else {
    //not connected
    alert("You are currently offine\nYour report will be sent when you are online");
    window.localStorage.packet = JSON.stringify(packet);
    ajaxSuccess();
  }
};

// ajax posting method
function sendJSON(packet){
  // Post packet to sever
  var jsonUrl = "http://judas.herokuapp.com/pestspotted";
  $.ajax({
    type: "POST",
    url: jsonUrl,
    data: packet,
    success: ajaxSuccess,
    error: function(jqXHR, textStatus, errorThrown){
      $.mobile.loading("hide");
      alert(JSON.stringify(jqXHR) + "error: " + errorThrown + "status: "+ textStatus);
    }
  });
};

// Returns true if connection detected
function checkConnection()
{
     if( !navigator.network )
     {
         // set the parent windows navigator network object to the child window
         navigator.network = window.top.navigator.network;
     }
    // return the type of connection found
   return ( (navigator.network.connection.type === "none" || navigator.network.connection.type === null ||
          navigator.network.connection.type === "unknown" ) ? false : true );
}

function ajaxSuccess(data, textStatus, jqHXR){
      $.mobile.loading("hide");
      var timeoutVal = 2000;
      switch (window.sessionStorage.currentPage) {
        case 'main':
          $( "#thanks-popup-main" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-main").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'cat':
          $( "#thanks-popup-cat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
          $("#thanks-popup-cat").popup('close', {transition: 'fade'});
          }, timeoutVal);
          break;
        case 'possum':
          $( "#thanks-popup-possum" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-possum").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'stoat':
          $( "#thanks-popup-stoat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-stoat").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
        case 'rat':
          $( "#thanks-popup-rat" ).popup( "open", {transition: 'fade'});
          setTimeout(function () {
            $("#thanks-popup-rat").popup('close', {transition: 'fade'});
           }, timeoutVal);
          break;
      }
};

// onError Callback receives a PositionError object
function onError(error) {
  $.mobile.loading("hide");
  alert("GPS error\nPlease ensure that you have your location enabled under settings.");
};

function reportLoginFailure(){
  alert("Report Failed\nYou are not logged in");
  $.mobile.changePage($("#login"));
  $.mobile.loading("hide");
};

// This script contains the more technical networking related functions

function bindsendreport(){
  //Button for reporting pests
  $( ".send-report" ).bind( "click", function(event, ui) {

    //Get the current page
    var currentPage = $.mobile.activePage.attr('id');
    currentPage = currentPage.substring(0, currentPage.indexOf("page"));
    window.sessionStorage.currentPage = currentPage;

    if (window.sessionStorage.currentPest === undefined){
      alert("Please select a pest before reporting");
    } else {
      //show loader
      $.mobile.loading( "show", {
        text: "Sending...",
        textVisible: true,
        theme: "a",
        html: ""
      });

      if (window.sessionStorage.loginstatus === "facebook"){
        //Check user is logged into Facebook
        FB.getLoginStatus(function(response){
            if (response.status === 'connected') {
              window.sessionStorage.accessToken = response.authResponse.accessToken;

              // UID not returned in login check so make api call for email
              FB.api('/me?fields=email,id', function(response){
                window.sessionStorage.userID = response.id;
                if (response.id != undefined) {
                  navigator.geolocation.getCurrentPosition(onSuccess, onError);
                } else {
                  alert("Could not retreive your ID");
                }
              });

            } else {
                reportLoginFailure();
            }
        });
      } else if (window.sessionStorage.loginstatus === "phone"){
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
      } else {
        reportLoginFailure();
      }

    }
    switch (currentPage) {
      case 'main':
        $('#popup-report-main').popup('close');
        break;
      case 'rat':
        $('#popup-report-rat').popup('close');
        break;
      case 'stoat':
        $('#popup-report-stoat').popup('close');
        break;
      case 'cat':
        $('#popup-report-cat').popup('close');
        break;
      case 'possum':
        $('#popup-report-possum').popup('close');
        break;
    }

  });
};

function bindphonelogin() {
  $("#phone-login").on("click", function(){
    window.sessionStorage.userID = device.name + device.uuid;
    window.sessionStorage.accessToken = "#PHONE";
    window.sessionStorage.loginstatus = "phone";
    $.mobile.changePage($("#mainpage"));
  });
/*
  accessToken
  userID*/
};

function getFacebookID(){
  // UID not returned in login check so make api call for email
  FB.api('/me?fields=email,id', function(response){
    window.sessionStorage.userID = response.id;
    if (response.id === undefined) {
      alert("Could not retreive your ID");
    }
  });
};

function initbuttons(){
    $.ajaxSetup ({
      cache: false
    });
    bindlogin();
    bindlogout();
    bindreportpage();
    bindloginmenu();
    bindswipe();
    bindmenupest();
	  bindsendreport();
    bindrecordcurrentpest();
    bindphotopopup();
    bindphonelogin();
};

// deviceready event listener, loads FB connect and checks if signed in
if (typeof CDV === 'undefined') {
        alert('CDV variable does not exist. Check that you have included cdv-plugin-fb-connect.js correctly');
    }
if (typeof FB === 'undefined') {
    alert('FB variable does not exist. Check that you have included the Facebook JS SDK file.');
}

document.addEventListener('deviceready', function() {

    try {
        // Initialise FB SDK with app id
        FB.init({
            appId: "628299267250368",
            nativeInterface: CDV.FB,
            useCachedDialogs: false
        });

        if(window.sessionStorage.loginstatus === "phone"){
          $.mobile.changePage($("#mainpage"));
        } else {
          // check if user is already signed in, if so forward to report screen
          FB.getLoginStatus(function(response){
            if (response.status === 'connected') {
              window.sessionStorage.loginstatus = "facebook";
              getFacebookID();
              $.mobile.changePage($("#mainpage"));
            }
          });
        }

    } catch (e) {
        alert(e);
    }

}, false);

//include in device ready once debuging is done
$(document).ready(function(){

    $.mobile.buttonMarkup.hoverdelay = 200;
    $.mobile.defaultPageTransition = 'none';

    initbuttons();
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#catpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/Matt/cat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#possumpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/possum";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-possum").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#ratpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/rat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
        }
      }, 'json');
  }
});

//this will fire when user navigates to a detailed page, it replaces a div with the count of pests they've spotted
$(document).on("pageshow","#stoatpage",function(){
  if (window.sessionStorage.userID != undefined){
    var jsonUrl = "http://judas.herokuapp.com/pestspotted/" + window.sessionStorage.userID + "/stoat";
    $.get(jsonUrl, function(data) {
      if (data.count != undefined){
        $("#count-div-cat").html("
" + data.count + "
");
       }
      }, 'json');
  }
});

// Event timer to check for offline objects
setInterval(
     function(){
        // Check to see if connection is restored
        if (checkConnection()){
          if (window.localStorage.packet != undefined){
            var stringPacket = window.localStorage.packet;
            window.localStorage.packet = undefined;
            var packet = JSON.parse(stringPacket);
            sendJSON(packet);
          }
        }
     },
     30000  //every 30 seconds
);<|endoftext|>


<commit_before>/**
 * Created with IntelliJ IDEA.
 * User: chr1smy3rs
 * Date: 7/18/13
 * Time: 1:58 PM
 *
 * Test cases to test call logging javascript objects.
 */

TestCase("CallLoggingTest", {
    "test log ani": function() {
        var call = new IvrCall("1111111111", "222222");
        assertEquals("1111111111", call.ani);
        assertEquals("222222", call.dnis);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    },
    "test log state": function() {
        var call = new IvrCall("1111111112", "222222");
        assertEquals("1111111112", call.ani);
        var currentState = call.addState("1020_initialize");
        assertEquals("1020_initialize", currentState.stateId);
        assertEquals(1, call.states.length);
        assertEquals("1020_initialize", call.states[0].stateId);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    },
    "test log states": function() {
        var call = new IvrCall("1111111113", "222222");
        assertEquals("1111111113", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_esiGreeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_esiGreeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    } ,
    "test log attempts": function() {
        var call = new IvrCall("1111111114", "222222");
        assertEquals("1111111114", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_esiGreeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        var currentState = call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_esiGreeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        currentState.addAttempt("nomatch")
        currentState.addAttempt("noinput")
        currentState.addAttempt("match", 0.96, "11111111111", "voice")
        assertEquals(3, currentState.attempts.length)
        assertEquals("nomatch", currentState.attempts[0].result)
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    }  ,
    "test log checkpoints": function() {
        var call = new IvrCall("1111111115", "222222");
        assertEquals("1111111115", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_esiGreeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        var currentState = call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_esiGreeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        currentState.addAttempt("nomatch")
        currentState.addAttempt("noinput")
        currentState.addAttempt("match", 0.96, "11111111111", "voice")
        assertEquals(3, currentState.attempts.length)
        assertEquals("nomatch", currentState.attempts[0].result)
        call.addCheckpoint("phone number retrieved")
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    }
});
<commit_msg>updates to call logging test<commit_after>/**
 * Created with IntelliJ IDEA.
 * User: chr1smy3rs
 * Date: 7/18/13
 * Time: 1:58 PM
 *
 * Test cases to test call logging javascript objects.
 */

TestCase("CallLoggingTest", {
    "test log ani": function() {
        var call = new IvrCall("1111111111", "222222");
        assertEquals("1111111111", call.ani);
        assertEquals("222222", call.dnis);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    },
    "test log state": function() {
        var call = new IvrCall("1111111112", "222222");
        assertEquals("1111111112", call.ani);
        var currentState = call.addState("1020_initialize");
        assertEquals("1020_initialize", currentState.stateId);
        assertEquals(1, call.states.length);
        assertEquals("1020_initialize", call.states[0].stateId);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    },
    "test log states": function() {
        var call = new IvrCall("1111111113", "222222");
        assertEquals("1111111113", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_greeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_greeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    } ,
    "test log attempts": function() {
        var call = new IvrCall("1111111114", "222222");
        assertEquals("1111111114", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_greeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        var currentState = call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_greeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        currentState.addAttempt("nomatch")
        currentState.addAttempt("noinput")
        currentState.addAttempt("match", 0.96, "11111111111", "voice")
        assertEquals(3, currentState.attempts.length)
        assertEquals("nomatch", currentState.attempts[0].result)
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    }  ,
    "test log checkpoints": function() {
        var call = new IvrCall("1111111115", "222222");
        assertEquals("1111111115", call.ani);
        assertEquals("222222", call.dnis);
        call.addState("1020_initialize");
        call.addState("1040_dnisLookup");
        call.addState("8020_greeting");
        call.addState("8040_aniLookup");
        call.addState("8200_noAniTransitional");
        var currentState = call.addState("2020_getPhoneNumber");
        assertEquals("1020_initialize", call.states[0].stateId);
        assertEquals("1040_dnisLookup", call.states[1].stateId);
        assertEquals("8020_greeting", call.states[2].stateId);
        assertEquals("8040_aniLookup", call.states[3].stateId);
        assertEquals("8200_noAniTransitional", call.states[4].stateId);
        assertEquals("2020_getPhoneNumber", call.states[5].stateId);
        assertEquals(6, call.states.length);
        currentState.addAttempt("nomatch")
        currentState.addAttempt("noinput")
        currentState.addAttempt("match", 0.96, "11111111111", "voice")
        assertEquals(3, currentState.attempts.length)
        assertEquals("nomatch", currentState.attempts[0].result)
        call.addCheckpoint("phone number retrieved")
        call.endCall("far end disconnect", "user disconnected")
        assertEquals("far end disconnect", call.disposition);
        assertEquals("user disconnected", call.reason);
    }
});
<|endoftext|>


<commit_before><commit_msg>made last change to favorites.js that makes the flawed method in it exactly like its working counterpart in savedseaches.js<commit_after><|endoftext|>


<commit_before>'use strict';

/**
 Copyright 2014 Google Inc. All rights reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const truncate = (str, width, left) => {
  if (!str) return "";

  if (str.length > width) {
    if (left) {
      return str.slice(0, width) + "...";
    } else {
      return "..." + str.slice(str.length - width, str.length);
    }
  } else {
    return str;
  }
};

var pods = [];
var services = [];
var controllers = [];
var deployments = [];
var nodes = [];
var uses = {};

var groups = {};

const insertByName = (index, value) => {
  // console.log("type = " + value.type + " labels = " + value.metadata.name);
  //	var list = groups[value.metadata.name];
  var key = value.metadata.labels.app ? value.metadata.labels.app : value.metadata.labels.run;
  var list = groups[key];
  if (!list) {
    list = [];
    groups[key] = list;
  }
  list.push(value);
};

const groupByName = () => {
  const entityArray = [pods.items, controllers.items, deployments.items, services.items];
  entityArray.filter(Boolean)
      .forEach(array => $.each(array, insertByName));
};

const matchesLabelQuery = (labels, selector) => {
  let match = true;
  $.each(selector, (key, value) => {
    if (labels[key] != value) {
      match = false;
    }
  });

  return match;
};

var connectDeployments = () => {
  //connectUses();

  if (deployments.items) {
    for (let i = 0; i < deployments.items.length; i++) {
      var deployment = deployments.items[i];
      for (let j = 0; j < pods.items.length; j++) {
        var pod = pods.items[j];
        if (matchesLabelQuery(pod.metadata.labels, deployment.spec.selector.matchLabels)) {
          //console.log('connect controller: ' + 'controller-' + controller.metadata.name + ' to pod-' + pod.metadata.name);
          jsPlumb.connect({
            source: 'deployment-' + deployment.metadata.name,
            target: 'pod-' + pod.metadata.name,
            anchors: ["Top", "Top"],
            paintStyle: {lineWidth: 3, strokeStyle: 'rgb(51,105,232)'},
            joinStyle: "round",
            endpointStyle: {fillStyle: 'rgb(51,105,232)', radius: 5},
            connector: ["Flowchart", {cornerRadius: 3}]
          });
        }
      }
    }
  }

  if (services.items) {
    for (var i = 0; i < services.items.length; i++) {
      var service = services.items[i];
      for (var j = 0; j < pods.items.length; j++) {
        const pod = pods.items[j];
        if (matchesLabelQuery(pod.metadata.labels, service.spec.selector)) {
          jsPlumb.connect(
              {
                source: 'service-' + service.metadata.name,
                target: 'pod-' + pod.metadata.name,
                anchors: ["Bottom", "Top"],
                paintStyle: {lineWidth: 5, strokeStyle: 'rgb(0,153,57)'},
                endpointStyle: {fillStyle: 'rgb(0,153,57)', radius: 7},
                connector: ["Flowchart", {cornerRadius: 3}]
              });
        }
      }
    }
  }
};

const colors = [
  'rgb(213,15,37)',
  'rgb(238,178,17)',
  'rgb(17,178,238)'
];

const connectUses = () => {
  var colorIx = 0;
  var keys = [];

  $.each(uses, key => keys.push(key));

  keys.sort((a, b) => a > b);

  $.each(keys, idx => {
    var key = keys[idx];
    var list = uses[key];
    var color = colors[colorIx];
    colorIx++;
    if (colorIx >= colors.length) {
      colorIx = 0;
    }
    $.each(pods.items, (i, pod) => {
      const podKey = pod.metadata.labels.app ? pod.metadata.labels.app : pod.metadata.labels.run;
      if (podKey == key) {
        $.each(list, (j, serviceId) => {
          //console.log('connect: ' + 'pod-' + pod.metadata.name + ' to service-' + serviceId);
          jsPlumb.connect(
              {
                source: 'pod-' + pod.metadata.name,
                target: 'service-' + serviceId,
                endpoint: "Blank",
                //anchors:["Bottom", "Top"],
                anchors: [[0.5, 1, 0, 1, -30, 0], "Top"],
                //connector: "Straight",
                connector: ["Bezier", {curviness: 75}],
                paintStyle: {lineWidth: 2, strokeStyle: color},
                overlays: [
                  ["Arrow", {width: 15, length: 10, location: 0.3}],
                  ["Arrow", {width: 15, length: 10, location: 0.6}],
                  ["Arrow", {width: 15, length: 10, location: 1}]
                ]
              });
        });
      }
    });
  });
};

const makeGroupOrder = () => {
  var groupScores = {};
  $.each(groups, key => {
    //console.log("group key: " + key);
    if (!groupScores[key]) {
      groupScores[key] = 0;
    }

    if (uses[key]) {
      const value = uses[key];
      $.each(value, function (ix, uses_label) {
        if (!groupScores[uses_label]) {
          groupScores[uses_label] = 1;
        } else {
          groupScores[uses_label]++;
        }
      });
    } else {
      if (!groupScores["no-service"]) {
        groupScores["no-service"] = 1;
      } else {
        groupScores["no-service"]++;
      }
    }
  });

  var groupOrder = [];
  $.each(groupScores, key => {
    groupOrder.push(key);
  });

  groupOrder.sort((a, b) => groupScores[a] - groupScores[b]);

  return groupOrder;
};

const renderNodes = () => {
  var y = 25;
  var x = 100;
  $.each(nodes.items, (index, value) => {

    const div = $('
');
    let ready = 'not_ready';
    $.each(value.status.conditions, (index, condition) => {
      if (condition.type === 'Ready') {
        ready = (condition.status === 'True' ? 'ready' : 'not_ready' )
      }
    });

    const eltDiv = $('
');
    eltDiv.html('Node

' +
        truncate(value.metadata.name, 6) +
        '');
    div.append(eltDiv);

    const elt = $('.nodesbar');
    elt.append(div);

    x += 120;
  });
};

const renderGroups = () => {
  var elt = $('#sheet');
  var y = 10;
  var serviceLeft = 0;
  var groupOrder = makeGroupOrder();
  var counts = {};
  $.each(groupOrder, (ix, key) => {
    const list = groups[key];
    if (!list) {
      return;
    }
    var div = $('
');
    var x = 100;
    $.each(list, (index, value) => {
      //console.log("render groups: " + value.type + ", " + value.metadata.name + ", " + index);
      var eltDiv = null;
      var phase = value.status.phase ? value.status.phase.toLowerCase() : '';
      if (value.type === "pod") {
        if ('deletionTimestamp' in value.metadata) {
          phase = 'terminating';
        }

        console.log("======");
        console.log(`size of containers within pod: ${value.status.containerStatuses.length}`);

        const anyDeadContainers = value.status.containerStatuses.some((x => x.ready === false));

        if (anyDeadContainers) {
          console.log(`Dead containers in pod which require restart`); // TODO: continue from here, identify the pod name
        }

        console.log("========");

        eltDiv = $('
');
        eltDiv.html('' +
            truncate(value.metadata.name, 8, true) +
            (value.metadata.labels.version ? "
" + value.metadata.labels.version : "") + "
" +
            (value.status.podIP ? value.status.podIP : "") + "

" +
            "(" + (value.spec.nodeName ? truncate(value.spec.nodeName, 6) : "None") + ")" +
            '');
      } else if (value.type === "service") {

        eltDiv = $('
');
        eltDiv.html('' +
            value.metadata.name +
            (value.metadata.labels.version ? "

" + value.metadata.labels.version : "") +
            (value.spec.clusterIP ? "

" + value.spec.clusterIP : "") +
            (value.status.loadBalancer && value.status.loadBalancer.ingress ? "
" + value.status.loadBalancer.ingress[0].ip + "" : "") +
            '');
      } else if (value.type === "deployment") {

        var key = 'deployment-' + (value.metadata.labels.app ? value.metadata.labels.app : value.metadata.labels.run);
        counts[key] = key in counts ? counts[key] + 1 : 0;
        //eltDiv = $('
');
        var minLeft = 900;
        var calcLeft = 400 + (value.status.replicas * 130);
        var left = minLeft > calcLeft ? minLeft : calcLeft;
        eltDiv = $('
');
        eltDiv.html('' +
            value.metadata.name +
            (value.metadata.labels.version ? "

" + value.metadata.labels.version : "") +
            '');
      }

      div.append(eltDiv);
      x += 130;
    });
    y += 400;
    serviceLeft += 200;
    elt.append(div);
  });
};

const insertUse = (name, use) => {
  for (var i = 0; i < uses[name].length; i++) {
    if (uses[name][i] == use) {
      return;
    }
  }
  uses[name].push(use);
};

const loadData = () => {
  var deferred = new $.Deferred();

  const req1 = $.getJSON("/api/v1/namespaces/default/pods?labelSelector=visualize%3Dtrue", data => {
    pods = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'pod';
        if (val.metadata.labels && val.metadata.labels.uses) {
          const key = val.metadata.labels.uses;
          if (!uses[key]) {
            uses[key] = key.split(",");
          } else {
            $.each(key.split(","), (ix, use) => insertUse(key, use));
          }
        }
      });
    }
  });

  //const req2 = $.getJSON("/api/v1/namespaces/default/replicationcontrollers?labelSelector=visualize%3Dtrue", data => {
  //  controllers = data;
  //
  //  if (data.items) {
  //    $.each(data.items, (key, val) => {
  //      val.type = 'replicationController';
  //      //console.log("Controller ID = " + val.metadata.name)
  //    });
  //  }
  //});

  const req3 = $.getJSON("/api/v1/namespaces/default/services?labelSelector=visualize%3Dtrue", data => {
    services = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'service';
        //console.log("service ID = " + val.metadata.name)
      });
    }
  });

  const req4 = $.getJSON("/api/v1/nodes", data => {
    nodes = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'node';
        //console.log("service ID = " + val.metadata.name)
      });
    }
  });

  const req5 = $.getJSON("/apis/extensions/v1beta1/namespaces/default/deployments?labelSelector=visualize%3Dtrue", data => {

    deployments = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'deployment';
        //console.log("Controller ID = " + val.metadata.name)
      });
    }
  });

  $.when(req1, req3, req4, req5).then(function () {
    deferred.resolve();
  });

  return deferred;
};

function refresh(instance) {
  pods = [];
  services = [];
  controllers = [];
  deployments = [];
  nodes = [];
  uses = {};
  groups = {};

  $.when(loadData())
      .then(() => {
        try {
          groupByName();
          $('#sheet').empty();
          renderNodes();
          renderGroups();
          connectDeployments();

        } finally {
          setTimeout(() => {
            refresh(instance);
          }, 1000);
        }
      });
}

jsPlumb.bind("ready", () => {
  var instance = jsPlumb.getInstance({
    // default drag options
    DragOptions: {cursor: 'pointer', zIndex: 2000},
    // the overlays to decorate each connection with.  note that the label overlay uses a function to generate the label text; in this
    // case it returns the 'labelText' member that we set on each connection in the 'init' method below.
    ConnectionOverlays: [
      ["Arrow", {location: 1}]
      [ "Label", {
      	location:0.1,
      	id:"label",
      	cssClass:"aLabel"
      }]
    ],
    Container: "flowchart-demo"
  });

  refresh(instance);
  jsPlumb.fire("jsPlumbDemoLoaded", instance);
});
<commit_msg>Visualization for any killed containers inside pods<commit_after>'use strict';

/**
 Copyright 2014 Google Inc. All rights reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const truncate = (str, width, left) => {
  if (!str) return "";

  if (str.length > width) {
    if (left) {
      return str.slice(0, width) + "...";
    } else {
      return "..." + str.slice(str.length - width, str.length);
    }
  } else {
    return str;
  }
};

var pods = [];
var services = [];
var controllers = [];
var deployments = [];
var nodes = [];
var uses = {};

var groups = {};

const insertByName = (index, value) => {
  // console.log("type = " + value.type + " labels = " + value.metadata.name);
  //	var list = groups[value.metadata.name];
  var key = value.metadata.labels.app ? value.metadata.labels.app : value.metadata.labels.run;
  var list = groups[key];
  if (!list) {
    list = [];
    groups[key] = list;
  }
  list.push(value);
};

const groupByName = () => {
  const entityArray = [pods.items, controllers.items, deployments.items, services.items];
  entityArray.filter(Boolean)
      .forEach(array => $.each(array, insertByName));
};

const matchesLabelQuery = (labels, selector) => {
  let match = true;
  $.each(selector, (key, value) => {
    if (labels[key] != value) {
      match = false;
    }
  });

  return match;
};

var connectDeployments = () => {
  //connectUses();

  if (deployments.items) {
    for (let i = 0; i < deployments.items.length; i++) {
      var deployment = deployments.items[i];
      for (let j = 0; j < pods.items.length; j++) {
        var pod = pods.items[j];
        if (matchesLabelQuery(pod.metadata.labels, deployment.spec.selector.matchLabels)) {
          //console.log('connect controller: ' + 'controller-' + controller.metadata.name + ' to pod-' + pod.metadata.name);
          jsPlumb.connect({
            source: 'deployment-' + deployment.metadata.name,
            target: 'pod-' + pod.metadata.name,
            anchors: ["Bottom", "Bottom"],
            paintStyle: {lineWidth: 3, strokeStyle: 'rgb(51,105,232)'},
            joinStyle: "round",
            endpointStyle: {fillStyle: 'rgb(51,105,232)', radius: 5},
            connector: ["Flowchart", {cornerRadius: 3}]
          });
        }
      }
    }
  }

  if (services.items) {
    for (var i = 0; i < services.items.length; i++) {
      var service = services.items[i];
      for (var j = 0; j < pods.items.length; j++) {
        const pod = pods.items[j];
        if (matchesLabelQuery(pod.metadata.labels, service.spec.selector)) {
          jsPlumb.connect(
              {
                source: 'service-' + service.metadata.name,
                target: 'pod-' + pod.metadata.name,
                anchors: ["Bottom", "Top"],
                paintStyle: {lineWidth: 5, strokeStyle: 'rgb(0,153,57)'},
                endpointStyle: {fillStyle: 'rgb(0,153,57)', radius: 7},
                connector: ["Flowchart", {cornerRadius: 3}]
              });
        }
      }
    }
  }
};

const colors = [
  'rgb(213,15,37)',
  'rgb(238,178,17)',
  'rgb(17,178,238)'
];

const connectUses = () => {
  var colorIx = 0;
  var keys = [];

  $.each(uses, key => keys.push(key));

  keys.sort((a, b) => a > b);

  $.each(keys, idx => {
    var key = keys[idx];
    var list = uses[key];
    var color = colors[colorIx];
    colorIx++;
    if (colorIx >= colors.length) {
      colorIx = 0;
    }
    $.each(pods.items, (i, pod) => {
      const podKey = pod.metadata.labels.app ? pod.metadata.labels.app : pod.metadata.labels.run;
      if (podKey == key) {
        $.each(list, (j, serviceId) => {
          //console.log('connect: ' + 'pod-' + pod.metadata.name + ' to service-' + serviceId);
          jsPlumb.connect(
              {
                source: 'pod-' + pod.metadata.name,
                target: 'service-' + serviceId,
                endpoint: "Blank",
                //anchors:["Bottom", "Top"],
                anchors: [[0.5, 1, 0, 1, -30, 0], "Top"],
                //connector: "Straight",
                connector: ["Bezier", {curviness: 75}],
                paintStyle: {lineWidth: 2, strokeStyle: color},
                overlays: [
                  ["Arrow", {width: 15, length: 10, location: 0.3}],
                  ["Arrow", {width: 15, length: 10, location: 0.6}],
                  ["Arrow", {width: 15, length: 10, location: 1}]
                ]
              });
        });
      }
    });
  });
};

const makeGroupOrder = () => {
  var groupScores = {};
  $.each(groups, key => {
    //console.log("group key: " + key);
    if (!groupScores[key]) {
      groupScores[key] = 0;
    }

    if (uses[key]) {
      const value = uses[key];
      $.each(value, function (ix, uses_label) {
        if (!groupScores[uses_label]) {
          groupScores[uses_label] = 1;
        } else {
          groupScores[uses_label]++;
        }
      });
    } else {
      if (!groupScores["no-service"]) {
        groupScores["no-service"] = 1;
      } else {
        groupScores["no-service"]++;
      }
    }
  });

  var groupOrder = [];
  $.each(groupScores, key => {
    groupOrder.push(key);
  });

  groupOrder.sort((a, b) => groupScores[a] - groupScores[b]);

  return groupOrder;
};

const renderNodes = () => {
  var y = 25;
  var x = 100;
  $.each(nodes.items, (index, value) => {

    const div = $('
');
    let ready = 'not_ready';
    $.each(value.status.conditions, (index, condition) => {
      if (condition.type === 'Ready') {
        ready = (condition.status === 'True' ? 'ready' : 'not_ready' )
      }
    });

    const eltDiv = $('
');
    eltDiv.html('Node

' +
        truncate(value.metadata.name, 6) +
        '');
    div.append(eltDiv);

    const elt = $('.nodesbar');
    elt.append(div);

    x += 120;
  });
};

const renderGroups = () => {
  var elt = $('#sheet');
  var y = 10;
  var serviceLeft = 0;
  var groupOrder = makeGroupOrder();
  var counts = {};
  $.each(groupOrder, (ix, key) => {
    const list = groups[key];
    if (!list) {
      return;
    }
    var div = $('
');
    var x = 100;
    $.each(list, (index, value) => {
      //console.log("render groups: " + value.type + ", " + value.metadata.name + ", " + index);
      var eltDiv = null;
      var phase = value.status.phase ? value.status.phase.toLowerCase() : '';
      if (value.type === "pod") {
        if ('deletionTimestamp' in value.metadata || anyDeadContainers(value)) {
          phase = 'terminating';
        }

        eltDiv = $('
');
        eltDiv.html('' +
            truncate(value.metadata.name, 8, true) +
            (value.metadata.labels.version ? "
" + value.metadata.labels.version : "") + "
" +
            (value.status.podIP ? value.status.podIP : "") + "

" +
            "(" + (value.spec.nodeName ? truncate(value.spec.nodeName, 6) : "None") + ")" +
            '');
      } else if (value.type === "service") {

        eltDiv = $('
');
        eltDiv.html('' +
            value.metadata.name +
            (value.metadata.labels.version ? "

" + value.metadata.labels.version : "") +
            (value.spec.clusterIP ? "

" + value.spec.clusterIP : "") +
            (value.status.loadBalancer && value.status.loadBalancer.ingress ? "
" + value.status.loadBalancer.ingress[0].ip + "" : "") +
            '');
      } else if (value.type === "deployment") {

        var key = 'deployment-' + (value.metadata.labels.app ? value.metadata.labels.app : value.metadata.labels.run);
        counts[key] = key in counts ? counts[key] + 1 : 0;
        //eltDiv = $('
');
        var minLeft = 900;
        var calcLeft = 400 + (value.status.replicas * 130);
        var left = minLeft > calcLeft ? minLeft : calcLeft;
        eltDiv = $('
');
        eltDiv.html('' +
            value.metadata.name +
            (value.metadata.labels.version ? "

" + value.metadata.labels.version : "") +
            '');
      }

      div.append(eltDiv);
      x += 130;
    });
    y += 400;
    serviceLeft += 200;
    elt.append(div);
  });
};

const anyDeadContainers = value => value.status.containerStatuses && value.status.containerStatuses.some((x => x.ready === false));

const insertUse = (name, use) => {
  for (var i = 0; i < uses[name].length; i++) {
    if (uses[name][i] == use) {
      return;
    }
  }
  uses[name].push(use);
};

const loadData = () => {
  var deferred = new $.Deferred();

  const req1 = $.getJSON("/api/v1/namespaces/default/pods?labelSelector=visualize%3Dtrue", data => {
    pods = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'pod';
        if (val.metadata.labels && val.metadata.labels.uses) {
          const key = val.metadata.labels.uses;
          if (!uses[key]) {
            uses[key] = key.split(",");
          } else {
            $.each(key.split(","), (ix, use) => insertUse(key, use));
          }
        }
      });
    }
  });

  const req3 = $.getJSON("/api/v1/namespaces/default/services?labelSelector=visualize%3Dtrue", data => {
    services = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'service';
        //console.log("service ID = " + val.metadata.name)
      });
    }
  });

  const req4 = $.getJSON("/api/v1/nodes", data => {
    nodes = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'node';
        //console.log("service ID = " + val.metadata.name)
      });
    }
  });

  const req5 = $.getJSON("/apis/extensions/v1beta1/namespaces/default/deployments?labelSelector=visualize%3Dtrue", data => {

    deployments = data;

    if (data.items) {
      $.each(data.items, (key, val) => {
        val.type = 'deployment';
        //console.log("Controller ID = " + val.metadata.name)
      });
    }
  });

  $.when(req1, req3, req4, req5).then(function () {
    deferred.resolve();
  });

  return deferred;
};

function refresh(instance) {
  pods = [];
  services = [];
  controllers = [];
  deployments = [];
  nodes = [];
  uses = {};
  groups = {};

  $.when(loadData())
      .then(() => {
        try {
          groupByName();
          $('#sheet').empty();
          renderNodes();
          renderGroups();
          connectDeployments();

        } finally {
          setTimeout(() => {
            refresh(instance);
          }, 1000);
        }
      });
}

jsPlumb.bind("ready", () => {
  var instance = jsPlumb.getInstance({
    // default drag options
    DragOptions: {cursor: 'pointer', zIndex: 2000},
    // the overlays to decorate each connection with.  note that the label overlay uses a function to generate the label text; in this
    // case it returns the 'labelText' member that we set on each connection in the 'init' method below.
    ConnectionOverlays: [
      ["Arrow", {location: 1}]
      [ "Label", {
      	location:0.1,
      	id:"label",
      	cssClass:"aLabel"
      }]
    ],
    Container: "flowchart-demo"
  });

  refresh(instance);
  jsPlumb.fire("jsPlumbDemoLoaded", instance);
});
<|endoftext|>


<commit_before>const CursorObservable = typeof window !== 'undefined' && window.Mars
  ? window.Mars.CursorObservable : require('../CursorObservable').default;

export class AngularCursorObservable extends CursorObservable {
  constructor(db, query) {
    super(db._collection, query);
    this.$q = db.$q;
  }

  observe(fn, $scope) {
    const stopper = super.observe(fn);
    if ($scope) {
      $scope.$on('$destroy', function() {
        stopper.stop();
      });
    }
    return stopper;
  }

  exec(...args) {
    return this.$q.resolve(super.exec(...args));
  }

  ids(...args) {
    return this.$q.resolve(super.ids(...args));
  }

  update(...args) {
    return this.$q.resolve(super.update(...args));
  }
}

export default AngularCursorObservable;
<commit_msg>added destroy method in angular cursor<commit_after>const CursorObservable = typeof window !== 'undefined' && window.Mars
  ? window.Mars.CursorObservable : require('../CursorObservable').default;

export class AngularCursorObservable extends CursorObservable {
  constructor(db, query) {
    super(db._collection, query);
    this.$q = db.$q;
  }

  /**
   * Stop observing given cursor, if passed and
   * observing.
   * It might be useful when you need to replace
   * previously created request with another one
   * (with different query, for example).
   *
   * @param  {CursorObservable} cursor
   */
  destroy(cursor) {
    if (cursor && cursor._prevStopper) {
      cursor._prevStopper.stop();
    }
  }

  /**
   * Original `observe` with one additional argument.
   * Second argument, if passed, a $scope for tracking
   * $destroy event and stopping observing when event
   * emited.
   *
   * @param  {Function} fn
   * @param  {Scope}   $scope
   * @return {Stooper}
   */
  observe(fn, $scope) {
    const stopper = super.observe(fn);
    if ($scope) {
      $scope.$on('$destroy', function() {
        stopper.stop();
      });
    }

    this._prevStopper = stopper;
    return stopper;
  }

  exec(...args) {
    return this.$q.resolve(super.exec(...args));
  }

  ids(...args) {
    return this.$q.resolve(super.ids(...args));
  }

  update(...args) {
    return this.$q.resolve(super.update(...args));
  }
}

export default AngularCursorObservable;
<|endoftext|>


<commit_before>$(document).ready(function () {
	// get root files and put in browser div
	$.get('/dir?path=', function (data, status) {
		if (status == 'success') {
			handleDirContents('browser', data);
			//$('#browser').html(data);
		}
	});
});

function handleDirContents(parentId, dirEntries) {
	var dirs = [];
	var files = [];
	for (var dirEntry of dirEntries) {
		if (dirEntry.type == 'dir') {
			dirs.push(dirEntry);
		} else if (dirEntry.type == 'file') {
			files.push(dirEntry);
		}
	}
	handleDirs(parentId, dirs);
	handleFiles(files);
}

function handleDirs(parentId, dirs) {
	$('#' + parentId).append('

');
	for (var dir of dirs) {
		$('#ul_' + parentId).append('
' + dir.name + '
');
		const name = dir.name;
		$('#li_' + dir.name).click(function () {
			console.log(name);
		});
	}
}

function handleFiles(files) {

}
<commit_msg>jquery handler wip<commit_after>$(document).ready(function () {
	// get root browser contents
	browser_bootstrap();
});

function browser_bootstrap() {
	$.get('/dir?path=', function (data, status) {
		if (status == 'success') {
			handleDirContents('div.browser', data);
		}
	});
}

function handleDirContents(parent, dirEntries) {
	var dirs = [];
	var files = [];
	for (var dirEntry of dirEntries) {
		if (dirEntry.type == 'dir') {
			dirs.push(dirEntry);
		} else if (dirEntry.type == 'file') {
			files.push(dirEntry);
		}
	}
	handleDirs(parent, dirs);
	handleFiles(files);
}

function handleDirs(parent, dirs) {
	$(parent).append('

');
	for (var dir of dirs) {
		$(parent + ' ul').append('
' + dir.name + '
');
		$(parent + ' ul li').last().data('dirUrl', dir.dirUrl);
	}
	$(parent + ' ul li').click(function () {
		var newParent = parent + ' ul li';
		var dirUrl = $(this).data('dirUrl');
		$.get(dirUrl, function (data, status) {
			if (status == 'success') {
				console.log(data);
				//handleDirContents(newParent, data);
			}
		});
	});
}

function handleFiles(files) {

}
<|endoftext|>


<commit_before>/* global browser */

'use strict';

exports.config = {
    onPrepare: function() {
      require('./utils/locators.js');
      browser.driver.manage().window().maximize();
    },
    //disable these if you want to run tests locally
    sauceUser: process.env.SAUCE_USERNAME,
    sauceKey: process.env.SAUCE_ACCESS_KEY,
    sauceBuild: process.env.TRAVIS_BUILD_NUMBER,
    rootElement: 'html',
    baseUrl: 'https://metadatamanagement-dev.cfapps.io/',
    specs: [
      'home/home.spec.js',
      'disclosure/disclosure.spec.js',
      'common/navbar.spec.js',
      'common/toolbar.spec.js',
    ],
    multiCapabilities: [{
      'name': 'Win10/Chrome',
      'platform': 'Windows 10',
      'browserName': 'chrome',
      'version': 'latest',
      'screenResolution': '1280x1024'
    }, {
      'name': 'Win10/Firefox',
      'platform': 'Windows 10',
      'browserName': 'firefox',
      'screenResolution': '1280x1024',
      'version': '54.0'
    }, {
      'name': 'Win10/Edge',
      'platform': 'Windows 10',
      'browserName': 'MicrosoftEdge',
      'version': 'latest',
      'screenResolution': '1280x1024',
      'seleniumVersion': '3.5.0'
    }, {
      'name': 'Win10/IE11',
      'platform': 'Windows 10',
      'browserName': 'internet explorer',
      'version': '11.0',
      'screenResolution': '1280x1024'
    }],
    //enable this for local tests without selenium
    //directConnect: true,
    jasmineNodeOpts: {
      defaultTimeoutInterval: 120000
    },
    allScriptsTimeout: 120000,
    getPageTimeout: 120000
  };
<commit_msg>#1315 using default selenium version for edge<commit_after>/* global browser */

'use strict';

exports.config = {
    onPrepare: function() {
      require('./utils/locators.js');
      browser.driver.manage().window().maximize();
    },
    //disable these if you want to run tests locally
    sauceUser: process.env.SAUCE_USERNAME,
    sauceKey: process.env.SAUCE_ACCESS_KEY,
    sauceBuild: process.env.TRAVIS_BUILD_NUMBER,
    rootElement: 'html',
    baseUrl: 'https://metadatamanagement-dev.cfapps.io/',
    specs: [
      'home/home.spec.js',
      'disclosure/disclosure.spec.js',
      'common/navbar.spec.js',
      'common/toolbar.spec.js',
    ],
    multiCapabilities: [{
      'name': 'Win10/Chrome',
      'platform': 'Windows 10',
      'browserName': 'chrome',
      'version': 'latest',
      'screenResolution': '1280x1024'
    }, {
      'name': 'Win10/Firefox',
      'platform': 'Windows 10',
      'browserName': 'firefox',
      'screenResolution': '1280x1024',
      'version': '54.0'
    }, {
      'name': 'Win10/Edge',
      'platform': 'Windows 10',
      'browserName': 'MicrosoftEdge',
      'version': 'latest',
      'screenResolution': '1280x1024'
    }, {
      'name': 'Win10/IE11',
      'platform': 'Windows 10',
      'browserName': 'internet explorer',
      'version': '11.0',
      'screenResolution': '1280x1024'
    }],
    //enable this for local tests without selenium
    //directConnect: true,
    jasmineNodeOpts: {
      defaultTimeoutInterval: 120000
    },
    allScriptsTimeout: 120000,
    getPageTimeout: 120000
  };
<|endoftext|>


<commit_before><commit_msg>fixed the content-type<commit_after><|endoftext|>