<commit_before>(function () {

    var IframeWatcher = function (linkId) {
        if (this.istatsCanBeUsed()) {
            this.addIstatsDependency(linkId);
        }
        else {
            this.createIframe(linkId);
        }
        this.updateSizeWhenWindowResizes();
    };

    IframeWatcher.prototype = {
        istatsCanBeUsed: function () {
            return ('require' in window) && this.onBbcDomain();
        },
        addIstatsDependency: function (linkId) {
            var iframeWatcher = this;
            require(['istats-1'], function (istats) {
                iframeWatcher.istats = istats;
                iframeWatcher.createIframe(linkId);
            });
        },
        updateSizeWhenWindowResizes: function () {
            var iframeWatcher = this;
            window.addEventListener('resize', function () {
                iframeWatcher.setDimensions();
            }, false);
        },
        data: {},
        istatsQueue: [],
        updateFrequency: 32,
        createIframe: function (linkId) {

            var link         = document.getElementById(linkId),
                href         = link.href,
                token        = link.parentNode.className,
                staticHeight = link.getAttribute('data-static-iframe-height'),
                iframeWatcher = this,
                hostId        = this.getWindowLocationOrigin(),
                urlParams     = window.location.hash || '',
                onBBC         = this.onBbcDomain();

            if (this.hostIsNewsApp(token)) {
                hostId = token;
            }

            this.elm = document.createElement('iframe');
            this.elm.className = 'responsive-iframe';
            this.elm.style.width = '100%';
            this.elm.scrolling = 'no';
            this.elm.allowfullscreen = true;
            this.elm.frameBorder = '0';

            this.decideHowToTalkToIframe(href);

            this.elm.src = href + '?hostid=' + hostId.split('//')[1] + '&onbbcdomain=' + onBBC + urlParams;

            link.parentNode.appendChild(this.elm);
            link.parentNode.removeChild(link);

            this.lastRecordedHeight = this.elm.height;
            this.iframeInstructionsRan = false;

            this.handleIframeLoad(function startIframing() {
                iframeWatcher.getAnyInstructionsFromIframe();
                iframeWatcher.setDimensions();
            });

        },
        handleIframeLoad: function (startIframing) {
            // IMPORTANT: Had to make this an onload because the
            // polyfilling and jquery on one page causes issues
            window.addEventListener('load', function () {
                startIframing();
            }, true);
            if (this.elm.onload) {
                this.elm.onload = startIframing;
            }
            // Bug in IE7 means onload doesn't fire when an iframe
            // loads, but the event will fire if you attach it correctly
            else if ('attachEvent' in this.elm) {
                this.elm.attachEvent('onload', startIframing);
            }
        },
        decideHowToTalkToIframe: function (href) {
            if (window.postMessage) { // if window.postMessage is supported, then support for JSON is assumed
                var uidForPostMessage = this.getPath(href);
                this.uidForPostMessage = this.getPath(href);
                this.setupPostMessage(uidForPostMessage);
            }
            else if (href.search(window.location.protocol + '//' + window.location.hostname) > -1) {
                this.setupIframeBridge();
            }
            else {
                this.data.height = staticHeight;
                this.elm.scrolling = 'yes';
            }
        },
        onBbcDomain: function () {
            return window.location.host.search('bbc.co') > -1;
        },
        setupPostMessage: function (uid) {
            var iframeWatcher = this;
            window.addEventListener('message', function (e) {
                iframeWatcher.postMessageCallback(e.data);
            }, false);
        },
        postMessageCallback: function (data) {
            if (this.postBackMessageForThisIframe(data)) {
                this.processCommunicationFromIframe(
                    this.getObjectNotationFromDataString(data)
                );
                if (this.istatsInTheData()) {
                    this.addToIstatsQueue();
                    this.emptyThisIstatsQueue(this.istatsQueue);
                }
            }
        },
        postBackMessageForThisIframe: function (data) {
            return data && (data.split('::')[0] === this.uidForPostMessage);
        },
        getObjectNotationFromDataString: function (data) {
            return JSON.parse(data.split('::')[1]);
        },
        istatsInTheData: function () {
            return this.data.istats && this.data.istats.actionType;
        },
        addToIstatsQueue: function () {
            this.istatsQueue.push({
                'actionType': this.data.istats.actionType,
                'actionName': this.data.istats.actionName,
                'viewLabel':  this.data.istats.viewLabel
            });
        },
        setupIframeBridge: function () {
            var iframeWatcher = this;
            window.setInterval(function () {
                iframeWatcher.iFrameBridgeCallback();
            }, iframeWatcher.updateFrequency);
        },
        iFrameBridgeCallback: function () {
            if (this.elm.contentWindow.iframeBridge) {
                this.processCommunicationFromIframe(this.elm.contentWindow.iframeBridge);
                this.emptyThisIstatsQueue(this.elm.contentWindow.istatsQueue);
            }
        },
        processCommunicationFromIframe: function (data) {
            this.data = data;
            this.setDimensions();
            this.getAnyInstructionsFromIframe();
        },
        istatsQueueLocked: false,
        emptyThisIstatsQueue: function (queue) {
            var istatCall;
            if (this.istats && queue) {
                this.istatsQueueLocked = true;
                for (var i = 0, len = queue.length; i < len; i++) {
                    istatCall = queue.pop();
                    this.istats.log(istatCall.actionType, istatCall.actionName, {'view': istatCall.viewLabel});
                }
                this.istatsQueueLocked = false;
            }
        },
        hostIsNewsApp: function (token) {
            return (token.indexOf('bbc_news_app') > -1);
        },
        getIframeContentHeight: function () {
            if (this.data.height) {
                this.lastRecordedHeight = this.data.height;
            }
            return this.lastRecordedHeight;
        },
        setDimensions: function () {
            this.elm.width  = this.elm.parentNode.clientWidth;
            this.elm.height = this.getIframeContentHeight();
        },
        getAnyInstructionsFromIframe: function () {
            if (
                this.data.hostPageCallback &&
                (!this.iframeInstructionsRan)
            ) {
                /* jshint evil:true */
                eval('var func = ' + this.data.hostPageCallback);
                func();
                this.iframeInstructionsRan = true;
            }
        },
        getPath: function (url) {
            var urlMinusProtocol = url.replace('http://', '');
            return urlMinusProtocol.substring(urlMinusProtocol.indexOf('/')).split('?')[0];
        },
        getWindowLocationOrigin: function () {
            if (window.location.origin) {
                return window.location.origin;
            }
            else {
                return window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
            }
        }
    };

    var iframe = new IframeWatcher('<%= iframeUid %>');

})();
<commit_msg>Update iframemanager__host.js<commit_after>(function () {

    var IframeWatcher = function (linkId) {
        if (this.istatsCanBeUsed()) {
            this.addIstatsDependency(linkId);
        }
        else {
            this.createIframe(linkId);
        }
        this.updateSizeWhenWindowResizes();
    };

    IframeWatcher.prototype = {
        istatsCanBeUsed: function () {
            return ('require' in window) && this.onBbcDomain();
        },
        addIstatsDependency: function (linkId) {
            var iframeWatcher = this;
            require(['istats-1'], function (istats) {
                iframeWatcher.istats = istats;
                iframeWatcher.createIframe(linkId);
            });
        },
        updateSizeWhenWindowResizes: function () {
            var iframeWatcher = this;
            window.addEventListener('resize', function () {
                iframeWatcher.setDimensions();
            }, false);
        },
        data: {},
        istatsQueue: [],
        updateFrequency: 32,
        createIframe: function (linkId) {

            var link         = document.getElementById(linkId),
                href         = link.href,
                token        = link.parentNode.className,
                staticHeight = link.getAttribute('data-static-iframe-height'),
                iframeWatcher = this,
                hostId        = this.getWindowLocationOrigin(),
                urlParams     = window.location.hash || '',
                onBBC         = this.onBbcDomain();

            if (this.hostIsNewsApp(token)) {
                hostId = token;
            }

            this.elm = document.createElement('iframe');
            this.elm.className = 'responsive-iframe';
            this.elm.style.width = '100%';
            this.elm.scrolling = 'no';
            this.elm.allowfullscreen = true;
            this.elm.frameBorder = '0';

            this.decideHowToTalkToIframe(href);

            this.elm.src = href + '?hostid=' + hostId.split('//')[1] + '&onbbcdomain=' + onBBC + urlParams;

            link.parentNode.appendChild(this.elm);
            link.parentNode.removeChild(link);

            this.lastRecordedHeight = this.elm.height;
            this.iframeInstructionsRan = false;

            this.handleIframeLoad(function startIframing() {
                iframeWatcher.getAnyInstructionsFromIframe();
                iframeWatcher.setDimensions();
            });

        },
        handleIframeLoad: function (startIframing) {
            // IMPORTANT: Had to make this an onload because the
            // polyfilling and jquery on one page causes issues
            window.addEventListener('load', function () {
                startIframing();
            }, true);
            if (this.elm.onload) {
                this.elm.onload = startIframing;
            }
            // Bug in IE7 means onload doesn't fire when an iframe
            // loads, but the event will fire if you attach it correctly
            else if ('attachEvent' in this.elm) {
                this.elm.attachEvent('onload', startIframing);
            }
        },
        decideHowToTalkToIframe: function (href) {
            if (window.postMessage) { // if window.postMessage is supported, then support for JSON is assumed
                var uidForPostMessage = this.getPath(href);
                this.uidForPostMessage = this.getPath(href);
                this.setupPostMessage(uidForPostMessage);
            }
            else if (href.search(window.location.protocol + '//' + window.location.hostname) > -1) {
                this.setupIframeBridge();
            }
            else {
                this.data.height = staticHeight;
                this.elm.scrolling = 'yes';
            }
        },
        onBbcDomain: function () {
            return window.location.host.search('bbc.co') > -1;
        },
        setupPostMessage: function (uid) {
            var iframeWatcher = this;
            window.addEventListener('message', function (e) {
                iframeWatcher.postMessageCallback(e.data);
            }, false);
        },
        postMessageCallback: function (data) {
            if (this.postBackMessageForThisIframe(data)) {
                this.processCommunicationFromIframe(
                    this.getObjectNotationFromDataString(data)
                );
                if (this.istatsInTheData()) {
                    this.addToIstatsQueue();
                    this.emptyThisIstatsQueue(this.istatsQueue);
                }
            }
        },
        postBackMessageForThisIframe: function (data) {
            return data && (data.split('::')[0] === this.uidForPostMessage);
        },
        getObjectNotationFromDataString: function (data) {
            return JSON.parse(data.split('::')[1]);
        },
        istatsInTheData: function () {
            return this.data.istats && this.data.istats.actionType;
        },
        addToIstatsQueue: function () {
            this.istatsQueue.push({
                'actionType': this.data.istats.actionType,
                'actionName': this.data.istats.actionName,
                'viewLabel':  this.data.istats.viewLabel
            });
        },
        setupIframeBridge: function () {
            var iframeWatcher = this;
            window.setInterval(function () {
                iframeWatcher.iFrameBridgeCallback();
            }, iframeWatcher.updateFrequency);
        },
        iFrameBridgeCallback: function () {
            if (this.elm.contentWindow.iframeBridge) {
                this.processCommunicationFromIframe(this.elm.contentWindow.iframeBridge);
                this.emptyThisIstatsQueue(this.elm.contentWindow.istatsQueue);
            }
        },
        processCommunicationFromIframe: function (data) {
            this.data = data;
            this.setDimensions();
            this.getAnyInstructionsFromIframe();
        },
        istatsQueueLocked: false,
        emptyThisIstatsQueue: function (queue) {
            var istatCall;
            if (this.istats && queue) {
                this.istatsQueueLocked = true;
                for (var i = 0, len = queue.length; i < len; i++) {
                    istatCall = queue.pop();
                    this.istats.log(istatCall.actionType, istatCall.actionName, {'view': istatCall.viewLabel});
                }
                this.istatsQueueLocked = false;
            }
        },
        hostIsNewsApp: function (token) {
            return (token.indexOf('bbc_news_app') > -1);
        },
        getIframeContentHeight: function () {
            if (this.data.height) {
                this.lastRecordedHeight = this.data.height;
            }
            return this.lastRecordedHeight;
        },
        setDimensions: function () {
            this.elm.width  = this.elm.parentNode.clientWidth;
            this.elm.height = this.getIframeContentHeight();
        },
        getAnyInstructionsFromIframe: function () {
            if (
                this.data.hostPageCallback &&
                (!this.iframeInstructionsRan)
            ) {
                this.iframeInstructionsRan = true;
            }
        },
        getPath: function (url) {
            var urlMinusProtocol = url.replace('http://', '');
            return urlMinusProtocol.substring(urlMinusProtocol.indexOf('/')).split('?')[0];
        },
        getWindowLocationOrigin: function () {
            if (window.location.origin) {
                return window.location.origin;
            }
            else {
                return window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
            }
        }
    };

    var iframe = new IframeWatcher('<%= iframeUid %>');

})();
<|endoftext|>


