<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qbs.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

var FileInfo = require("qbs.FileInfo");
var Utilities = require("qbs.Utilities");

var _deviceMap = {
    "mac": undefined, // only devices have an ID
    "iphone": 1,
    "ipad": 2,
    "tv": 3,
    "watch": 4,
    "car": 5
};

var _platformMap = {
    "ios": "iPhone",
    "macos": "MacOSX",
    "tvos": "AppleTV",
    "watchos": "Watch"
};

var _platformDeviceMap = {
    "ios": ["iphone", "ipad"],
    "macos": ["mac"],
    "tvos": ["tv"],
    "watchos": ["watch"]
}

/**
  * Returns the numeric identifier corresponding to an Apple device name
  * (i.e. for use by TARGETED_DEVICE_FAMILY).
  */
function appleDeviceNumber(deviceName) {
    return _deviceMap[deviceName];
}

/**
  * Returns the list of target devices available for the given qbs target OS list.
  */
function targetDevices(targetOS) {
    for (var key in _platformDeviceMap) {
        if (targetOS.contains(key))
            return _platformDeviceMap[key];
    }
}

/**
  * Returns the TARGETED_DEVICE_FAMILY string given a list of target device names.
  */
function targetedDeviceFamily(deviceNames) {
    return deviceNames.map(function (deviceName) {
        return appleDeviceNumber(deviceName);
    }).join(",");
}

/**
  * Returns the most appropriate Apple platform name given a targetOS list.
  */
function applePlatformName(targetOSList, platformType) {
    return applePlatformDirectoryName(targetOSList, platformType).toLowerCase();
}

/**
  * Returns the most appropriate Apple platform directory name given a targetOS list and version.
  */
function applePlatformDirectoryName(targetOSList, platformType, version, throwOnError) {
    var suffixMap = {
        "device": "OS",
        "simulator": "Simulator"
    };

    for (var key in _platformMap) {
        if (targetOSList.contains(key))
            return _platformMap[key] + (suffixMap[platformType] || "") + (version || "");
    }

    if (throwOnError || throwOnError === undefined)
        throw("No Apple platform corresponds to target OS list: " + targetOSList);
}

/**
  * Returns the localization of the resource at the given path,
  * or undefined if the path does not contain an {xx}.lproj path segment.
  */
function localizationKey(path) {
    return _resourceFileProperties(path)[0];
}

/**
  * Returns the path of a localized resource at the given path,
  * relative to its containing {xx}.lproj directory, or '.'
  * if the resource is unlocalized (not contained in an lproj directory).
  */
function relativeResourcePath(path) {
    return _resourceFileProperties(path)[1];
}

function _resourceFileProperties(path) {
    var lprojKey = ".lproj/";
    var lproj = path.indexOf(lprojKey);
    if (lproj >= 0) {
        // The slash preceding XX.lproj
        var slashIndex = path.slice(0, lproj).lastIndexOf('/');
        if (slashIndex >= 0) {
            var localizationKey = path.slice(slashIndex + 1, lproj);
            var relativeResourcePath = FileInfo.path(path.slice(lproj + lprojKey.length));
            return [ localizationKey, relativeResourcePath ];
        }
    }

    return [ undefined, '.' ];
}

var PropertyListVariableExpander = (function () {
    function PropertyListVariableExpander() {
    }
    /**
      * Recursively perform variable replacements in an environment dictionary.
      */
    PropertyListVariableExpander.prototype.expand = function (obj, env) {
        var $this = this;

        // Possible syntaxes for wrapping an environment variable name
        var syntaxes = [
            {"open": "${", "close": "}"},
            {"open": "$(", "close": ")"},
            {"open": "@",  "close": "@"}
        ];

        /**
          * Finds the first index of a replacement starting with one of the supported syntaxes
          * This is needed so we don't do recursive substitutions
          */
        function indexOfReplacementStart(syntaxes, str, offset) {
            var syntax;
            var idx = str.length;
            for (var i in syntaxes) {
                var j = str.indexOf(syntaxes[i].open, offset);
                if (j !== -1 && j < idx) {
                    syntax = syntaxes[i];
                    idx = j;
                }
            }
            return { "syntax": syntax, "index": idx === str.length ? -1 : idx };
        }

        function expandRecursive(obj, env, checked) {
            checked.push(obj);
            for (var key in obj) {
                var value = obj[key];
                var type = typeof(value);
                if (type === "object") {
                    if (checked.indexOf(value) !== -1)
                        continue;
                    expandRecursive(value, env, checked);
                }
                if (type !== "string")
                    continue;
                var repl = indexOfReplacementStart(syntaxes, value);
                var i = repl.index;
                var changes = false;
                while (i !== -1) {
                    var j = value.indexOf(repl.syntax.close, i + repl.syntax.open.length);
                    if (j === -1)
                        break;
                    var varParts = value.slice(i + repl.syntax.open.length, j).split(':');
                    var varName = varParts[0];
                    var varFormatter = varParts[1];
                    var varValue = env[varName];
                    if (undefined === varValue) {
                        // skip replacement
                        if ($this.undefinedVariableFunction)
                            $this.undefinedVariableFunction(key, varName);
                        i = j + repl.syntax.close.length;
                    } else {
                        changes = true;
                        varValue = String(varValue);
                        if (varFormatter !== undefined)
                            varFormatter = varFormatter.toLowerCase();
                        if (varFormatter === "rfc1034identifier")
                            varValue = Utilities.rfc1034Identifier(varValue);
                        value = value.slice(0, i) + varValue + value.slice(j + repl.syntax.close.length);
                        // avoid recursive substitutions to avoid potentially infinite loops
                        i += varValue.length;
                    }
                    repl = indexOfReplacementStart(syntaxes, value, i);
                    i = repl.index;
                }
                if (changes)
                    obj[key] = value;
            }
        }
        expandRecursive(obj, env, []);
        return obj;
    };
    return PropertyListVariableExpander;
}());

/**
  * JSON.stringify(expandPlistEnvironmentVariables({a:"$(x)3$$(y)",b:{t:"%$(y) $(k)"}},
  *                                                {x:"X",y:"Y"}, true))
  *    Warning undefined variable  k  in variable expansion
  * => {"a":"X3$Y","b":{"t":"%Y $(k)"}}
  */
function expandPlistEnvironmentVariables(obj, env, warn) {
    var expander = new PropertyListVariableExpander();
    expander.undefinedVariableFunction = function (key, varName) {
        if (warn)
            console.warn("undefined variable " + varName + " in variable expansion");
    };
    return expander.expand(obj, env);
}

/**
  * Recursively removes any undefined, null, or empty string values from the property list.
  */
function cleanPropertyList(plist) {
    if (typeof(plist) !== "object")
        return;

    for (var key in plist) {
        if (plist[key] === undefined || plist[key] === null || plist[key] === "")
            delete plist[key];
        else
            cleanPropertyList(plist[key]);
    }
}

function _codeSignTimestampFlags(product) {
    // If signingTimestamp is undefined, do not specify the flag at all -
    // this uses the system-specific default behavior
    var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp");
    if (signingTimestamp !== undefined) {
        // If signingTimestamp is an empty string, specify the flag but do
        // not specify a value - this uses a default Apple-provided server
        var flag = "--timestamp";
        if (signingTimestamp)
            flag += "=" + signingTimestamp;
        return [flag];
    }

    return [];
}
<commit_msg>Fix detecting path to the MacOSX.platform<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qbs.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

var FileInfo = require("qbs.FileInfo");
var Utilities = require("qbs.Utilities");

var _deviceMap = {
    "mac": undefined, // only devices have an ID
    "iphone": 1,
    "ipad": 2,
    "tv": 3,
    "watch": 4,
    "car": 5
};

var _platformMap = {
    "ios": "iPhone",
    "macos": "MacOSX",
    "tvos": "AppleTV",
    "watchos": "Watch"
};

var _platformDeviceMap = {
    "ios": ["iphone", "ipad"],
    "macos": ["mac"],
    "tvos": ["tv"],
    "watchos": ["watch"]
}

/**
  * Returns the numeric identifier corresponding to an Apple device name
  * (i.e. for use by TARGETED_DEVICE_FAMILY).
  */
function appleDeviceNumber(deviceName) {
    return _deviceMap[deviceName];
}

/**
  * Returns the list of target devices available for the given qbs target OS list.
  */
function targetDevices(targetOS) {
    for (var key in _platformDeviceMap) {
        if (targetOS.contains(key))
            return _platformDeviceMap[key];
    }
}

/**
  * Returns the TARGETED_DEVICE_FAMILY string given a list of target device names.
  */
function targetedDeviceFamily(deviceNames) {
    return deviceNames.map(function (deviceName) {
        return appleDeviceNumber(deviceName);
    }).join(",");
}

/**
  * Returns the most appropriate Apple platform name given a targetOS list.
  */
function applePlatformName(targetOSList, platformType) {
    return applePlatformDirectoryName(targetOSList, platformType).toLowerCase();
}

/**
  * Returns the most appropriate Apple platform directory name given a targetOS list and version.
  */
function applePlatformDirectoryName(targetOSList, platformType, version, throwOnError) {
    var suffixMap = {
        "device": "OS",
        "simulator": "Simulator"
    };

    for (var key in _platformMap) {
        if (targetOSList.contains(key)) {
            // there are no MacOSXOS or MacOSXSimulator platforms
            var suffix = (key !== "macos") ? (suffixMap[platformType] || "") : "";
            return _platformMap[key] + suffix + (version || "");
        }
    }

    if (throwOnError || throwOnError === undefined)
        throw("No Apple platform corresponds to target OS list: " + targetOSList);
}

/**
  * Returns the localization of the resource at the given path,
  * or undefined if the path does not contain an {xx}.lproj path segment.
  */
function localizationKey(path) {
    return _resourceFileProperties(path)[0];
}

/**
  * Returns the path of a localized resource at the given path,
  * relative to its containing {xx}.lproj directory, or '.'
  * if the resource is unlocalized (not contained in an lproj directory).
  */
function relativeResourcePath(path) {
    return _resourceFileProperties(path)[1];
}

function _resourceFileProperties(path) {
    var lprojKey = ".lproj/";
    var lproj = path.indexOf(lprojKey);
    if (lproj >= 0) {
        // The slash preceding XX.lproj
        var slashIndex = path.slice(0, lproj).lastIndexOf('/');
        if (slashIndex >= 0) {
            var localizationKey = path.slice(slashIndex + 1, lproj);
            var relativeResourcePath = FileInfo.path(path.slice(lproj + lprojKey.length));
            return [ localizationKey, relativeResourcePath ];
        }
    }

    return [ undefined, '.' ];
}

