<commit_before>/* global sauce, jQuery */

(function() {
    'use strict';

    self.sauce = self.sauce || {};

    sauce.propDefined = function(propertyAccessor, callback, options) {
        options = options || {};
        return new Promise(resolve => {
            function catchDefine(obj, props) {
                function onSet(value) {
                    if (props.length > 1) {
                        if (Object.isExtensible(value)) {
                            catchDefine(value, props.slice(1));
                        }
                    } else {
                        if (callback) {
                            callback(value);
                        }
                        resolve(value);
                    }
                }
                const prop = props[0];
                const existing = Object.getOwnPropertyDescriptor(obj, prop);
                if (existing && existing.set && existing.set.listeners) {
                    existing.set.listeners.push(onSet);
                    console.assert(existing.set.listeners.length < 1000);
                } else {
                    let internalValue = existing ? existing.value : undefined;
                    const set = function(value) {
                        if (Object.is(internalValue, value)) {
                            return;
                        }
                        internalValue = value;
                        for (const fn of set.listeners) {
                            fn(value);
                        }
                    };
                    set.listeners = [onSet];
                    Object.defineProperty(obj, prop, {
                        enumerable: true,
                        get: () => internalValue,
                        set
                    });
                    if (existing) {
                        for (const fn of set.listeners) {
                            fn(internalValue);
                        }
                    }
                }
            }
            catchDefine(options.root || self, propertyAccessor.split('.'));
        });
    };

    if (!sauce.testing) {
        sauce.propDefined('pageView', view => {
            const addCustomRoutes = view.addCustomRoutes;
            view.addCustomRoutes = menuRouter => {
                addCustomRoutes.call(view, menuRouter);
                // Fix for reload hang on /analysis page
                if (!('route:analysis' in menuRouter._events)) {
                    menuRouter.addRoute('/analysis', 'analysis');
                    menuRouter.on('route:analysis', () => {
                        view.handleAnalysisClicked();
                        view.menuView.handleRouteChange('analysis');
                    });
                }
            };
            if (!document.querySelector('#pagenav li [data-menu="analysis"]')) {
                // Create stub element for analysis menu, but hide it until analysis
                // can do the right thing with it.  It needs to exist early so initial
                // routes can set classes on this element.
                const pageNav = document.querySelector('#pagenav');
                // Some indoor workouts for non-premium members don't have pageNav (ie. peleton)
                if (pageNav) {
                    const li = document.createElement('li');
                    li.style.display = 'none';
                    li.classList.add('sauce-stub');
                    li.innerHTML = `<a data-menu="analysis"></a>`;
                    const overview = pageNav.querySelector('[data-menu="overview"]').closest('li');
                    pageNav.insertBefore(li, overview.nextSibling);
                }
            }
        });

        sauce.propDefined('Strava.Charts.Activities.BasicAnalysisElevation', Klass => {
            // Monkey patch analysis views so we can react to selection changes.
            const saveFn = Klass.prototype.displayDetails;
            Klass.prototype.displayDetails = function(start, end) {
                start = start === undefined ? start : Number(start);
                end = end === undefined ? end : Number(end);
                if (sauce.analysis) {
                    sauce.analysis.schedUpdateAnalysisStats(start, end);
                } else {
                    sauce.analysisStatsIntent = {start, end};
                }
                return saveFn.apply(this, arguments);
            };
        });

        sauce.propDefined('Strava.Charts.Activities.LabelBox', Klass => {
            // This is called when zoom selections change or are unset in the profile graph.
            const saveFn = Klass.prototype.handleStreamHover;
            Klass.prototype.handleStreamHover = function(_, start, end) {
                start = start === undefined ? start : Number(start);
                end = end === undefined ? end : Number(end);
                if (sauce.analysis) {
                    sauce.analysis.schedUpdateAnalysisStats(start, end);
                } else {
                    sauce.analysisStatsIntent = {start, end};
                }
                return saveFn.apply(this, arguments);
            };
        });

        sauce.propDefined('Strava.Labs.Activities.BasicAnalysisView', Klass => {
            // Monkey patch the analysis view so we always have our hook for extra stats.
            const saveFn = Klass.prototype.renderTemplate;
            Klass.prototype.renderTemplate = function() {
                const $el = saveFn.apply(this, arguments);
                if (sauce.analysis) {
                    sauce.analysis.attachAnalysisStats($el);
                } else {
                    sauce.analysisStatsIntent = {start: undefined, end: undefined};
                }
                return $el;
            };
        });

        /* Patch dragging bug when scrolled in this old jquery ui code.
         * NOTE: We must use Promise.then instead of a callback because the
         * draggable widget isn't fully baked when it's first defined.  The
         * promise resolution won't execute until the assignment is completed.
         */
        sauce.propDefined('jQuery.ui.draggable').then(draggable => {
            const $ = jQuery;
            jQuery.widget('ui.draggable', draggable, {
                _convertPositionTo: function(d, pos) {
                    pos = pos || this.position;
                    const mod = d === "absolute" ? 1 : -1;
                    const useOffsetParent = this.cssPosition === "absolute" &&
                        (this.scrollParent[0] === this.document[0] || !$.contains(this.scrollParent[0], this.offsetParent[0]));
                    const scroll = useOffsetParent ? this.offsetParent : this.scrollParent;
                    const scrollIsRootNode = useOffsetParent && (/(html|body)/i).test(scroll[0].nodeName);
                    if (!this.offset.scroll) {
                        this.offset.scroll = {top: scroll.scrollTop(), left: scroll.scrollLeft()};
                    }
                    const scrollTop = mod * this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollTop() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.top);
                    const scrollLeft = mod * this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollLeft() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.left);
                    return {
                        top: pos.top + this.offset.relative.top * mod + this.offset.parent.top * mod - scrollTop,
                        left: pos.left + this.offset.relative.left * mod + this.offset.parent.left * mod - scrollLeft
                    };
                },
                _generatePosition: function(ev) {
                    let top;
                    let left;
                    const useOffsetParent = this.cssPosition === "absolute" &&
                        (this.scrollParent[0] === this.document[0] || !$.contains(this.scrollParent[0], this.offsetParent[0]));
                    const scroll = useOffsetParent ? this.offsetParent : this.scrollParent;
                    const scrollIsRootNode = useOffsetParent && (/(html|body)/i).test(scroll[0].nodeName);
                    let pageX = ev.pageX;
                    let pageY = ev.pageY;
                    if (!this.offset.scroll) {
                        this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
                    }
                    if (this.originalPosition) {
                        let containment;
                        if (this.containment) {
                            if (this.relative_container){
                                const co = this.relative_container.offset();
                                containment = [
                                    this.containment[0] + co.left,
                                    this.containment[1] + co.top,
                                    this.containment[2] + co.left,
                                    this.containment[3] + co.top
                                ];
                            } else {
                                containment = this.containment;
                            }
                            if(ev.pageX - this.offset.click.left < containment[0]) {
                                pageX = containment[0] + this.offset.click.left;
                            }
                            if(ev.pageY - this.offset.click.top < containment[1]) {
                                pageY = containment[1] + this.offset.click.top;
                            }
                            if(ev.pageX - this.offset.click.left > containment[2]) {
                                pageX = containment[2] + this.offset.click.left;
                            }
                            if(ev.pageY - this.offset.click.top > containment[3]) {
                                pageY = containment[3] + this.offset.click.top;
                            }
                        }
                        const o = this.options;
                        if (o.grid) {
                            top = o.grid[1] ?
                                this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] :
                                this.originalPageY;
                            pageY = containment ?
                                ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ?
                                    top :
                                    ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) :
                                top;
                            left = o.grid[0] ?
                                this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] :
                                this.originalPageX;
                            pageX = containment ?
                                ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ?
                                    left :
                                    ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) :
                                left;
                        }
                    }
                    const scrollTop = this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollTop() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.top);
                    const scrollLeft = this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollLeft() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.left);
                    return {
                        top: pageY - this.offset.click.top - this.offset.relative.top - this.offset.parent.top + scrollTop,
                        left: pageX - this.offset.click.left - this.offset.relative.left - this.offset.parent.left + scrollLeft
                    };
                }
            });
        });

        // Allow html titles and icons for dialogs.
        sauce.propDefined('jQuery.ui.dialog').then(dialog => {
            jQuery.widget('ui.dialog', dialog, {
                _title: function(title) {
                    if (!this.options.title) {
                        title.html(' ');
                    } else {
                        title.replaceWith(`

${this.options.title}

${this.options.icon || ''}

                        `);
                    }
                }
            });
        });

        // Allow html titles and icons for dialogs.
        let _SegmentEffortsTableView;
        sauce.propDefined('Strava.Labs.Activities.SegmentEffortsTableView', View => {
            // Our reassignment will cause a recursive loop without a short circuit.
            if (!_SegmentEffortsTableView) {
                _SegmentEffortsTableView = function(_, options) {
                    const activity = options.context.chartContext.activity().clone();
                    if (activity.isRun() && sauce.options && sauce.options['analysis-detailed-run-segments']) {
                        activity.set('type', 'Ride');
                        options.context.chartContext.activity(activity);
                    }
                    View.prototype.constructor.apply(this, arguments);
                };
                _SegmentEffortsTableView.prototype = View.prototype;
                self.Strava.Labs.Activities.SegmentEffortsTableView = _SegmentEffortsTableView;
            }
        });

        sauce.propDefined('Strava.Labs.Activities.SegmentsView', View => {
            const initSave = View.prototype.initialize;
            View.prototype.initialize = function(pageView) {
                if (pageView.isRun() && sauce.options && sauce.options['analysis-detailed-run-segments']) {
                    pageView = Object.create(pageView);
                    pageView.activity(pageView.activity().clone());
                    pageView.activity().set('type', 'Ride');
                }
                return initSave.call(this, pageView);
            };

            const renderSave = View.prototype.render;
            View.prototype.render = function() {
                renderSave.apply(this, arguments);
                if (self.pageView.isRun() && this.pageView.isRide() && sauce.options &&
                    sauce.options['analysis-detailed-run-segments']) {
                    this.$el.prepend(`

`);
                }
                return this;
            };
        });

        // Provide race-free detection of pending requests.
        sauce.propDefined('Strava.Labs.Activities.StreamsRequest', Model => {
            const requireSave = Model.prototype.require;
            Model.prototype.require = function() {
                if (!this.pending) {
                    this.pending = new Promise(resolve => {
                        this.deferred.always(() => {
                            this.pending = false;
                            resolve();
                        });
                    });
                }
                return requireSave.apply(this, arguments);
            };
        });
    }
})();
<commit_msg>Buf fixes for propDefined<commit_after>/* global sauce, jQuery */