<commit_before>/*
 * Copyright (c)  2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var gatewayPort = location.port -9443 + 8243; //Calculate the port offset based gateway port.
var serverUrl = "https://"+location.hostname +":"+ gatewayPort+"/LogAnalyzerRestApi/1.0";
var client = new AnalyticsClient().init(null, null, serverUrl);
var div = "#tblFilteredMessages";
var from = new Date(moment().subtract(1, 'year')).getTime();
var to = new Date(moment()).getTime();
var dataM = [];
var initState = true;
var filterdMessage;

var meta = {
    "names": ["message", "class", "timestamp", "trace"],
    "types": ["ordinal", "ordinal", "ordinal", "ordinal"]
};

var configTable = {
    key: "timestamp",
    title:"FilteredMessages",
    charts: [{
        type: "table",
        columns: ["message", "class", "timestamp", "trace"],
        columnTitles: ["ERROR Message", "Class", "Event Time Stamp", "Error Trace"]
    }
    ],
    width: $(window).width()* 0.95,
    height: $(window).width() * 0.65 > $(window).height() ? $(window).height() : $(window).width() * 0.65,
    padding: { "top": 100, "left": 30, "bottom": 22, "right": 70 }
};

function initialize() {
    //fetch();
    $(div).html(getDefaultText());
}

function getDefaultText() {
    return '
'+
        '
'+
        '
No content to display
'+
        '
Please select a Log ERROR Message to view details.
'+
        '
'+
        '
';
};

function getEmptyRecordsText() {
    return '
'+
        '
'+
        '
No records found
'+
        '
Please select a date range to view stats.
'+
        '
'+
        '
';
}

$(document).ready(function () {
    initialize();
});

function fetch() {
    dataM.length = 0;
    var queryInfo;
    console.log("FilteredMessagesFetching");
    queryInfo = {
        tableName: "LOGANALYZER_NON_DUPLICATION",
        searchParams: {
            query: "_content: \"" +filterdMessage+"\"",
            start : 0, //starting index of the matching record set
            count : 100 //page size for pagination
        }
    };
    console.log(queryInfo);
    client.search(queryInfo, function (d) {
        var obj = JSON.parse(d["message"]);
        if (d["status"] === "success") {
            for (var i =0; i < obj.length ;i++){
                dataM.push([obj[i].values._content,obj[i].values._class,new Date(obj[i].values._eventTimeStamp).toUTCString(),obj[i].values._trace]);
            }
            drawLogAPIMArtifactTableChart();

        }
    }, function (error) {
        console.log("error occured: " + error);
    });
}

function drawLogAPIMArtifactTableChart() {
    $("#tblFilteredMessages").empty();
    var table = new vizg(
        [
            {
                "metadata": this.meta,
                "data": dataM
            }
        ],
        configTable
    );
    table.draw(div);
    var table2 = $('#FilteredMessages').DataTable();
    $("#tableChart-FilteredMessages > tr").on( "click", function( event ) {
        publish({timestamp : new Date(this.getElementsByClassName("timestamp")[0].textContent).getTime()});
    });
}

function publish (data) {
    gadgets.Hub.publish("publisher2", data);
};

function subscribe(callback) {
    gadgets.HubSettings.onConnect = function () {
        gadgets.Hub.subscribe("subscriber2", function (topic, data, subscriber) {
            callback(topic, data, subscriber)
        });
    };
    console.log("APIM subscribed");
}

subscribe(function (topic, data, subscriber) {
    console.log("Received Data :"+data["selected"]);
    filterdMessage = data["selected"].replace(/\"/g,"\\\"");
    fetch();
});<commit_msg>Update main.js<commit_after>/*
 * Copyright (c)  2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var gatewayPort = location.port -9443 + 8243; //Calculate the port offset based gateway port.
var serverUrl = "https://"+location.hostname +":"+ gatewayPort+"/LogAnalyzerRestApi/1.0";
var client = new AnalyticsClient().init(null, null, serverUrl);
var div = "#tblFilteredMessages";
var from = new Date(moment().subtract(1, 'year')).getTime();
var to = new Date(moment()).getTime();
var dataM = [];
var initState = true;
var filterdMessage;

var meta = {
    "names": ["message", "class", "timestamp", "trace"],
    "types": ["ordinal", "ordinal", "ordinal", "ordinal"]
};

var configTable = {
    key: "timestamp",
    title:"FilteredMessages",
    charts: [{
        type: "table",
        columns: ["message", "class", "timestamp", "trace"],
        columnTitles: ["ERROR Message", "Class", "Event Time Stamp", "Error Trace"]
    }
    ],
    width: $(window).width()* 0.95,
    height: $(window).width() * 0.65 > $(window).height() ? $(window).height() : $(window).width() * 0.65,
    padding: { "top": 100, "left": 30, "bottom": 22, "right": 70 }
};

function initialize() {
    //fetch();
    $(div).html(getDefaultText());
}

function getDefaultText() {
    return '
'+
        '
'+
        '
No content to display
'+
        '
Please select a Log ERROR Message to view details.
'+
        '
'+
        '
';
};

function getEmptyRecordsText() {
    return '
'+
        '
'+
        '
No records found
'+
        '
Please select a date range to view stats.
'+
        '
'+
        '
';
}

$(document).ready(function () {
    initialize();
});

function fetch() {
    dataM.length = 0;
    var queryInfo;
    console.log("FilteredMessagesFetching");
    queryInfo = {
        tableName: "LOGANALYZER",
        searchParams: {
            query: "_content: \"" +filterdMessage+"\"",
            start : 0, //starting index of the matching record set
            count : 100 //page size for pagination
        }
    };
    console.log(queryInfo);
    client.search(queryInfo, function (d) {
        var obj = JSON.parse(d["message"]);
        if (d["status"] === "success") {
            for (var i =0; i < obj.length ;i++){
                dataM.push([obj[i].values._content,obj[i].values._class,new Date(obj[i].values._eventTimeStamp).toUTCString(),obj[i].values._trace]);
            }
            drawLogAPIMArtifactTableChart();

        }
    }, function (error) {
        console.log("error occured: " + error);
    });
}

function drawLogAPIMArtifactTableChart() {
    $("#tblFilteredMessages").empty();
    var table = new vizg(
        [
            {
                "metadata": this.meta,
                "data": dataM
            }
        ],
        configTable
    );
    table.draw(div);
    var table2 = $('#FilteredMessages').DataTable();
    $("#tableChart-FilteredMessages > tr").on( "click", function( event ) {
        publish({timestamp : new Date(this.getElementsByClassName("timestamp")[0].textContent).getTime()});
    });
}

function publish (data) {
    gadgets.Hub.publish("publisher2", data);
};

function subscribe(callback) {
    gadgets.HubSettings.onConnect = function () {
        gadgets.Hub.subscribe("subscriber2", function (topic, data, subscriber) {
            callback(topic, data, subscriber)
        });
    };
    console.log("APIM subscribed");
}

subscribe(function (topic, data, subscriber) {
    console.log("Received Data :"+data["selected"]);
    filterdMessage = data["selected"].replace(/\"/g,"\\\"");
    fetch();
});
<|endoftext|>


<commit_before>.pragma library
var mainbackgroundcolor = "white";
var edgecolor = "lightgrey"
var alternatecolor1 = "lightgrey"
var alternatecolor2 = "white"
var alternatecolor3 = "#F7F9FC"
var selectedColor = "#99CCFF"
var rowHeight = 20
<commit_msg>added color<commit_after>.pragma library
var mainbackgroundcolor = "white";
var edgecolor = "lightgrey"
var alternatecolor1 = "lightgrey"
var alternatecolor2 = "white"
var alternatecolor3 = "#F7F9FC"
var alternatecolor4 = "#eee"
var selectedColor = "#99CCFF"
var rowHeight = 20
<|endoftext|>


<commit_before>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2015-2020 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const Bluebird = require('bluebird');

const kerror = require('../../kerror');
const { get } = require('../../util/safeObject');

const assertionError = kerror.wrap('api', 'assert');

// Base class for all controllers
class BaseController {
  constructor() {
    this.__actions = new Set();
  }

  get _actions() {
    return this.__actions;
  }

  _addAction (name, fn) {
    this.__actions.add(name);
    this[name] = fn;
  }

  /**
   * Check if the provided action name exists within that controller.
   * This check's purpose is to prevent actions leak by making actions exposure
   * explicit.
   *
   * @param  {string} name
   * @returns {boolean}
   */
  _isAction (name) {
    return this.__actions.has(name);
  }
}