var PropertyListVariableExpander = (function () {
    function PropertyListVariableExpander() {
    }
    /**
      * Recursively perform variable replacements in an environment dictionary.
      */
    PropertyListVariableExpander.prototype.expand = function (obj, env) {
        var $this = this;

        // Possible syntaxes for wrapping an environment variable name
        var syntaxes = [
            {"open": "${", "close": "}"},
            {"open": "$(", "close": ")"},
            {"open": "@",  "close": "@"}
        ];

        /**
          * Finds the first index of a replacement starting with one of the supported syntaxes
          * This is needed so we don't do recursive substitutions
          */
        function indexOfReplacementStart(syntaxes, str, offset) {
            var syntax;
            var idx = str.length;
            for (var i in syntaxes) {
                var j = str.indexOf(syntaxes[i].open, offset);
                if (j !== -1 && j < idx) {
                    syntax = syntaxes[i];
                    idx = j;
                }
            }
            return { "syntax": syntax, "index": idx === str.length ? -1 : idx };
        }

        function expandRecursive(obj, env, checked) {
            checked.push(obj);
            for (var key in obj) {
                var value = obj[key];
                var type = typeof(value);
                if (type === "object") {
                    if (checked.indexOf(value) !== -1)
                        continue;
                    expandRecursive(value, env, checked);
                }
                if (type !== "string")
                    continue;
                var repl = indexOfReplacementStart(syntaxes, value);
                var i = repl.index;
                var changes = false;
                while (i !== -1) {
                    var j = value.indexOf(repl.syntax.close, i + repl.syntax.open.length);
                    if (j === -1)
                        break;
                    var varParts = value.slice(i + repl.syntax.open.length, j).split(':');
                    var varName = varParts[0];
                    var varFormatter = varParts[1];
                    var varValue = env[varName];
                    if (undefined === varValue) {
                        // skip replacement
                        if ($this.undefinedVariableFunction)
                            $this.undefinedVariableFunction(key, varName);
                        i = j + repl.syntax.close.length;
                    } else {
                        changes = true;
                        varValue = String(varValue);
                        if (varFormatter !== undefined)
                            varFormatter = varFormatter.toLowerCase();
                        if (varFormatter === "rfc1034identifier")
                            varValue = Utilities.rfc1034Identifier(varValue);
                        value = value.slice(0, i) + varValue + value.slice(j + repl.syntax.close.length);
                        // avoid recursive substitutions to avoid potentially infinite loops
                        i += varValue.length;
                    }
                    repl = indexOfReplacementStart(syntaxes, value, i);
                    i = repl.index;
                }
                if (changes)
                    obj[key] = value;
            }
        }
        expandRecursive(obj, env, []);
        return obj;
    };
    return PropertyListVariableExpander;
}());

/**
  * JSON.stringify(expandPlistEnvironmentVariables({a:"$(x)3$$(y)",b:{t:"%$(y) $(k)"}},
  *                                                {x:"X",y:"Y"}, true))
  *    Warning undefined variable  k  in variable expansion
  * => {"a":"X3$Y","b":{"t":"%Y $(k)"}}
  */
function expandPlistEnvironmentVariables(obj, env, warn) {
    var expander = new PropertyListVariableExpander();
    expander.undefinedVariableFunction = function (key, varName) {
        if (warn)
            console.warn("undefined variable " + varName + " in variable expansion");
    };
    return expander.expand(obj, env);
}

/**
  * Recursively removes any undefined, null, or empty string values from the property list.
  */
function cleanPropertyList(plist) {
    if (typeof(plist) !== "object")
        return;

    for (var key in plist) {
        if (plist[key] === undefined || plist[key] === null || plist[key] === "")
            delete plist[key];
        else
            cleanPropertyList(plist[key]);
    }
}

function _codeSignTimestampFlags(product) {
    // If signingTimestamp is undefined, do not specify the flag at all -
    // this uses the system-specific default behavior
    var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp");
    if (signingTimestamp !== undefined) {
        // If signingTimestamp is an empty string, specify the flag but do
        // not specify a value - this uses a default Apple-provided server
        var flag = "--timestamp";
        if (signingTimestamp)
            flag += "=" + signingTimestamp;
        return [flag];
    }

    return [];
}
<|endoftext|>


<commit_before>function GameOfLife(zeroGeneration, canvas) {
  var GoL         = GameOfLife
    , canvas      = GoL.Support.parseCanvas(canvas)
    , generation  = GoL.Support.parseCellGrid(zeroGeneration);

  return {
    evolve: function () {
      var graphics        = GoL.Graphics(canvas, generation)
        , numGenerations  = 0;

      function doEvolve() {
        /*console.log("GENERATION")
        _.each(generation, function (row) {
          console.log(row)
        });*/

        graphics.drawFrame(generation, numGenerations);
        generation = GoL.Generation.tick(generation);
        numGenerations += 1;
      }

      doEvolve();
      setInterval(function () {
        doEvolve();
      }, 2000);
    }
  };
}
<commit_msg>Remove commented code<commit_after>function GameOfLife(zeroGeneration, canvas) {
  var GoL         = GameOfLife
    , canvas      = GoL.Support.parseCanvas(canvas)
    , generation  = GoL.Support.parseCellGrid(zeroGeneration);

  return {
    evolve: function () {
      var graphics        = GoL.Graphics(canvas, generation)
        , numGenerations  = 0;

      function doEvolve() {
        graphics.drawFrame(generation, numGenerations);
        generation = GoL.Generation.tick(generation);
        numGenerations += 1;
      }

      doEvolve();
      setInterval(function () {
        doEvolve();
      }, 2000);
    }
  };
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('app')
        .controller('HomeController', HomeController);

    HomeController.$inject = ['UserService', '$rootScope'];
    function HomeController(UserService, $rootScope) {
        var vm = this;

        vm.user = null;
        vm.allUsers = [];
        vm.deleteUser = deleteUser;

        initController();

        function initController() {
            loadCurrentUser();
            loadAllUsers();
        }

        function loadCurrentUser() {
            UserService.GetByUsername($rootScope.globals.currentUser.username)
                .then(function (user) {
                    vm.user = user;
                });
        }

        function loadAllUsers() {
            UserService.GetAll()
                .then(function (users) {
                    vm.allUsers = users;
                });
        }

        function deleteUser(id) {
            UserService.Delete(id)
            .then(function () {
                loadAllUsers();
            });
        }
    }

})();<commit_msg>Create home.controller.js<commit_after>(function () {
    'use strict';

    angular
        .module('app')
        .controller('HomeController', HomeController);

    HomeController.$inject = ['UserService', '$rootScope'];
    function HomeController(UserService, $rootScope) {
        var vm = this;

        vm.user = null;
       // vm.allUsers = [];
        vm.deleteUser = deleteUser;

        initController();

        function initController() {
            loadCurrentUser();
           // loadAllUsers();
        }

        function loadCurrentUser() {
            UserService.GetByUsername($rootScope.globals.currentUser.username)
                .then(function (user) {
                    vm.user = user;
                });
        }

     /* function loadAllUsers() {
            UserService.GetAll()
                .then(function (users) {
                    vm.allUsers = users;
                });
        }*/

       /* function deleteUser(id) {
            UserService.Delete(id)
            .then(function () {
                loadAllUsers();
            });
        }*/

        function deleteUser(id) {
            UserService.Delete(id)
            .then(function () {
                loadCurrentUser();
            });
        }
    }

})();
<|endoftext|>


<commit_before>"use strict";

var q     = require('q'),
    https = require('https'),
    merge = require('merge');

module.exports = function GitHubAPI(options) {

    // Publish simple API
    return {
      loadFrom : loadAllPages
    };

  /**
   * For the specified Github API EndPoint, load 1..n pages
   * of JSON data...
   */
  function loadAllPages( path, headers ) {
    var jsonResponse  = '', result = [], deferred = q.defer();
    var concatData    = function (chunk) {  jsonResponse += chunk;  };
    var reject        = function (e) {  console.log(e);   deferred.reject(e); };
    var requestOptions = {
      port    : 443,
      method  : 'GET',
      host    : 'api.github.com',
      headers : merge({
        'Content-Type': 'application/json',
        'User-Agent'  : 'contributors-list'
      }, headers || { })
    };

    // Load all data pages from the GitHub API using the requestOptions
    loadPage(path);

    return deferred.promise;

    /**
     *  Recursive function used to load 1..n pages of requets data,
     *  and resolve with formatted JSON results.
     */
    function loadPage( path ) {
      jsonResponse = '';
      if (path) requestOptions.path = path;

      https.request(requestOptions, function (response) {
        response.on('error', reject);
        response.on('data', concatData);
        response.on('end', function () {
          result = result.concat(JSON.parse(jsonResponse));

          // Do we have more than 1 page of data ?
          var page = findPageLink(response);
          if (page) {
            loadPage(page);
            return;
          }

          deferred.resolve(result);
          cleanup();
        });
      }).end();
    }

    /**
     * Cleanup paging caches
     */
    function cleanup() {
      result = [];
      deferred = q.defer();
      jsonResponse = '';
    }

    /**
     * Do we have another page of data that should be loaded
     * and concatenated ?
     */
    function findPageLink(response) {
      var link = response.headers.link;
      var hasLink = link && link.indexOf('next') >= 0;
      if (hasLink) {
        link = link.split(',');
        link = link[0].match(/<(.*?)>/)[1];
      }
      return hasLink ? link : null;
    }

  }
};

<commit_msg>fix(githubLoader): infinite recursion of loadPage()<commit_after>"use strict";

var q     = require('q'),
    https = require('https'),
    merge = require('merge');

module.exports = function GitHubAPI(options) {

    // Publish simple API
    return {
      loadFrom : loadAllPages
    };

  /**
   * For the specified Github API EndPoint, load 1..n pages
   * of JSON data...
   */
  function loadAllPages( path, headers ) {
    var jsonResponse  = '', result = [], deferred = q.defer();
    var concatData    = function (chunk) {  jsonResponse += chunk;  };
    var reject        = function (e) {  console.log(e);   deferred.reject(e); };
    var requestOptions = {
      port    : 443,
      method  : 'GET',
      host    : 'api.github.com',
      headers : merge({
        'Content-Type': 'application/json',
        'User-Agent'  : 'contributors-list'
      }, headers || { })
    };

    // Load all data pages from the GitHub API using the requestOptions
    loadPage(path);

    return deferred.promise;

    /**
     *  Recursive function used to load 1..n pages of requets data,
     *  and resolve with formatted JSON results.
     */
    function loadPage( path ) {
      jsonResponse = '';
      if (path) requestOptions.path = path;

      https.request(requestOptions, function (response) {
        response.on('error', reject);
        response.on('data', concatData);
        response.on('end', function () {
          result = result.concat(JSON.parse(jsonResponse));

          // Do we have more than 1 page of data ?
          var page = findPageLink(response);
          if (page) {
            loadPage(page);
            return;
          }

          deferred.resolve(result);
          cleanup();
        });
      }).end();
    }

    /**
     * Cleanup paging caches
     */
    function cleanup() {
      result = [];
      deferred = q.defer();
      jsonResponse = '';
    }

    /**
     * Do we have another page of data that should be loaded
     * and concatenated ?
     */
    function findPageLink(response) {
      var link = response.headers.link;
      var hasLink = link && link.indexOf('next') >= 0;
      if (hasLink) {
        link = link.split(',');
        if (link[0].indexOf('next') !== -1) {
          link = link[0].match(/<(.*?)>/)[1];
        } else if (link[1].indexOf('next') !== -1) {
          link = link[1].match(/<(.*?)>/)[1];
        }
      }
      return hasLink ? link : null;
    }

  }
};
<|endoftext|>