(function() {
    'use strict';

    self.sauce = self.sauce || {};

    sauce.propDefined = function(propertyAccessor, callback, options) {
        options = options || {};
        return new Promise(resolve => {
            function catchDefine(obj, props) {
                function onSet(value) {
                    if (props.length > 1) {
                        if (Object.isExtensible(value)) {
                            catchDefine(value, props.slice(1));
                        }
                    } else {
                        if (callback) {
                            callback(value);
                        }
                        resolve(value);
                    }
                }
                const prop = props[0];
                const propDesc = Object.getOwnPropertyDescriptor(obj, prop);
                if (propDesc && propDesc.set && propDesc.set.listeners) {
                    propDesc.set.listeners.push(onSet);
                    console.assert(propDesc.set.listeners.length < 1000);
                } else {
                    let internalValue = propDesc ? propDesc.value : undefined;
                    const set = function(value) {
                        if (Object.is(internalValue, value)) {
                            return;
                        }
                        internalValue = value;
                        for (const fn of set.listeners) {
                            fn(value);
                        }
                    };
                    set.listeners = [onSet];
                    Object.defineProperty(obj, prop, {
                        enumerable: true,
                        get: () => internalValue,
                        set
                    });
                }
                const curValue = obj[prop];
                if (curValue !== undefined) {  // Not stoaked on this test.
                    const listeners = propDesc && propDesc.set && propDesc.set.listeners ?
                        propDesc.set.listeners :
                        Object.getOwnPropertyDescriptor(obj, prop).set.listeners;
                    for (const fn of listeners) {
                        fn(curValue);
                    }
                }
            }
            catchDefine(options.root || self, propertyAccessor.split('.'));
        });
    };

    if (!sauce.testing) {
        sauce.propDefined('pageView', view => {
            const addCustomRoutes = view.addCustomRoutes;
            view.addCustomRoutes = menuRouter => {
                addCustomRoutes.call(view, menuRouter);
                // Fix for reload hang on /analysis page
                if (!('route:analysis' in menuRouter._events)) {
                    menuRouter.addRoute('/analysis', 'analysis');
                    menuRouter.on('route:analysis', () => {
                        view.handleAnalysisClicked();
                        view.menuView.handleRouteChange('analysis');
                    });
                }
            };
            if (!document.querySelector('#pagenav li [data-menu="analysis"]')) {
                // Create stub element for analysis menu, but hide it until analysis
                // can do the right thing with it.  It needs to exist early so initial
                // routes can set classes on this element.
                const pageNav = document.querySelector('#pagenav');
                // Some indoor workouts for non-premium members don't have pageNav (ie. peleton)
                if (pageNav) {
                    const li = document.createElement('li');
                    li.style.display = 'none';
                    li.classList.add('sauce-stub');
                    li.innerHTML = `<a data-menu="analysis"></a>`;
                    const overview = pageNav.querySelector('[data-menu="overview"]').closest('li');
                    pageNav.insertBefore(li, overview.nextSibling);
                }
            }
        });

        sauce.propDefined('Strava.Charts.Activities.BasicAnalysisElevation', Klass => {
            // Monkey patch analysis views so we can react to selection changes.
            const saveFn = Klass.prototype.displayDetails;
            Klass.prototype.displayDetails = function(start, end) {
                start = start === undefined ? start : Number(start);
                end = end === undefined ? end : Number(end);
                if (sauce.analysis) {
                    sauce.analysis.schedUpdateAnalysisStats(start, end);
                } else {
                    sauce.analysisStatsIntent = {start, end};
                }
                return saveFn.apply(this, arguments);
            };
        });

        sauce.propDefined('Strava.Charts.Activities.LabelBox', Klass => {
            // This is called when zoom selections change or are unset in the profile graph.
            const saveFn = Klass.prototype.handleStreamHover;
            Klass.prototype.handleStreamHover = function(_, start, end) {
                start = start === undefined ? start : Number(start);
                end = end === undefined ? end : Number(end);
                if (sauce.analysis) {
                    sauce.analysis.schedUpdateAnalysisStats(start, end);
                } else {
                    sauce.analysisStatsIntent = {start, end};
                }
                return saveFn.apply(this, arguments);
            };
        });

        sauce.propDefined('Strava.Labs.Activities.BasicAnalysisView', Klass => {
            // Monkey patch the analysis view so we always have our hook for extra stats.
            const saveFn = Klass.prototype.renderTemplate;
            Klass.prototype.renderTemplate = function() {
                const $el = saveFn.apply(this, arguments);
                if (sauce.analysis) {
                    sauce.analysis.attachAnalysisStats($el);
                } else {
                    sauce.analysisStatsIntent = {start: undefined, end: undefined};
                }
                return $el;
            };
        });

        /* Patch dragging bug when scrolled in this old jquery ui code.
         * NOTE: We must use Promise.then instead of a callback because the
         * draggable widget isn't fully baked when it's first defined.  The
         * promise resolution won't execute until the assignment is completed.
         */
        sauce.propDefined('jQuery.ui.draggable').then(draggable => {
            const $ = jQuery;
            jQuery.widget('ui.draggable', draggable, {
                _convertPositionTo: function(d, pos) {
                    pos = pos || this.position;
                    const mod = d === "absolute" ? 1 : -1;
                    const useOffsetParent = this.cssPosition === "absolute" &&
                        (this.scrollParent[0] === this.document[0] || !$.contains(this.scrollParent[0], this.offsetParent[0]));
                    const scroll = useOffsetParent ? this.offsetParent : this.scrollParent;
                    const scrollIsRootNode = useOffsetParent && (/(html|body)/i).test(scroll[0].nodeName);
                    if (!this.offset.scroll) {
                        this.offset.scroll = {top: scroll.scrollTop(), left: scroll.scrollLeft()};
                    }
                    const scrollTop = mod * this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollTop() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.top);
                    const scrollLeft = mod * this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollLeft() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.left);
                    return {
                        top: pos.top + this.offset.relative.top * mod + this.offset.parent.top * mod - scrollTop,
                        left: pos.left + this.offset.relative.left * mod + this.offset.parent.left * mod - scrollLeft
                    };
                },
                _generatePosition: function(ev) {
                    let top;
                    let left;
                    const useOffsetParent = this.cssPosition === "absolute" &&
                        (this.scrollParent[0] === this.document[0] || !$.contains(this.scrollParent[0], this.offsetParent[0]));
                    const scroll = useOffsetParent ? this.offsetParent : this.scrollParent;
                    const scrollIsRootNode = useOffsetParent && (/(html|body)/i).test(scroll[0].nodeName);
                    let pageX = ev.pageX;
                    let pageY = ev.pageY;
                    if (!this.offset.scroll) {
                        this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
                    }
                    if (this.originalPosition) {
                        let containment;
                        if (this.containment) {
                            if (this.relative_container){
                                const co = this.relative_container.offset();
                                containment = [
                                    this.containment[0] + co.left,
                                    this.containment[1] + co.top,
                                    this.containment[2] + co.left,
                                    this.containment[3] + co.top
                                ];
                            } else {
                                containment = this.containment;
                            }
                            if(ev.pageX - this.offset.click.left < containment[0]) {
                                pageX = containment[0] + this.offset.click.left;
                            }
                            if(ev.pageY - this.offset.click.top < containment[1]) {
                                pageY = containment[1] + this.offset.click.top;
                            }
                            if(ev.pageX - this.offset.click.left > containment[2]) {
                                pageX = containment[2] + this.offset.click.left;
                            }
                            if(ev.pageY - this.offset.click.top > containment[3]) {
                                pageY = containment[3] + this.offset.click.top;
                            }
                        }
                        const o = this.options;
                        if (o.grid) {
                            top = o.grid[1] ?
                                this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] :
                                this.originalPageY;
                            pageY = containment ?
                                ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ?
                                    top :
                                    ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) :
                                top;
                            left = o.grid[0] ?
                                this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] :
                                this.originalPageX;
                            pageX = containment ?
                                ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ?
                                    left :
                                    ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) :
                                left;
                        }
                    }
                    const scrollTop = this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollTop() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.top);
                    const scrollLeft = this.cssPosition === "fixed" ?
                        -this.scrollParent.scrollLeft() :
                        (scrollIsRootNode ? 0 : this.offset.scroll.left);
                    return {
                        top: pageY - this.offset.click.top - this.offset.relative.top - this.offset.parent.top + scrollTop,
                        left: pageX - this.offset.click.left - this.offset.relative.left - this.offset.parent.left + scrollLeft
                    };
                }
            });
        });

        // Allow html titles and icons for dialogs.
        sauce.propDefined('jQuery.ui.dialog').then(dialog => {
            jQuery.widget('ui.dialog', dialog, {
                _title: function(title) {
                    if (!this.options.title) {
                        title.html(' ');
                    } else {
                        title.replaceWith(`

${this.options.title}

${this.options.icon || ''}

                        `);
                    }
                }
            });
        });

        // Allow html titles and icons for dialogs.
        let _SegmentEffortsTableView;
        sauce.propDefined('Strava.Labs.Activities.SegmentEffortsTableView', View => {
            // Our reassignment will cause a recursive loop without a short circuit.
            if (!_SegmentEffortsTableView) {
                _SegmentEffortsTableView = function(_, options) {
                    const activity = options.context.chartContext.activity().clone();
                    if (activity.isRun() && sauce.options && sauce.options['analysis-detailed-run-segments']) {
                        activity.set('type', 'Ride');
                        options.context.chartContext.activity(activity);
                    }
                    View.prototype.constructor.apply(this, arguments);
                };
                _SegmentEffortsTableView.prototype = View.prototype;
                self.Strava.Labs.Activities.SegmentEffortsTableView = _SegmentEffortsTableView;
            }
        });

        sauce.propDefined('Strava.Labs.Activities.SegmentsView', View => {
            const initSave = View.prototype.initialize;
            View.prototype.initialize = function(pageView) {
                if (pageView.isRun() && sauce.options && sauce.options['analysis-detailed-run-segments']) {
                    pageView = Object.create(pageView);
                    pageView.activity(pageView.activity().clone());
                    pageView.activity().set('type', 'Ride');
                }
                return initSave.call(this, pageView);
            };

            const renderSave = View.prototype.render;
            View.prototype.render = function() {
                renderSave.apply(this, arguments);
                if (self.pageView.isRun() && this.pageView.isRide() && sauce.options &&
                    sauce.options['analysis-detailed-run-segments']) {
                    this.$el.prepend(`

`);
                }
                return this;
            };
        });

        // Provide race-free detection of pending requests.
        sauce.propDefined('Strava.Labs.Activities.StreamsRequest', Model => {
            const requireSave = Model.prototype.require;
            Model.prototype.require = function() {
                if (!this.pending) {
                    this.pending = new Promise(resolve => {
                        this.deferred.always(() => {
                            this.pending = false;
                            resolve();
                        });
                    });
                }
                return requireSave.apply(this, arguments);
            };
        });
    }
})();
<|endoftext|>