class NativeController extends BaseController {
  constructor(actions = []) {
    super();

    this.ask = global.kuzzle.ask.bind(global.kuzzle);
    this.pipe = global.kuzzle.pipe.bind(global.kuzzle);
    this.__actions = new Set(actions);
  }

  /**
   * Controller optional initialization method.
   * Used to perform asynchronous initialization safely: the funnel will wait
   * for all controllers to be initialized before accepting requests.
   *
   * @returns {Promise}
   */
  init () {
    return Bluebird.resolve();
  }

  async translateKoncorde (koncordeFilters) {
    if (Object.keys(koncordeFilters).length === 0) {
      return {};
    }

    if (typeof koncordeFilters !== 'object') {
      throw assertionError.get('invalid_type', 'body.query', 'object');
    }

    try {
      global.kuzzle.koncorde.validate(koncordeFilters);
    }
    catch (error) {
      throw assertionError.getFrom(error, 'koncorde_dsl_error', error.message);
    }

    try {
      return await this.ask('core:storage:public:translate', koncordeFilters);
    }
    catch (error) {
      if (! error.keyword) {
        throw error;
      }

      throw assertionError.get(
        'koncorde_restricted_keyword',
        error.keyword.type,
        error.keyword.name);
    }
  }

  /**
   * Throws if the body contain one of the specified attribute
   *
   * @param {Request} request
   * @param  {...any} paths
   */
  assertBodyHasNotAttributes (request, ...paths) {
    if (request.input.body !== null) {
      for (const path of paths) {
        if (get(request.input.body, path)) {
          throw assertionError.get('forbidden_argument', `body.${path}`);
        }
      }
    }
  }

  /**
   * Throws if the strategy does not exists
   *
   * @todo move this method in some kind of "Security" class
   * @param {String} strategy
   */
  assertIsStrategyRegistered (strategy) {
    if (! global.kuzzle.pluginsManager.listStrategies().includes(strategy)) {
      throw kerror.get('security', 'credentials', 'unknown_strategy', strategy);
    }
  }

  /**
   * Throw if some target have:
   * - missing properties
   * - invalid types
   * - unauthorized values
   *
   * @param {Array<{index:string, collections?: string[]}>} targets Array of targets
   * @param {*} options
   */
  assertAreTargetsValid(targets, { emptyCollectionsAllowed } = {}) {
    for (let i = 0; i < targets.length; i++) {
      const target = targets[i];

      if (!target.index) {
        throw kerror.get('api', 'assert', 'missing_argument', `targets[${i}].index`);
      }
      if (this._hasMultiTargets(target.index)) {
        throw kerror.get('services', 'storage', 'invalid_target_format', `targets[${i}].index`, target.index);
      }

      if (!emptyCollectionsAllowed && !target.collections) {
        throw kerror.get('api', 'assert', 'missing_argument', `targets[${i}].collections`);
      }

      if (target.collections && !Array.isArray(target.collections)) {
        throw kerror.get('api', 'assert', 'invalid_type', `targets[${i}].collections`, 'array');
      }

      if (!emptyCollectionsAllowed && target.collections.length === 0) {
        throw kerror.get('api', 'assert', 'empty_argument', `targets[${i}].collections`);
      }

      for (let j = 0; j < target.collections.length; j++) {
        const collection = target.collections[j];

        if (typeof collection !== 'string') {
          throw kerror.get('api', 'assert', 'invalid_type', `targets[${i}].collections[${j}]`, 'string');
        }

        if (this._hasMultiTargets(collection)) {
          throw kerror.get('services', 'storage', 'invalid_target_format', `targets[${i}].collections[${j}]`, collection);
        }
      }
    }
  }

  _hasMultiTargets (str) {
    return [',', '*', '+'].some(chr => str.includes(chr)) || str === '_all';
  }

  /**
   * Throws if page size exceeed Kuzzle limits
   *
   * @param {Number} asked
   * @throws
   */
  assertNotExceedMaxFetch (asked) {
    const limit = global.kuzzle.config.limits.documentsFetchCount;

    if (asked > limit) {
      throw kerror.get('services', 'storage', 'get_limit_exceeded');
    }
  }

  /**
   * Throws if number of documents exceeed Kuzzle limits
   *
   * @param {Number} asked
   * @throws
   */
  assertNotExceedMaxWrite (asked) {
    const limit = global.kuzzle.config.limits.documentsWriteCount;

    if (asked > limit) {
      throw kerror.get('services', 'storage', 'write_limit_exceeded');
    }
  }
}

module.exports = { BaseController, NativeController };
<commit_msg>fix wrong behaviour when asserting targets are valid<commit_after>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2015-2020 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const Bluebird = require('bluebird');

const kerror = require('../../kerror');
const { get } = require('../../util/safeObject');

const assertionError = kerror.wrap('api', 'assert');

// Base class for all controllers
class BaseController {
  constructor() {
    this.__actions = new Set();
  }

  get _actions() {
    return this.__actions;
  }

  _addAction (name, fn) {
    this.__actions.add(name);
    this[name] = fn;
  }

  /**
   * Check if the provided action name exists within that controller.
   * This check's purpose is to prevent actions leak by making actions exposure
   * explicit.
   *
   * @param  {string} name
   * @returns {boolean}
   */
  _isAction (name) {
    return this.__actions.has(name);
  }
}

class NativeController extends BaseController {
  constructor(actions = []) {
    super();

    this.ask = global.kuzzle.ask.bind(global.kuzzle);
    this.pipe = global.kuzzle.pipe.bind(global.kuzzle);
    this.__actions = new Set(actions);
  }

  /**
   * Controller optional initialization method.
   * Used to perform asynchronous initialization safely: the funnel will wait
   * for all controllers to be initialized before accepting requests.
   *
   * @returns {Promise}
   */
  init () {
    return Bluebird.resolve();
  }

  async translateKoncorde (koncordeFilters) {
    if (Object.keys(koncordeFilters).length === 0) {
      return {};
    }

    if (typeof koncordeFilters !== 'object') {
      throw assertionError.get('invalid_type', 'body.query', 'object');
    }

    try {
      global.kuzzle.koncorde.validate(koncordeFilters);
    }
    catch (error) {
      throw assertionError.getFrom(error, 'koncorde_dsl_error', error.message);
    }

    try {
      return await this.ask('core:storage:public:translate', koncordeFilters);
    }
    catch (error) {
      if (! error.keyword) {
        throw error;
      }

      throw assertionError.get(
        'koncorde_restricted_keyword',
        error.keyword.type,
        error.keyword.name);
    }
  }

  /**
   * Throws if the body contain one of the specified attribute
   *
   * @param {Request} request
   * @param  {...any} paths
   */
  assertBodyHasNotAttributes (request, ...paths) {
    if (request.input.body !== null) {
      for (const path of paths) {
        if (get(request.input.body, path)) {
          throw assertionError.get('forbidden_argument', `body.${path}`);
        }
      }
    }
  }

  /**
   * Throws if the strategy does not exists
   *
   * @todo move this method in some kind of "Security" class
   * @param {String} strategy
   */
  assertIsStrategyRegistered (strategy) {
    if (! global.kuzzle.pluginsManager.listStrategies().includes(strategy)) {
      throw kerror.get('security', 'credentials', 'unknown_strategy', strategy);
    }
  }