<commit_before>'use babel';

export default class GodsDjsView {

  constructor(serializedState) {
    // Create root element
    this.element = document.createElement('div');
    this.element.classList.add('godsdjs');
	this.element.addEventListener("click", this.toggle);

    // Create message element
    const toggle = document.createElement('span');
    toggle.classList.add('icon, icon-flame');
    this.element.appendChild(toggle);

	this.playing = serializedState.playing || false;
	this.audio = new window.AudioContext();
	this.stream = null;
  }

  // Returns an object that can be retrieved when package is activated
  serialize() {
	return {
		playing: this.playing
	};
  }

  toggle() {
	if (this.playing) {
		this.playing = false;
		this.element.classList.remove("pulsating");
		this.stream.disconnect(); //this.audio.createMediaStreamSource()
		this.stream = null;
	} else {
		this.playing = true;
		this.element.classList.add("pulsating");
		this.stream = this.audio.createMediaStreamSource("http://www.godsdjsradio.com:8080/stream");
		this.stream.connect(this.audio.destination);
	}

  }

  // Tear down any state and detach
  destroy() {
	this.element.removeEventListener("click", this.toggle);
    this.element.remove();
	this.stream.disconnect();
	this.stream = null;
	this.audio = null;
  }

  getElement() {
    return this.element;
  }

}
<commit_msg>ooops<commit_after>'use babel';

export default class GodsDjsView {

  constructor(serializedState) {
    // Create root element
    this.element = document.createElement('div');
    this.element.classList.add('godsdjs');
	this.element.addEventListener("click", this.toggle);

    // Create message element
    const toggle = document.createElement('span');
    toggle.classList.add('icon', 'icon-flame');
    this.element.appendChild(toggle);

	this.playing = serializedState.playing || false;
	this.audio = new window.AudioContext();
	this.stream = null;
  }

  // Returns an object that can be retrieved when package is activated
  serialize() {
	return {
		playing: this.playing
	};
  }

  toggle() {
	if (this.playing) {
		this.playing = false;
		this.element.classList.remove("pulsating");
		this.stream.disconnect(); //this.audio.createMediaStreamSource()
		this.stream = null;
	} else {
		this.playing = true;
		this.element.classList.add("pulsating");
		this.stream = this.audio.createMediaStreamSource("http://www.godsdjsradio.com:8080/stream");
		this.stream.connect(this.audio.destination);
	}

  }

  // Tear down any state and detach
  destroy() {
	this.element.removeEventListener("click", this.toggle);
    this.element.remove();
	this.stream.disconnect();
	this.stream = null;
	this.audio = null;
  }

  getElement() {
    return this.element;
  }

}
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

const log = require('../net2/logger.js')(__filename, 'info');

const Hook = require('./Hook.js');

const sem = require('../sensor/SensorEventManager.js').getInstance();

const country = require('../extension/country/country.js');

const rclient = require('../util/redis_manager.js').getRedisClient()

const f = require("../net2/Firewalla.js")

const Promise = require('bluebird');

const IntelTool = require('../net2/IntelTool');
const intelTool = new IntelTool();

const IntelManager = require('../net2/IntelManager.js');
const intelManager = new IntelManager();

const CategoryUpdater = require('../control/CategoryUpdater.js')
const categoryUpdater = new CategoryUpdater()
const CountryUpdater = require('../control/CountryUpdater.js')
const countryUpdater = new CountryUpdater()

const SysManager = require('../net2/SysManager.js')
const sysManager = new SysManager('info');

const IP_SET_TO_BE_PROCESSED = "ip_set_to_be_processed";

const ITEMS_PER_FETCH = 100;
const QUEUE_SIZE_PAUSE = 2000;
const QUEUE_SIZE_RESUME = 1000;

const TRUST_THRESHOLD = 10 // to be updated

const MONITOR_QUEUE_SIZE_INTERVAL = 10 * 1000; // 10 seconds;

class DestIPFoundHook extends Hook {

  constructor() {
    super();

    this.config.intelExpireTime = 2 * 24 * 3600; // two days
    this.pendingIPs = {};
  }

  appendNewIP(ip) {
    log.debug("Enqueue new ip for intels", ip);
    return rclient.zaddAsync(IP_SET_TO_BE_PROCESSED, 0, ip);
  }

  appendNewFlow(ip, fd, retryCount) {
    let flow = {
       ip:ip,
       fd:fd,
       retryCount: retryCount || 0
    };
    return rclient.zaddAsync(IP_SET_TO_BE_PROCESSED, 0, JSON.stringify(flow));
  }

  isFirewalla(host) {
    let patterns = [/\.encipher\.io$/,
      /^encipher\.io$/,
      /^firewalla\.com$/,
      /\.firewalla\.com$/];

    return patterns.filter(p => host.match(p)).length > 0;
  }

  // TBD
  // select the best fit intel from intel results from cloud

  selectIntel(intels) {

  }

  aggregateIntelResult(ip, sslInfo, dnsInfo, cloudIntelInfos) {
    let intel = {
      ip: ip
    };

    // sslInfo is an object, dnsInfo is a string
    if(dnsInfo) {
      intel.host = dnsInfo;
      intel.dnsHost = dnsInfo;
    }

    if(sslInfo && sslInfo.server_name) {
      intel.host = sslInfo.server_name
      intel.sslHost = sslInfo.server_name
      intel.org = sslInfo.O
    }

    // app
    cloudIntelInfos.forEach((info) => {

      if (info.failed) {
        intel.cloudFailed = true;
      }

/*
      let hashes = [intel.ip, intel.host].map(
        x => flowUtil.hashHost(x).map(y => y.length > 1 && y[1])
      )
      hashes = [].concat.apply([], hashes);
*/

      // check if the host matches the result from cloud

      // FIXME: ignore IP check because intel result from cloud does
      // NOT have "ip" all the time.

      // In the future, intel result needs to be enhanced to support
      // batch query

      // if(hashes.filter(x => x === info.ip).length > 0) {
      if(info.apps) {
        intel.apps = info.apps; // json string format
        try {
          const apps = JSON.parse(info.apps)
          const keys = Object.keys(apps);
          if(keys && keys[0]) {
            intel.app = keys[0];
          }
        } catch(err) {
          log.error("Failed to parse app json, err:", err);
        }
      }

      // always try to use the general domain pattern with same category
      // a.b.c.d => porn
      // b.c.d => porn
      // c.d => search engine
      //
      // 'b.c.d => porn' should be used

      if(info.c) {
        if(intel.category && info.c === intel.category) { // ignore if they are same category
          return
        }
        intel.category = info.c;
      }

      if(info.action && info.action.block) {
        intel.action = "block"
      }

      if(info.s) {
        intel.s = info.s;
      }

      if(info.t) {
        intel.t = info.t;
      }

      if(info.cc) {
        intel.cc = info.cc;
      }

      if(info.cs) {
        intel.cs = info.cs;
      }

      if(info.v) {
        intel.v = info.v;
      }

      if(info.originIP) {
        intel.originIP = info.originIP
      }
      //      }
    });

    const domains = this.getDomains(sslInfo, dnsInfo);

    if(intel.originIP && !domains.includes(intel.originIP)) {
      // it's a pattern
      intel.isOriginIPAPattern = true
    }

    return intel;
  }

  getDomains(sslInfo, dnsInfo) {
    // sslInfo is an object, dnsInfo is a string
    let domain = sslInfo && sslInfo.server_name;
    if(!domain) {
      domain = dnsInfo;
    }

    let domains = [];
    if(domain)
      domains.push(domain);

    return domains;
  }

  async enrichCountry(ip) {
    const ipinfo = await intelManager.ipinfo(ip);
    return ipinfo && ipinfo.country || country.getCountry(ip);
  }

  async updateCategoryDomain(intel) {
    if(intel.host && intel.category && intel.t > TRUST_THRESHOLD) {
      if(intel.originIP) {
        await categoryUpdater.updateDomain(intel.category, intel.originIP, intel.isOriginIPAPattern)
      } else {
        await categoryUpdater.updateDomain(intel.category, intel.host)
      }
    }
  }

  async updateCountryIP(intel) {
    if(intel.ip && intel.country) {
      await countryUpdater.updateIP(intel.country, intel.ip)
    }
  }

  _isSimilarHost(h1, h2) {
    if (!h1 || !h2)
      return false;
    const h1Sections = h1.split('.').reverse();
    const h2Sections = h2.split('.').reverse();
    // compare at most last three sections
    const limit = Math.min(h1Sections.length - 1, h2Sections.length - 1, 3);
    for (let i = 0; i != limit; i++) {
      if (h1Sections[i] !== h2Sections[i])
        return false;
    }
    return true;
  }