<commit_before>// Smite Data API Methods

// Dependencies
const request = require('request')
const util = require('../util')
const SessionAPI = require('../sessions/sessionAPI')

const API = {
  PC: 'http://api.smitegame.com/smiteapi.svc/',
  XBOX: 'http://api.xbox.smitegame.com/smiteapi.svc/',
  PS4: 'http://api.ps4.smitegame.com/smiteapi.svc/'
}

class Smite {
  constructor (args, platform) {
    this.devId = args.devId
    this.authKey = args.authKey
    this.smiteUrl = API[platform.toUpperCase()]
    this.platform = platform.toUpperCase()
    this.session = new SessionAPI(this.smiteUrl, this.devId, this.authKey, `smite${this.platform}`)
    this.session.test().then(tested => {
      if (tested.startsWith('Invalid session id.') || !this.session.exitsts()) {
        this.session.generate()
      }
    })
  }

  getFriends (userName) {
    let url = util.genUrl(this.smiteUrl, 'getfriends', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getEsportsProLeagueDetails () {
    let url = util.genUrl(this.smiteUrl, 'getesportsproleaguedetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodRanks (userName) {
    let url = util.genUrl(this.smiteUrl, 'getgodranks', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGods () {
    let url = util.genUrl(this.smiteUrl, 'getgods', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodSkins (godId) {
    let url = util.genUrl(this.smiteUrl, 'getgodskins', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodRecommendedItems (godId) {
    let url = util.genUrl(this.smiteUrl, 'getgodrecommendeditems', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getItems () {
    let url = util.genUrl(this.smiteUrl, 'getitems', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchDetails (matchId) {
    let url = util.genUrl(this.smiteUrl, 'getmatchdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + matchId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchPlayerDetails (matchId) {
    let url = util.genUrl(this.smiteUrl, 'getmatchplayerdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + matchId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchIdsByQueue (queue, date, time) {
    let url = util.genUrl(this.smiteUrl, 'getmatchidsbyqueue', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue +
      '/' + date + '/' + time
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getLeagueLeaderBoard (queue, tier, season) {
    let url = util.genUrl(this.smiteUrl, 'getleagueleaderboard', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue +
    '/' + tier + '/' + season
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodLeaderBoard (godId, queue) {
    let url = util.genUrl(this.smiteUrl, 'getgotleaderboard', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId +
    '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getLeagueSeasons (queue) {
    let url = util.genUrl(this.smiteUrl, 'getleagueseasons', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchHistory (userName) {
    let url = util.genUrl(this.smiteUrl, 'getmatchhistory', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMotd () {
    let url = util.genUrl(this.smiteUrl, 'getmotd', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayer (userName) {
    let url = util.genUrl(this.smiteUrl, 'getplayer', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayerStatus (userName) {
    let url = util.genUrl(this.smiteUrl, 'getplayerstatus', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getQueueStats (userName, queue) {
    let url = util.genUrl(this.smiteUrl, 'getqueuestats', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName +
      '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTeamDetails (teamId) {
    let url = util.genUrl(this.smiteUrl, 'getteamdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + teamId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTeamPlayers (teamId) {
    let url = util.genUrl(this.smiteUrl, 'getteamplayers', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + teamId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTopMatches () {
    let url = util.genUrl(this.smiteUrl, 'gettopmatches', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  searchTeams (teamName) {
    let url = util.genUrl(this.smiteUrl, 'searchteams', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + encodeURIComponent(teamName)
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayerAchievements (userId) {
    let url = util.genUrl(this.smiteUrl, 'getplayerachievements', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPatchInfo () {
    let url = util.genUrl(this.smiteUrl, 'getpatchinfo', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  ping () {
    let url = this.smiteUrl + 'pingjson'
    return new Promise((resolve, reject) => {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(console.error(body))
        }
      })
    })
  }

  getDataUsed () {
    let url = util.genUrl(this.smiteUrl, 'getdataused', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }
}

module.exports = Smite
<commit_msg>fix typo in getgodleaderboard api call<commit_after>// Smite Data API Methods

// Dependencies
const request = require('request')
const util = require('../util')
const SessionAPI = require('../sessions/sessionAPI')

const API = {
  PC: 'http://api.smitegame.com/smiteapi.svc/',
  XBOX: 'http://api.xbox.smitegame.com/smiteapi.svc/',
  PS4: 'http://api.ps4.smitegame.com/smiteapi.svc/'
}

class Smite {
  constructor (args, platform) {
    this.devId = args.devId
    this.authKey = args.authKey
    this.smiteUrl = API[platform.toUpperCase()]
    this.platform = platform.toUpperCase()
    this.session = new SessionAPI(this.smiteUrl, this.devId, this.authKey, `smite${this.platform}`)
    this.session.test().then(tested => {
      if (tested.startsWith('Invalid session id.') || !this.session.exitsts()) {
        this.session.generate()
      }
    })
  }

  getFriends (userName) {
    let url = util.genUrl(this.smiteUrl, 'getfriends', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getEsportsProLeagueDetails () {
    let url = util.genUrl(this.smiteUrl, 'getesportsproleaguedetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodRanks (userName) {
    let url = util.genUrl(this.smiteUrl, 'getgodranks', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGods () {
    let url = util.genUrl(this.smiteUrl, 'getgods', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodSkins (godId) {
    let url = util.genUrl(this.smiteUrl, 'getgodskins', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodRecommendedItems (godId) {
    let url = util.genUrl(this.smiteUrl, 'getgodrecommendeditems', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getItems () {
    let url = util.genUrl(this.smiteUrl, 'getitems', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/1'
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchDetails (matchId) {
    let url = util.genUrl(this.smiteUrl, 'getmatchdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + matchId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchPlayerDetails (matchId) {
    let url = util.genUrl(this.smiteUrl, 'getmatchplayerdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + matchId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchIdsByQueue (queue, date, time) {
    let url = util.genUrl(this.smiteUrl, 'getmatchidsbyqueue', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue +
      '/' + date + '/' + time
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getLeagueLeaderBoard (queue, tier, season) {
    let url = util.genUrl(this.smiteUrl, 'getleagueleaderboard', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue +
    '/' + tier + '/' + season
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getGodLeaderBoard (godId, queue) {
    let url = util.genUrl(this.smiteUrl, 'getgodleaderboard', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + godId +
    '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getLeagueSeasons (queue) {
    let url = util.genUrl(this.smiteUrl, 'getleagueseasons', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMatchHistory (userName) {
    let url = util.genUrl(this.smiteUrl, 'getmatchhistory', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getMotd () {
    let url = util.genUrl(this.smiteUrl, 'getmotd', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayer (userName) {
    let url = util.genUrl(this.smiteUrl, 'getplayer', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayerStatus (userName) {
    let url = util.genUrl(this.smiteUrl, 'getplayerstatus', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getQueueStats (userName, queue) {
    let url = util.genUrl(this.smiteUrl, 'getqueuestats', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userName +
      '/' + queue
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTeamDetails (teamId) {
    let url = util.genUrl(this.smiteUrl, 'getteamdetails', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + teamId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTeamPlayers (teamId) {
    let url = util.genUrl(this.smiteUrl, 'getteamplayers', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + teamId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getTopMatches () {
    let url = util.genUrl(this.smiteUrl, 'gettopmatches', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  searchTeams (teamName) {
    let url = util.genUrl(this.smiteUrl, 'searchteams', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + encodeURIComponent(teamName)
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPlayerAchievements (userId) {
    let url = util.genUrl(this.smiteUrl, 'getplayerachievements', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`]) + '/' + userId
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  getPatchInfo () {
    let url = util.genUrl(this.smiteUrl, 'getpatchinfo', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }

  ping () {
    let url = this.smiteUrl + 'pingjson'
    return new Promise((resolve, reject) => {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(console.error(body))
        }
      })
    })
  }

  getDataUsed () {
    let url = util.genUrl(this.smiteUrl, 'getdataused', this.devId, this.authKey, process.env[`SMITE_${this.platform}_SESSION`])
    return new Promise(function (resolve, reject) {
      request(url, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          resolve(JSON.parse(body))
        } else {
          reject(error)
        }
      })
    })
  }
}

module.exports = Smite
<|endoftext|>


<commit_before>define([
  'angular',
  'lodash',
  'app/core/utils/datemath',
  './directives',
  './zabbixAPIWrapper',
  './helperFunctions',
  './queryCtrl'
],
function (angular, _, dateMath) {
  'use strict';

  var module = angular.module('grafana.services');

  module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv, alertSrv, ZabbixAPI, zabbixHelperSrv) {

    /**
     * Datasource initialization. Calls when you refresh page, add
     * or modify datasource.
     *
     * @param {Object} datasource Grafana datasource object.
     */
    function ZabbixAPIDatasource(datasource) {
      this.name             = datasource.name;
      this.url              = datasource.url;
      this.basicAuth        = datasource.basicAuth;
      this.withCredentials  = datasource.withCredentials;

      if (datasource.jsonData) {
        this.username         = datasource.jsonData.username;
        this.password         = datasource.jsonData.password;

        // Use trends instead history since specified time
        this.trends           = datasource.jsonData.trends;
        this.trendsFrom       = datasource.jsonData.trendsFrom || '7d';

        // Limit metrics per panel for templated request
        this.limitmetrics     = datasource.jsonData.limitMetrics || 100;
      } else {
        // DEPRECATED. Loads settings from plugin.json file.
        // For backward compatibility only.
        this.username         = datasource.meta.username;
        this.password         = datasource.meta.password;
        this.trends           = datasource.meta.trends;
        this.trendsFrom       = datasource.meta.trendsFrom || '7d';
        this.limitmetrics     = datasource.meta.limitmetrics || 100;
      }

      // Initialize Zabbix API
      this.zabbixAPI = new ZabbixAPI(this.url, this.username, this.password, this.basicAuth, this.withCredentials);
    }

    /**
     * Test connection to Zabbix API
     *
     * @return {object} Connection status and Zabbix API version
     */
    ZabbixAPIDatasource.prototype.testDatasource = function() {
      var self = this;
      return this.zabbixAPI.getZabbixAPIVersion().then(function (apiVersion) {
        return self.zabbixAPI.performZabbixAPILogin().then(function (auth) {
          if (auth) {
            return {
              status: "success",
              title: "Success",
              message: "Zabbix API version: " + apiVersion
            };
          } else {
            return {
              status: "error",
              title: "Invalid user name or password",
              message: "Zabbix API version: " + apiVersion
            };
          }
        });
      }, function(error) {
        return {
          status: "error",
          title: "Connection failed",
          message: "Could not connect to " + error.config.url
        };
      });
    };

    /**
     * Calls for each panel in dashboard.
     *
     * @param  {Object} options   Query options. Contains time range, targets
     *                            and other info.
     *
     * @return {Object}           Grafana metrics object with timeseries data
     *                            for each target.
     */
    ZabbixAPIDatasource.prototype.query = function(options) {

      // get from & to in seconds
      var from = Math.ceil(dateMath.parse(options.range.from) / 1000);
      var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
      var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);

      // Create request for each target
      var promises = _.map(options.targets, function(target) {

        if (target.mode !== 1) {
          // Don't show undefined and hidden targets
          if (target.hide || !target.group || !target.host
            || !target.application || !target.item) {
            return [];
          }

          // Replace templated variables
          var groupname = templateSrv.replace(target.group.name, options.scopedVars);
          var hostname = templateSrv.replace(target.host.name, options.scopedVars);
          var appname = templateSrv.replace(target.application.name, options.scopedVars);
          var itemname = templateSrv.replace(target.item.name, options.scopedVars);

          // Extract zabbix groups, hosts and apps from string:
          // "{host1,host2,...,hostN}" --> [host1, host2, ..., hostN]
          var groups = zabbixHelperSrv.splitMetrics(groupname);
          var hosts = zabbixHelperSrv.splitMetrics(hostname);
          var apps = zabbixHelperSrv.splitMetrics(appname);

          // Remove hostnames from item names and then
          // extract item names
          // "hostname: itemname" --> "itemname"
          var delete_hostname_pattern = /(?:\[[\w\.]+]:\s)/g;
          var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, ''));

          var self = this;

          // Query numeric data
          if (!target.mode) {

            // Find items by item names and perform queries
            return this.zabbixAPI.itemFindQuery(groups, hosts, apps)
              .then(function (items) {

                // Filter hosts by regex
                if (target.host.visible_name === 'All') {
                  if (target.hostFilter && _.every(items, _.identity.hosts)) {

                    // Use templated variables in filter
                    var host_pattern = new RegExp(templateSrv.replace(target.hostFilter, options.scopedVars));
                    items = _.filter(items, function (item) {
                      return _.some(item.hosts, function (host) {
                        return host_pattern.test(host.name);
                      });
                    });
                  }
                }

                if (itemnames[0] === 'All') {

                  // Filter items by regex
                  if (target.itemFilter) {

                    // Use templated variables in filter
                    var item_pattern = new RegExp(templateSrv.replace(target.itemFilter, options.scopedVars));
                    return _.filter(items, function (item) {
                      return item_pattern.test(zabbixHelperSrv.expandItemName(item));
                    });
                  } else {
                    return items;
                  }
                } else {

                  // Filtering items
                  return _.filter(items, function (item) {
                    return _.contains(itemnames, zabbixHelperSrv.expandItemName(item));
                  });
                }
              }).then(function (items) {

                // Don't perform query for high number of items
                // to prevent Grafana slowdown
                if (items.length > self.limitmetrics) {
                  var message = "Try to increase limitmetrics parameter in datasource config.<br>"
                    + "Current limitmetrics value is " + self.limitmetrics;
                  alertSrv.set("Metrics limit exceeded", message, "warning", 10000);
                  return [];
                } else {
                  items = _.flatten(items);

                  // Use alias only for single metric, otherwise use item names
                  var alias = target.item.name === 'All' || itemnames.length > 1 ?
                                undefined : templateSrv.replace(target.alias, options.scopedVars);

                  var history;
                  if ((from < useTrendsFrom) && self.trends) {
                    var points = target.downsampleFunction ? target.downsampleFunction.value : "avg";
                    history = self.zabbixAPI.getTrends(items, from, to)
                      .then(_.bind(zabbixHelperSrv.handleTrendResponse, zabbixHelperSrv, items, alias, target.scale, points));
                  } else {
                    history = self.zabbixAPI.getHistory(items, from, to)
                      .then(_.bind(zabbixHelperSrv.handleHistoryResponse, zabbixHelperSrv, items, alias, target.scale));
                  }

                  return history.then(function (timeseries) {
                      var timeseries_data = _.flatten(timeseries);
                      return _.map(timeseries_data, function (timeseries) {

                        // Series downsampling
                        if (timeseries.datapoints.length > options.maxDataPoints) {
                          var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000;
                          var downsampleFunc = target.downsampleFunction ? target.downsampleFunction.value : "avg";
                          timeseries.datapoints = zabbixHelperSrv.downsampleSeries(timeseries.datapoints, to, ms_interval, downsampleFunc);
                        }
                        return timeseries;
                      });
                    });
                }
              });
          }

          // Query text data
          else if (target.mode === 2) {

            // Find items by item names and perform queries
            return this.zabbixAPI.itemFindQuery(groups, hosts, apps, "text")
              .then(function (items) {
                items = _.filter(items, function (item) {
                  return _.contains(itemnames, zabbixHelperSrv.expandItemName(item));
                });
                return self.zabbixAPI.getHistory(items, from, to).then(function(history) {
                  return {
                    target: target.item.name,
                    datapoints: _.map(history, function (p) {
                      return [p.value, p.clock * 1000];
                    })
                  };
                });
              });
          }
        }

        // IT services mode
        else if (target.mode === 1) {
          // Don't show undefined and hidden targets
          if (target.hide || !target.itservice || !target.slaProperty) {
            return [];
          } else {
            return this.zabbixAPI.getSLA(target.itservice.serviceid, from, to)
              .then(_.bind(zabbixHelperSrv.handleSLAResponse, zabbixHelperSrv, target.itservice, target.slaProperty));
          }
        }
      }, this);

      return $q.all(_.flatten(promises)).then(function (results) {
        var timeseries_data = _.flatten(results);
        return { data: timeseries_data };
      });
    };

    ////////////////
    // Templating //
    ////////////////

    /**
     * Find metrics from templated request.
     *
     * @param  {string} query Query from Templating
     * @return {string}       Metric name - group, host, app or item or list
     *                        of metrics in "{metric1,metcic2,...,metricN}" format.
     */
    ZabbixAPIDatasource.prototype.metricFindQuery = function (query) {
      // Split query. Query structure:
      // group.host.app.item
      var parts = [];
      _.each(query.split('.'), function (part) {
        part = templateSrv.replace(part);
        if (part[0] === '{') {
          // Convert multiple mettrics to array
          // "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN]
          parts.push(zabbixHelperSrv.splitMetrics(part));
        } else {
          parts.push(part);
        }
      });
      var template = _.object(['group', 'host', 'app', 'item'], parts);

      // Get items
      if (parts.length === 4) {
        return this.zabbixAPI.itemFindQuery(template.group, template.host, template.app)
          .then(function (result) {
            return _.map(result, function (item) {
              var itemname = zabbixHelperSrv.expandItemName(item);
              return {
                text: itemname,
                expandable: false
              };
            });
          });
      }
      // Get applications
      else if (parts.length === 3) {
        return this.zabbixAPI.appFindQuery(template.host, template.group).then(function (result) {
          return _.map(result, function (app) {
            return {
              text: app.name,
              expandable: false
            };
          });
        });
      }
      // Get hosts
      else if (parts.length === 2) {
        return this.zabbixAPI.hostFindQuery(template.group).then(function (result) {
          return _.map(result, function (host) {
            return {
              text: host.name,
              expandable: false
            };
          });
        });
      }
      // Get groups
      else if (parts.length === 1) {
        return this.zabbixAPI.getGroupByName(template.group).then(function (result) {
          return _.map(result, function (hostgroup) {
            return {
              text: hostgroup.name,
              expandable: false
            };
          });
        });
      }
      // Return empty object for invalid request
      else {
        var d = $q.defer();
        d.resolve([]);
        return d.promise;
      }
    };

    /////////////////
    // Annotations //
    /////////////////

    ZabbixAPIDatasource.prototype.annotationQuery = function(options) {
      var from = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
      var to = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
      var self = this;

      // Remove events below the chose severity
      var severities = [];
      for (var i = 5; i >= options.annotation.minseverity; i--) {
        severities.push(i);
      }
      var params = {
        output: ['triggerid', 'description', 'priority'],
        preservekeys: 1,
        filter: { 'priority': severities },
        search: {
          'description': options.annotation.trigger
        },
        searchWildcardsEnabled: true,
        expandDescription: true
      };
      if (options.annotation.host) {
        params.host = templateSrv.replace(options.annotation.host);
      }
      else if (options.annotation.group) {
        params.group = templateSrv.replace(options.annotation.group);
      }

      return this.zabbixAPI.performZabbixAPIRequest('trigger.get', params)
        .then(function (result) {
          if(result) {
            var objects = result;
            var params = {
              output: 'extend',
              time_from: from,
              time_till: to,
              objectids: _.keys(objects),
              select_acknowledges: 'extend',
              selectHosts: 'extend'
            };

            // Show problem events only
            if (!options.annotation.showOkEvents) {
              params.value = 1;
            }

            return self.zabbixAPI.performZabbixAPIRequest('event.get', params)
              .then(function (result) {
                var events = [];

                var title ='';
                if (options.annotation.showHostname) {
                  title += e.hosts[0]['name'] + ': ';
                }
                title += Number(e.value) ? 'Problem' : 'OK';

                _.each(result, function(e) {
                  // Hide acknowledged events
                  if (e.acknowledges.length > 0 && options.annotation.showAcknowledged) { return; }

                  var formatted_acknowledges = zabbixHelperSrv.formatAcknowledges(e.acknowledges);
                  events.push({
                    annotation: options.annotation,
                    time: e.clock * 1000,
                    title: title,
                    text: objects[e.objectid].description + formatted_acknowledges
                  });
                });
                return events;
              });
          } else {
            return [];
          }
        });
    };

    return ZabbixAPIDatasource;
  });
});
<commit_msg>Fixed "e is undefined" error.<commit_after>define([
  'angular',
  'lodash',
  'app/core/utils/datemath',
  './directives',
  './zabbixAPIWrapper',
  './helperFunctions',
  './queryCtrl'
],
function (angular, _, dateMath) {
  'use strict';

  var module = angular.module('grafana.services');

  module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv, alertSrv, ZabbixAPI, zabbixHelperSrv) {

    /**
     * Datasource initialization. Calls when you refresh page, add
     * or modify datasource.
     *
     * @param {Object} datasource Grafana datasource object.
     */
    function ZabbixAPIDatasource(datasource) {
      this.name             = datasource.name;
      this.url              = datasource.url;
      this.basicAuth        = datasource.basicAuth;
      this.withCredentials  = datasource.withCredentials;

      if (datasource.jsonData) {
        this.username         = datasource.jsonData.username;
        this.password         = datasource.jsonData.password;

        // Use trends instead history since specified time
        this.trends           = datasource.jsonData.trends;
        this.trendsFrom       = datasource.jsonData.trendsFrom || '7d';

        // Limit metrics per panel for templated request
        this.limitmetrics     = datasource.jsonData.limitMetrics || 100;
      } else {
        // DEPRECATED. Loads settings from plugin.json file.
        // For backward compatibility only.
        this.username         = datasource.meta.username;
        this.password         = datasource.meta.password;
        this.trends           = datasource.meta.trends;
        this.trendsFrom       = datasource.meta.trendsFrom || '7d';
        this.limitmetrics     = datasource.meta.limitmetrics || 100;
      }

      // Initialize Zabbix API
      this.zabbixAPI = new ZabbixAPI(this.url, this.username, this.password, this.basicAuth, this.withCredentials);
    }

    /**
     * Test connection to Zabbix API
     *
     * @return {object} Connection status and Zabbix API version
     */
    ZabbixAPIDatasource.prototype.testDatasource = function() {
      var self = this;
      return this.zabbixAPI.getZabbixAPIVersion().then(function (apiVersion) {
        return self.zabbixAPI.performZabbixAPILogin().then(function (auth) {
          if (auth) {
            return {
              status: "success",
              title: "Success",
              message: "Zabbix API version: " + apiVersion
            };
          } else {
            return {
              status: "error",
              title: "Invalid user name or password",
              message: "Zabbix API version: " + apiVersion
            };
          }
        });
      }, function(error) {
        return {
          status: "error",
          title: "Connection failed",
          message: "Could not connect to " + error.config.url
        };
      });
    };

    /**
     * Calls for each panel in dashboard.
     *
     * @param  {Object} options   Query options. Contains time range, targets
     *                            and other info.
     *
     * @return {Object}           Grafana metrics object with timeseries data
     *                            for each target.
     */
    ZabbixAPIDatasource.prototype.query = function(options) {

      // get from & to in seconds
      var from = Math.ceil(dateMath.parse(options.range.from) / 1000);
      var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
      var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);

      // Create request for each target
      var promises = _.map(options.targets, function(target) {

        if (target.mode !== 1) {
          // Don't show undefined and hidden targets
          if (target.hide || !target.group || !target.host
            || !target.application || !target.item) {
            return [];
          }

          // Replace templated variables
          var groupname = templateSrv.replace(target.group.name, options.scopedVars);
          var hostname = templateSrv.replace(target.host.name, options.scopedVars);
          var appname = templateSrv.replace(target.application.name, options.scopedVars);
          var itemname = templateSrv.replace(target.item.name, options.scopedVars);

          // Extract zabbix groups, hosts and apps from string:
          // "{host1,host2,...,hostN}" --> [host1, host2, ..., hostN]
          var groups = zabbixHelperSrv.splitMetrics(groupname);
          var hosts = zabbixHelperSrv.splitMetrics(hostname);
          var apps = zabbixHelperSrv.splitMetrics(appname);

          // Remove hostnames from item names and then
          // extract item names
          // "hostname: itemname" --> "itemname"
          var delete_hostname_pattern = /(?:\[[\w\.]+]:\s)/g;
          var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, ''));

          var self = this;

          // Query numeric data
          if (!target.mode) {

            // Find items by item names and perform queries
            return this.zabbixAPI.itemFindQuery(groups, hosts, apps)
              .then(function (items) {

                // Filter hosts by regex
                if (target.host.visible_name === 'All') {
                  if (target.hostFilter && _.every(items, _.identity.hosts)) {

                    // Use templated variables in filter
                    var host_pattern = new RegExp(templateSrv.replace(target.hostFilter, options.scopedVars));
                    items = _.filter(items, function (item) {
                      return _.some(item.hosts, function (host) {
                        return host_pattern.test(host.name);
                      });
                    });
                  }
                }

                if (itemnames[0] === 'All') {

                  // Filter items by regex
                  if (target.itemFilter) {

                    // Use templated variables in filter
                    var item_pattern = new RegExp(templateSrv.replace(target.itemFilter, options.scopedVars));
                    return _.filter(items, function (item) {
                      return item_pattern.test(zabbixHelperSrv.expandItemName(item));
                    });
                  } else {
                    return items;
                  }
                } else {

                  // Filtering items
                  return _.filter(items, function (item) {
                    return _.contains(itemnames, zabbixHelperSrv.expandItemName(item));
                  });
                }
              }).then(function (items) {

                // Don't perform query for high number of items
                // to prevent Grafana slowdown
                if (items.length > self.limitmetrics) {
                  var message = "Try to increase limitmetrics parameter in datasource config.<br>"
                    + "Current limitmetrics value is " + self.limitmetrics;
                  alertSrv.set("Metrics limit exceeded", message, "warning", 10000);
                  return [];
                } else {
                  items = _.flatten(items);

                  // Use alias only for single metric, otherwise use item names
                  var alias = target.item.name === 'All' || itemnames.length > 1 ?
                                undefined : templateSrv.replace(target.alias, options.scopedVars);

                  var history;
                  if ((from < useTrendsFrom) && self.trends) {
                    var points = target.downsampleFunction ? target.downsampleFunction.value : "avg";
                    history = self.zabbixAPI.getTrends(items, from, to)
                      .then(_.bind(zabbixHelperSrv.handleTrendResponse, zabbixHelperSrv, items, alias, target.scale, points));
                  } else {
                    history = self.zabbixAPI.getHistory(items, from, to)
                      .then(_.bind(zabbixHelperSrv.handleHistoryResponse, zabbixHelperSrv, items, alias, target.scale));
                  }

                  return history.then(function (timeseries) {
                      var timeseries_data = _.flatten(timeseries);
                      return _.map(timeseries_data, function (timeseries) {

                        // Series downsampling
                        if (timeseries.datapoints.length > options.maxDataPoints) {
                          var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000;
                          var downsampleFunc = target.downsampleFunction ? target.downsampleFunction.value : "avg";
                          timeseries.datapoints = zabbixHelperSrv.downsampleSeries(timeseries.datapoints, to, ms_interval, downsampleFunc);
                        }
                        return timeseries;
                      });
                    });
                }
              });
          }

          // Query text data
          else if (target.mode === 2) {

            // Find items by item names and perform queries
            return this.zabbixAPI.itemFindQuery(groups, hosts, apps, "text")
              .then(function (items) {
                items = _.filter(items, function (item) {
                  return _.contains(itemnames, zabbixHelperSrv.expandItemName(item));
                });
                return self.zabbixAPI.getHistory(items, from, to).then(function(history) {
                  return {
                    target: target.item.name,
                    datapoints: _.map(history, function (p) {
                      return [p.value, p.clock * 1000];
                    })
                  };
                });
              });
          }
        }

        // IT services mode
        else if (target.mode === 1) {
          // Don't show undefined and hidden targets
          if (target.hide || !target.itservice || !target.slaProperty) {
            return [];
          } else {
            return this.zabbixAPI.getSLA(target.itservice.serviceid, from, to)
              .then(_.bind(zabbixHelperSrv.handleSLAResponse, zabbixHelperSrv, target.itservice, target.slaProperty));
          }
        }
      }, this);

      return $q.all(_.flatten(promises)).then(function (results) {
        var timeseries_data = _.flatten(results);
        return { data: timeseries_data };
      });
    };

    ////////////////
    // Templating //
    ////////////////

    /**
     * Find metrics from templated request.
     *
     * @param  {string} query Query from Templating
     * @return {string}       Metric name - group, host, app or item or list
     *                        of metrics in "{metric1,metcic2,...,metricN}" format.
     */
    ZabbixAPIDatasource.prototype.metricFindQuery = function (query) {
      // Split query. Query structure:
      // group.host.app.item
      var parts = [];
      _.each(query.split('.'), function (part) {
        part = templateSrv.replace(part);
        if (part[0] === '{') {
          // Convert multiple mettrics to array
          // "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN]
          parts.push(zabbixHelperSrv.splitMetrics(part));
        } else {
          parts.push(part);
        }
      });
      var template = _.object(['group', 'host', 'app', 'item'], parts);

      // Get items
      if (parts.length === 4) {
        return this.zabbixAPI.itemFindQuery(template.group, template.host, template.app)
          .then(function (result) {
            return _.map(result, function (item) {
              var itemname = zabbixHelperSrv.expandItemName(item);
              return {
                text: itemname,
                expandable: false
              };
            });
          });
      }
      // Get applications
      else if (parts.length === 3) {
        return this.zabbixAPI.appFindQuery(template.host, template.group).then(function (result) {
          return _.map(result, function (app) {
            return {
              text: app.name,
              expandable: false
            };
          });
        });
      }
      // Get hosts
      else if (parts.length === 2) {
        return this.zabbixAPI.hostFindQuery(template.group).then(function (result) {
          return _.map(result, function (host) {
            return {
              text: host.name,
              expandable: false
            };
          });
        });
      }
      // Get groups
      else if (parts.length === 1) {
        return this.zabbixAPI.getGroupByName(template.group).then(function (result) {
          return _.map(result, function (hostgroup) {
            return {
              text: hostgroup.name,
              expandable: false
            };
          });
        });
      }
      // Return empty object for invalid request
      else {
        var d = $q.defer();
        d.resolve([]);
        return d.promise;
      }
    };

    /////////////////
    // Annotations //
    /////////////////

    ZabbixAPIDatasource.prototype.annotationQuery = function(options) {
      var from = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
      var to = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
      var self = this;

      // Remove events below the chose severity
      var severities = [];
      for (var i = 5; i >= options.annotation.minseverity; i--) {
        severities.push(i);
      }
      var params = {
        output: ['triggerid', 'description', 'priority'],
        preservekeys: 1,
        filter: { 'priority': severities },
        search: {
          'description': options.annotation.trigger
        },
        searchWildcardsEnabled: true,
        expandDescription: true
      };
      if (options.annotation.host) {
        params.host = templateSrv.replace(options.annotation.host);
      }
      else if (options.annotation.group) {
        params.group = templateSrv.replace(options.annotation.group);
      }

      return this.zabbixAPI.performZabbixAPIRequest('trigger.get', params)
        .then(function (result) {
          if(result) {
            var objects = result;
            var params = {
              output: 'extend',
              time_from: from,
              time_till: to,
              objectids: _.keys(objects),
              select_acknowledges: 'extend',
              selectHosts: 'extend'
            };

            // Show problem events only
            if (!options.annotation.showOkEvents) {
              params.value = 1;
            }

            return self.zabbixAPI.performZabbixAPIRequest('event.get', params)
              .then(function (result) {
                var events = [];

                _.each(result, function(e) {
                  var title ='';
                  if (options.annotation.showHostname) {
                    title += e.hosts[0]['name'] + ': ';
                  }
                  title += Number(e.value) ? 'Problem' : 'OK';

                  // Hide acknowledged events
                  if (e.acknowledges.length > 0 && options.annotation.showAcknowledged) { return; }

                  var formatted_acknowledges = zabbixHelperSrv.formatAcknowledges(e.acknowledges);
                  events.push({
                    annotation: options.annotation,
                    time: e.clock * 1000,
                    title: title,
                    text: objects[e.objectid].description + formatted_acknowledges
                  });
                });
                return events;
              });
          } else {
            return [];
          }
        });
    };

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


<commit_before>/*
 * ningjs - Live.js
 */

'use strict'

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

import 'styles/pages/article.scss'

export default class Live extends Component {

  constructor(props) {
    super(props);
    this.state = {
      selected: 0,
      videos: [{
        name: '2016-09-03 Morning',
        url: 'http://ningjs.cn-bj.ufileos.com/2016-09-03-Morning.mp4'
      }, {
        name: '2016-09-03 Afternoon'
      }, {
        name: '2016-09-04 Morning'
      }, {
        name: '2016-09-04 Afternoon'
      }]
    }
  }

  componentDidMount() {
    const options = {
    }
    videojs('ningjs_live', {flash: options, html5: options})
  }

  onSelectVideo(i, e) {
    e.preventDefault();
    e.stopPropagation();

    this.setState({
      selected: i
    })
  }

  render() {
    const { __, query } = this.props
    const { selected, videos } = this.state;
    const video = videos[selected];

    return (

        {/* video */}

                {
                  videos.map((v, i) => {
                    return (

                          {v.name}

                    )
                  })
                }

              {/* masthead */}
              <video
                id='ningjs_live'
                className='video-js vjs-default-skin'
                controls
                preload='auto'
                poster=''>
                <source src={video.url} type='video/mp4' />
              </video>

    )
  }
}
<commit_msg>Add more videos<commit_after>/*
 * ningjs - Live.js
 */

'use strict'

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

import 'styles/pages/article.scss'

export default class Live extends Component {

  constructor(props) {
    super(props);
    this.state = {
      selected: 0,
      videos: [{
        name: '2016-09-03 Morning',
        url: 'http://ningjs2.ufile.ucloud.com.cn/2016-09-03-Morning.mp4'
      }, {
        name: '2016-09-03 Afternoon',
        url: 'http://ningjs2.ufile.ucloud.com.cn/2016-09-03-Afternoon.mp4'
      }, {
        name: '2016-09-04 Morning'
      }, {
        name: '2016-09-04 Afternoon',
        url: 'http://ningjs2.ufile.ucloud.com.cn/2016-09-04-Afternoon.mp4'
      }]
    }
  }

  componentDidMount() {
    const options = {
    }
    videojs('ningjs_live', {flash: options, html5: options})
  }

  onSelectVideo(i, e) {
    e.preventDefault();
    e.stopPropagation();
    const { videos } = this.state;
    var player = videojs.getPlayers()['ningjs_live']
    player.src({
      type: 'video/mp4',
      src: videos[i].url
    })
    player.play()
  }

  render() {
    const { __, query } = this.props
    const { selected, videos } = this.state;
    const video = videos[selected];

    return (

        {/* video */}

                {
                  videos.map((v, i) => {
                    return (

                          {v.name}

                    )
                  })
                }

{__('Thanks UCloud Support CDN Service.')}

              {/* masthead */}
              <video
                id='ningjs_live'
                className='video-js vjs-default-skin'
                controls
                preload='auto'
                poster=''>
                <source src={video.url} type='video/mp4' />
              </video>

    )
  }
}
<|endoftext|>