  /**
   * Throw if some target have:
   * - missing properties
   * - invalid types
   * - unauthorized values
   *
   * @param {Array<{index:string, collections?: string[]}>} targets Array of targets
   * @param {*} options
   */
  assertAreTargetsValid(targets, { emptyCollectionsAllowed } = {}) {
    for (let i = 0; i < targets.length; i++) {
      const target = targets[i];

      if (!target.index) {
        throw kerror.get('api', 'assert', 'missing_argument', `targets[${i}].index`);
      }
      if (this._hasMultiTargets(target.index)) {
        throw kerror.get('services', 'storage', 'invalid_target_format', `targets[${i}].index`, target.index);
      }

      if (!emptyCollectionsAllowed && !target.collections) {
        throw kerror.get('api', 'assert', 'missing_argument', `targets[${i}].collections`);
      }

      if (target.collections && !Array.isArray(target.collections)) {
        throw kerror.get('api', 'assert', 'invalid_type', `targets[${i}].collections`, 'array');
      }

      if (!emptyCollectionsAllowed && target.collections.length === 0) {
        throw kerror.get('api', 'assert', 'empty_argument', `targets[${i}].collections`);
      }

      if (emptyCollectionsAllowed && !target.collections || target.collections.length === 0) {
        continue;
      }

      for (let j = 0; j < target.collections.length; j++) {
        const collection = target.collections[j];

        if (typeof collection !== 'string') {
          throw kerror.get('api', 'assert', 'invalid_type', `targets[${i}].collections[${j}]`, 'string');
        }

        if (this._hasMultiTargets(collection)) {
          throw kerror.get('services', 'storage', 'invalid_target_format', `targets[${i}].collections[${j}]`, collection);
        }
      }
    }
  }

  _hasMultiTargets (str) {
    return [',', '*', '+'].some(chr => str.includes(chr)) || str === '_all';
  }

  /**
   * Throws if page size exceeed Kuzzle limits
   *
   * @param {Number} asked
   * @throws
   */
  assertNotExceedMaxFetch (asked) {
    const limit = global.kuzzle.config.limits.documentsFetchCount;

    if (asked > limit) {
      throw kerror.get('services', 'storage', 'get_limit_exceeded');
    }
  }

  /**
   * Throws if number of documents exceeed Kuzzle limits
   *
   * @param {Number} asked
   * @throws
   */
  assertNotExceedMaxWrite (asked) {
    const limit = global.kuzzle.config.limits.documentsWriteCount;

    if (asked > limit) {
      throw kerror.get('services', 'storage', 'write_limit_exceeded');
    }
  }
}

module.exports = { BaseController, NativeController };
<|endoftext|>


<commit_before>/**
 * The Document List class
 * (on the client side)
 *
 * @constructor
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.3
 *
 * @param    {Object}   record   A record containing the main & related data
 * @param    {Object}   options
 */
var DocumentList = Function.inherits(['Alchemy.Client.Base', 'Array'], 'Alchemy.Client', function DocumentList(records, options) {

	if (records == null) {
		records = [];
	}

	// Store the options
	this.options = options || {};

	// Add all the entries to this instance
	Object.assign(this, records);

	// Also keep a reference to the original array
	this.records = records;

	// Store the amount of records there are
	this.length = records.length;
});

/**
 * unDry an object
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @param    {Object}   obj
 *
 * @return   {Hawkejs.DocumentList}
 */
DocumentList.setStatic(function unDry(obj) {
	var result = new this(obj.records, obj.options);
	return result;
});

/**
 * Iterator method
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.1.0
 * @version  1.1.0
 */
DocumentList.setMethod(Symbol.iterator, function* iterate() {

	var i;

	for (i = 0; i < this.records.length; i++) {
		yield this.records[i];
	}
});

/**
 * Return an object for json-drying this list
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @return   {Object}
 */
DocumentList.setMethod(function toDry() {
	return {
		value: {
			options    : this.options,
			records    : this.records
		}
	};
});

/**
 * Simplify the object for Hawkejs
 *
 * @author   Jelle De Loecker <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @param    {WeakMap}   wm
 *
 * @return   {Object}
 */
DocumentList.setMethod(function toHawkejs(wm) {

	var records,
	    result;

	records = JSON.clone(this.records, 'toHawkejs', wm);

	result = new Blast.Classes.Alchemy.Client.DocumentList(records);

	return result;
});

/**
 * Return a new array with the records
 *
 * @author   Jelle De Loecker <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.3
 *
 * @param    {Array|Object}
 *
 * @return   {Array}
 */
DocumentList.setMethod(function toArray(options) {

	if (!options) {
		return this.records.slice(0);
	}

	return this.toSimpleArray(options);
});

/**
 * Return a simple list of the main data
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.3
 * @version  1.0.3
 *
 * @param    {Array|Object}   options
 *
 * @return   {Array}
 */
DocumentList.setMethod(function toSimpleArray(options) {

	var result = [],
	    entry,
	    field,
	    temp,
	    i,
	    j;

	if (Array.isArray(options)) {
		options = {
			fields: options
		};
	}

	for (i = 0; i < this.length; i++) {
		entry = this[i];
		temp = {};

		if (options.fields) {
			for (j = 0; j < options.fields.length; j++) {
				field = options.fields[j];

				temp[field] = entry[field];
			}

			result.push(temp);
		} else {
			result.push(entry.$main)
		}
	}

	return result;
});<commit_msg>Add DocumentList#createIterator() method<commit_after>/**
 * The Document List class
 * (on the client side)
 *
 * @constructor
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.3
 *
 * @param    {Object}   record   A record containing the main & related data
 * @param    {Object}   options
 */
var DocumentList = Function.inherits(['Alchemy.Client.Base', 'Array'], 'Alchemy.Client', function DocumentList(records, options) {

	if (records == null) {
		records = [];
	}

	// Store the options
	this.options = options || {};

	// Add all the entries to this instance
	Object.assign(this, records);

	// Also keep a reference to the original array
	this.records = records;

	// Store the amount of records there are
	this.length = records.length;
});

/**
 * unDry an object
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @param    {Object}   obj
 *
 * @return   {Hawkejs.DocumentList}
 */
DocumentList.setStatic(function unDry(obj) {
	var result = new this(obj.records, obj.options);
	return result;
});

/**
 * Iterator method
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.1.0
 * @version  1.1.0
 */
DocumentList.setMethod(Symbol.iterator, function* iterate() {

	var i;

	for (i = 0; i < this.records.length; i++) {
		yield this.records[i];
	}
});

/**
 * Create an old-style iterator
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.1.0
 * @version  1.1.0
 *
 * @return   {Iterator}
 */
DocumentList.setMethod(function createIterator() {
	return new Blast.Classes.Iterator(this.records);
});

/**
 * Return an object for json-drying this list
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @return   {Object}
 */
DocumentList.setMethod(function toDry() {
	return {
		value: {
			options    : this.options,
			records    : this.records
		}
	};
});

/**
 * Simplify the object for Hawkejs
 *
 * @author   Jelle De Loecker <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.0
 *
 * @param    {WeakMap}   wm
 *
 * @return   {Object}
 */
DocumentList.setMethod(function toHawkejs(wm) {

	var records,
	    result;

	records = JSON.clone(this.records, 'toHawkejs', wm);

	result = new Blast.Classes.Alchemy.Client.DocumentList(records);

	return result;
});

/**
 * Return a new array with the records
 *
 * @author   Jelle De Loecker <jelle@develry.be>
 * @since    1.0.0
 * @version  1.0.3
 *
 * @param    {Array|Object}
 *
 * @return   {Array}
 */
DocumentList.setMethod(function toArray(options) {

	if (!options) {
		return this.records.slice(0);
	}

	return this.toSimpleArray(options);
});

/**
 * Return a simple list of the main data
 *
 * @author   Jelle De Loecker   <jelle@develry.be>
 * @since    1.0.3
 * @version  1.0.3
 *
 * @param    {Array|Object}   options
 *
 * @return   {Array}
 */
DocumentList.setMethod(function toSimpleArray(options) {

	var result = [],
	    entry,
	    field,
	    temp,
	    i,
	    j;

	if (Array.isArray(options)) {
		options = {
			fields: options
		};
	}

	for (i = 0; i < this.length; i++) {
		entry = this[i];
		temp = {};

		if (options.fields) {
			for (j = 0; j < options.fields.length; j++) {
				field = options.fields[j];

				temp[field] = entry[field];
			}

			result.push(temp);
		} else {
			result.push(entry.$main)
		}
	}

	return result;
});<|endoftext|>


<commit_before>/**
 * @name tinto.ComponentAssertion
 * @kind class
 * @augments tinto.Assertion
 */

/**
 * @name tinto.ComponentAssertion#be
 * @type {tinto.StateAssertion}
 */

/**
 * @name tinto.ComponentAssertion#have
 * @type {tinto.PropertyAssertion}
 */

/**
 * @name tinto.ComponentAssertion#have
 * @kind function
 * @param {Number} count
 * @returns {tinto.PropertyAssertion}
 */
<commit_msg>improved documentation<commit_after>/**
 * @name tinto.ComponentAssertion
 * @kind class
 * @augments tinto.Assertion
 */

/**
 * @name tinto.ComponentAssertion#be
 * @type {tinto.StateAssertion}
 */

/**
 * @name tinto.ComponentAssertion#have
 * @type {tinto.PropertyAssertion}
 */

/**
 * @name tinto.ComponentAssertion#have
 * @kind function
 * @param {Number} count
 * @returns {tinto.CountAssertion}
 */
<|endoftext|>


<commit_before>var powerSaveBlocker

powerSaveBlocker = process.atomBinding('power_save_blocker').powerSaveBlocker

module.exports = powerSaveBlocker
<commit_msg>:lipstick: Make the power-save-blocker a bit more concise<commit_after>module.exports = process.atomBinding('power_save_blocker').powerSaveBlocker
<|endoftext|>


<commit_before>const cors = require('../middleware/cors');
const user = require('../middleware/user');
const locals = require('../middleware/locals');
const cleanUpQueryParams = require('../middleware/clean-up-query-params');
const layergroupToken = require('../middleware/layergroup-token');
const credentials = require('../middleware/credentials');
const dbConnSetup = require('../middleware/db-conn-setup');
const authorize = require('../middleware/authorize');
const cacheControlHeader = require('../middleware/cache-control-header');
const cacheChannelHeader = require('../middleware/cache-channel-header');
const surrogateKeyHeader = require('../middleware/surrogate-key-header');
const lastModifiedHeader = require('../middleware/last-modified-header');
const sendResponse = require('../middleware/send-response');
const vectorError = require('../middleware/vector-error');
const rateLimit = require('../middleware/rate-limit');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit;