  async processIP(flow, options) {
    let ip = null;
    let fd = 'in';
    let retryCount = 0;

    if (flow) {
      let parsed = null;
      try {
        parsed = JSON.parse(flow);
        if (parsed.fd) {
          fd = parsed.fd;
          ip = parsed.ip;
          retryCount = parsed.retryCount || 0;
        } else {
          ip = flow;
          fd = 'in';
        }
      } catch(e) {
        ip = flow;
      }
    }
    options = options || {};

    if (sysManager.isLocalIP(ip)) {
      return
    }

    const skipReadLocalCache = options.skipReadLocalCache;
    const skipWriteLocalCache = options.skipWriteLocalCache;
    let sslInfo = await intelTool.getSSLCertificate(ip);
    let dnsInfo = await intelTool.getDNS(ip);
    let domains = this.getDomains(sslInfo, dnsInfo); // domains should contain at most one domain
    if (domains.length == 0 && retryCount < 5) {
      // domain is not fetched from either dns or ssl entries, retry in next job() schedule
      this.appendNewFlow(ip, fd, retryCount + 1);
    }

    try {
      let intel;
      if (!skipReadLocalCache) {
        intel = await intelTool.getIntel(ip);

        if (intel && !intel.cloudFailed) {
          // use cache data if host is similar or ssl org is identical (relatively loose condition to avoid calling intel API too frequently)
          if (domains.length == 0 || (sslInfo && intel.org && sslInfo.O === intel.org) || (intel.host && this._isSimilarHost(domains[0], intel.host))) {
            await this.updateCategoryDomain(intel);
            await this.updateCountryIP(intel);
            return;
          }
        }
      }

      log.debug("Found new IP " + ip + " fd " +fd+ " flow "+flow+ " domain " + domains + ", checking intels...");

      let ips = [ip];

      let cloudIntelInfo = [];

      // ignore if domain contain firewalla domain
      if(domains.filter(d => this.isFirewalla(d)).length === 0) {
        try {
          cloudIntelInfo = await intelTool.checkIntelFromCloud(ips, domains, fd);
        } catch(err) {
          // marks failure while not blocking local enrichement, e.g. country
          cloudIntelInfo.push({failed: true});

          if(options.noUpdateOnError) {
            return null;
          }
        }
      }

      // Update intel rdns:ip:xxx.xxx.xxx.xxx so that legacy can use it for better performance
      let aggrIntelInfo = this.aggregateIntelResult(ip, sslInfo, dnsInfo, cloudIntelInfo);
      aggrIntelInfo.country = aggrIntelInfo.country || await this.enrichCountry(ip) || ""; // empty string for unidentified country

      // update category pool if necessary
      await this.updateCategoryDomain(aggrIntelInfo);
      await this.updateCountryIP(aggrIntelInfo);

      // only set default action when cloud succeeded
      if(!aggrIntelInfo.action &&
        aggrIntelInfo.category !== 'intel' && // a special workaround here, only reset action when category is no longer intel
        !aggrIntelInfo.cloudFailed &&
        skipReadLocalCache
      ) {
        const oldIntel = await intelTool.getIntel(ip);
        if(oldIntel.category === 'intel') {
          log.info("Reset local intel action since it's not intel categary anymore.");
          aggrIntelInfo.action = "none";
        }
      }

      if(!skipWriteLocalCache) {
        // remove intel in case some keys in old intel hash is not updated if number of keys in new intel is less than that in old intel
        await intelTool.removeIntel(ip);
        await intelTool.addIntel(ip, aggrIntelInfo, this.config.intelExpireTime);
      }

      return aggrIntelInfo;

    } catch(err) {
      log.error(`Failed to process IP ${ip}, error:`, err);
      return null;
    }
  }

  async job() {
    log.debug("Checking if any IP Addresses pending for intel analysis...")

    try {
      let ips = await rclient.zrangeAsync(IP_SET_TO_BE_PROCESSED, 0, ITEMS_PER_FETCH);

      if(ips.length > 0) {
        let promises = ips.map((ip) => this.processIP(ip));

        await Promise.all(promises)

        let args = [IP_SET_TO_BE_PROCESSED];
        args.push.apply(args, ips);

        await rclient.zremAsync(args)

        log.debug(ips.length + "IP Addresses are analyzed with intels");

      } else {
        // log.info("No IP Addresses are pending for intels");
      }
    } catch(err) {
      log.error("Got error when handling new dest IP addresses, err:", err)
    }

    setTimeout(() => {
      this.job(); // sleep for only 500 mill-seconds
    }, 500);
  }

  run() {
    sem.on('DestIPFound', (event) => {
      let ip = event.ip;

      // ignore reserved ip address
      if(f.isReservedBlockingIP(ip)) {
        return;
      }

      let fd = event.fd;
      if (fd == null) {
        fd = 'in'
      }

      if(!ip)
        return;

      if(this.paused)
        return;

      this.appendNewFlow(ip, fd);
    });

    sem.on('DestIP', (event) => {
      const skipReadLocalCache = event.skipReadLocalCache;
      const noUpdateOnError = event.noUpdateOnError;
      this.processIP(event.ip, {skipReadLocalCache, noUpdateOnError});
    })

    this.job();

    setInterval(() => {
      this.monitorQueue()
    }, MONITOR_QUEUE_SIZE_INTERVAL)
  }

  async monitorQueue() {
    let count = await rclient.zcountAsync(IP_SET_TO_BE_PROCESSED, "-inf", "+inf")
    if(count > QUEUE_SIZE_PAUSE) {
      this.paused = true;
    }
    if(count < QUEUE_SIZE_RESUME) {
      this.paused = false;
    }
  }
}

module.exports = DestIPFoundHook;
<commit_msg>BUG: incompatibility fix<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

const log = require('../net2/logger.js')(__filename, 'info');

const Hook = require('./Hook.js');

const sem = require('../sensor/SensorEventManager.js').getInstance();

const country = require('../extension/country/country.js');

const rclient = require('../util/redis_manager.js').getRedisClient()

const f = require("../net2/Firewalla.js")

const Promise = require('bluebird');

const IntelTool = require('../net2/IntelTool');
const intelTool = new IntelTool();

const IntelManager = require('../net2/IntelManager.js');
const intelManager = new IntelManager();

const CategoryUpdater = require('../control/CategoryUpdater.js')
const categoryUpdater = new CategoryUpdater()
const CountryUpdater = require('../control/CountryUpdater.js')
const countryUpdater = new CountryUpdater()

const SysManager = require('../net2/SysManager.js')
const sysManager = new SysManager('info');

const IP_SET_TO_BE_PROCESSED = "ip_set_to_be_processed";

const ITEMS_PER_FETCH = 100;
const QUEUE_SIZE_PAUSE = 2000;
const QUEUE_SIZE_RESUME = 1000;

const TRUST_THRESHOLD = 10 // to be updated

const MONITOR_QUEUE_SIZE_INTERVAL = 10 * 1000; // 10 seconds;

class DestIPFoundHook extends Hook {

  constructor() {
    super();

    this.config.intelExpireTime = 2 * 24 * 3600; // two days
    this.pendingIPs = {};
  }

  appendNewIP(ip) {
    log.debug("Enqueue new ip for intels", ip);
    return rclient.zaddAsync(IP_SET_TO_BE_PROCESSED, 0, ip);
  }

  appendNewFlow(ip, fd, retryCount) {
    let flow = {
       ip:ip,
       fd:fd,
       retryCount: retryCount || 0
    };
    return rclient.zaddAsync(IP_SET_TO_BE_PROCESSED, 0, JSON.stringify(flow));
  }

  isFirewalla(host) {
    let patterns = [/\.encipher\.io$/,
      /^encipher\.io$/,
      /^firewalla\.com$/,
      /\.firewalla\.com$/];

    return patterns.filter(p => host.match(p)).length > 0;
  }

  // TBD
  // select the best fit intel from intel results from cloud

  selectIntel(intels) {

  }

  aggregateIntelResult(ip, sslInfo, dnsInfo, cloudIntelInfos) {
    let intel = {
      ip: ip
    };

    // sslInfo is an object, dnsInfo is a string
    if(dnsInfo) {
      intel.host = dnsInfo;
      intel.dnsHost = dnsInfo;
    }

    if(sslInfo && sslInfo.server_name) {
      intel.host = sslInfo.server_name
      intel.sslHost = sslInfo.server_name
      intel.org = sslInfo.O
    }

    // app
    cloudIntelInfos.forEach((info) => {

      if (info.failed) {
        intel.cloudFailed = true;
      }

/*
      let hashes = [intel.ip, intel.host].map(
        x => flowUtil.hashHost(x).map(y => y.length > 1 && y[1])
      )
      hashes = [].concat.apply([], hashes);
*/

      // check if the host matches the result from cloud

      // FIXME: ignore IP check because intel result from cloud does
      // NOT have "ip" all the time.

      // In the future, intel result needs to be enhanced to support
      // batch query

      // if(hashes.filter(x => x === info.ip).length > 0) {
      if(info.app) {
        intel.apps = info.app; // json string format
        try {
          const apps = JSON.parse(intel.apps)
          const keys = Object.keys(apps);
          if(keys && keys[0]) {
            intel.app = keys[0];
          }
        } catch(err) {
          log.error("Failed to parse app json, err:", err);
        }
      }

      // always try to use the general domain pattern with same category
      // a.b.c.d => porn
      // b.c.d => porn
      // c.d => search engine
      //
      // 'b.c.d => porn' should be used

      if(info.c) {
        if(intel.category && info.c === intel.category) { // ignore if they are same category
          return
        }
        intel.category = info.c;
      }

      if(info.action && info.action.block) {
        intel.action = "block"
      }

      if(info.s) {
        intel.s = info.s;
      }

      if(info.t) {
        intel.t = info.t;
      }

      if(info.cc) {
        intel.cc = info.cc;
      }

      if(info.cs) {
        intel.cs = info.cs;
      }

      if(info.v) {
        intel.v = info.v;
      }

      if(info.originIP) {
        intel.originIP = info.originIP
      }
      //      }
    });

    const domains = this.getDomains(sslInfo, dnsInfo);

    if(intel.originIP && !domains.includes(intel.originIP)) {
      // it's a pattern
      intel.isOriginIPAPattern = true
    }

    return intel;
  }

  getDomains(sslInfo, dnsInfo) {
    // sslInfo is an object, dnsInfo is a string
    let domain = sslInfo && sslInfo.server_name;
    if(!domain) {
      domain = dnsInfo;
    }

    let domains = [];
    if(domain)
      domains.push(domain);

    return domains;
  }

  async enrichCountry(ip) {
    const ipinfo = await intelManager.ipinfo(ip);
    return ipinfo && ipinfo.country || country.getCountry(ip);
  }

  async updateCategoryDomain(intel) {
    if(intel.host && intel.category && intel.t > TRUST_THRESHOLD) {
      if(intel.originIP) {
        await categoryUpdater.updateDomain(intel.category, intel.originIP, intel.isOriginIPAPattern)
      } else {
        await categoryUpdater.updateDomain(intel.category, intel.host)
      }
    }
  }

  async updateCountryIP(intel) {
    if(intel.ip && intel.country) {
      await countryUpdater.updateIP(intel.country, intel.ip)
    }
  }

  _isSimilarHost(h1, h2) {
    if (!h1 || !h2)
      return false;
    const h1Sections = h1.split('.').reverse();
    const h2Sections = h2.split('.').reverse();
    // compare at most last three sections
    const limit = Math.min(h1Sections.length - 1, h2Sections.length - 1, 3);
    for (let i = 0; i != limit; i++) {
      if (h1Sections[i] !== h2Sections[i])
        return false;
    }
    return true;
  }