const DEFAULT_ZOOM_CENTER = {
    zoom: 1,
    center: {
        lng: 0,
        lat: 0
    }
};

function numMapper(n) {
    return +n;
}

function getRequestParams(locals) {
    const params = Object.assign({}, locals);

    delete params.template;
    delete params.affectedTables;
    delete params.mapConfigProvider;
    delete params.allowedQueryParams;

    return params;
}

function NamedMapsController (
    namedMapProviderCache,
    tileBackend,
    previewBackend,
    surrogateKeysCache,
    tablesExtentApi,
    metadataBackend,
    pgConnection,
    authApi,
    userLimitsApi
) {
    this.namedMapProviderCache = namedMapProviderCache;
    this.tileBackend = tileBackend;
    this.previewBackend = previewBackend;
    this.surrogateKeysCache = surrogateKeysCache;
    this.tablesExtentApi = tablesExtentApi;
    this.metadataBackend = metadataBackend;
    this.pgConnection = pgConnection;
    this.authApi = authApi;
    this.userLimitsApi = userLimitsApi;
}

module.exports = NamedMapsController;

NamedMapsController.prototype.register = function(app) {
    const { base_url_mapconfig: mapconfigBasePath, base_url_templated: templateBasePath } = app;

    app.get(
        `${templateBasePath}/:template_id/:layer/:z/:x/:y.(:format)`,
        cors(),
        cleanUpQueryParams(),
        locals(),
        user(),
        rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_TILES),
        layergroupToken(),
        credentials(),
        authorize(this.authApi),
        dbConnSetup(this.pgConnection),
        getNamedMapProvider({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'NAMED_MAP_TILE'
        }),
        getTile({
            tileBackend: this.tileBackend,
            label: 'NAMED_MAP_TILE'
        }),
        setContentTypeHeader(),
        cacheControlHeader(),
        cacheChannelHeader(),
        surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
        lastModifiedHeader(),
        sendResponse(),
        vectorError()
    );

    app.get(
        `${mapconfigBasePath}/static/named/:template_id/:width/:height.:format`,
        cors(),
        cleanUpQueryParams(['layer', 'zoom', 'lon', 'lat', 'bbox']),
        locals(),
        user(),
        rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.STATIC_NAMED),
        layergroupToken(),
        credentials(),
        authorize(this.authApi),
        dbConnSetup(this.pgConnection),
        getNamedMapProvider({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'STATIC_VIZ_MAP', forcedFormat: 'png'
        }),
        getTemplate({ label: 'STATIC_VIZ_MAP' }),
        prepareLayerFilterFromPreviewLayers({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'STATIC_VIZ_MAP'
        }),
        getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }),
        getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }),
        setContentTypeHeader(),
        incrementMapViews({ metadataBackend: this.metadataBackend }),
        cacheControlHeader(),
        cacheChannelHeader(),
        surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
        lastModifiedHeader(),
        sendResponse()
    );
};

function getNamedMapProvider ({ namedMapProviderCache, label, forcedFormat = null }) {
    return function getNamedMapProviderMiddleware (req, res, next) {
        const { user, token, cache_buster, api_key } = res.locals;
        const { dbuser, dbname, dbpassword, dbhost, dbport } = res.locals;
        const { template_id, layer, z, x, y, format } = req.params;

        const params = {
            user, token, cache_buster, api_key,
            dbuser, dbname, dbpassword, dbhost, dbport,
            template_id, layer, z, x, y, format
        };

        if (forcedFormat) {
            params.format = forcedFormat;
            params.layer = params.layer || 'all';
        }

        const { config, auth_token } = req.query;

        namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, namedMapProvider) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.mapConfigProvider = namedMapProvider;

            next();
        });
    };
}

function getTemplate ({ label }) {
    return function getTemplateMiddleware (req, res, next) {
        const { mapConfigProvider } = res.locals;

        mapConfigProvider.getTemplate((err, template) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.template = template;

            next();
        });
    };
}

function prepareLayerFilterFromPreviewLayers ({ namedMapProviderCache, label }) {
    return function prepareLayerFilterFromPreviewLayersMiddleware (req, res, next) {
        const { user, template } = res.locals;
        const { template_id } = req.params;
        const { config, auth_token } = req.query;

        if (!template || !template.view || !template.view.preview_layers) {
            return next();
        }

        var previewLayers = template.view.preview_layers;
        var layerVisibilityFilter = [];

        template.layergroup.layers.forEach((layer, index) => {
            if (previewLayers[''+index] !== false && previewLayers[layer.id] !== false) {
                layerVisibilityFilter.push(''+index);
            }
        });

        if (!layerVisibilityFilter.length) {
            return next();
        }

        const params = getRequestParams(res.locals);

        // overwrites 'all' default filter
        params.layer = layerVisibilityFilter.join(',');

        // recreates the provider
        namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, provider) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.mapConfigProvider = provider;

            next();
        });
    };
}

function getTile ({ tileBackend, label }) {
    return function getTileMiddleware (req, res, next) {
        const { mapConfigProvider, format } = res.locals;

        tileBackend.getTile(mapConfigProvider, req.params, (err, tile, headers, stats) => {
            req.profiler.add(stats);
            req.profiler.done('render-' + format);

            if (err) {
                err.label = label;
                return next(err);
            }

            if (headers) {
                res.set(headers);
            }

            res.body = tile;

            next();
        });
    };
}

function getStaticImageOptions ({ tablesExtentApi }) {
    return function getStaticImageOptionsMiddleware(req, res, next) {
        const { user, mapConfigProvider, template } = res.locals;

        const imageOpts = getImageOptions(res.locals, template);

        if (imageOpts) {
            res.locals.imageOpts = imageOpts;
            return next();
        }

        res.locals.imageOpts = DEFAULT_ZOOM_CENTER;

        mapConfigProvider.getAffectedTables((err, affectedTables) => {
            if (err) {
                return next();
            }

            var tables = affectedTables.tables || [];

            if (tables.length === 0) {
                return next();
            }

            tablesExtentApi.getBounds(user, tables, (err, bounds) => {
                if (err) {
                    return next();
                }

                res.locals.imageOpts = bounds;

                return next();
            });
        });
    };
}

function getImageOptions (params, template) {
    const { zoom, lon, lat, bbox } = params;

    let imageOpts = getImageOptionsFromCoordinates(zoom, lon, lat);
    if (imageOpts) {
        return imageOpts;
    }

    imageOpts = getImageOptionsFromBoundingBox(bbox);
    if (imageOpts) {
        return imageOpts;
    }

    imageOpts = getImageOptionsFromTemplate(template, zoom);
    if (imageOpts) {
        return imageOpts;
    }
}

function getImageOptionsFromCoordinates (zoom, lon, lat) {
    if ([zoom, lon, lat].map(numMapper).every(Number.isFinite)) {
        return {
            zoom: zoom,
            center: {
                lng: lon,
                lat: lat
            }
        };
    }
}

function getImageOptionsFromTemplate (template, zoom) {
    if (template.view) {
        var zoomCenter = templateZoomCenter(template.view);
        if (zoomCenter) {
            if (Number.isFinite(+zoom)) {
                zoomCenter.zoom = +zoom;
            }

            return zoomCenter;
        }

        var bounds = templateBounds(template.view);
        if (bounds) {
            return bounds;
        }
    }
}

function getImageOptionsFromBoundingBox (bbox = '') {
    var _bbox = bbox.split(',').map(numMapper);

    if (_bbox.length === 4 && _bbox.every(Number.isFinite)) {
        return {
            bounds: {
                west: _bbox[0],
                south: _bbox[1],
                east: _bbox[2],
                north: _bbox[3]
            }
        };
    }
}

function getImage({ previewBackend, label }) {
    return function getImageMiddleware (req, res, next) {
        const { imageOpts, mapConfigProvider } = res.locals;
        const { zoom, center, bounds } = imageOpts;

        let { width, height } = req.params;

        width = +width;
        height = +height;

        const format = req.params.format === 'jpg' ? 'jpeg' : 'png';

        if (zoom !== undefined && center) {
            return previewBackend.getImage(mapConfigProvider, format, width, height, zoom, center,
                (err, image, headers, stats) => {
                req.profiler.add(stats);

                if (err) {
                    err.label = label;
                    return next(err);
                }

                if (headers) {
                    res.set(headers);
                }

                res.body = image;

                next();
            });
        }

        previewBackend.getImage(mapConfigProvider, format, width, height, bounds, (err, image, headers, stats) => {
            req.profiler.add(stats);
            req.profiler.done('render-' + format);

            if (err) {
                err.label = label;
                return next(err);
            }

            if (headers) {
                res.set(headers);
            }

            res.body = image;

            next();
        });
    };
}

function setContentTypeHeader () {
    return function setContentTypeHeaderMiddleware(req, res, next) {
        res.set('Content-Type', res.get('content-type') || res.get('Content-Type') || 'image/png');

        next();
    };
}

function incrementMapViewsError (ctx) {
    return `ERROR: failed to increment mapview count for user '${ctx.user}': ${ctx.err}`;
}

function incrementMapViews ({ metadataBackend }) {
    return function incrementMapViewsMiddleware(req, res, next) {
        const { user, mapConfigProvider } = res.locals;

        mapConfigProvider.getMapConfig((err, mapConfig) => {
            if (err) {
                global.logger.log(incrementMapViewsError({ user, err }));
                return next();
            }

            const statTag = mapConfig.obj().stat_tag;

            metadataBackend.incMapviewCount(user, statTag, (err) => {
                if (err) {
                    global.logger.log(incrementMapViewsError({ user, err }));
                }

                next();
            });
        });
    };
}

function templateZoomCenter(view) {
    if (view.zoom !== undefined && view.center) {
        return {
            zoom: view.zoom,
            center: view.center
        };
    }
    return false;
}