  async processIP(flow, options) {
    let ip = null;
    let fd = 'in';
    let retryCount = 0;

    if (flow) {
      let parsed = null;
      try {
        parsed = JSON.parse(flow);
        if (parsed.fd) {
          fd = parsed.fd;
          ip = parsed.ip;
          retryCount = parsed.retryCount || 0;
        } else {
          ip = flow;
          fd = 'in';
        }
      } catch(e) {
        ip = flow;
      }
    }
    options = options || {};

    if (sysManager.isLocalIP(ip)) {
      return
    }

    const skipReadLocalCache = options.skipReadLocalCache;
    const skipWriteLocalCache = options.skipWriteLocalCache;
    let sslInfo = await intelTool.getSSLCertificate(ip);
    let dnsInfo = await intelTool.getDNS(ip);
    let domains = this.getDomains(sslInfo, dnsInfo); // domains should contain at most one domain
    if (domains.length == 0 && retryCount < 5) {
      // domain is not fetched from either dns or ssl entries, retry in next job() schedule
      this.appendNewFlow(ip, fd, retryCount + 1);
    }

    try {
      let intel;
      if (!skipReadLocalCache) {
        intel = await intelTool.getIntel(ip);

        if (intel && !intel.cloudFailed) {
          // use cache data if host is similar or ssl org is identical (relatively loose condition to avoid calling intel API too frequently)
          if (domains.length == 0 || (sslInfo && intel.org && sslInfo.O === intel.org) || (intel.host && this._isSimilarHost(domains[0], intel.host))) {
            await this.updateCategoryDomain(intel);
            await this.updateCountryIP(intel);
            return;
          }
        }
      }

      log.debug("Found new IP " + ip + " fd " +fd+ " flow "+flow+ " domain " + domains + ", checking intels...");

      let ips = [ip];

      let cloudIntelInfo = [];

      // ignore if domain contain firewalla domain
      if(domains.filter(d => this.isFirewalla(d)).length === 0) {
        try {
          cloudIntelInfo = await intelTool.checkIntelFromCloud(ips, domains, fd);
        } catch(err) {
          // marks failure while not blocking local enrichement, e.g. country
          cloudIntelInfo.push({failed: true});

          if(options.noUpdateOnError) {
            return null;
          }
        }
      }

      // Update intel rdns:ip:xxx.xxx.xxx.xxx so that legacy can use it for better performance
      let aggrIntelInfo = this.aggregateIntelResult(ip, sslInfo, dnsInfo, cloudIntelInfo);
      aggrIntelInfo.country = aggrIntelInfo.country || await this.enrichCountry(ip) || ""; // empty string for unidentified country

      // update category pool if necessary
      await this.updateCategoryDomain(aggrIntelInfo);
      await this.updateCountryIP(aggrIntelInfo);

      // only set default action when cloud succeeded
      if(!aggrIntelInfo.action &&
        aggrIntelInfo.category !== 'intel' && // a special workaround here, only reset action when category is no longer intel
        !aggrIntelInfo.cloudFailed &&
        skipReadLocalCache
      ) {
        const oldIntel = await intelTool.getIntel(ip);
        if(oldIntel.category === 'intel') {
          log.info("Reset local intel action since it's not intel categary anymore.");
          aggrIntelInfo.action = "none";
        }
      }

      if(!skipWriteLocalCache) {
        // remove intel in case some keys in old intel hash is not updated if number of keys in new intel is less than that in old intel
        await intelTool.removeIntel(ip);
        await intelTool.addIntel(ip, aggrIntelInfo, this.config.intelExpireTime);
      }

      return aggrIntelInfo;

    } catch(err) {
      log.error(`Failed to process IP ${ip}, error:`, err);
      return null;
    }
  }

  async job() {
    log.debug("Checking if any IP Addresses pending for intel analysis...")

    try {
      let ips = await rclient.zrangeAsync(IP_SET_TO_BE_PROCESSED, 0, ITEMS_PER_FETCH);

      if(ips.length > 0) {
        let promises = ips.map((ip) => this.processIP(ip));

        await Promise.all(promises)

        let args = [IP_SET_TO_BE_PROCESSED];
        args.push.apply(args, ips);

        await rclient.zremAsync(args)

        log.debug(ips.length + "IP Addresses are analyzed with intels");

      } else {
        // log.info("No IP Addresses are pending for intels");
      }
    } catch(err) {
      log.error("Got error when handling new dest IP addresses, err:", err)
    }

    setTimeout(() => {
      this.job(); // sleep for only 500 mill-seconds
    }, 500);
  }

  run() {
    sem.on('DestIPFound', (event) => {
      let ip = event.ip;

      // ignore reserved ip address
      if(f.isReservedBlockingIP(ip)) {
        return;
      }

      let fd = event.fd;
      if (fd == null) {
        fd = 'in'
      }

      if(!ip)
        return;

      if(this.paused)
        return;

      this.appendNewFlow(ip, fd);
    });

    sem.on('DestIP', (event) => {
      const skipReadLocalCache = event.skipReadLocalCache;
      const noUpdateOnError = event.noUpdateOnError;
      this.processIP(event.ip, {skipReadLocalCache, noUpdateOnError});
    })

    this.job();

    setInterval(() => {
      this.monitorQueue()
    }, MONITOR_QUEUE_SIZE_INTERVAL)
  }

  async monitorQueue() {
    let count = await rclient.zcountAsync(IP_SET_TO_BE_PROCESSED, "-inf", "+inf")
    if(count > QUEUE_SIZE_PAUSE) {
      this.paused = true;
    }
    if(count < QUEUE_SIZE_RESUME) {
      this.paused = false;
    }
  }
}

module.exports = DestIPFoundHook;
<|endoftext|>


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

const _ = require('lodash');
const fs = require('fs-extra');
const gtfs = require('gtfs');
const sanitize = require('sanitize-filename');
const Timer = require('timer-machine');

const fileUtils = require('./file-utils');
const logUtils = require('./log-utils');
const utils = require('./utils');

/*
 * Generate HTML timetables from GTFS.
 */
module.exports = initialConfig => {
  const config = utils.setDefaultConfig(initialConfig);
  config.log = logUtils.log(config);
  config.logWarning = logUtils.logWarning(config);

  if (!config.agencies || config.agencies.length === 0) {
    throw new Error('No agencies defined in `config.json`');
  }

  return Promise.all(config.agencies.map(async agency => {
    const timer = new Timer();
    const agencyKey = agency.agency_key;
    const exportPath = path.join(process.cwd(), 'html', sanitize(agencyKey));
    const outputStats = {
      timetables: 0,
      timetablePages: 0,
      calendars: 0,
      trips: 0,
      routes: 0,
      stops: 0
    };

    timer.start();

    if (!config.skipImport) {
      // Import GTFS
      const agencyConfig = _.clone(_.omit(config, 'agencies'));
      agencyConfig.agencies = [agency];

      await gtfs.import(agencyConfig);
    }

    const timetablePages = [];
    const timetablePageIds = _.map(await utils.getTimetablePages(agencyKey, config), 'timetable_page_id');
    await fileUtils.prepDirectory(exportPath);

    const bar = logUtils.progressBar(`${agencyKey}: Generating ${config.outputFormat.toUpperCase()} timetables [:bar] :current/:total`, { total: timetablePageIds.length }, config);

    /* eslint-disable no-await-in-loop */
    for (const timetablePageId of timetablePageIds) {
      const timetablePage = await utils.getFormattedTimetablePage(agencyKey, timetablePageId, config);

      if (timetablePage.timetables.length === 0) {
        bar.interrupt(logUtils.formatWarn(`${agencyKey}: No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`));
        continue;
      }

      outputStats.timetables += timetablePage.timetables.length;
      outputStats.timetablePages += 1;

      const datePath = fileUtils.generateFolderName(timetablePage);

      // Make directory if it doesn't exist
      await fs.ensureDir(path.join(exportPath, datePath));
      config.assetPath = '../';

      timetablePage.relativePath = path.join(datePath, sanitize(timetablePage.filename));

      const results = await utils.generateHTML(timetablePage, config);

      _.each(outputStats, (stat, key) => {
        if (results.stats[key]) {
          outputStats[key] += results.stats[key];
        }
      });

      const htmlPath = path.join(exportPath, datePath, sanitize(timetablePage.filename));
      await fs.writeFile(htmlPath, results.html);

      if (config.outputFormat === 'pdf') {
        await fileUtils.renderPdf(htmlPath);
      }

      bar.tick();
      timetablePages.push(timetablePage);
    }
    /* eslint-enable no-await-in-loop */

    // Generate route summary index.html
    config.assetPath = '';
    const html = await utils.generateOverviewHTML(agencyKey, timetablePages, config);
    await fs.writeFile(path.join(exportPath, 'index.html'), html);

    // Generate output log.txt
    const logText = await logUtils.generateLogText(agency, outputStats, config);
    await fs.writeFile(path.join(exportPath, 'log.txt'), logText);

    // Zip output, if specified
    if (config.zipOutput) {
      await fileUtils.zipFolder(exportPath);
    }

    const fullExportPath = exportPath + config.zipOutput ? '/timetables.zip' : '';

    timer.stop();

    // Print stats
    config.log(`${agencyKey}: ${config.outputFormat.toUpperCase()} timetables created at ${fullExportPath}`);

    logUtils.logStats(outputStats, config);

    const seconds = Math.round(timer.time() / 1000);
    config.log(`${agencyKey}: ${config.outputFormat.toUpperCase()} timetable generation required ${seconds} seconds`);
  }));
};
<commit_msg>Fix for output path<commit_after>const path = require('path');

const _ = require('lodash');
const fs = require('fs-extra');
const gtfs = require('gtfs');
const sanitize = require('sanitize-filename');
const Timer = require('timer-machine');

const fileUtils = require('./file-utils');
const logUtils = require('./log-utils');
const utils = require('./utils');

/*
 * Generate HTML timetables from GTFS.
 */
module.exports = initialConfig => {
  const config = utils.setDefaultConfig(initialConfig);
  config.log = logUtils.log(config);
  config.logWarning = logUtils.logWarning(config);

  if (!config.agencies || config.agencies.length === 0) {
    throw new Error('No agencies defined in `config.json`');
  }

  return Promise.all(config.agencies.map(async agency => {
    const timer = new Timer();
    const agencyKey = agency.agency_key;
    const exportPath = path.join(process.cwd(), 'html', sanitize(agencyKey));
    const outputStats = {
      timetables: 0,
      timetablePages: 0,
      calendars: 0,
      trips: 0,
      routes: 0,
      stops: 0
    };

    timer.start();

    if (!config.skipImport) {
      // Import GTFS
      const agencyConfig = _.clone(_.omit(config, 'agencies'));
      agencyConfig.agencies = [agency];

      await gtfs.import(agencyConfig);
    }

    const timetablePages = [];
    const timetablePageIds = _.map(await utils.getTimetablePages(agencyKey, config), 'timetable_page_id');
    await fileUtils.prepDirectory(exportPath);

    const bar = logUtils.progressBar(`${agencyKey}: Generating ${config.outputFormat.toUpperCase()} timetables [:bar] :current/:total`, { total: timetablePageIds.length }, config);

    /* eslint-disable no-await-in-loop */
    for (const timetablePageId of timetablePageIds) {
      const timetablePage = await utils.getFormattedTimetablePage(agencyKey, timetablePageId, config);

      if (timetablePage.timetables.length === 0) {
        bar.interrupt(logUtils.formatWarn(`${agencyKey}: No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`));
        continue;
      }

      outputStats.timetables += timetablePage.timetables.length;
      outputStats.timetablePages += 1;

      const datePath = fileUtils.generateFolderName(timetablePage);

      // Make directory if it doesn't exist
      await fs.ensureDir(path.join(exportPath, datePath));
      config.assetPath = '../';

      timetablePage.relativePath = path.join(datePath, sanitize(timetablePage.filename));

      const results = await utils.generateHTML(timetablePage, config);

      _.each(outputStats, (stat, key) => {
        if (results.stats[key]) {
          outputStats[key] += results.stats[key];
        }
      });

      const htmlPath = path.join(exportPath, datePath, sanitize(timetablePage.filename));
      await fs.writeFile(htmlPath, results.html);

      if (config.outputFormat === 'pdf') {
        await fileUtils.renderPdf(htmlPath);
      }

      bar.tick();
      timetablePages.push(timetablePage);
    }
    /* eslint-enable no-await-in-loop */

    // Generate route summary index.html
    config.assetPath = '';
    const html = await utils.generateOverviewHTML(agencyKey, timetablePages, config);
    await fs.writeFile(path.join(exportPath, 'index.html'), html);

    // Generate output log.txt
    const logText = await logUtils.generateLogText(agency, outputStats, config);
    await fs.writeFile(path.join(exportPath, 'log.txt'), logText);

    // Zip output, if specified
    if (config.zipOutput) {
      await fileUtils.zipFolder(exportPath);
    }

    const fullExportPath = path.join(exportPath, config.zipOutput ? '/timetables.zip' : '');

    timer.stop();

    // Print stats
    config.log(`${agencyKey}: ${config.outputFormat.toUpperCase()} timetables created at ${fullExportPath}`);

    logUtils.logStats(outputStats, config);

    const seconds = Math.round(timer.time() / 1000);
    config.log(`${agencyKey}: ${config.outputFormat.toUpperCase()} timetable generation required ${seconds} seconds`);
  }));
};
<|endoftext|>


<commit_before>/* eslint-env mocha, browser */
/* global proclaim */

// See: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.some

beforeEach(function() {
	this.array = [0, 2, 4, 6, 8, 10, 12, 14];
});

it("Should not accept a function argument that is not callable", function() {
	var array = this.array;
	proclaim.throws(function() { array.some({}); }, TypeError);
});

it("Should accept a function with three parameters: the value of the element, the index of the element and the object being traversed", function() {
	var array = this.array;

	array.some(function(value, index, object) {
		proclaim.strictEqual(object, array);
		proclaim.equal(object[index], value);
		return false;
	});
});

it("Should accept an optional 'this' argument as its second argument which becomes the 'this' value for the function argument", function() {
	var mockThis = { foo: "bar" };
	var array = this.array;

	array.some(function() {
		proclaim.strictEqual(this, mockThis);
		proclaim.equal(this.foo, mockThis.foo);
		return false;
	}, mockThis);
});

it("Should pass a reference to the array as the third parameter to the function argument", function() {
	var array = [10];

	array.some(function(value, index, object) {
		object[0] = 100;
		return false;
	});

	proclaim.equal(array[0], 100);
});

it("Should not iterate over elements appended to the array after the call to some.  The range is fixed before the first call to the callback", function() {
	var array = [1, 2, 3, 4, 5, 6];
	var visited = [];

	array.some(function(value, index) {
		array.push(index);
		visited[index] = value;
		return false;
	});

	proclaim.deepEqual(visited, [1, 2, 3, 4, 5, 6]);

	// Expect the original array to be the same for the first 6 elements, with
	// the additional 0, 1, .. 5 appended (the indices of the first 6 elements
	// in the range covered by some at the start of its invocation
	proclaim.deepEqual(array, [1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5]);
});

it("Should return false if the array is empty", function() {
	var a = [];
	proclaim.equal(a.some(function() { return true; }), false);
});

it("Should not visit elements that are deleted after the call to some begins and before being visited", function() {
	var a = [1, 2, 3, 4, 5, 6];
	var visited = [];

	a.some(function(value, index, object) {
		delete object[5];
		visited.push(index);
		return false;
	});

	// Should only visit the first 5 indices
	proclaim.deepEqual(visited, [0, 1, 2, 3, 4]);
});

it("Should return true as soon as the callback returns true", function() {
	var a = [0, 1, 2, 3, 4];
	var visited = [];
	proclaim.equal(a.some(function(value) {
		visited.push(value);
		return value > 2;
	}), true);

	proclaim.deepEqual(visited, [0, 1, 2, 3]);
});