function templateBounds(view) {
    if (view.bounds) {
        var hasAllBounds = ['west', 'south', 'east', 'north'].every(prop => Number.isFinite(view.bounds[prop]));

        if (hasAllBounds) {
            return {
                bounds: {
                    west: view.bounds.west,
                    south: view.bounds.south,
                    east: view.bounds.east,
                    north: view.bounds.north
                }
            };
        } else {
            return false;
        }
    }
    return false;
}
<commit_msg>Pass only needed properties to named map provider cache (static endpoint)<commit_after>const cors = require('../middleware/cors');
const user = require('../middleware/user');
const locals = require('../middleware/locals');
const cleanUpQueryParams = require('../middleware/clean-up-query-params');
const layergroupToken = require('../middleware/layergroup-token');
const credentials = require('../middleware/credentials');
const dbConnSetup = require('../middleware/db-conn-setup');
const authorize = require('../middleware/authorize');
const cacheControlHeader = require('../middleware/cache-control-header');
const cacheChannelHeader = require('../middleware/cache-channel-header');
const surrogateKeyHeader = require('../middleware/surrogate-key-header');
const lastModifiedHeader = require('../middleware/last-modified-header');
const sendResponse = require('../middleware/send-response');
const vectorError = require('../middleware/vector-error');
const rateLimit = require('../middleware/rate-limit');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit;

const DEFAULT_ZOOM_CENTER = {
    zoom: 1,
    center: {
        lng: 0,
        lat: 0
    }
};

function numMapper(n) {
    return +n;
}

function getRequestParams(locals) {
    const params = Object.assign({}, locals);

    delete params.template;
    delete params.affectedTables;
    delete params.mapConfigProvider;
    delete params.allowedQueryParams;

    return params;
}

function NamedMapsController (
    namedMapProviderCache,
    tileBackend,
    previewBackend,
    surrogateKeysCache,
    tablesExtentApi,
    metadataBackend,
    pgConnection,
    authApi,
    userLimitsApi
) {
    this.namedMapProviderCache = namedMapProviderCache;
    this.tileBackend = tileBackend;
    this.previewBackend = previewBackend;
    this.surrogateKeysCache = surrogateKeysCache;
    this.tablesExtentApi = tablesExtentApi;
    this.metadataBackend = metadataBackend;
    this.pgConnection = pgConnection;
    this.authApi = authApi;
    this.userLimitsApi = userLimitsApi;
}

module.exports = NamedMapsController;

NamedMapsController.prototype.register = function(app) {
    const { base_url_mapconfig: mapconfigBasePath, base_url_templated: templateBasePath } = app;

    app.get(
        `${templateBasePath}/:template_id/:layer/:z/:x/:y.(:format)`,
        cors(),
        cleanUpQueryParams(),
        locals(),
        user(),
        rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_TILES),
        layergroupToken(),
        credentials(),
        authorize(this.authApi),
        dbConnSetup(this.pgConnection),
        getNamedMapProvider({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'NAMED_MAP_TILE'
        }),
        getTile({
            tileBackend: this.tileBackend,
            label: 'NAMED_MAP_TILE'
        }),
        setContentTypeHeader(),
        cacheControlHeader(),
        cacheChannelHeader(),
        surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
        lastModifiedHeader(),
        sendResponse(),
        vectorError()
    );

    app.get(
        `${mapconfigBasePath}/static/named/:template_id/:width/:height.:format`,
        cors(),
        cleanUpQueryParams(['layer', 'zoom', 'lon', 'lat', 'bbox']),
        locals(),
        user(),
        rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.STATIC_NAMED),
        layergroupToken(),
        credentials(),
        authorize(this.authApi),
        dbConnSetup(this.pgConnection),
        getNamedMapProvider({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'STATIC_VIZ_MAP', forcedFormat: 'png'
        }),
        getTemplate({ label: 'STATIC_VIZ_MAP' }),
        prepareLayerFilterFromPreviewLayers({
            namedMapProviderCache: this.namedMapProviderCache,
            label: 'STATIC_VIZ_MAP'
        }),
        getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }),
        getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }),
        setContentTypeHeader(),
        incrementMapViews({ metadataBackend: this.metadataBackend }),
        cacheControlHeader(),
        cacheChannelHeader(),
        surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
        lastModifiedHeader(),
        sendResponse()
    );
};

function getNamedMapProvider ({ namedMapProviderCache, label, forcedFormat = null }) {
    return function getNamedMapProviderMiddleware (req, res, next) {
        const { user, token, cache_buster, api_key } = res.locals;
        const { dbuser, dbname, dbpassword, dbhost, dbport } = res.locals;
        const { template_id, layer, z, x, y, format } = req.params;

        const params = {
            user, token, cache_buster, api_key,
            dbuser, dbname, dbpassword, dbhost, dbport,
            template_id, layer, z, x, y, format
        };

        if (forcedFormat) {
            params.format = forcedFormat;
            params.layer = params.layer || 'all';
        }

        const { config, auth_token } = req.query;

        namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, namedMapProvider) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.mapConfigProvider = namedMapProvider;

            next();
        });
    };
}

function getTemplate ({ label }) {
    return function getTemplateMiddleware (req, res, next) {
        const { mapConfigProvider } = res.locals;

        mapConfigProvider.getTemplate((err, template) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.template = template;

            next();
        });
    };
}

function prepareLayerFilterFromPreviewLayers ({ namedMapProviderCache, label }) {
    return function prepareLayerFilterFromPreviewLayersMiddleware (req, res, next) {
        const { template } = res.locals;
        const { config, auth_token } = req.query;

        if (!template || !template.view || !template.view.preview_layers) {
            return next();
        }

        var previewLayers = template.view.preview_layers;
        var layerVisibilityFilter = [];

        template.layergroup.layers.forEach((layer, index) => {
            if (previewLayers[''+index] !== false && previewLayers[layer.id] !== false) {
                layerVisibilityFilter.push(''+index);
            }
        });

        if (!layerVisibilityFilter.length) {
            return next();
        }

        const { user, token, cache_buster, api_key } = res.locals;
        const { dbuser, dbname, dbpassword, dbhost, dbport } = res.locals;
        const { template_id, format } = req.params;

        const params = {
            user, token, cache_buster, api_key,
            dbuser, dbname, dbpassword, dbhost, dbport,
            template_id, format
        };

        // overwrites 'all' default filter
        params.layer = layerVisibilityFilter.join(',');

        // recreates the provider
        namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, provider) => {
            if (err) {
                err.label = label;
                return next(err);
            }

            res.locals.mapConfigProvider = provider;

            next();
        });
    };
}

function getTile ({ tileBackend, label }) {
    return function getTileMiddleware (req, res, next) {
        const { mapConfigProvider, format } = res.locals;

        tileBackend.getTile(mapConfigProvider, req.params, (err, tile, headers, stats) => {
            req.profiler.add(stats);
            req.profiler.done('render-' + format);

            if (err) {
                err.label = label;
                return next(err);
            }

            if (headers) {
                res.set(headers);
            }

            res.body = tile;

            next();
        });
    };
}

function getStaticImageOptions ({ tablesExtentApi }) {
    return function getStaticImageOptionsMiddleware(req, res, next) {
        const { user, mapConfigProvider, template } = res.locals;

        const imageOpts = getImageOptions(res.locals, template);

        if (imageOpts) {
            res.locals.imageOpts = imageOpts;
            return next();
        }

        res.locals.imageOpts = DEFAULT_ZOOM_CENTER;

        mapConfigProvider.getAffectedTables((err, affectedTables) => {
            if (err) {
                return next();
            }

            var tables = affectedTables.tables || [];

            if (tables.length === 0) {
                return next();
            }

            tablesExtentApi.getBounds(user, tables, (err, bounds) => {
                if (err) {
                    return next();
                }

                res.locals.imageOpts = bounds;

                return next();
            });
        });
    };
}

function getImageOptions (params, template) {
    const { zoom, lon, lat, bbox } = params;

    let imageOpts = getImageOptionsFromCoordinates(zoom, lon, lat);
    if (imageOpts) {
        return imageOpts;
    }

    imageOpts = getImageOptionsFromBoundingBox(bbox);
    if (imageOpts) {
        return imageOpts;
    }

    imageOpts = getImageOptionsFromTemplate(template, zoom);
    if (imageOpts) {
        return imageOpts;
    }
}

function getImageOptionsFromCoordinates (zoom, lon, lat) {
    if ([zoom, lon, lat].map(numMapper).every(Number.isFinite)) {
        return {
            zoom: zoom,
            center: {
                lng: lon,
                lat: lat
            }
        };
    }
}

function getImageOptionsFromTemplate (template, zoom) {
    if (template.view) {
        var zoomCenter = templateZoomCenter(template.view);
        if (zoomCenter) {
            if (Number.isFinite(+zoom)) {
                zoomCenter.zoom = +zoom;
            }

            return zoomCenter;
        }

        var bounds = templateBounds(template.view);
        if (bounds) {
            return bounds;
        }
    }
}

function getImageOptionsFromBoundingBox (bbox = '') {
    var _bbox = bbox.split(',').map(numMapper);

    if (_bbox.length === 4 && _bbox.every(Number.isFinite)) {
        return {
            bounds: {
                west: _bbox[0],
                south: _bbox[1],
                east: _bbox[2],
                north: _bbox[3]
            }
        };
    }
}

function getImage({ previewBackend, label }) {
    return function getImageMiddleware (req, res, next) {
        const { imageOpts, mapConfigProvider } = res.locals;
        const { zoom, center, bounds } = imageOpts;

        let { width, height } = req.params;

        width = +width;
        height = +height;

        const format = req.params.format === 'jpg' ? 'jpeg' : 'png';

        if (zoom !== undefined && center) {
            return previewBackend.getImage(mapConfigProvider, format, width, height, zoom, center,
                (err, image, headers, stats) => {
                req.profiler.add(stats);

                if (err) {
                    err.label = label;
                    return next(err);
                }

                if (headers) {
                    res.set(headers);
                }

                res.body = image;

                next();
            });
        }

        previewBackend.getImage(mapConfigProvider, format, width, height, bounds, (err, image, headers, stats) => {
            req.profiler.add(stats);
            req.profiler.done('render-' + format);

            if (err) {
                err.label = label;
                return next(err);
            }

            if (headers) {
                res.set(headers);
            }

            res.body = image;

            next();
        });
    };
}