it("Should return false if the callback never returns true", function() {
	var a = [0, 1, 2, 3, 4];
	var visited = [];
	proclaim.equal(a.some(function(value) {
		visited.push(value);
		return false;
	}), false);

	proclaim.deepEqual(visited, a);
});
<commit_msg>improve test coverage for Array.prototype.some (#1630)<commit_after>/* eslint-env mocha */
/* globals proclaim */

it('is a function', function () {
	proclaim.isFunction(Array.prototype.some);
});

it('has correct arity', function () {
	proclaim.arity(Array.prototype.some, 1);
});

it('has correct name', function () {
	proclaim.hasName(Array.prototype.some, 'some');
});

it('is not enumerable', function () {
	proclaim.nonEnumerable(Array.prototype, 'some');
});

beforeEach(function() {
	this.array = [0, 2, 4, 6, 8, 10, 12, 14];
});

it("Should not accept a function argument that is not callable", function() {
	var array = this.array;
	proclaim.throws(function() { array.some({}); }, TypeError);
});

it("Should accept a function with three parameters: the value of the element, the index of the element and the object being traversed", function() {
	var array = this.array;

	array.some(function(value, index, object) {
		proclaim.strictEqual(object, array);
		proclaim.equal(object[index], value);
		return false;
	});
});

it("Should accept an optional 'this' argument as its second argument which becomes the 'this' value for the function argument", function() {
	var mockThis = { foo: "bar" };
	var array = this.array;

	array.some(function() {
		proclaim.strictEqual(this, mockThis);
		proclaim.equal(this.foo, mockThis.foo);
		return false;
	}, mockThis);
});

it("Should pass a reference to the array as the third parameter to the function argument", function() {
	var array = [10];

	array.some(function(value, index, object) {
		object[0] = 100;
		return false;
	});

	proclaim.equal(array[0], 100);
});

it("Should not iterate over elements appended to the array after the call to some.  The range is fixed before the first call to the callback", function() {
	var array = [1, 2, 3, 4, 5, 6];
	var visited = [];

	array.some(function(value, index) {
		array.push(index);
		visited[index] = value;
		return false;
	});

	proclaim.deepEqual(visited, [1, 2, 3, 4, 5, 6]);

	// Expect the original array to be the same for the first 6 elements, with
	// the additional 0, 1, .. 5 appended (the indices of the first 6 elements
	// in the range covered by some at the start of its invocation
	proclaim.deepEqual(array, [1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5]);
});

it("Should return false if the array is empty", function() {
	var a = [];
	proclaim.equal(a.some(function() { return true; }), false);
});

it("Should not visit elements that are deleted after the call to some begins and before being visited", function() {
	var a = [1, 2, 3, 4, 5, 6];
	var visited = [];

	a.some(function(value, index, object) {
		delete object[5];
		visited.push(index);
		return false;
	});

	// Should only visit the first 5 indices
	proclaim.deepEqual(visited, [0, 1, 2, 3, 4]);
});

it("Should return true as soon as the callback returns true", function() {
	var a = [0, 1, 2, 3, 4];
	var visited = [];
	proclaim.equal(a.some(function(value) {
		visited.push(value);
		return value > 2;
	}), true);

	proclaim.deepEqual(visited, [0, 1, 2, 3]);
});

it("Should return false if the callback never returns true", function() {
	var a = [0, 1, 2, 3, 4];
	var visited = [];
	proclaim.equal(a.some(function(value) {
		visited.push(value);
		return false;
	}), false);

	proclaim.deepEqual(visited, a);
});
<|endoftext|>


<commit_before>var dataarray,$dataTable;
$(function(){
  "use strict";
  /**
    Get values from object and put them into an array
    @method jsonTable
    @param data {Object} Parsed JSON Object containing column and row data
    @return {Array} array of object values
  */
  function objArray(obj){
    return Object.keys(obj).map(function(k){return obj[k];});
  }

  /* Define two custom functions (asc and desc) for string sorting */
  /*
  jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
  };

  jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
    return ((x < y) ?  1 : ((x > y) ? -1 : 0));
  };  */
  var $statusMsg = $("#status-msg"),
      $hbTable = $("#heartbeat-table"),
      $logmsgTable = $("#logmsg-table"),
      lmCapacity = 20,
      $row,
      $pos;

  /* Bind Events */
  KDBCONNECT.bind("event","ws_event",function(data){
    // Data is default message that is set in KDBCONNECT.js
    $statusMsg.html(data);
  });
  KDBCONNECT.bind("event","error",function(data){
    $statusMsg.html("Error - " + data);
  });

  /* Bind data - Data type "start" will execute the callback function */
  KDBCONNECT.bind("data","start",function(data){

    // Check that data is not empty
    if(data.hbtable.length !== 0){

      // Write HTML table to div element with id heartbeat-table this builds the table
      $hbTable.html(MONITOR.jsonTable(data.hbtable));
      $dataTable = $hbTable.find('table').DataTable({
        "aaSorting": [ [4,'desc'], [5,'desc'] ],
        "aoColumns": [
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          { "sType": 'string' },
          { "sType": 'string' },
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false}            // warning and error columns are both sorted descending
        ],
        "sDom": '<"top"i>rt<"clear">',     // Place search filter box on bottom
        "bAutoWidth": false,
        "bPaginate": false,                // Do not paginate results
        "bInfo": false,
      });
    }
    if(data.lmtable.length !== 0){  $logmsgTable.html(MONITOR.jsonTable(data.lmtable)); } // Write HTML table to div element with id logmsg-table
    if(data.lmchart.length !== 0){  MONITOR.barChart(data.lmchart,"logmsg-chart","Error Count","myTab");  }  // Log message error chart
  });
  KDBCONNECT.bind("data","upd",function(data){

    // Do nothing if there is no table data
    if(data.tabledata.length === 0){ return; }

    // Table doesn't exist
    if($hbTable.find('table').length === 0){
      // $hbTable.html(MONITOR.jsonTable(data.tabledata));
      // Write HTML table to div element with id heartbeat-table this builds the table
      $hbTable.html(MONITOR.jsonTable(data.tabledata));
      $dataTable = $hbTable.find('table').DataTable({
        "aaSorting": [ [4,'desc'], [5,'desc'] ],
        "aoColumns": [
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          { "sType": 'string' },
          { "sType": 'string' },
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false}            // warning and error columns are both sorted descending
        ],
        "sDom": '<"top"i>rt<"clear">',     // Place search filter box on bottom
        "bAutoWidth": false,
        "bPaginate": false,                // Do not paginate results
        "bInfo": false
      });
    }

    // Do something with the heartbeat table
    if(data.tablename === "heartbeat"){
    // Assuming single message at a time, use procname as unique identifier column 2 i.e. nth-child(2)
      $row = $hbTable.find('table tbody td:nth-child(2):contains("' + data.tabledata[0].procname + '")');

      if($row.length === 0){
        // Add rows
        $dataTable.fnAddData(objArray(data.tabledata[0]));
      }
      if($row.length>0){
        // Get position of row
        $pos = $dataTable.fnGetPosition($row[0])[0];
        // Update row - with data array, position of row
        $dataTable.fnUpdate(objArray(data.tabledata[0]),$pos);
      }
    }

     // Do something with logmsg table
     if(data.tablename === "logmsg"){

       // No rows? Create new table
      if($logmsgTable.find('tbody tr').length === 0){

        // Assumes max 20 will be recieved, therefore could limit this via data.tabledata.splice(20,data.tabledata.length)
        $logmsgTable.html(MONITOR.jsonTable(data.tabledata));
      } else {

        // Add row to top of table
        $(MONITOR.makeRows(data.tabledata)).prependTo($logmsgTable.find('tbody')).find(':parent').effect('highlight', 2000);
      }

      // Row count >= lmCapacity delete row
      if($logmsgTable.find('tbody tr').length >= lmCapacity){

        // Remove first row if over 20 rows
        $logmsgTable.find('tbody tr:last').remove();
      }

    }

    // Do something with lmchart
    // DEV - currently send all lmchart[], included in monitor.q t=`logmsg
    if(data.tablename === "lmchart"){
      console.log("LMCHART - ", data);
      MONITOR.barChart(data.tabledata,"logmsg-chart","Error Count","myTab");
    }
  });
  KDBCONNECT.bind("data","bucketlmchart",function(data){
    if(data[0].length>0){ MONITOR.barChart(data[0],"logmsg-chart","Error Count","myTab");}
  });

  /*
    UI - Highlighting
    highlightRow(tableId,colNumber,conditionArray,cssClass);
  */
  MONITOR.highlightRow('#heartbeat-table',4,["=","true"],"warning-row");
  MONITOR.highlightRow('#heartbeat-table',5,["=","true"],"error-row");
  MONITOR.highlightColCell('#logmsg-table','logmsg-error',3);

  /* Bucket chart input - Grab value from input and send function argument */
  MONITOR.bucketChart('#bucket-time',"bucketlmchart");

  /* Extra UI configurations - Logmsg tabs */
  $('#myTab a').click(function (e) {
    e.preventDefault();
    $(this).tab('show');
    $(window).scrollTop($(this).offset().top);
  });
  $('#bucket-time').click(function (e) {
    e.preventDefault();
    $(window).scrollTop($(this).offset().top);
  });
});
<commit_msg>Startmonitor clean-up Removed unnecessary comma and comment Aligned comments<commit_after>var dataarray,$dataTable;
$(function(){
  "use strict";
  /**
    Get values from object and put them into an array
    @method jsonTable
    @param data {Object} Parsed JSON Object containing column and row data
    @return {Array} array of object values
  */
  function objArray(obj){
    return Object.keys(obj).map(function(k){return obj[k];});
  }

  /* Define two custom functions (asc and desc) for string sorting */
  /*
  jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
  };

  jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
    return ((x < y) ?  1 : ((x > y) ? -1 : 0));
  };  */
  var $statusMsg = $("#status-msg"),
      $hbTable = $("#heartbeat-table"),
      $logmsgTable = $("#logmsg-table"),
      lmCapacity = 20,
      $row,
      $pos;

  /* Bind Events */
  KDBCONNECT.bind("event","ws_event",function(data){
    // Data is default message that is set in KDBCONNECT.js
    $statusMsg.html(data);
  });
  KDBCONNECT.bind("event","error",function(data){
    $statusMsg.html("Error - " + data);
  });

  /* Bind data - Data type "start" will execute the callback function */
  KDBCONNECT.bind("data","start",function(data){

    // Check that data is not empty
    if(data.hbtable.length !== 0){

      // Write HTML table to div element with id heartbeat-table this builds the table
      $hbTable.html(MONITOR.jsonTable(data.hbtable));
      $dataTable = $hbTable.find('table').DataTable({
        "aaSorting": [ [4,'desc'], [5,'desc'] ],
        "aoColumns": [
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          { "sType": 'string' },
          { "sType": 'string' },           // warning and error columns are both sorted descending
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false}
        ],
        "sDom": '<"top"i>rt<"clear">',     // Place search filter box on bottom
        "bAutoWidth": false,
        "bPaginate": false,                // Do not paginate results
        "bInfo": false
      });
    }
    if(data.lmtable.length !== 0){  $logmsgTable.html(MONITOR.jsonTable(data.lmtable)); } // Write HTML table to div element with id logmsg-table
    if(data.lmchart.length !== 0){  MONITOR.barChart(data.lmchart,"logmsg-chart","Error Count","myTab");  }  // Log message error chart
  });
  KDBCONNECT.bind("data","upd",function(data){

    // Do nothing if there is no table data
    if(data.tabledata.length === 0){ return; }

    // Table doesn't exist
    if($hbTable.find('table').length === 0){
      // Write HTML table to div element with id heartbeat-table this builds the table
      $hbTable.html(MONITOR.jsonTable(data.tabledata));
      $dataTable = $hbTable.find('table').DataTable({
        "aaSorting": [ [4,'desc'], [5,'desc'] ],
        "aoColumns": [
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false},
          { "sType": 'string' },
          { "sType": 'string' },           // warning and error columns are both sorted descending
          {"bSortable": false},
          {"bSortable": false},
          {"bSortable": false}
        ],
        "sDom": '<"top"i>rt<"clear">',     // Place search filter box on bottom
        "bAutoWidth": false,
        "bPaginate": false,                // Do not paginate results
        "bInfo": false
      });
    }

    // Do something with the heartbeat table
    if(data.tablename === "heartbeat"){
      // Assuming single message at a time, use procname as unique identifier column 2 i.e. nth-child(2)
      $row = $hbTable.find('table tbody td:nth-child(2):contains("' + data.tabledata[0].procname + '")');

      if($row.length === 0){
        // Add rows
        $dataTable.fnAddData(objArray(data.tabledata[0]));
      }
      if($row.length>0){
        // Get position of row
        $pos = $dataTable.fnGetPosition($row[0])[0];
        // Update row - with data array, position of row
        $dataTable.fnUpdate(objArray(data.tabledata[0]),$pos);
      }
    }

     // Do something with logmsg table
     if(data.tablename === "logmsg"){

      // No rows? Create new table
      if($logmsgTable.find('tbody tr').length === 0){

        // Assumes max 20 will be recieved, therefore could limit this via data.tabledata.splice(20,data.tabledata.length)
        $logmsgTable.html(MONITOR.jsonTable(data.tabledata));
      } else {

        // Add row to top of table
        $(MONITOR.makeRows(data.tabledata)).prependTo($logmsgTable.find('tbody')).find(':parent').effect('highlight', 2000);
      }

      // Row count >= lmCapacity delete row
      if($logmsgTable.find('tbody tr').length >= lmCapacity){

        // Remove first row if over 20 rows
        $logmsgTable.find('tbody tr:last').remove();
      }

    }

    // Do something with lmchart
    // DEV - currently send all lmchart[], included in monitor.q t=`logmsg
    if(data.tablename === "lmchart"){
      console.log("LMCHART - ", data);
      MONITOR.barChart(data.tabledata,"logmsg-chart","Error Count","myTab");
    }
  });
  KDBCONNECT.bind("data","bucketlmchart",function(data){
    if(data[0].length>0){ MONITOR.barChart(data[0],"logmsg-chart","Error Count","myTab");}
  });

  /*
    UI - Highlighting
    highlightRow(tableId,colNumber,conditionArray,cssClass);
  */
  MONITOR.highlightRow('#heartbeat-table',4,["=","true"],"warning-row");
  MONITOR.highlightRow('#heartbeat-table',5,["=","true"],"error-row");
  MONITOR.highlightColCell('#logmsg-table','logmsg-error',3);

  /* Bucket chart input - Grab value from input and send function argument */
  MONITOR.bucketChart('#bucket-time',"bucketlmchart");

  /* Extra UI configurations - Logmsg tabs */
  $('#myTab a').click(function (e) {
    e.preventDefault();
    $(this).tab('show');
    $(window).scrollTop($(this).offset().top);
  });
  $('#bucket-time').click(function (e) {
    e.preventDefault();
    $(window).scrollTop($(this).offset().top);
  });
});
<|endoftext|>


<commit_before>// Copyright (c) 2017, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const express = require('express'),
    _ = require('underscore'),
    AsmDocsApi = require('./asm-docs-api'),
    FormatterHandler = require('./formatting'),
    utils = require('../utils'),
    logger = require('../logger').logger,
    clientStateNormalizer = require('../clientstate-normalizer').ClientStateNormalizer;

class ApiHandler {
    constructor(compileHandler, ceProps, storageHandler) {
        this.compilers = [];
        this.languages = [];
        this.usedLangIds = [];
        this.options = null;
        this.storageHandler = storageHandler;
        this.handle = express.Router();
        const cacheHeader = `public, max-age=${ceProps('apiMaxAgeSecs', 24 * 60 * 60)}`;
        this.handle.use((req, res, next) => {
            res.header(
                {
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
                    'Cache-Control': cacheHeader,
                },
            );
            next();
        });
        this.handle.get('/compilers', this.handleCompilers.bind(this));
        this.handle.get('/compilers/:language', this.handleCompilers.bind(this));
        this.handle.get('/languages', this.handleLanguages.bind(this));
        this.handle.get('/libraries/:language', this.handleLangLibraries.bind(this));
        this.handle.get('/libraries', this.handleAllLibraries.bind(this));

        const asmDocsHandler = new AsmDocsApi.Handler();
        this.handle.get('/asm/:opcode', asmDocsHandler.handle.bind(asmDocsHandler));

        this.handle.post('/compiler/:compiler/compile', compileHandler.handle.bind(compileHandler));
        this.handle.post('/popularArguments/:compiler', compileHandler.handlePopularArguments.bind(compileHandler));
        this.handle.post('/optimizationArguments/:compiler',
            compileHandler.handleOptimizationArguments.bind(compileHandler));

        this.handle.get('/popularArguments/:compiler', compileHandler.handlePopularArguments.bind(compileHandler));
        this.handle.get('/optimizationArguments/:compiler',
            compileHandler.handleOptimizationArguments.bind(compileHandler));

        const formatter = new FormatterHandler(ceProps);
        this.handle.post('/format/:tool', formatter.formatHandler.bind(formatter));
        this.handle.get('/formats', formatter.listHandler.bind(formatter));

        this.handle.get('/shortlinkinfo/:id', this.shortlinkInfoHandler.bind(this));
    }