function setContentTypeHeader () {
    return function setContentTypeHeaderMiddleware(req, res, next) {
        res.set('Content-Type', res.get('content-type') || res.get('Content-Type') || 'image/png');

        next();
    };
}

function incrementMapViewsError (ctx) {
    return `ERROR: failed to increment mapview count for user '${ctx.user}': ${ctx.err}`;
}

function incrementMapViews ({ metadataBackend }) {
    return function incrementMapViewsMiddleware(req, res, next) {
        const { user, mapConfigProvider } = res.locals;

        mapConfigProvider.getMapConfig((err, mapConfig) => {
            if (err) {
                global.logger.log(incrementMapViewsError({ user, err }));
                return next();
            }

            const statTag = mapConfig.obj().stat_tag;

            metadataBackend.incMapviewCount(user, statTag, (err) => {
                if (err) {
                    global.logger.log(incrementMapViewsError({ user, err }));
                }

                next();
            });
        });
    };
}

function templateZoomCenter(view) {
    if (view.zoom !== undefined && view.center) {
        return {
            zoom: view.zoom,
            center: view.center
        };
    }
    return false;
}

function templateBounds(view) {
    if (view.bounds) {
        var hasAllBounds = ['west', 'south', 'east', 'north'].every(prop => Number.isFinite(view.bounds[prop]));

        if (hasAllBounds) {
            return {
                bounds: {
                    west: view.bounds.west,
                    south: view.bounds.south,
                    east: view.bounds.east,
                    north: view.bounds.north
                }
            };
        } else {
            return false;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>import lonlat from '@conveyal/lonlat'
import React, { Component, PropTypes } from 'react'
import { FormGroup } from 'react-bootstrap'
import { connect } from 'react-redux'
import Geocoder from 'react-select-geocoder'

import { setLocation, clearLocation } from '../../actions/map'

class LocationField extends Component {

  static propTypes = {
    location: PropTypes.object,
    label: PropTypes.string,
    setLocation: PropTypes.func,
    type: PropTypes.string // replace with locationType?
  }
  constructor (props) {
    super(props)
    this.state = {}
  }
  _onChange = (value, option) => {
    console.log(value, option)
    if (value && value.geometry) {
      let location = lonlat.fromCoordinates(value.geometry.coordinates)
      location.name = value.properties.label
      this.props.setLocation(this.props.type, location)
    } else if (value.feature) {
      //TODO: remove temp fix required for handling r-s-g geolocated option
      let location = lonlat.fromCoordinates(value.feature.geometry.coordinates)
      location.name = value.feature.properties.label
      this.props.setLocation(this.props.type, location)
    } else {
      this.props.clearLocation(this.props.type)
    }
  }
  _toValue = (location) => {
    return location && {
      value: `${location.lon},${location.lat}`,
      label: location.name
    }
  }
  render () {
    const { config, location } = this.props
    // TODO: add geolocation (in react-select-geocoder?)
    return (
      <form>
        <FormGroup>
          <Geocoder
            apiKey={config.geocoder.MAPZEN_KEY}
            boundary={config.geocoder.boundary}
            placeholder={this.props.label || this.props.type}
            focusPoint={[config.map.initLon, config.map.initLat]}
            value={this._toValue(location)}
            onChange={this._onChange}
            geolocate
            // optionRenderer={location === null ? (option) => <Icon type={option.icon} /> {option.label} : undefined}
            />
        </FormGroup>
      </form>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    config: state.otp.config,
    location: state.otp.currentQuery[ownProps.type]
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    setLocation: (type, location) => { dispatch(setLocation({ type, location })) },
    clearLocation: (type) => { dispatch(clearLocation({ type })) }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(LocationField)
<commit_msg>missing space<commit_after>import lonlat from '@conveyal/lonlat'
import React, { Component, PropTypes } from 'react'
import { FormGroup } from 'react-bootstrap'
import { connect } from 'react-redux'
import Geocoder from 'react-select-geocoder'

import { setLocation, clearLocation } from '../../actions/map'

class LocationField extends Component {

  static propTypes = {
    location: PropTypes.object,
    label: PropTypes.string,
    setLocation: PropTypes.func,
    type: PropTypes.string // replace with locationType?
  }
  constructor (props) {
    super(props)
    this.state = {}
  }
  _onChange = (value, option) => {
    console.log(value, option)
    if (value && value.geometry) {
      let location = lonlat.fromCoordinates(value.geometry.coordinates)
      location.name = value.properties.label
      this.props.setLocation(this.props.type, location)
    } else if (value.feature) {
      // TODO: remove temp fix required for handling r-s-g geolocated option
      let location = lonlat.fromCoordinates(value.feature.geometry.coordinates)
      location.name = value.feature.properties.label
      this.props.setLocation(this.props.type, location)
    } else {
      this.props.clearLocation(this.props.type)
    }
  }
  _toValue = (location) => {
    return location && {
      value: `${location.lon},${location.lat}`,
      label: location.name
    }
  }
  render () {
    const { config, location } = this.props
    // TODO: add geolocation (in react-select-geocoder?)
    return (
      <form>
        <FormGroup>
          <Geocoder
            apiKey={config.geocoder.MAPZEN_KEY}
            boundary={config.geocoder.boundary}
            placeholder={this.props.label || this.props.type}
            focusPoint={[config.map.initLon, config.map.initLat]}
            value={this._toValue(location)}
            onChange={this._onChange}
            geolocate
            // optionRenderer={location === null ? (option) => <Icon type={option.icon} /> {option.label} : undefined}
            />
        </FormGroup>
      </form>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    config: state.otp.config,
    location: state.otp.currentQuery[ownProps.type]
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    setLocation: (type, location) => { dispatch(setLocation({ type, location })) },
    clearLocation: (type) => { dispatch(clearLocation({ type })) }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(LocationField)
<|endoftext|>


<commit_before>var TOPIC = "subscriber";
var timeFrom;
var timeTo;
var timeUnit = null;
var page = gadgetUtil.getCurrentPage();
var qs = gadgetUtil.getQueryString();
var oTable;

$(function() {
    if (qs[PARAM_ID] == null) {
        $("#canvas").html(gadgetUtil.getDefaultText());
        return;
    }
    timeFrom = gadgetUtil.timeFrom();
    timeTo = gadgetUtil.timeTo();
    console.log("MESSAGE_TABLE[" + page.name + "]: TimeFrom: " + timeFrom + " TimeTo: " + timeTo);

    oTable = $('#tblMessages').DataTable({
        dom: '<"dataTablesTop"' +
             'f' +
             '<"dataTables_toolbar">' +
             '>' +
             'rt' +
             '<"dataTablesBottom"' +
             'lip' +
             '>',
        "processing": true,
        "serverSide": true,
        "columns" : [
                    { title: "Message ID" },
                    { title: "Host" },
                    { title: "Start Time" },
                    { title: "Status" }
        ],
        "ajax": {
            "url" : CONTEXT,
            "data" :  {
               "id" : qs.id,
               "type" : page.type,
               "timeFrom" : timeFrom,
               "timeTo" : timeTo,
               "entryPoint" : qs.entryPoint
           }
        }
    });

    $('#tblMessages').on('click', 'tr', function() {
        var id = $(this).find("td:first").html();
        if ($(this).hasClass('selected')) {
            $(this).removeClass('selected');
        } else {
            oTable.$('tr.selected').removeClass('selected');
            $(this).addClass('selected');
        }
        if( timeUnit == null) {
            timeUnit = qs.timeUnit;
        }
        // var targetUrl = MESSAGE_PAGE_URL + "?" + PARAM_ID + "=" + id + "&timeFrom=" + timeFrom + "&timeTo=" + timeTo + "&timeUnit=" + timeUnit;;
        var targetUrl = MESSAGE_PAGE_URL + "?" + PARAM_ID + "=" + id;
        parent.window.location = targetUrl;
    });

});

gadgets.HubSettings.onConnect = function() {
    gadgets.Hub.subscribe(TOPIC, function(topic, data, subscriberData) {
        onTimeRangeChanged(data);
    });
};

function onTimeRangeChanged(data) {
    timeFrom = data.timeFrom;
    timeTo = data.timeTo;
    timeUnit = data.timeUnit;

    oTable.clear().draw();
    //oTable.ajax.reload().draw();
};

function onData(response) {
    try {
        var data = response.message;
        console.log(data.length);
        if (data.length <= 0) {
            $("#canvas").html(gadgetUtil.getEmptyRecordsText());
            return;
        }
        $("#tblMessages thead tr").empty();
        $("#tblMessages tbody").empty();
        var columns = page.columns;
        var thead = $("#tblMessages thead tr");
        columns.forEach(function(column) {
            var th = jQuery('<th/>');
            th.append(column.label);
            th.appendTo(thead);
        });

        var tbody = $("#tblMessages tbody");
        data.forEach(function(row, i) {
            var tr = jQuery('<tr/>');
            columns.forEach(function(column) {
                var td = jQuery('<td/>');
                var value = row[column.name];
                td.text(value);
                td.appendTo(tr);

            });
            tr.appendTo(tbody);

        });

        dataTable = $('#tblMessages').DataTable({
            dom: '<"dataTablesTop"' +
                'f' +
                '<"dataTables_toolbar">' +
                '>' +
                'rt' +
                '<"dataTablesBottom"' +
                'lip' +
                '>'
        });
    } catch (e) {
        $("#canvas").html(gadgetUtil.getErrorText(e));
    }
};

function onError(msg) {
    $("#canvas").html(gadgetUtil.getErrorText(msg));
};<commit_msg>Fixing Message_Table's time range not updated issue<commit_after>var TOPIC = "subscriber";
var timeFrom;
var timeTo;
var timeUnit = null;
var page = gadgetUtil.getCurrentPage();
var qs = gadgetUtil.getQueryString();
var oTable;

$(function() {
    if (qs[PARAM_ID] == null) {
        $("#canvas").html(gadgetUtil.getDefaultText());
        return;
    }
    timeFrom = gadgetUtil.timeFrom();
    timeTo = gadgetUtil.timeTo();
    console.log("MESSAGE_TABLE[" + page.name + "]: TimeFrom: " + timeFrom + " TimeTo: " + timeTo);

    oTable = $('#tblMessages').DataTable({
        dom: '<"dataTablesTop"' +
             'f' +
             '<"dataTables_toolbar">' +
             '>' +
             'rt' +
             '<"dataTablesBottom"' +
             'lip' +
             '>',
        "processing": true,
        "serverSide": true,
        "columns" : [
                    { title: "Message ID" },
                    { title: "Host" },
                    { title: "Start Time" },
                    { title: "Status" }
        ],
        "ajax": {
            "url" : CONTEXT,
            "data" : function (d) {
                d.id = qs.id;
                d.type = page.type;
                d.timeFrom = timeFrom;
                d.timeTo = timeTo;
                d.entryPoint = qs.entryPoint;
            }
        }
    });

    $('#tblMessages').on('click', 'tr', function() {
        var id = $(this).find("td:first").html();
        if ($(this).hasClass('selected')) {
            $(this).removeClass('selected');
        } else {
            oTable.$('tr.selected').removeClass('selected');
            $(this).addClass('selected');
        }
        if( timeUnit == null) {
            timeUnit = qs.timeUnit;
        }
        // var targetUrl = MESSAGE_PAGE_URL + "?" + PARAM_ID + "=" + id + "&timeFrom=" + timeFrom + "&timeTo=" + timeTo + "&timeUnit=" + timeUnit;;
        var targetUrl = MESSAGE_PAGE_URL + "?" + PARAM_ID + "=" + id;
        parent.window.location = targetUrl;
    });

});

gadgets.HubSettings.onConnect = function() {
    gadgets.Hub.subscribe(TOPIC, function(topic, data, subscriberData) {
        onTimeRangeChanged(data);
    });
};

function onTimeRangeChanged(data) {
    timeFrom = data.timeFrom;
    timeTo = data.timeTo;
    timeUnit = data.timeUnit;

    oTable.clear().draw();
    var data = {
        "foo": "bar"
    };
    oTable.ajax.data(data);
    oTable.ajax.reload().draw();
};

function onData(response) {
    try {
        var data = response.message;
        console.log(data.length);
        if (data.length <= 0) {
            $("#canvas").html(gadgetUtil.getEmptyRecordsText());
            return;
        }
        $("#tblMessages thead tr").empty();
        $("#tblMessages tbody").empty();
        var columns = page.columns;
        var thead = $("#tblMessages thead tr");
        columns.forEach(function(column) {
            var th = jQuery('<th/>');
            th.append(column.label);
            th.appendTo(thead);
        });

        var tbody = $("#tblMessages tbody");
        data.forEach(function(row, i) {
            var tr = jQuery('<tr/>');
            columns.forEach(function(column) {
                var td = jQuery('<td/>');
                var value = row[column.name];
                td.text(value);
                td.appendTo(tr);

            });
            tr.appendTo(tbody);

        });

        dataTable = $('#tblMessages').DataTable({
            dom: '<"dataTablesTop"' +
                'f' +
                '<"dataTables_toolbar">' +
                '>' +
                'rt' +
                '<"dataTablesBottom"' +
                'lip' +
                '>'
        });
    } catch (e) {
        $("#canvas").html(gadgetUtil.getErrorText(e));
    }
};

function onError(msg) {
    $("#canvas").html(gadgetUtil.getErrorText(msg));
};<|endoftext|>


<commit_before>/**
 * Created by Ray on 14.3.27.
 */
var currentLocation = new google.maps.LatLng(54.696164, 25.277769);
var idleCenter = new google.maps.LatLng(54.68901487769897, 25.227699279785);
var map;
var waypoints = new Array();
var waypointlim = 8;
var waypointlinreached = false;
var elemAvailableTrips = $("");
var elemRoutePlanner = $("");

function Initialise() {
    var mapElement = document.getElementById("map-canvas");

    var mapOptions = {
        center: idleCenter,
        zoom: 13,
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
            position: google.maps.ControlPosition.BOTTOM_CENTER
        },
        pancontrol: true,
        panControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        zoomControl: true,
        zoomControlOptions: {
            style: google.maps.ZoomControlStyle.LARGE,
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        scaleControl: true,
        scaleControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        streetViewControl: true,
        streetViewControlOptions: {
            position: google.maps.ControlPosition.RIGHT_CONTROL
        }
    };

    map = new google.maps.Map(mapElement, mapOptions);

    google.maps.event.addListener(map, 'rightclick', function (event) {
        console.log('Current waypoints elements:' + waypoints.length);
        if (waypoints.length == 0) {
            startRoutePlan();
        }
        addWaypoint(event);
    });
    function startRoutePlan() {
        hideAvailableTrips();
        showRoutePlanner();
    }

    function finishRoutePlan() {
        hideRoutePlanner();
        showAvailableTrips();
        waypoints.length = 0;
    }
}
function addWaypoint(event) {
    if (!(waypoints.length > waypointlim)) {
        var waypoint = new google.maps.Marker({
            animation: google.maps.Animation.DROP,
            position: event.latLng,
            map: map
        });
        waypoints.push(waypoint);
    } else {
    }
};
function hideAvailableTrips() {
    console.log('trying to hide available trips');
}
function showAvailableTrips() {
    console.log('trying to show available trips');
}
function showRoutePlanner() {
    console.log('trying to show routePlanner');
    //Add event listeners like added marker or something
    //Initialise variables
    //Initialise form
}
function hideRoutePlanner() {
    console.log('trying to hide route planner');
    //Remove event listeners
    //Clear form variables
    //Hide form
    //recenter the map
    map.panTo(idleCenter);
}
google.maps.event.addDomListener(window, 'load', Initialise);
<commit_msg>Updated map javascript now responds properly to waypoints and draws a route right<commit_after>/**
 * Created by Ray on 14.3.27.
 */
var currentLocation = new google.maps.LatLng(54.696164, 25.277769);
var idleCenter = new google.maps.LatLng(54.68901487769897, 25.227699279785);
var map;
var waypoints = new Array();
var waypointlim = 8;

var routeWaypoints = new Array();

var elemAvailableTrips = $("");
var elemRoutePlanner = $("");

function Initialise() {
    directionsService = new google.maps.DirectionsService();
    directionsDisplay = new google.maps.DirectionsRenderer({
        'draggable':true,
        'markerOptions':{
            animation: google.maps.Animation.DROP,
            flat:false,
            raiseOnDrag:true
        },
        'polylineOptions':{
            editable:false,
            draggable:false,
            clickable:false,
            strokeColor:'#736AFF',
            strokeWeight:5,
            strokeOpacity:0.9
        },
        'preserveViewport': true,
    });

    var mapElement = document.getElementById("map-canvas");

    var mapOptions = {
        center: idleCenter,
        zoom: 13,
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
            position: google.maps.ControlPosition.BOTTOM_CENTER
        },
        pancontrol: true,
        panControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        zoomControl: true,
        zoomControlOptions: {
            style: google.maps.ZoomControlStyle.LARGE,
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        scaleControl: true,
        scaleControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        },
        streetViewControl: true,
        streetViewControlOptions: {
            position: google.maps.ControlPosition.RIGHT_CONTROL
        }
    };

    map = new google.maps.Map(mapElement, mapOptions);
    directionsDisplay.setMap(map);

    google.maps.event.addListener(map, 'click', function (event) {
        if (waypoints.length == 0) {
            startRoutePlan();
        }
        addWaypoint(event);
        plotRoute();
    });
    function startRoutePlan() {
        hideAvailableTrips();
        showRoutePlanner();
    }

    function finishRoutePlan() {
        hideRoutePlanner();
        showAvailableTrips();
        waypoints.length = 0;
    }
}
function addWaypoint(event) {
    if (!(waypoints.length > waypointlim)) {
        var waypoint = new google.maps.Marker({
            animation: google.maps.Animation.DROP,
            position: event.latLng,
            map: map
        });
        waypoints.push(waypoint);
    } else {
    }
};

function plotRoute(){
    var routeOrigin = currentLocation;
    var routeDestinationWaypoint = waypoints[waypoints.length-1];

    var routeDestination = routeDestinationWaypoint.getPosition();

    var routeWaypoints =[];

    if (waypoints.length > 1){
        for (var i = 0,n = waypoints.length;i<n;i++){
            routeWaypoints[i] = {location:waypoints[i].getPosition(),
                                stopover:true}
        }
        routeWaypoints.pop();
    }
    console.log(routeWaypoints);

    var request = {
        origin: routeOrigin,
        destination: routeDestination,
        travelMode: google.maps.TravelMode.DRIVING,
        waypoints:routeWaypoints,
        //provideRouteAlternatives: Boolean,
        region: 'lt'
    };

    directionsService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
        }
    });
};

function hideAvailableTrips() {
}
function showAvailableTrips() {
}
function showRoutePlanner() {
    //Add event listeners like added marker or something
    //Initialise variables
    //Initialise form
}
function hideRoutePlanner() {
    //Remove event listeners
    //Clear form variables
    //Hide form
    //recenter the map
}
google.maps.event.addDomListener(window, 'load', Initialise);
<|endoftext|>