    shortlinkInfoHandler(req, res, next) {
        const id = req.params.id;
        this.storageHandler.expandId(id)
            .then(result => {
                const config = JSON.parse(result.config);

                if (config.content) {
                    const normalizer = new clientStateNormalizer();
                    normalizer.fromGoldenLayout(config);

                    res.send(normalizer.normalized);
                } else {
                    res.send(config);
                }
            })
            .catch(err => {
                logger.warn(`Exception thrown when expanding ${id}: `, err);
                next({
                    statusCode: 404,
                    message: `ID "${id}" could not be found`,
                });
            });
    }

    handleLanguages(req, res) {
        const availableLanguages = this.usedLangIds.map(val => {
            let lang = this.languages[val];
            let newLangObj = Object.assign({}, lang);
            if (this.options) {
                newLangObj.defaultCompiler = this.options.options.defaultCompiler[lang.id];
            }
            return newLangObj;
        });

        this.outputList(availableLanguages, 'Id', req, res);
    }

    filterCompilerProperties(list, selectedFields) {
        return _.map(list, (compiler) => {
            const filteredProps = {};
            const allKeys = Object.keys(compiler);

            _.each(selectedFields, (field) => {
                if (allKeys.includes(field)) {
                    filteredProps[field] = compiler[field];
                }
            });

            return filteredProps;
        });
    }

    outputList(list, title, req, res) {
        if (req.accepts(['text', 'json']) === 'json') {
            if (req.query.fields === 'all') {
                res.send(list);
            } else {
                const defaultfields = ['id', 'name', 'lang', 'compilerType', 'semver', 'extensions', 'monaco'];
                if (req.query.fields) {
                    const filteredList = this.filterCompilerProperties(list, req.query.fields.split(','));
                    res.send(filteredList);
                } else {
                    const filteredList = this.filterCompilerProperties(list, defaultfields);
                    res.send(filteredList);
                }
            }
            return;
        }

        const maxLength = _.max(_.pluck(_.pluck(list, 'id').concat([title]), 'length'));
        res.set('Content-Type', 'text/plain');
        res.send(utils.padRight(title, maxLength) + ' | Name\n'
            + list.map(lang => utils.padRight(lang.id, maxLength) + ' | ' + lang.name).join('\n'));
    }

    getLibrariesAsArray(languageId) {
        const libsForLanguageObj = this.options.options.libs[languageId];
        if (!libsForLanguageObj) return [];

        return Object.keys(libsForLanguageObj).map((key) => {
            const language = libsForLanguageObj[key];
            const versionArr = Object.keys(language.versions).map((key) => {
                let versionObj = Object.assign({}, language.versions[key]);
                versionObj.id = key;
                return versionObj;
            });

            return {
                id: key,
                name: language.name,
                description: language.description,
                url: language.url,
                versions: versionArr,
            };
        });
    }

    handleLangLibraries(req, res, next) {
        if (this.options) {
            if (req.params.language) {
                res.send(this.getLibrariesAsArray(req.params.language));
            } else {
                next({
                    statusCode: 404,
                    message: 'Language is required',
                });
            }
        } else {
            next({
                statusCode: 500,
                message: 'Internal error',
            });
        }
    }

    handleAllLibraries(req, res, next) {
        if (this.options) {
            res.send(this.options.options.libs);
        } else {
            next({
                statusCode: 500,
                message: 'Internal error',
            });
        }
    }

    handleCompilers(req, res) {
        let filteredCompilers = this.compilers;
        if (req.params.language) {
            filteredCompilers = this.compilers.filter((val) => val.lang === req.params.language);
        }

        this.outputList(filteredCompilers, 'Compiler Name', req, res);
    }

    setCompilers(compilers) {
        this.compilers = compilers;
        this.usedLangIds = _.uniq(_.pluck(this.compilers, 'lang'));
    }

    setLanguages(languages) {
        this.languages = languages;
    }

    setOptions(options) {
        this.options = options;
    }
}

module.exports.Handler = ApiHandler;
<commit_msg>extra default field to offer more backward compatibility<commit_after>// Copyright (c) 2017, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const express = require('express'),
    _ = require('underscore'),
    AsmDocsApi = require('./asm-docs-api'),
    FormatterHandler = require('./formatting'),
    utils = require('../utils'),
    logger = require('../logger').logger,
    clientStateNormalizer = require('../clientstate-normalizer').ClientStateNormalizer;

class ApiHandler {
    constructor(compileHandler, ceProps, storageHandler) {
        this.compilers = [];
        this.languages = [];
        this.usedLangIds = [];
        this.options = null;
        this.storageHandler = storageHandler;
        this.handle = express.Router();
        const cacheHeader = `public, max-age=${ceProps('apiMaxAgeSecs', 24 * 60 * 60)}`;
        this.handle.use((req, res, next) => {
            res.header(
                {
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
                    'Cache-Control': cacheHeader,
                },
            );
            next();
        });
        this.handle.get('/compilers', this.handleCompilers.bind(this));
        this.handle.get('/compilers/:language', this.handleCompilers.bind(this));
        this.handle.get('/languages', this.handleLanguages.bind(this));
        this.handle.get('/libraries/:language', this.handleLangLibraries.bind(this));
        this.handle.get('/libraries', this.handleAllLibraries.bind(this));

        const asmDocsHandler = new AsmDocsApi.Handler();
        this.handle.get('/asm/:opcode', asmDocsHandler.handle.bind(asmDocsHandler));

        this.handle.post('/compiler/:compiler/compile', compileHandler.handle.bind(compileHandler));
        this.handle.post('/popularArguments/:compiler', compileHandler.handlePopularArguments.bind(compileHandler));
        this.handle.post('/optimizationArguments/:compiler',
            compileHandler.handleOptimizationArguments.bind(compileHandler));

        this.handle.get('/popularArguments/:compiler', compileHandler.handlePopularArguments.bind(compileHandler));
        this.handle.get('/optimizationArguments/:compiler',
            compileHandler.handleOptimizationArguments.bind(compileHandler));

        const formatter = new FormatterHandler(ceProps);
        this.handle.post('/format/:tool', formatter.formatHandler.bind(formatter));
        this.handle.get('/formats', formatter.listHandler.bind(formatter));

        this.handle.get('/shortlinkinfo/:id', this.shortlinkInfoHandler.bind(this));
    }

    shortlinkInfoHandler(req, res, next) {
        const id = req.params.id;
        this.storageHandler.expandId(id)
            .then(result => {
                const config = JSON.parse(result.config);

                if (config.content) {
                    const normalizer = new clientStateNormalizer();
                    normalizer.fromGoldenLayout(config);

                    res.send(normalizer.normalized);
                } else {
                    res.send(config);
                }
            })
            .catch(err => {
                logger.warn(`Exception thrown when expanding ${id}: `, err);
                next({
                    statusCode: 404,
                    message: `ID "${id}" could not be found`,
                });
            });
    }

    handleLanguages(req, res) {
        const availableLanguages = this.usedLangIds.map(val => {
            let lang = this.languages[val];
            let newLangObj = Object.assign({}, lang);
            if (this.options) {
                newLangObj.defaultCompiler = this.options.options.defaultCompiler[lang.id];
            }
            return newLangObj;
        });

        this.outputList(availableLanguages, 'Id', req, res);
    }

    filterCompilerProperties(list, selectedFields) {
        return _.map(list, (compiler) => {
            const filteredProps = {};
            const allKeys = Object.keys(compiler);

            _.each(selectedFields, (field) => {
                if (allKeys.includes(field)) {
                    filteredProps[field] = compiler[field];
                }
            });

            return filteredProps;
        });
    }

    outputList(list, title, req, res) {
        if (req.accepts(['text', 'json']) === 'json') {
            if (req.query.fields === 'all') {
                res.send(list);
            } else {
                const defaultfields = ['id', 'name', 'lang', 'compilerType', 'semver', 'extensions', 'monaco', 'exe'];
                if (req.query.fields) {
                    const filteredList = this.filterCompilerProperties(list, req.query.fields.split(','));
                    res.send(filteredList);
                } else {
                    const filteredList = this.filterCompilerProperties(list, defaultfields);
                    res.send(filteredList);
                }
            }
            return;
        }

        const maxLength = _.max(_.pluck(_.pluck(list, 'id').concat([title]), 'length'));
        res.set('Content-Type', 'text/plain');
        res.send(utils.padRight(title, maxLength) + ' | Name\n'
            + list.map(lang => utils.padRight(lang.id, maxLength) + ' | ' + lang.name).join('\n'));
    }

    getLibrariesAsArray(languageId) {
        const libsForLanguageObj = this.options.options.libs[languageId];
        if (!libsForLanguageObj) return [];

        return Object.keys(libsForLanguageObj).map((key) => {
            const language = libsForLanguageObj[key];
            const versionArr = Object.keys(language.versions).map((key) => {
                let versionObj = Object.assign({}, language.versions[key]);
                versionObj.id = key;
                return versionObj;
            });

            return {
                id: key,
                name: language.name,
                description: language.description,
                url: language.url,
                versions: versionArr,
            };
        });
    }

    handleLangLibraries(req, res, next) {
        if (this.options) {
            if (req.params.language) {
                res.send(this.getLibrariesAsArray(req.params.language));
            } else {
                next({
                    statusCode: 404,
                    message: 'Language is required',
                });
            }
        } else {
            next({
                statusCode: 500,
                message: 'Internal error',
            });
        }
    }

    handleAllLibraries(req, res, next) {
        if (this.options) {
            res.send(this.options.options.libs);
        } else {
            next({
                statusCode: 500,
                message: 'Internal error',
            });
        }
    }

    handleCompilers(req, res) {
        let filteredCompilers = this.compilers;
        if (req.params.language) {
            filteredCompilers = this.compilers.filter((val) => val.lang === req.params.language);
        }

        this.outputList(filteredCompilers, 'Compiler Name', req, res);
    }

    setCompilers(compilers) {
        this.compilers = compilers;
        this.usedLangIds = _.uniq(_.pluck(this.compilers, 'lang'));
    }

    setLanguages(languages) {
        this.languages = languages;
    }

    setOptions(options) {
        this.options = options;
    }
}

module.exports.Handler = ApiHandler;
<|endoftext|>