<commit_before>/**
 * (c) 2016 Tieto Finland Oy
 * Licensed under the MIT license.
 */
'use strict';

/**
 * @ngdoc directive
 * @name dashboard.proposal:proposalDirective
 * @description
 * # proposalDirective
 */
angular.module('dashboard')
    .constant('PROP', {
        'MODE': {
            COLLAPSED: 'COLLAPSED',
            OPEN: 'OPEN',
            EDIT: 'EDIT'
        }
    })
    .directive('dbProposal', [function () {

        var controller = ['$log', '$scope', 'PROPS', 'PROP', '$rootScope', 'AhjoProposalsSrv', 'StorageSrv', 'CONST', '$timeout', 'Utils', function ($log, $scope, PROPS, PROP, $rootScope, AhjoProposalsSrv, StorageSrv, CONST, $timeout, Utils) {
            var self = this;
            self.isTooltips = $rootScope.isTooltips;
            self.uiProposal = null;

            self.mode = null;
            self.modes = PROP.MODE;
            self.status = PROPS.PUBLISHED;
            self.editedText = null;
            self.updating = false;
            self.publishConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_SEND_PROP', yes: 'STR_YES' };
            self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES' };
            var previousIsPublished = null;
            var createDisabled = false;

            self.editor = {
                'menu': []
            };

            function setMode(mode) {
                self.mode = mode;
            }

            function setProposal(proposal) {
                if (angular.isObject(proposal)) {
                    self.uiProposal = proposal;
                    setMode(PROP.MODE.COLLAPSED);

                    if (proposal.isOwnProposal) {
                        if (proposal.isPublished === null) {
                            $timeout(function () {
                                setMode(PROP.MODE.EDIT);
                            }, 0);
                            previousIsPublished = proposal.isPublished;
                        }
                    }

                    // missing person name will be replaced by last name and first name
                    if (!self.uiProposal.personName) {
                        var lastName = self.uiProposal.lastName ? self.uiProposal.lastName : '';
                        var space = lastName ? ' ' : '';
                        var firstName = self.uiProposal.firstName ? self.uiProposal.firstName : '';
                        self.uiProposal.personName = lastName + space + firstName;
                    }

                    // delete confirm dialog setup
                    if (self.uiProposal.isPublished) {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PUBLIC_PROP', yes: 'STR_YES' };
                    }
                    else if (self.uiProposal.isPublishedIcon) {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES', optionText: 'STR_CNFM_DEL_PROP_OPT' };
                    }
                    else {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES' };
                    }
                }
            }

            function postProposal(proposal) {
                $log.debug("dbProposal: postProposal: " + JSON.stringify(proposal));
                if (angular.isObject(proposal)) {
                    self.updating = true;

                    var copy = angular.copy(proposal);
                    if (copy.isPublished === null) {
                        copy.isPublished = PROPS.PUBLISHED.NO;
                    }
                    else if (copy.isPublished === PROPS.PUBLISHED.NO) {
                        copy.isPublished = PROPS.PUBLISHED.YES;
                    }

                    AhjoProposalsSrv.post(copy).$promise.then(function (response) {
                        $log.debug("dbProposal: post then: " + JSON.stringify(response));
                        if (angular.isObject(response) && angular.isObject(response.Data)) {
                            if (copy.isPublished === PROPS.PUBLISHED.NO) {
                                angular.merge($scope.proposal, response.Data);
                                $rootScope.successInfo('STR_SAVE_SUCCESS');
                            }
                            else if (copy.isPublished === PROPS.PUBLISHED.YES) {
                                $scope.proposal.isPublishedIcon = PROPS.PUBLISHED.YES;
                                angular.merge(copy, response.Data);
                                // proposal guid copy needs to be copied her
                                // otherwise  puhblished version deletion is not working
                                $scope.proposal.proposalGuidCopy = copy.proposalGuid;
                                $scope.onAdd({ data: { proposal: copy } });
                                $rootScope.successInfo('STR_PUBLISH_SUCCESS');
                            }
                            else {
                                $log.error('dbProposal: postProposal unsupported status');
                            }
                        }
                        else {
                            $log.error('dbProposal: postProposal invalid response');
                        }
                    }, function (error) {
                        $log.error("dbProposal: post error: " + JSON.stringify(error));
                        $rootScope.failedInfo('STR_SAVE_FAILED');
                    }).finally(function () {
                        $log.debug("dbProposal: post finally: ");
                        self.updating = false;
                        $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
                    });
                }
                else {
                    $log.error('dbProposal: postProposal invalid parameter');
                }
            }

            function deleteProposal(proposal) {
                $log.debug("dbProposal: deleteProposal: " + JSON.stringify(proposal));
                if (angular.isObject(proposal)) {
                    if (proposal.isPublished === PROPS.PUBLISHED.NO || proposal.isPublished === PROPS.PUBLISHED.YES) {
                        self.updating = true;
                        AhjoProposalsSrv.delete(proposal).$promise.then(function (response) {
                            $log.debug("dbProposal: delete then: " + JSON.stringify(response));
                            if (angular.isObject(response) && angular.isObject(response.Data)) {
                                $scope.onRemove({ data: { 'proposal': response.Data } });
                                $rootScope.successInfo('STR_DELETE_SUCCESS');
                            }
                            else {
                                $log.error('dbProposal: deleteProposal invalid response');
                            }
                        }, function (error) {
                            $log.error("dbProposal: delete error: " + JSON.stringify(error));
                            $rootScope.failedInfo('STR_DELETE_FAILED');
                        }).finally(function () {
                            $log.debug("dbProposal: delete finally: ");
                            self.updating = false;
                        });
                    }
                    else {
                        $scope.onRemove({ data: { 'proposal': proposal } });
                    }
                }
                else {
                    $log.error('dbProposal: deleteProposal invalid parameter');
                }
            }

            function updatePolledEvents() {
                $log.debug("dbProposal: updatePolledEvents");
                var events = angular.copy(StorageSrv.getKey(CONST.KEY.PROPOSAL_EVENT_ARRAY));
                if (angular.isArray(events)) {
                    var found = false;
                    for (var index = events.length + CONST.NOTFOUND; index > CONST.NOTFOUND; index--) {
                        var event = events[index];
                        if (angular.isObject(event.proposal) && angular.equals(event.proposal.proposalGuid, $scope.proposal.proposalGuid)) {
                            events.splice(index, 1);
                            found = true;
                        }
                    }
                    if (found) {
                        StorageSrv.setKey(CONST.KEY.PROPOSAL_EVENT_ARRAY, events);
                    }
                }
            }

            self.typeText = function (value) {
                var obj = Utils.objWithVal(PROPS.TYPE, 'value', value);
                return (obj && obj.text) ? obj.text : value;
            };

            self.itemClicked = function () {
                if (self.mode === PROP.MODE.COLLAPSED) {
                    setMode(PROP.MODE.OPEN);
                }
                else if (self.mode === PROP.MODE.OPEN) {
                    setMode(PROP.MODE.COLLAPSED);
                }
            };

            self.toggleCollapse = function () {
                if (self.mode === PROP.MODE.COLLAPSED) {
                    setMode(PROP.MODE.OPEN);
                    if (self.uiProposal.isModified) {
                        updatePolledEvents();
                        $scope.proposal.isModified = false;
                    }
                }
                else {
                    setMode(PROP.MODE.COLLAPSED);
                }
            };

            self.edit = function () {
                self.editedText = $scope.proposal.text;
                previousIsPublished = $scope.proposal.isPublished;
                $scope.proposal.isPublished = null;
                setMode(PROP.MODE.EDIT);
                $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
            };

            self.remove = function (data) {
                deleteProposal($scope.proposal);
                if (angular.isObject(data) && data.value === true) {
                    $rootScope.$emit(PROPS.REMOVE, { guid: $scope.proposal.proposalGuidCopy });
                }
            };

            self.accept = function () {
                $scope.proposal.text = self.editedText ? self.editedText : '';
                postProposal($scope.proposal);
                setMode(PROP.MODE.OPEN);
            };

            self.cancel = function () {
                $scope.proposal.isPublished = previousIsPublished;
                if ($scope.proposal.isPublished === null) {
                    deleteProposal($scope.proposal);
                }
                setMode(PROP.MODE.OPEN);
                $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
            };

            self.send = function () {
                postProposal($scope.proposal);
            };

            setProposal($scope.proposal);

            $scope.$watch(function () {
                return {
                    proposal: $scope.proposal
                };
            }, function (data) {
                // scope.proposal is acting level and self.uiProposal is showing level
                // this is implemented for performance reasons to avoid two way binding
                // when data is changed in acting level it will be updated to showing level via setProposal function
                if (!angular.equals(data.proposal, self.uiProposal)) {
                    setProposal(data.proposal);
                }
            }, true);

            $scope.$watch(function () {
                return {
                    disableCreate: $scope.disableCreate
                };
            }, function (data) {
                if (angular.isObject(data)) {
                    if (createDisabled !== data.disableCreate) {
                        createDisabled = data.disableCreate;
                    }
                }
            }, true);

            var watcher = $rootScope.$on(PROPS.TOGGLE, function (event, data) {
                if (($scope.proposal.isPublished === PROPS.PUBLISHED.YES)) {
                    if (data) {
                        setMode(PROP.MODE.OPEN);
                    }
                    else {
                        setMode(PROP.MODE.COLLAPSED);
                    }
                }
            });

            var removeWatcher = $rootScope.$on(PROPS.REMOVE, function (event, data) {
                if (angular.isObject(data)) {
                    if (angular.equals(data.guid, $scope.proposal.proposalGuid)) {
                        deleteProposal($scope.proposal);
                    }
                }
                else {
                    $log.error('dbProposal: removeWatcher missing data');
                }
            });

            $scope.$on('$destroy', watcher);
            $scope.$on('$destroy', removeWatcher);

            $scope.$on('$destroy', function () {
                $log.debug("dbProposal: DESTROY");
            });
        }];

        return {
            scope: {
                proposal: '=',
                guid: '=',
                disableCreate: '=',
                onRemove: '&',
                onAdd: '&'
            },
            templateUrl: 'views/proposal.directive.html',
            restrict: 'AE',
            controller: controller,
            controllerAs: 'c',
            replace: 'true'
        };
    }]);
<commit_msg>comment fixed<commit_after>/**
 * (c) 2016 Tieto Finland Oy
 * Licensed under the MIT license.
 */
'use strict';

/**
 * @ngdoc directive
 * @name dashboard.proposal:proposalDirective
 * @description
 * # proposalDirective
 */
angular.module('dashboard')
    .constant('PROP', {
        'MODE': {
            COLLAPSED: 'COLLAPSED',
            OPEN: 'OPEN',
            EDIT: 'EDIT'
        }
    })
    .directive('dbProposal', [function () {

        var controller = ['$log', '$scope', 'PROPS', 'PROP', '$rootScope', 'AhjoProposalsSrv', 'StorageSrv', 'CONST', '$timeout', 'Utils', function ($log, $scope, PROPS, PROP, $rootScope, AhjoProposalsSrv, StorageSrv, CONST, $timeout, Utils) {
            var self = this;
            self.isTooltips = $rootScope.isTooltips;
            self.uiProposal = null;

            self.mode = null;
            self.modes = PROP.MODE;
            self.status = PROPS.PUBLISHED;
            self.editedText = null;
            self.updating = false;
            self.publishConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_SEND_PROP', yes: 'STR_YES' };
            self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES' };
            var previousIsPublished = null;
            var createDisabled = false;

            self.editor = {
                'menu': []
            };

            function setMode(mode) {
                self.mode = mode;
            }

            function setProposal(proposal) {
                if (angular.isObject(proposal)) {
                    self.uiProposal = proposal;
                    setMode(PROP.MODE.COLLAPSED);

                    if (proposal.isOwnProposal) {
                        if (proposal.isPublished === null) {
                            $timeout(function () {
                                setMode(PROP.MODE.EDIT);
                            }, 0);
                            previousIsPublished = proposal.isPublished;
                        }
                    }

                    // missing person name will be replaced by last name and first name
                    if (!self.uiProposal.personName) {
                        var lastName = self.uiProposal.lastName ? self.uiProposal.lastName : '';
                        var space = lastName ? ' ' : '';
                        var firstName = self.uiProposal.firstName ? self.uiProposal.firstName : '';
                        self.uiProposal.personName = lastName + space + firstName;
                    }

                    // delete confirm dialog setup
                    if (self.uiProposal.isPublished) {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PUBLIC_PROP', yes: 'STR_YES' };
                    }
                    else if (self.uiProposal.isPublishedIcon) {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES', optionText: 'STR_CNFM_DEL_PROP_OPT' };
                    }
                    else {
                        self.deleteConfig = { title: 'STR_CONFIRM', text: 'STR_CNFM_DEL_PROP', yes: 'STR_YES' };
                    }
                }
            }

            function postProposal(proposal) {
                $log.debug("dbProposal: postProposal: " + JSON.stringify(proposal));
                if (angular.isObject(proposal)) {
                    self.updating = true;

                    var copy = angular.copy(proposal);
                    if (copy.isPublished === null) {
                        copy.isPublished = PROPS.PUBLISHED.NO;
                    }
                    else if (copy.isPublished === PROPS.PUBLISHED.NO) {
                        copy.isPublished = PROPS.PUBLISHED.YES;
                    }

                    AhjoProposalsSrv.post(copy).$promise.then(function (response) {
                        $log.debug("dbProposal: post then: " + JSON.stringify(response));
                        if (angular.isObject(response) && angular.isObject(response.Data)) {
                            if (copy.isPublished === PROPS.PUBLISHED.NO) {
                                angular.merge($scope.proposal, response.Data);
                                $rootScope.successInfo('STR_SAVE_SUCCESS');
                            }
                            else if (copy.isPublished === PROPS.PUBLISHED.YES) {
                                $scope.proposal.isPublishedIcon = PROPS.PUBLISHED.YES;
                                angular.merge(copy, response.Data);
                                // proposal guid copy needs to be copied
                                // otherwise published version deletion is not working
                                $scope.proposal.proposalGuidCopy = copy.proposalGuid;
                                $scope.onAdd({ data: { proposal: copy } });
                                $rootScope.successInfo('STR_PUBLISH_SUCCESS');
                            }
                            else {
                                $log.error('dbProposal: postProposal unsupported status');
                            }
                        }
                        else {
                            $log.error('dbProposal: postProposal invalid response');
                        }
                    }, function (error) {
                        $log.error("dbProposal: post error: " + JSON.stringify(error));
                        $rootScope.failedInfo('STR_SAVE_FAILED');
                    }).finally(function () {
                        $log.debug("dbProposal: post finally: ");
                        self.updating = false;
                        $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
                    });
                }
                else {
                    $log.error('dbProposal: postProposal invalid parameter');
                }
            }

            function deleteProposal(proposal) {
                $log.debug("dbProposal: deleteProposal: " + JSON.stringify(proposal));
                if (angular.isObject(proposal)) {
                    if (proposal.isPublished === PROPS.PUBLISHED.NO || proposal.isPublished === PROPS.PUBLISHED.YES) {
                        self.updating = true;
                        AhjoProposalsSrv.delete(proposal).$promise.then(function (response) {
                            $log.debug("dbProposal: delete then: " + JSON.stringify(response));
                            if (angular.isObject(response) && angular.isObject(response.Data)) {
                                $scope.onRemove({ data: { 'proposal': response.Data } });
                                $rootScope.successInfo('STR_DELETE_SUCCESS');
                            }
                            else {
                                $log.error('dbProposal: deleteProposal invalid response');
                            }
                        }, function (error) {
                            $log.error("dbProposal: delete error: " + JSON.stringify(error));
                            $rootScope.failedInfo('STR_DELETE_FAILED');
                        }).finally(function () {
                            $log.debug("dbProposal: delete finally: ");
                            self.updating = false;
                        });
                    }
                    else {
                        $scope.onRemove({ data: { 'proposal': proposal } });
                    }
                }
                else {
                    $log.error('dbProposal: deleteProposal invalid parameter');
                }
            }

            function updatePolledEvents() {
                $log.debug("dbProposal: updatePolledEvents");
                var events = angular.copy(StorageSrv.getKey(CONST.KEY.PROPOSAL_EVENT_ARRAY));
                if (angular.isArray(events)) {
                    var found = false;
                    for (var index = events.length + CONST.NOTFOUND; index > CONST.NOTFOUND; index--) {
                        var event = events[index];
                        if (angular.isObject(event.proposal) && angular.equals(event.proposal.proposalGuid, $scope.proposal.proposalGuid)) {
                            events.splice(index, 1);
                            found = true;
                        }
                    }
                    if (found) {
                        StorageSrv.setKey(CONST.KEY.PROPOSAL_EVENT_ARRAY, events);
                    }
                }
            }

            self.typeText = function (value) {
                var obj = Utils.objWithVal(PROPS.TYPE, 'value', value);
                return (obj && obj.text) ? obj.text : value;
            };

            self.itemClicked = function () {
                if (self.mode === PROP.MODE.COLLAPSED) {
                    setMode(PROP.MODE.OPEN);
                }
                else if (self.mode === PROP.MODE.OPEN) {
                    setMode(PROP.MODE.COLLAPSED);
                }
            };

            self.toggleCollapse = function () {
                if (self.mode === PROP.MODE.COLLAPSED) {
                    setMode(PROP.MODE.OPEN);
                    if (self.uiProposal.isModified) {
                        updatePolledEvents();
                        $scope.proposal.isModified = false;
                    }
                }
                else {
                    setMode(PROP.MODE.COLLAPSED);
                }
            };

            self.edit = function () {
                self.editedText = $scope.proposal.text;
                previousIsPublished = $scope.proposal.isPublished;
                $scope.proposal.isPublished = null;
                setMode(PROP.MODE.EDIT);
                $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
            };

            self.remove = function (data) {
                deleteProposal($scope.proposal);
                if (angular.isObject(data) && data.value === true) {
                    $rootScope.$emit(PROPS.REMOVE, { guid: $scope.proposal.proposalGuidCopy });
                }
            };

            self.accept = function () {
                $scope.proposal.text = self.editedText ? self.editedText : '';
                postProposal($scope.proposal);
                setMode(PROP.MODE.OPEN);
            };

            self.cancel = function () {
                $scope.proposal.isPublished = previousIsPublished;
                if ($scope.proposal.isPublished === null) {
                    deleteProposal($scope.proposal);
                }
                setMode(PROP.MODE.OPEN);
                $rootScope.$emit(PROPS.UPDATED, { sender: $scope.proposal });
            };

            self.send = function () {
                postProposal($scope.proposal);
            };

            setProposal($scope.proposal);

            $scope.$watch(function () {
                return {
                    proposal: $scope.proposal
                };
            }, function (data) {
                // scope.proposal is acting level and self.uiProposal is showing level
                // this is implemented for performance reasons to avoid two way binding
                // when data is changed in acting level it will be updated to showing level via setProposal function
                if (!angular.equals(data.proposal, self.uiProposal)) {
                    setProposal(data.proposal);
                }
            }, true);

            $scope.$watch(function () {
                return {
                    disableCreate: $scope.disableCreate
                };
            }, function (data) {
                if (angular.isObject(data)) {
                    if (createDisabled !== data.disableCreate) {
                        createDisabled = data.disableCreate;
                    }
                }
            }, true);

            var watcher = $rootScope.$on(PROPS.TOGGLE, function (event, data) {
                if (($scope.proposal.isPublished === PROPS.PUBLISHED.YES)) {
                    if (data) {
                        setMode(PROP.MODE.OPEN);
                    }
                    else {
                        setMode(PROP.MODE.COLLAPSED);
                    }
                }
            });

            var removeWatcher = $rootScope.$on(PROPS.REMOVE, function (event, data) {
                if (angular.isObject(data)) {
                    if (angular.equals(data.guid, $scope.proposal.proposalGuid)) {
                        deleteProposal($scope.proposal);
                    }
                }
                else {
                    $log.error('dbProposal: removeWatcher missing data');
                }
            });

            $scope.$on('$destroy', watcher);
            $scope.$on('$destroy', removeWatcher);

            $scope.$on('$destroy', function () {
                $log.debug("dbProposal: DESTROY");
            });
        }];

        return {
            scope: {
                proposal: '=',
                guid: '=',
                disableCreate: '=',
                onRemove: '&',
                onAdd: '&'
            },
            templateUrl: 'views/proposal.directive.html',
            restrict: 'AE',
            controller: controller,
            controllerAs: 'c',
            replace: 'true'
        };
    }]);
<|endoftext|>


<commit_before>/**
 * (c) 2016 Tieto Finland Oy
 * Licensed under the MIT license.
 */
'use strict';

/**
 * @ngdoc directive
 * @name dashboard.textareaDirective
 * @description
 * # textareaDirective
 */
angular.module('dashboard')
    .directive('dbTextarea', ['$timeout', function ($timeout) {
        return {
            scope: false,
            restrict: 'A',
            replace: 'true',
            link: function (scope, element/*, attrs*/) {
                scope.initialHeight = scope.initialHeight || element[0].style.height;
                var resize = function resize() {
                    element.css('height', element[0].scrollHeight + "px");
                };

                scope.$watch(
                    function () {
                        return element[0].scrollHeight;
                    },
                    function () {
                        $timeout(resize, 0);
                    },
                    true
                );
            }
        };
    }]);
<commit_msg>unused code removed<commit_after>/**
 * (c) 2016 Tieto Finland Oy
 * Licensed under the MIT license.
 */
'use strict';

/**
 * @ngdoc directive
 * @name dashboard.textareaDirective
 * @description
 * # textareaDirective
 */
angular.module('dashboard')
    .directive('dbTextarea', ['$timeout', function ($timeout) {
        return {
            scope: false,
            restrict: 'A',
            replace: 'true',
            link: function (scope, element/*, attrs*/) {

                var resize = function resize() {
                    element.css('height', element[0].scrollHeight + "px");
                };

                scope.$watch(
                    function () {
                        return element[0].scrollHeight;
                    },
                    function () {
                        $timeout(resize, 0);
                    },
                    true
                );
            }
        };
    }]);
<|endoftext|>


<commit_before>goog.provide('gmf.AbstractController');

goog.require('gmf');
/** @suppress {extraRequire} */
goog.require('gmf.QueryManager');
/** @suppress {extraRequire} */
goog.require('gmf.TreeManager');
/** @suppress {extraRequire} */
goog.require('gmf.Themes');
/** @suppress {extraRequire} */
goog.require('gmf.layertreeDirective');
/** @suppress {extraRequire} */
goog.require('gmf.mapDirective');
/** @suppress {extraRequire} */
goog.require('gmf.searchDirective');
/** @suppress {extraRequire} */
goog.require('gmf.themeselectorDirective');
goog.require('ngeo.FeatureOverlayMgr');
goog.require('ngeo.GetBrowserLanguage');
goog.require('ngeo.StateManager');
goog.require('ngeo.ToolActivate');
goog.require('ngeo.ToolActivateMgr');

/**
 * Application abstract controller.
 *
 * This file includes `goog.require` for base components/directives used
 * by the HTML page and the controller to provide the configuration.
 *
 * @param {gmfx.Config} config A part of the application config.
 * @param {angular.Scope} $scope Scope.
 * @param {angular.$injector} $injector Main injector.
 * @constructor
 * @ngInject
 * @export
 */
gmf.AbstractController = function(config, $scope, $injector) {

  goog.asserts.assertInstanceof(this.map, ol.Map);

  var gmfTreeManager = $injector.get('gmfTreeManager');
  /**
   * A reference to the current theme
   * @type {GmfThemesNode}
   * @export
   */
  this.theme = gmfTreeManager.tree;

  /**
   * Themes service
   * @type {gmf.Themes}
   */
  var gmfThemes = $injector.get('gmfThemes');
  gmfThemes.loadThemes();

  /**
   * @type {Array.<gmfx.SearchDirectiveDatasource>}
   * @export
   */
  this.searchDatasources = [{
    labelKey: 'label',
    groupValues: /** @type {Array.<string>} **/ ($injector.get('gmfSearchGroups')),
    groupActions: /** @type {Array.<string>} **/ ($injector.get('gmfSearchActions')),
    projection: 'EPSG:' + (config.srid || 21781),
    url: /** @type {string} **/ ($injector.get('fulltextsearchUrl'))
  }];

  /**
   * @type {Array.<string>}
   * @export
   */
  this.searchCoordinatesProjections = ['EPSG:21781', 'EPSG:2056', 'EPSG:4326']

  /**
   * @type {boolean}
   * @export
   */
  this.leftNavVisible = false;

  /**
   * @type {boolean}
   * @export
   */
  this.rightNavVisible = false;

  /**
   * The active state of the ngeo query directive.
   * @type {boolean}
   * @export
   */
  this.queryActive = true;

  // Not used in this file but the QueryManager must be injected to be watched.
  $injector.get('gmfQueryManager');

  /**
   * The active state of the directive responsible of point measurements.
   * @type {boolean}
   * @export
   */
  this.measurePointActive = false;

  /**
   * The active state of the directive responsible of length measurements.
   * @type {boolean}
   * @export
   */
  this.measureLengthActive = false;

  /**
   * @type {gmf.User}
   * @export
   */
  this.gmfUser = $injector.get('gmfUser');

  // close right nave on successful login
  $scope.$watch(function() {
    return this.gmfUser.username;
  }.bind(this), function(newVal) {
    if (newVal !== null && this.navIsVisible) {
      this.rightNavVisible = false;
    }
  }.bind(this));

  /**
   * @type {ngeo.GetBrowserLanguage}
   */
  this.getBrowserLanguage = $injector.get('ngeoGetBrowserLanguage');

  /**
   * @type {ngeo.StateManager}
   */
  this.stateManager = $injector.get('ngeoStateManager');

  /**
   * @type {angular.Scope}
   */
  this.$scope = $scope;

  /**
   * Default language
   * @type {string}
   */
  this.defaultLang = $injector.get('defaultLang');

  /**
   * Languages URL
   * @type {!Object.<string, string>}
   */
  this.langUrls = $injector.get('langUrls');

  /**
   * The gettext catalog
   * @type {angularGettext.Catalog}
   */
  this.gettextCatalog = $injector.get('gettextCatalog');

  this.initLanguage();

  /**
   * The ngeo feature overlay manager service
   * @type {ngeo.FeatureOverlayMgr}
   */
  var ngeoFeatureOverlayMgr = $injector.get('ngeoFeatureOverlayMgr');
  ngeoFeatureOverlayMgr.init(this.map);

  /**
   * The ngeo ToolActivate manager service.
   * @type {ngeo.ToolActivateMgr}
   */
  var ngeoToolActivateMgr = $injector.get('ngeoToolActivateMgr');

  var queryToolActivate = new ngeo.ToolActivate(this, 'queryActive');
  ngeoToolActivateMgr.registerTool('mapTools', queryToolActivate, true);

  var measurePointActivate = new ngeo.ToolActivate(this, 'measurePointActive');
  ngeoToolActivateMgr.registerTool('mapTools', measurePointActivate, false);

  var measureLengthActivate = new ngeo.ToolActivate(
      this, 'measureLengthActive');
  ngeoToolActivateMgr.registerTool('mapTools', measureLengthActivate, false);

};

/**
 * @param {string} lang Language code.
 * @export
 */
gmf.AbstractController.prototype.switchLanguage = function(lang) {
  goog.asserts.assert(lang in this.langUrls);
  this.gettextCatalog.setCurrentLanguage(lang);
  this.gettextCatalog.loadRemote(this.langUrls[lang]);
  this['lang'] = lang;
};

/**
 */
gmf.AbstractController.prototype.initLanguage = function() {
  this.$scope.$watch(function() {
    return this['lang'];
  }.bind(this), function(newValue) {
    this.stateManager.updateState({
      'lang': newValue
    });
  }.bind(this));

  var browserLanguage = /** @type {string|undefined} */
      (this.getBrowserLanguage(Object.keys(this.langUrls)));
  var urlLanguage = /** @type {string|undefined} */
      (this.stateManager.getInitialValue('lang'));

  if (urlLanguage !== undefined && urlLanguage in this.langUrls) {
    this.switchLanguage(urlLanguage);
    return;
  } else if (browserLanguage !== undefined && browserLanguage in this.langUrls) {
    this.switchLanguage(browserLanguage);
    return;
  } else {
    // if there is no information about language preference,
    // fallback to default language

    this.switchLanguage(this.defaultLang);
    return;
  }
};

gmf.module.controller('AbstractController', gmf.AbstractController);
<commit_msg>Determine the background layer in gmf.AbstractController<commit_after>goog.provide('gmf.AbstractController');

goog.require('gmf');
/** @suppress {extraRequire} */
goog.require('gmf.QueryManager');
/** @suppress {extraRequire} */
goog.require('gmf.TreeManager');
/** @suppress {extraRequire} */
goog.require('gmf.Themes');
/** @suppress {extraRequire} */
goog.require('gmf.layertreeDirective');
/** @suppress {extraRequire} */
goog.require('gmf.mapDirective');
/** @suppress {extraRequire} */
goog.require('gmf.searchDirective');
/** @suppress {extraRequire} */
goog.require('gmf.themeselectorDirective');
/** @suppress {extraRequire} */
goog.require('ngeo.BackgroundLayerMgr');
goog.require('ngeo.FeatureOverlayMgr');
goog.require('ngeo.GetBrowserLanguage');
goog.require('ngeo.StateManager');
goog.require('ngeo.ToolActivate');
goog.require('ngeo.ToolActivateMgr');

/**
 * Application abstract controller.
 *
 * This file includes `goog.require` for base components/directives used
 * by the HTML page and the controller to provide the configuration.
 *
 * @param {gmfx.Config} config A part of the application config.
 * @param {angular.Scope} $scope Scope.
 * @param {angular.$injector} $injector Main injector.
 * @constructor
 * @ngInject
 * @export
 */
gmf.AbstractController = function(config, $scope, $injector) {

  goog.asserts.assertInstanceof(this.map, ol.Map);

  var gmfTreeManager = $injector.get('gmfTreeManager');
  /**
   * A reference to the current theme
   * @type {GmfThemesNode}
   * @export
   */
  this.theme = gmfTreeManager.tree;

  /**
   * Themes service
   * @type {gmf.Themes}
   */
  var gmfThemes = $injector.get('gmfThemes');
  gmfThemes.loadThemes();

  /**
   * @type {Array.<gmfx.SearchDirectiveDatasource>}
   * @export
   */
  this.searchDatasources = [{
    labelKey: 'label',
    groupValues: /** @type {Array.<string>} **/ ($injector.get('gmfSearchGroups')),
    groupActions: /** @type {Array.<string>} **/ ($injector.get('gmfSearchActions')),
    projection: 'EPSG:' + (config.srid || 21781),
    url: /** @type {string} **/ ($injector.get('fulltextsearchUrl'))
  }];

  /**
   * @type {Array.<string>}
   * @export
   */
  this.searchCoordinatesProjections = ['EPSG:21781', 'EPSG:2056', 'EPSG:4326']

  /**
   * @type {boolean}
   * @export
   */
  this.leftNavVisible = false;

  /**
   * @type {boolean}
   * @export
   */
  this.rightNavVisible = false;

  /**
   * The active state of the ngeo query directive.
   * @type {boolean}
   * @export
   */
  this.queryActive = true;

  // Not used in this file but the QueryManager must be injected to be watched.
  $injector.get('gmfQueryManager');

  /**
   * The active state of the directive responsible of point measurements.
   * @type {boolean}
   * @export
   */
  this.measurePointActive = false;

  /**
   * The active state of the directive responsible of length measurements.
   * @type {boolean}
   * @export
   */
  this.measureLengthActive = false;

  /**
   * @type {gmf.User}
   * @export
   */
  this.gmfUser = $injector.get('gmfUser');

  // close right nave on successful login
  $scope.$watch(function() {
    return this.gmfUser.username;
  }.bind(this), function(newVal) {
    if (newVal !== null && this.navIsVisible) {
      this.rightNavVisible = false;
    }
  }.bind(this));

  /**
   * @type {ngeo.GetBrowserLanguage}
   */
  this.getBrowserLanguage = $injector.get('ngeoGetBrowserLanguage');

  /**
   * @type {ngeo.StateManager}
   */
  this.stateManager = $injector.get('ngeoStateManager');

  /**
   * @type {angular.Scope}
   */
  this.$scope = $scope;

  /**
   * Default language
   * @type {string}
   */
  this.defaultLang = $injector.get('defaultLang');

  /**
   * Languages URL
   * @type {!Object.<string, string>}
   */
  this.langUrls = $injector.get('langUrls');

  /**
   * The gettext catalog
   * @type {angularGettext.Catalog}
   */
  this.gettextCatalog = $injector.get('gettextCatalog');

  this.initLanguage();

  /**
   * The ngeo feature overlay manager service
   * @type {ngeo.FeatureOverlayMgr}
   */
  var ngeoFeatureOverlayMgr = $injector.get('ngeoFeatureOverlayMgr');
  ngeoFeatureOverlayMgr.init(this.map);

  /**
   * The ngeo ToolActivate manager service.
   * @type {ngeo.ToolActivateMgr}
   */
  var ngeoToolActivateMgr = $injector.get('ngeoToolActivateMgr');

  var queryToolActivate = new ngeo.ToolActivate(this, 'queryActive');
  ngeoToolActivateMgr.registerTool('mapTools', queryToolActivate, true);

  var measurePointActivate = new ngeo.ToolActivate(this, 'measurePointActive');
  ngeoToolActivateMgr.registerTool('mapTools', measurePointActivate, false);

  var measureLengthActivate = new ngeo.ToolActivate(
      this, 'measureLengthActive');
  ngeoToolActivateMgr.registerTool('mapTools', measureLengthActivate, false);

  gmfThemes.getBgLayers().then(function(layers) {
    // get the background from the permalink
    var permalink = $injector.get('gmfPermalink');
    var background = permalink.getBackgroundLayer(layers);
    if (!background) {
      // get the background from the user settings
      var functionalities = this.gmfUser.functionalities;
      if (functionalities) {
        var defaultBasemapArray = functionalities.default_basemap;
        if (defaultBasemapArray.length > 0) {
          var defaultBasemapLabel = defaultBasemapArray[0];
          background = ol.array.find(layers, function(layer) {
            return layer.get('label') === defaultBasemapLabel;
          });
        }
      }
    }
    if (!background) {
      // fallback to the layers list, use the second one because the first
      // is the blank layer
      background = layers[1];
    }

    var backgroundLayerMgr = $injector.get('ngeoBackgroundLayerMgr');
    backgroundLayerMgr.set(this.map, background);
  }.bind(this));

};

/**
 * @param {string} lang Language code.
 * @export
 */
gmf.AbstractController.prototype.switchLanguage = function(lang) {
  goog.asserts.assert(lang in this.langUrls);
  this.gettextCatalog.setCurrentLanguage(lang);
  this.gettextCatalog.loadRemote(this.langUrls[lang]);
  this['lang'] = lang;
};

/**
 */
gmf.AbstractController.prototype.initLanguage = function() {
  this.$scope.$watch(function() {
    return this['lang'];
  }.bind(this), function(newValue) {
    this.stateManager.updateState({
      'lang': newValue
    });
  }.bind(this));

  var browserLanguage = /** @type {string|undefined} */
      (this.getBrowserLanguage(Object.keys(this.langUrls)));
  var urlLanguage = /** @type {string|undefined} */
      (this.stateManager.getInitialValue('lang'));

  if (urlLanguage !== undefined && urlLanguage in this.langUrls) {
    this.switchLanguage(urlLanguage);
    return;
  } else if (browserLanguage !== undefined && browserLanguage in this.langUrls) {
    this.switchLanguage(browserLanguage);
    return;
  } else {
    // if there is no information about language preference,
    // fallback to default language

    this.switchLanguage(this.defaultLang);
    return;
  }
};

gmf.module.controller('AbstractController', gmf.AbstractController);
<|endoftext|>


<commit_before>backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, AppUtils, gettextCatalog) {

    var longpolltime = 5 * 60 * 1000;

    var waitingfortask = {};

    var state = {
        lastEventId: -1,
        lastDataUpdateId: -1,
        lastNotificationUpdateId: -1,
        estimatedPauseEnd: new Date("0001-01-01T00:00:00"),
        activeTask: null,
        programState: null,
        lastErrorMessage: null,
        connectionState: 'connected',
        xsfrerror: false,
        connectionAttemptTimer: 0,
        failedConnectionAttempts: 0,
        lastPgEvent: null,
        updaterState: 'Waiting',
        updatedVersion: null,
        updateReady: false,
        updateDownloadProgress: 0,
        proposedSchedule: [],
        schedulerQueueIds: []
    };

    this.state = state;
    var self = this;

    function reloadTexts() {
        self.progress_state_text = {
            'Backup_Begin': gettextCatalog.getString('Starting ...'),
            'Backup_PreBackupVerify': gettextCatalog.getString('Verifying backend data ...'),
            'Backup_PostBackupTest': gettextCatalog.getString('Verifying remote data ...'),
            'Backup_PreviousBackupFinalize': gettextCatalog.getString('Completing previous backup ...'),
            'Backup_ProcessingFiles': null,
            'Backup_Finalize': gettextCatalog.getString('Completing backup ...'),
            'Backup_WaitForUpload': gettextCatalog.getString('Waiting for upload ...'),
            'Backup_Delete': gettextCatalog.getString('Deleting unwanted files ...'),
            'Backup_Compact': gettextCatalog.getString('Compacting remote data ...'),
            'Backup_VerificationUpload': gettextCatalog.getString('Uploading verification file ...'),
            'Backup_PostBackupVerify': gettextCatalog.getString('Verifying backend data ...'),
            'Backup_Complete': gettextCatalog.getString('Finished!'),
            'Restore_Begin': gettextCatalog.getString('Starting ...'),
            'Restore_RecreateDatabase': gettextCatalog.getString('Rebuilding local database ...'),
            'Restore_PreRestoreVerify': gettextCatalog.getString('Verifying remote data ...'),
            'Restore_CreateFileList': gettextCatalog.getString('Building list of files to restore ...'),
            'Restore_CreateTargetFolders': gettextCatalog.getString('Creating target folders ...'),
            'Restore_ScanForExistingFiles': gettextCatalog.getString('Scanning existing files ...'),
            'Restore_ScanForLocalBlocks': gettextCatalog.getString('Scanning for local blocks ...'),
            'Restore_PatchWithLocalBlocks': gettextCatalog.getString('Patching files with local blocks ...'),
            'Restore_DownloadingRemoteFiles': gettextCatalog.getString('Downloading files ...'),
            'Restore_PostRestoreVerify': gettextCatalog.getString('Verifying restored files ...'),
            'Restore_Complete': gettextCatalog.getString('Finished!'),
            'Recreate_Running': gettextCatalog.getString('Recreating database ...'),
            'Repair_Running': gettextCatalog.getString('Reparing ...'),
            'Verify_Running': gettextCatalog.getString('Verifying ...'),
            'BugReport_Running': gettextCatalog.getString('Creating bug report ...'),
            'Delete_Listing': gettextCatalog.getString('Listing remote files ...'),
            'Delete_Deleting': gettextCatalog.getString('Deleting remote files ...'),
            'Error': gettextCatalog.getString('Error!')
        };
    };

    reloadTexts();
    $rootScope.$on('gettextLanguageChanged', reloadTexts);

    this.watch = function(scope, m) {
        scope.$on('serverstatechanged', function() {
            $timeout(function() {
                if (m) m();
                scope.$digest();
            });
        });

        if (m) $timeout(m);
        return state;
    }

    this.resume = function() {
        return AppService.post('/serverstate/resume');
    };

    this.pause = function(duration) {
        return AppService.post('/serverstate/pause' + (duration == null ? '' : '?duration=' + duration));
    };

    this.callWhenTaskCompletes = function(taskid, callback) {
        if (waitingfortask[taskid] == null)
            waitingfortask[taskid] = [];
        waitingfortask[taskid].push(callback);
    };

    var lastTaskId = null;
    $rootScope.$on('serverstatechanged.activeTask', function() {
        var currentTaskId = state.activeTask == null ? null : state.activeTask.Item1;

        if (lastTaskId != null && currentTaskId != lastTaskId && waitingfortask[lastTaskId] != null) {
            for(var i in waitingfortask[lastTaskId])
                waitingfortask[lastTaskId][i]();
            delete waitingfortask[lastTaskId];
        }

        lastTaskId = currentTaskId;
    });

    var progressPollTimer = null;
    var progressPollInProgress = false;
    var progressPollWait = 2000;

    function startUpdateProgressPoll() {
        if (progressPollInProgress)
            return;

        if (state.activeTask == null) {
            if (progressPollTimer != null)
                clearTimeout(progressPollTimer);
            progressPollTimer = null;
            state.lastPgEvent = null;
        } else {
            progressPollInProgress = true;

            if (progressPollTimer != null)
                clearTimeout(progressPollTimer);
            progressPollTimer = null;

            AppService.get('/progressstate').then(
                function(resp) {
                    state.lastPgEvent = resp.data;
                    progressPollInProgress = false;
                    progressPollTimer = setTimeout(startUpdateProgressPoll, progressPollWait);
                },

                function(resp) {
                    progressPollInProgress = false;
                    progressPollTimer = setTimeout(startUpdateProgressPoll, progressPollWait);
                }
            );
        }
    };

    var longPollRetryTimer = null;
    var countdownForForReLongPoll = function(m) {
        if (longPollRetryTimer != null) {
            window.clearInterval(longPollRetryTimer);
            longPollRetryTimer = null;
        }

        var retryAt = new Date(new Date().getTime() + (state.xsfrerror ? 5000 : 15000));
        state.connectionAttemptTimer = new Date() - retryAt;
        $rootScope.$broadcast('serverstatechanged');

        longPollRetryTimer = window.setInterval(function() {
            state.connectionAttemptTimer = retryAt - new Date();
            if (state.connectionAttemptTimer <= 0)
                m();
            else {
                $rootScope.$broadcast('serverstatechanged');
            }

        }, 1000);
    };

    var updatepausetimer = null;
    function pauseTimerUpdater(skipNotify) {
        var prev = state.pauseTimeRemain;

        state.pauseTimeRemain = Math.max(0, AppUtils.parseDate(state.estimatedPauseEnd) - new Date());
        if (state.pauseTimeRemain > 0 && updatepausetimer == null) {
            updatepausetimer = setInterval(pauseTimerUpdater, 500);
        } else if (state.pauseTimeRemain <= 0 && updatepausetimer != null) {
            clearInterval(updatepausetimer);
            updatepausetimer = null;
        }

        if (prev != state.pauseTimeRemain && !skipNotify)
            $rootScope.$broadcast('serverstatechanged.pauseTimeRemain', state.pauseTimeRemain);

        return prev != state.pauseTimeRemain;
    }

    var notifyIfChanged = function (data, dataname, varname) {
        if (state[varname] != data[dataname]) {
            state[varname] = data[dataname];
            $rootScope.$broadcast('serverstatechanged.' + varname, state[varname]);
            return true;
        }

        return false;
    }

    var longpoll = function() {
        if (longPollRetryTimer != null) {
            window.clearInterval(longPollRetryTimer);
            longPollRetryTimer = null;
        }

        if (state.connectionState != 'connected') {
            state.connectionState = 'connecting';
            $rootScope.$broadcast('serverstatechanged');
        }

        var url = '/serverstate/?lasteventid=' + parseInt(state.lastEventId) + '&longpoll=' + (state.lastEventId > 0 ? 'true' : 'false') + '&duration=' + parseInt((longpolltime-1000) / 1000) + 's';
        AppService.get(url, {timeout: state.lastEventId > 0 ? longpolltime : 5000}).then(
            function (response) {
                var oldEventId = state.lastEventId;
                var anychanged =
                    notifyIfChanged(response.data, 'LastEventID', 'lastEventId') |
                    notifyIfChanged(response.data, 'LastDataUpdateID', 'lastDataUpdateId') |
                    notifyIfChanged(response.data, 'LastNotificationUpdateID', 'lastNotificationUpdateId') |
                    notifyIfChanged(response.data, 'ActiveTask', 'activeTask') |
                    notifyIfChanged(response.data, 'ProgramState', 'programState') |
                    notifyIfChanged(response.data, 'EstimatedPauseEnd', 'estimatedPauseEnd')
                    notifyIfChanged(response.data, 'UpdaterState', 'updaterState') |
                    notifyIfChanged(response.data, 'UpdateReady', 'updateReady') |
                    notifyIfChanged(response.data, 'UpdatedVersion', 'updatedVersion')|
                    notifyIfChanged(response.data, 'UpdateDownloadProgress', 'updateDownloadProgress');

                if (!angular.equals(state.proposedSchedule, response.data.ProposedSchedule)) {
                    state.proposedSchedule.length = 0;
                    state.proposedSchedule.push.apply(state.proposedSchedule, response.data.ProposedSchedule);
                    $rootScope.$broadcast('serverstatechanged.proposedSchedule', state.proposedSchedule);
                    anychanged = true;
                }

                if (!angular.equals(state.schedulerQueueIds, response.data.SchedulerQueueIds)) {
                    state.schedulerQueueIds.length = 0;
                    state.schedulerQueueIds.push.apply(state.schedulerQueueIds, response.data.SchedulerQueueIds);
                    $rootScope.$broadcast('serverstatechanged.schedulerQueueIds', state.schedulerQueueIds);
                    anychanged = true;
                }

                // Clear error indicators
                state.failedConnectionAttempts = 0;
                state.xsfrerror = false;

                if (state.connectionState != 'connected') {
                    state.connectionState = 'connected';
                    $rootScope.$broadcast('serverstatechanged.connectionState', state.connectionState);
                    anychanged = true;

                    // Reload page, server restarted
                    if (oldEventId > state.lastEventId)
                        location.reload(true);
                }

                anychanged |= pauseTimerUpdater(true);

                if (anychanged)
                    $rootScope.$broadcast('serverstatechanged');

                if (state.activeTask != null)
                    startUpdateProgressPoll();

                longpoll();
            },

            function(response) {

                var oldxsfrstate = state.xsfrerror;
                state.failedConnectionAttempts++;
                state.xsfrerror = response.statusText.toLowerCase().indexOf('xsrf') >= 0;

                // First failure, we ignore
                if (state.connectionState == 'connected' && state.failedConnectionAttempts == 1) {

                    // Try again
                    longpoll();
                } else {

                    state.connectionState = 'disconnected';

                    //If we got a new XSRF token this time, quickly retry
                    if (state.xsfrerror && !oldxsfrstate) {
                        longpoll();
                    } else {
                        // Otherwise, start countdown to next try
                        countdownForForReLongPoll(longpoll);
                    }
                }

                // Notify
                $rootScope.$broadcast('serverstatechanged');

            }
        );
    };

    this.reconnect = longpoll;

    longpoll();
});
<commit_msg>bugfix? missing |?<commit_after>backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, AppUtils, gettextCatalog) {

    var longpolltime = 5 * 60 * 1000;

    var waitingfortask = {};

    var state = {
        lastEventId: -1,
        lastDataUpdateId: -1,
        lastNotificationUpdateId: -1,
        estimatedPauseEnd: new Date("0001-01-01T00:00:00"),
        activeTask: null,
        programState: null,
        lastErrorMessage: null,
        connectionState: 'connected',
        xsfrerror: false,
        connectionAttemptTimer: 0,
        failedConnectionAttempts: 0,
        lastPgEvent: null,
        updaterState: 'Waiting',
        updatedVersion: null,
        updateReady: false,
        updateDownloadProgress: 0,
        proposedSchedule: [],
        schedulerQueueIds: []
    };

    this.state = state;
    var self = this;

    function reloadTexts() {
        self.progress_state_text = {
            'Backup_Begin': gettextCatalog.getString('Starting ...'),
            'Backup_PreBackupVerify': gettextCatalog.getString('Verifying backend data ...'),
            'Backup_PostBackupTest': gettextCatalog.getString('Verifying remote data ...'),
            'Backup_PreviousBackupFinalize': gettextCatalog.getString('Completing previous backup ...'),
            'Backup_ProcessingFiles': null,
            'Backup_Finalize': gettextCatalog.getString('Completing backup ...'),
            'Backup_WaitForUpload': gettextCatalog.getString('Waiting for upload ...'),
            'Backup_Delete': gettextCatalog.getString('Deleting unwanted files ...'),
            'Backup_Compact': gettextCatalog.getString('Compacting remote data ...'),
            'Backup_VerificationUpload': gettextCatalog.getString('Uploading verification file ...'),
            'Backup_PostBackupVerify': gettextCatalog.getString('Verifying backend data ...'),
            'Backup_Complete': gettextCatalog.getString('Finished!'),
            'Restore_Begin': gettextCatalog.getString('Starting ...'),
            'Restore_RecreateDatabase': gettextCatalog.getString('Rebuilding local database ...'),
            'Restore_PreRestoreVerify': gettextCatalog.getString('Verifying remote data ...'),
            'Restore_CreateFileList': gettextCatalog.getString('Building list of files to restore ...'),
            'Restore_CreateTargetFolders': gettextCatalog.getString('Creating target folders ...'),
            'Restore_ScanForExistingFiles': gettextCatalog.getString('Scanning existing files ...'),
            'Restore_ScanForLocalBlocks': gettextCatalog.getString('Scanning for local blocks ...'),
            'Restore_PatchWithLocalBlocks': gettextCatalog.getString('Patching files with local blocks ...'),
            'Restore_DownloadingRemoteFiles': gettextCatalog.getString('Downloading files ...'),
            'Restore_PostRestoreVerify': gettextCatalog.getString('Verifying restored files ...'),
            'Restore_Complete': gettextCatalog.getString('Finished!'),
            'Recreate_Running': gettextCatalog.getString('Recreating database ...'),
            'Repair_Running': gettextCatalog.getString('Reparing ...'),
            'Verify_Running': gettextCatalog.getString('Verifying ...'),
            'BugReport_Running': gettextCatalog.getString('Creating bug report ...'),
            'Delete_Listing': gettextCatalog.getString('Listing remote files ...'),
            'Delete_Deleting': gettextCatalog.getString('Deleting remote files ...'),
            'Error': gettextCatalog.getString('Error!')
        };
    };

    reloadTexts();
    $rootScope.$on('gettextLanguageChanged', reloadTexts);

    this.watch = function(scope, m) {
        scope.$on('serverstatechanged', function() {
            $timeout(function() {
                if (m) m();
                scope.$digest();
            });
        });

        if (m) $timeout(m);
        return state;
    }

    this.resume = function() {
        return AppService.post('/serverstate/resume');
    };

    this.pause = function(duration) {
        return AppService.post('/serverstate/pause' + (duration == null ? '' : '?duration=' + duration));
    };

    this.callWhenTaskCompletes = function(taskid, callback) {
        if (waitingfortask[taskid] == null)
            waitingfortask[taskid] = [];
        waitingfortask[taskid].push(callback);
    };

    var lastTaskId = null;
    $rootScope.$on('serverstatechanged.activeTask', function() {
        var currentTaskId = state.activeTask == null ? null : state.activeTask.Item1;

        if (lastTaskId != null && currentTaskId != lastTaskId && waitingfortask[lastTaskId] != null) {
            for(var i in waitingfortask[lastTaskId])
                waitingfortask[lastTaskId][i]();
            delete waitingfortask[lastTaskId];
        }

        lastTaskId = currentTaskId;
    });

    var progressPollTimer = null;
    var progressPollInProgress = false;
    var progressPollWait = 2000;

    function startUpdateProgressPoll() {
        if (progressPollInProgress)
            return;

        if (state.activeTask == null) {
            if (progressPollTimer != null)
                clearTimeout(progressPollTimer);
            progressPollTimer = null;
            state.lastPgEvent = null;
        } else {
            progressPollInProgress = true;

            if (progressPollTimer != null)
                clearTimeout(progressPollTimer);
            progressPollTimer = null;

            AppService.get('/progressstate').then(
                function(resp) {
                    state.lastPgEvent = resp.data;
                    progressPollInProgress = false;
                    progressPollTimer = setTimeout(startUpdateProgressPoll, progressPollWait);
                },

                function(resp) {
                    progressPollInProgress = false;
                    progressPollTimer = setTimeout(startUpdateProgressPoll, progressPollWait);
                }
            );
        }
    };

    var longPollRetryTimer = null;
    var countdownForForReLongPoll = function(m) {
        if (longPollRetryTimer != null) {
            window.clearInterval(longPollRetryTimer);
            longPollRetryTimer = null;
        }

        var retryAt = new Date(new Date().getTime() + (state.xsfrerror ? 5000 : 15000));
        state.connectionAttemptTimer = new Date() - retryAt;
        $rootScope.$broadcast('serverstatechanged');

        longPollRetryTimer = window.setInterval(function() {
            state.connectionAttemptTimer = retryAt - new Date();
            if (state.connectionAttemptTimer <= 0)
                m();
            else {
                $rootScope.$broadcast('serverstatechanged');
            }

        }, 1000);
    };

    var updatepausetimer = null;
    function pauseTimerUpdater(skipNotify) {
        var prev = state.pauseTimeRemain;

        state.pauseTimeRemain = Math.max(0, AppUtils.parseDate(state.estimatedPauseEnd) - new Date());
        if (state.pauseTimeRemain > 0 && updatepausetimer == null) {
            updatepausetimer = setInterval(pauseTimerUpdater, 500);
        } else if (state.pauseTimeRemain <= 0 && updatepausetimer != null) {
            clearInterval(updatepausetimer);
            updatepausetimer = null;
        }

        if (prev != state.pauseTimeRemain && !skipNotify)
            $rootScope.$broadcast('serverstatechanged.pauseTimeRemain', state.pauseTimeRemain);

        return prev != state.pauseTimeRemain;
    }

    var notifyIfChanged = function (data, dataname, varname) {
        if (state[varname] != data[dataname]) {
            state[varname] = data[dataname];
            $rootScope.$broadcast('serverstatechanged.' + varname, state[varname]);
            return true;
        }

        return false;
    }

    var longpoll = function() {
        if (longPollRetryTimer != null) {
            window.clearInterval(longPollRetryTimer);
            longPollRetryTimer = null;
        }

        if (state.connectionState != 'connected') {
            state.connectionState = 'connecting';
            $rootScope.$broadcast('serverstatechanged');
        }

        var url = '/serverstate/?lasteventid=' + parseInt(state.lastEventId) + '&longpoll=' + (state.lastEventId > 0 ? 'true' : 'false') + '&duration=' + parseInt((longpolltime-1000) / 1000) + 's';
        AppService.get(url, {timeout: state.lastEventId > 0 ? longpolltime : 5000}).then(
            function (response) {
                var oldEventId = state.lastEventId;
                var anychanged =
                    notifyIfChanged(response.data, 'LastEventID', 'lastEventId') |
                    notifyIfChanged(response.data, 'LastDataUpdateID', 'lastDataUpdateId') |
                    notifyIfChanged(response.data, 'LastNotificationUpdateID', 'lastNotificationUpdateId') |
                    notifyIfChanged(response.data, 'ActiveTask', 'activeTask') |
                    notifyIfChanged(response.data, 'ProgramState', 'programState') |
                    notifyIfChanged(response.data, 'EstimatedPauseEnd', 'estimatedPauseEnd') |
                    notifyIfChanged(response.data, 'UpdaterState', 'updaterState') |
                    notifyIfChanged(response.data, 'UpdateReady', 'updateReady') |
                    notifyIfChanged(response.data, 'UpdatedVersion', 'updatedVersion')|
                    notifyIfChanged(response.data, 'UpdateDownloadProgress', 'updateDownloadProgress');

                if (!angular.equals(state.proposedSchedule, response.data.ProposedSchedule)) {
                    state.proposedSchedule.length = 0;
                    state.proposedSchedule.push.apply(state.proposedSchedule, response.data.ProposedSchedule);
                    $rootScope.$broadcast('serverstatechanged.proposedSchedule', state.proposedSchedule);
                    anychanged = true;
                }

                if (!angular.equals(state.schedulerQueueIds, response.data.SchedulerQueueIds)) {
                    state.schedulerQueueIds.length = 0;
                    state.schedulerQueueIds.push.apply(state.schedulerQueueIds, response.data.SchedulerQueueIds);
                    $rootScope.$broadcast('serverstatechanged.schedulerQueueIds', state.schedulerQueueIds);
                    anychanged = true;
                }

                // Clear error indicators
                state.failedConnectionAttempts = 0;
                state.xsfrerror = false;

                if (state.connectionState != 'connected') {
                    state.connectionState = 'connected';
                    $rootScope.$broadcast('serverstatechanged.connectionState', state.connectionState);
                    anychanged = true;

                    // Reload page, server restarted
                    if (oldEventId > state.lastEventId)
                        location.reload(true);
                }

                anychanged |= pauseTimerUpdater(true);

                if (anychanged)
                    $rootScope.$broadcast('serverstatechanged');

                if (state.activeTask != null)
                    startUpdateProgressPoll();

                longpoll();
            },

            function(response) {

                var oldxsfrstate = state.xsfrerror;
                state.failedConnectionAttempts++;
                state.xsfrerror = response.statusText.toLowerCase().indexOf('xsrf') >= 0;

                // First failure, we ignore
                if (state.connectionState == 'connected' && state.failedConnectionAttempts == 1) {

                    // Try again
                    longpoll();
                } else {

                    state.connectionState = 'disconnected';

                    //If we got a new XSRF token this time, quickly retry
                    if (state.xsfrerror && !oldxsfrstate) {
                        longpoll();
                    } else {
                        // Otherwise, start countdown to next try
                        countdownForForReLongPoll(longpoll);
                    }
                }

                // Notify
                $rootScope.$broadcast('serverstatechanged');

            }
        );
    };

    this.reconnect = longpoll;

    longpoll();
});
<|endoftext|>


<commit_before>'use strict';

const co = require('co');
const _ = require('lodash');

const api = requireLocal('services/api-proxy');

const sponsoring = {};

/**
 * Sends the occurred error back to the client, and logs it to the bunyan global logger.
 * @param res
 * @param errMsg
 * @param err
 * @returns {*}
 */
const sendErr = (res, errMsg, err) => {

  if (err) logger.error(errMsg, err);
  else logger.error(errMsg);

  res.status(500).send({error: errMsg});
};

/**
 * Creates a sponsoring.
 * @param req
 * @param res
 * @param next
 */

sponsoring.create = (req, res, next) => co(function*() {

  let body = {};
  if (Number(req.body.amountPerKm_range) !== Number(req.body.amountPerKm_text)) {
    return sendErr(res, 'amountPerKm is malformed');
  }

  try {
    let obj = JSON.parse(req.body.team);
    body.team = obj.team;
    body.event = obj.event;
  } catch (ex) {
    return sendErr(res, ex.message, ex);
  }

  body.amountPerKm = req.body.amountPerKm_range;
  if (req.body.limit) body.limit = req.body.limit;
  //TODO add proper limit (BACKEND HACK)
  else body.limit = 1000000000;

  //OFFLINE PART
  if (req.body.street) {
    body.unregisteredSponsor = {};
    body.unregisteredSponsor.address = {
      street: req.body.street,
      housenumber: req.body.housenumber,
      zipcode: req.body.zipcode,
      city: req.body.city,
      country: req.body.country
    };
    body.unregisteredSponsor.firstname = req.body.firstname;
    body.unregisteredSponsor.lastname = req.body.lastname;
    body.unregisteredSponsor.company = req.body.company;
    body.unregisteredSponsor.gender = req.body.gender;

    if (!req.body.url) body.unregisteredSponsor.url = "";
    else body.unregisteredSponsor.url = req.body.url;

    if (req.body.selfChallengeDescription.length !== req.body.selfChallengeAmount.length) {
      return sendErr(res, 'Unequal amount of challenge descriptions and challenge amounts');
    }

    body.challenges = yield req.body.selfChallengeDescription.map(
      (e, i) => {
        let currBody = {
          amount: req.body.selfChallengeAmount[i],
          description: e,
          unregisteredSponsor: body.unregisteredSponsor
        };
        if(currBody.amount > 0) {
          return api.challenge.create(req.user, body.event, body.team, currBody);
        }
        else return null;
      });
  }

  for(var i = 0; i < body.challenges.length; i++) {
    if (body.challenges[i] && req.file) {
      console.log(body.challenges);
      return api.uploadPicture(req.file, body.challenges[i].contract);
    }

  }

  let sponsoring = null;

  if(body.amountPerKm > 0) {
    sponsoring = yield api.sponsoring.create(req.user, body.event, body.team, body);
    if (req.file) {
      yield api.uploadPicture(req.file, sponsoring.contract);
    }
  } else if(req.body.selfChallengeDescription.length === 0) {
    return sendErr(res, 'Missing amountPerKm and challanges, at least one variable has to be present');
  }

  let challengesCreated = body.challenges.reduce((c1, c2) => !!c1 || !!c2);

  if(!challengesCreated && !sponsoring) {
    return sendErr(res, 'Neither sponsorings nor challenges created');
  }

  res.send(sponsoring);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.getAllTeams = (req) => co(function*() {
  const events = yield api.event.all();

  let teamsByEvent = yield events.map((e) => api.getModel(`event/${e.id}/team`, req.user));

  let allTeams = teamsByEvent.map((teams, index) => {
    return teams.map(team => {
      team.city = events[index].city;
      team.event = events[index].id;
      return team;
    });
  });

  allTeams = _.flatten(allTeams);
  allTeams = allTeams.filter(t => t.members.length === 2);
  return _.sortBy(allTeams,t => t.name);

}).catch(ex => {
  throw ex;
});

sponsoring.getByTeam = (req) => co(function*() {

  let allSponsorings = yield api.sponsoring.getByTeam(
    req.user.me.participant.eventId,
    req.user.me.participant.teamId);

  let callSponsorings = allSponsorings.filter(c => !!c.userId);

  let sponsors = yield callSponsorings.map(s => api.user.get(s.userId));

  return allSponsorings.map(sponsoring => {
    sponsoring.sponsor = sponsors.filter(s => s.id = sponsoring.userId)[0];
    return sponsoring;
  });

}).catch(ex => {
  throw ex;
});

sponsoring.getBySponsor = (req) => co(function*() {

  return yield api.sponsoring.getBySponsor(
    req.user,
    req.user.me.id);

}).catch(ex => {
  throw ex;
});

sponsoring.accept = (req, res, next) => co(function*() {

  yield api.sponsoring.accept(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.reject = (req, res, next) => co(function*() {

  yield api.sponsoring.reject(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.delete = (req, res, next) => co(function*() {

  yield api.sponsoring.delete(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge = {};

sponsoring.challenge.create = (req, res, next) => co(function*() {

  let body = {};

  try {
    let obj = JSON.parse(req.body.addChallengeTeam);
    body.team = obj.team;
    body.event = obj.event;
  } catch (ex) {
    return sendErr(res, ex.message, ex);
  }

  if (req.body.addChallengeDescription.length !== req.body.addChallengeAmount.length) {
    return sendErr(res, 'Unequal amount of challenge descriptions and challenge amounts');
  }

  let test = yield req.body.addChallengeDescription.map(
    (e, i) => {
      let currBody = {
        amount: req.body.addChallengeAmount[i],
        description: e
      };
      return api.challenge.create(req.user, body.event, body.team, currBody)
    });

  res.sendStatus(200);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.getByTeam = (req) => co(function*() {

  let allChallenges = yield api.challenge.getByTeam(
    req.user.me.participant.eventId,
    req.user.me.participant.teamId);

  let callChallenges = allChallenges.filter(c => !!c.userId);

  let sponsors = yield callChallenges.map(c => api.user.get(c.userId));

  return allChallenges.map(challenge => {
    challenge.sponsor = sponsors.filter(s => s.id = challenge.userId)[0];
    return challenge;
  });

}).catch(ex => {
  throw ex;
});

sponsoring.challenge.getBySponsor = (req) => co(function*() {

  return yield api.challenge.getBySponsor(
    req.user,
    req.user.me.id);

}).catch(ex => {
  throw ex;
});

sponsoring.challenge.accept = (req, res, next) => co(function*() {

  yield api.challenge.accept(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.reject = (req, res, next) => co(function*() {

  yield api.challenge.reject(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.delete = (req, res, next) => co(function*() {

  yield api.challenge.delete(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

module.exports = sponsoring;<commit_msg>only returns fully paid teams in sponsoring view<commit_after>'use strict';

const co = require('co');
const _ = require('lodash');

const api = requireLocal('services/api-proxy');

const sponsoring = {};

/**
 * Sends the occurred error back to the client, and logs it to the bunyan global logger.
 * @param res
 * @param errMsg
 * @param err
 * @returns {*}
 */
const sendErr = (res, errMsg, err) => {

  if (err) logger.error(errMsg, err);
  else logger.error(errMsg);

  res.status(500).send({error: errMsg});
};

/**
 * Creates a sponsoring.
 * @param req
 * @param res
 * @param next
 */

sponsoring.create = (req, res, next) => co(function*() {

  let body = {};
  if (Number(req.body.amountPerKm_range) !== Number(req.body.amountPerKm_text)) {
    return sendErr(res, 'amountPerKm is malformed');
  }

  try {
    let obj = JSON.parse(req.body.team);
    body.team = obj.team;
    body.event = obj.event;
  } catch (ex) {
    return sendErr(res, ex.message, ex);
  }

  body.amountPerKm = req.body.amountPerKm_range;
  if (req.body.limit) body.limit = req.body.limit;
  //TODO add proper limit (BACKEND HACK)
  else body.limit = 1000000000;

  //OFFLINE PART
  if (req.body.street) {
    body.unregisteredSponsor = {};
    body.unregisteredSponsor.address = {
      street: req.body.street,
      housenumber: req.body.housenumber,
      zipcode: req.body.zipcode,
      city: req.body.city,
      country: req.body.country
    };
    body.unregisteredSponsor.firstname = req.body.firstname;
    body.unregisteredSponsor.lastname = req.body.lastname;
    body.unregisteredSponsor.company = req.body.company;
    body.unregisteredSponsor.gender = req.body.gender;

    if (!req.body.url) body.unregisteredSponsor.url = "";
    else body.unregisteredSponsor.url = req.body.url;

    if (req.body.selfChallengeDescription.length !== req.body.selfChallengeAmount.length) {
      return sendErr(res, 'Unequal amount of challenge descriptions and challenge amounts');
    }

    body.challenges = yield req.body.selfChallengeDescription.map(
      (e, i) => {
        let currBody = {
          amount: req.body.selfChallengeAmount[i],
          description: e,
          unregisteredSponsor: body.unregisteredSponsor
        };
        if(currBody.amount > 0) {
          return api.challenge.create(req.user, body.event, body.team, currBody);
        }
        else return null;
      });
  }

  for(var i = 0; i < body.challenges.length; i++) {
    if (body.challenges[i] && req.file) {
      console.log(body.challenges);
      return api.uploadPicture(req.file, body.challenges[i].contract);
    }

  }

  let sponsoring = null;

  if(body.amountPerKm > 0) {
    sponsoring = yield api.sponsoring.create(req.user, body.event, body.team, body);
    if (req.file) {
      yield api.uploadPicture(req.file, sponsoring.contract);
    }
  } else if(req.body.selfChallengeDescription.length === 0) {
    return sendErr(res, 'Missing amountPerKm and challanges, at least one variable has to be present');
  }

  let challengesCreated = body.challenges.reduce((c1, c2) => !!c1 || !!c2);

  if(!challengesCreated && !sponsoring) {
    return sendErr(res, 'Neither sponsorings nor challenges created');
  }

  res.send(sponsoring);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.getAllTeams = (req) => co(function*() {
  const events = yield api.event.all();

  let teamsByEvent = yield events.map((e) => api.getModel(`event/${e.id}/team`, req.user));

  let allTeams = teamsByEvent.map((teams, index) => {
    return teams.map(team => {
      team.city = events[index].city;
      team.event = events[index].id;
      return team;
    });
  });

  allTeams = _.flatten(allTeams);
  allTeams = allTeams.filter(t => t.hasFullyPaid);
  return _.sortBy(allTeams,t => t.name);

}).catch(ex => {
  throw ex;
});

sponsoring.getByTeam = (req) => co(function*() {

  let allSponsorings = yield api.sponsoring.getByTeam(
    req.user.me.participant.eventId,
    req.user.me.participant.teamId);

  let callSponsorings = allSponsorings.filter(c => !!c.userId);

  let sponsors = yield callSponsorings.map(s => api.user.get(s.userId));

  return allSponsorings.map(sponsoring => {
    sponsoring.sponsor = sponsors.filter(s => s.id = sponsoring.userId)[0];
    return sponsoring;
  });

}).catch(ex => {
  throw ex;
});

sponsoring.getBySponsor = (req) => co(function*() {

  return yield api.sponsoring.getBySponsor(
    req.user,
    req.user.me.id);

}).catch(ex => {
  throw ex;
});

sponsoring.accept = (req, res, next) => co(function*() {

  yield api.sponsoring.accept(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.reject = (req, res, next) => co(function*() {

  yield api.sponsoring.reject(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.delete = (req, res, next) => co(function*() {

  yield api.sponsoring.delete(req.user, req.body.eventId, req.body.teamId, req.body.sponsoringId);

  return res.sendStatus(200);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge = {};

sponsoring.challenge.create = (req, res, next) => co(function*() {

  let body = {};

  try {
    let obj = JSON.parse(req.body.addChallengeTeam);
    body.team = obj.team;
    body.event = obj.event;
  } catch (ex) {
    return sendErr(res, ex.message, ex);
  }

  if (req.body.addChallengeDescription.length !== req.body.addChallengeAmount.length) {
    return sendErr(res, 'Unequal amount of challenge descriptions and challenge amounts');
  }

  let test = yield req.body.addChallengeDescription.map(
    (e, i) => {
      let currBody = {
        amount: req.body.addChallengeAmount[i],
        description: e
      };
      return api.challenge.create(req.user, body.event, body.team, currBody)
    });

  res.sendStatus(200);

}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.getByTeam = (req) => co(function*() {

  let allChallenges = yield api.challenge.getByTeam(
    req.user.me.participant.eventId,
    req.user.me.participant.teamId);

  let callChallenges = allChallenges.filter(c => !!c.userId);

  let sponsors = yield callChallenges.map(c => api.user.get(c.userId));

  return allChallenges.map(challenge => {
    challenge.sponsor = sponsors.filter(s => s.id = challenge.userId)[0];
    return challenge;
  });

}).catch(ex => {
  throw ex;
});

sponsoring.challenge.getBySponsor = (req) => co(function*() {

  return yield api.challenge.getBySponsor(
    req.user,
    req.user.me.id);

}).catch(ex => {
  throw ex;
});

sponsoring.challenge.accept = (req, res, next) => co(function*() {

  yield api.challenge.accept(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.reject = (req, res, next) => co(function*() {

  yield api.challenge.reject(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

sponsoring.challenge.delete = (req, res, next) => co(function*() {

  yield api.challenge.delete(req.user, req.body.eventId, req.body.teamId, req.body.challengeId);

  return res.sendStatus(200);
}).catch(ex => {
  sendErr(res, ex.message, ex);
});

module.exports = sponsoring;<|endoftext|>


<commit_before>var assert = require("assert");

var bitset = function(value,bit) {
  return !!(value & (1 << bit));
};

var bitsSet = function(value) {
  var bits = numberOfBits(value);
  var ret = [];
  for (var i=0;i<bits;++i) {
    ret.push(bitset(value,i) ? 1 : 0);
  }
  return ret;
};

var numberOfBits = function(value) {
  if (value <= 2) {
    return value;
  }

  var log2 = Math.log(value) / Math.LN2;
  var maxVal = Math.pow(2,log2);
  return (maxVal >= value) ? log2 : log2 + 1;
};

var hasAdjacentElements = function(arr,needle) {
  if (arr.length < 2) {
    return false;
  }

  for (var i=0;i<arr.length-1;++i) {
    if (arr[i] === arr[i+1] && arr[i] === needle) {
      return true;
    }
  }
  return false;
};

var adjacentCounts = function(bitCount) {
  var maxNum = Math.pow(2,bitCount);
  var count = 0;
  for (var i=0;i<maxNum;++i) {
    if (!hasAdjacentElements(bitsSet(i),1)) {
      count++;
    }
  }
  return count;
};

describe('Diversion', function() {
  it('has a bit that is set', function() {
    assert(bitset(1,0));
    assert(bitset(256,8));
  });

  it('number of bits within a value', function() {
    assert.equal(8, numberOfBits(256));
    assert.equal(1, numberOfBits(1));
    assert.equal(2, numberOfBits(2));
    assert.equal(0, numberOfBits(0));
  });

  it('has bits that are not set', function() {
    assert(!bitset(257,7));
  });

  it('returns the binary representation', function() {
    assert.deepEqual([], bitsSet(0));
    assert.deepEqual([0,1], bitsSet(2));
    assert.deepEqual([1,1], bitsSet(3));
    assert.deepEqual([1,0,1,0,0,0,0,1], bitsSet(133));
  });

  it('bit shift operations', function() {
    assert.equal(1, 1 << 0);
    assert.equal(2, 1 << 1);
    assert.equal(4, 1 << 2);
  });

  it('can detect adjacent elements', function() {
    assert.equal(false, hasAdjacentElements([],1));
    assert.equal(false, hasAdjacentElements([1],1));
    assert.equal(true, hasAdjacentElements([1,1],1));
    assert.equal(false, hasAdjacentElements([1,2,3],0));
    assert.equal(false, hasAdjacentElements([0,1,1,0],0));
    assert.equal(true, hasAdjacentElements([1,1],1));
    assert.equal(true, hasAdjacentElements([0,1,1,0],1));
  });

  it('n digit numbers that don\'t have adjacent bits', function() {
    assert.equal(5, adjacentCounts(3));
    assert.equal(8, adjacentCounts(4));
    assert.equal(13, adjacentCounts(5));
    assert.equal(21, adjacentCounts(6));
    assert.equal(34, adjacentCounts(7));
    assert.equal(21 + 34, adjacentCounts(8));
  });
});<commit_msg>finish retro<commit_after>"use strict";

var assert = require("assert");

var bitset = function(value,bit) {
  return !!(value & (1 << bit));
};

var bitsSet = function(value) {
  var bits = numberOfBits(value);
  var ret = [];
  for (var i=0;i<bits;++i) {
    ret.push(bitset(value,i) ? 1 : 0);
  }
  return ret;
};

var numberOfBits = function(value) {
  if (value <= 2) {
    return value;
  }

  var log2 = Math.log(value) / Math.LN2;
  var maxVal = Math.pow(2,log2);
  return (maxVal >= value) ? log2 : log2 + 1;
};

var hasAdjacentElements = function(arr,needle) {
  if (arr.length < 2) {
    return false;
  }

  for (var i=0;i<arr.length-1;++i) {
    if (arr[i] === arr[i+1] && arr[i] === needle) {
      return true;
    }
  }
  return false;
};

var adjacentCounts = function(bitCount) {
  var maxNum = Math.pow(2,bitCount);
  var count = 0;
  for (var i=0;i<maxNum;++i) {
    if (!hasAdjacentElements(bitsSet(i),1)) {
      count++;
    }
  }
  return count;
};

describe('Diversion', function() {
  it('has a bit that is set', function() {
    assert(bitset(1,0));
    assert(bitset(256,8));
  });

  it('number of bits within a value', function() {
    assert.equal(8, numberOfBits(256));
    assert.equal(1, numberOfBits(1));
    assert.equal(2, numberOfBits(2));
    assert.equal(0, numberOfBits(0));
  });

  it('has bits that are not set', function() {
    assert(!bitset(257,7));
  });

  it('returns the binary representation', function() {
    assert.deepEqual([], bitsSet(0));
    assert.deepEqual([0,1], bitsSet(2));
    assert.deepEqual([1,1], bitsSet(3));
    assert.deepEqual([1,0,1,0,0,0,0,1], bitsSet(133));
  });

  it('bit shift operations', function() {
    assert.equal(1, 1 << 0);
    assert.equal(2, 1 << 1);
    assert.equal(4, 1 << 2);
  });

  it('can detect adjacent elements', function() {
    assert.equal(false, hasAdjacentElements([],1));
    assert.equal(false, hasAdjacentElements([1],1));
    assert.equal(true, hasAdjacentElements([1,1],1));
    assert.equal(false, hasAdjacentElements([1,2,3],0));
    assert.equal(false, hasAdjacentElements([0,1,1,0],0));
    assert.equal(true, hasAdjacentElements([1,1],1));
    assert.equal(true, hasAdjacentElements([0,1,1,0],1));
  });

  it('n digit numbers that don\'t have adjacent bits', function() {
    assert.equal(5, adjacentCounts(3));
    assert.equal(8, adjacentCounts(4));
    assert.equal(13, adjacentCounts(5));
    assert.equal(21, adjacentCounts(6));
    assert.equal(34, adjacentCounts(7));
    assert.equal(21 + 34, adjacentCounts(8));
  });
});

// Retro
// - mocha is awesome, particular mocha -w <filename> (though annoyingly compilation fails break it) - I should fix this
// - bits shifting around works as I expect
// - no base N log function but Math.log(foo) / Math.LN<X> works as you'd expect<|endoftext|>


<commit_before>exports.run = async (client, message, [member]) => {
    const sql = require("sqlite");
    sql.open("./bwd/data/score.sqlite");

    var user = client.funcs.userSearch(client, message, member);

    if (user.username === null || user.username === undefined) { return; }
    if (user.bot === true) { return message.reply("Bots don't have any records!"); }

    sql.get(`SELECT * FROM scores WHERE userId = "${user.id}"`).then(row => {
        if (!row) { return message.reply("That person hasn't signed up with `m~daily` yet! D:"); }

        var Time = (((Date.now() - row.daily) / 86400000)).toFixed(3);
        var time = (((Date.now() - row.repDaily) / 86400000)).toFixed(3);

        const embed = new client.methods.Embed()
            .setTimestamp()
            .setAuthor(message.guild.name, message.guild.iconURL())
            .setThumbnail(user.avatarURL())
            .setColor("#4d5fd")
            .addField("User:", `${user.username} (${user.id})`)
            .addField("Credits:", (row.credits).toLocaleString(), true);
            if (Time >= 14) { embed.addField("Last Daily:", `${Time / 7} weeks ago`, true); }
            else if (Time >= 1) { embed.addField("Last Daily:", `${Time} days ago`, true); }
            else { embed.addField("Last Daily:", `${(Time * 24).toFixed(3)} hours ago`, true); }
            embed.addField("Reputation:", row.rep, true);
            if (time >= 14) { embed.addField("Last rep given:", `${(time / 7).toFixed(3)} weeks ago`, true); }
            else if (time >= 1) { embed.addField("Last rep given:", `${time} days ago`, true); }
            else { embed.addField("Last rep given:", `${(time * 24).toFixed(3)} hours ago`, true); }

        message.channel.send({embed});
    }).catch(error => {
        console.log(error);
        return message.reply("Error in command. Please try again later.");
    });
};

exports.conf = {
    enabled: true,
    runIn: ["text"],
    aliases: ["bal", "credits", "profile"],
    permLevel: 0,
    botPerms: [],
    requiredFuncs: [],
};

exports.help = {
    name: "balance",
    description: "Check credit amount and the last time the user recieved their daily.",
    usage: "[member:str]",
    usageDelim: "",
};
<commit_msg>Update balance.js<commit_after>exports.run = async (client, message, [member]) => {
    const sqlite3 = require("sqlite3").verbose();
    let db = new sqlite3.Database("./bwd/data/score.sqlite");

    var user = client.funcs.userSearch(client, message, member);

    if (user.username === null || user.username === undefined) { return; }
    if (user.bot === true) { return message.reply("Bots don't have any records!"); }

    db.get(`SELECT * FROM scores WHERE userId = "${user.id}"`, [], (err, row) => {
        if (err) { return console.log(err); }
        if (!row) { return message.reply("That person hasn't signed up with `m~daily` yet! D:"); }

        var Time = (((Date.now() - row.daily) / 86400000)).toFixed(3);
        var time = (((Date.now() - row.repDaily) / 86400000)).toFixed(3);

        const embed = new client.methods.Embed()
            .setTimestamp()
            .setAuthor(message.guild.name, message.guild.iconURL())
            .setThumbnail(user.avatarURL())
            .setColor("#4d5fd")
            .addField("User:", `${user.username} (${user.id})`)
            .addField("Credits:", (row.credits).toLocaleString(), true);
            if (Time >= 14) { embed.addField("Last Daily:", `${Time / 7} weeks ago`, true); }
            else if (Time >= 1) { embed.addField("Last Daily:", `${Time} days ago`, true); }
            else { embed.addField("Last Daily:", `${(Time * 24).toFixed(3)} hours ago`, true); }
            embed.addField("Reputation:", row.rep, true);
            if (time >= 14) { embed.addField("Last rep given:", `${(time / 7).toFixed(3)} weeks ago`, true); }
            else if (time >= 1) { embed.addField("Last rep given:", `${time} days ago`, true); }
            else { embed.addField("Last rep given:", `${(time * 24).toFixed(3)} hours ago`, true); }

        message.channel.send({embed});
    });
    db.close();
};

exports.conf = {
    enabled: true,
    runIn: ["text"],
    aliases: ["bal", "credits", "profile"],
    permLevel: 0,
    botPerms: [],
    requiredFuncs: [],
};

exports.help = {
    name: "balance",
    description: "Check credit amount and the last time the user recieved their daily.",
    usage: "[member:str]",
    usageDelim: "",
};
<|endoftext|>


<commit_before>const request = require('request-promise');
const discord = require('discord.js');

let weatherConfig;
let tokens;
const geocodeEndpoint = 'https://maps.googleapis.com/maps/api/geocode/json?key=gkey&address=input';
const darkskyEndpoint = 'https://api.darksky.net/forecast/key/lat,lng';

function fahrenheitToCelcius(degree) {
  return (((degree - 32) * 5) / 9).toFixed(0);
}

function getGeocodeData(address) {
  let requestURL = geocodeEndpoint
    .replace('gkey', tokens.google_geocode)
    .replace('input', address);
  requestURL = encodeURI(requestURL);

  return request(requestURL).then((body) => {
    const geocodeData = JSON.parse(body);

    if (geocodeData.status !== 'OK') {
      // eslint-disable-next-line no-throw-literal
      throw 'I\'m sorry, the address couldn\'t be detected.';
    }

    const result = {
      address: geocodeData.results[0].formatted_address,
      coordinate: geocodeData.results[0].geometry.location,
    };

    return result;
  });
}

function getWeatherData(location) {
  const requestURL = darkskyEndpoint
    .replace('key', tokens.darksky)
    .replace('lat', location.coordinate.lat)
    .replace('lng', location.coordinate.lng);

  return request(requestURL).then((body) => {
    const weatherData = JSON.parse(body);

    const offset = weatherData.offset;
    const utcTime = weatherData.currently.time;
    // datetime is weird in javascript, please do change this part if you can
    const localTime = new Date(utcTime * 1000);
    localTime.setHours(localTime.getHours() + offset);
    let dateString;
    // toGMTString prints out timezone of host so we slice it off
    if (offset > 0) {
      dateString = localTime.toUTCString() + ' +' + offset;
    } else {
      dateString = localTime.toUTCString() + ' ' + offset;
    }

    const temperatureF = weatherData.currently.temperature.toFixed(0);
    const temperatureC = fahrenheitToCelcius(temperatureF);
    const summary = weatherData.currently.summary;
    const humidity = (weatherData.currently.humidity * 100).toFixed(0);
    // convert speed to freedom units
    const windSpeed = (weatherData.currently.windSpeed * 1.61).toFixed(0);
    const pressure = weatherData.currently.pressure.toFixed(0);
    const icon = weatherData.currently.icon;
    const timezone = weatherData.timezone;

    const result = {
      location,
      offset,
      localTime,
      dateString,
      temperatureC,
      temperatureF,
      summary,
      humidity,
      windSpeed,
      pressure,
      icon,
      timezone,
    };

    return result;
  });
}

function generateEmbed(data, verbose) {
  const embed = new discord.RichEmbed();

  if (verbose) {
    embed.setColor('#4286f4')
      .setFooter(`Local Time: ${data.dateString}`)
      .setTitle(`Weather in ${data.location}`)
      .addField('Summary', data.summary)
      .addField('Temperature °C', `${data.temperatureC} °C`, true)
      .addField('Temperature °F', `${data.temperatureF} °F`, true)
      .addField('Timezone', data.timezone, true)
      .addField('Humidity', `${data.humidity}%`, true)
      .addField('Wind Speed', `${data.windSpeed} km/h`, true)
      .addField('Air Pressure', `${data.pressure} mbar`, true)
      .setDescription(weatherConfig.icons[data.icon]);
  } else {
    embed.setColor('#4286f4')
      .setFooter(`Local Time: ${data.dateString}`)
      .setTitle(`Weather in ${data.address}`)
      .addField('Summary', data.summary)
      .addField('Temperature', `${data.temperatureC} °C / ${data.temperatureF} °F`, true)
      .addField('Humidity', `${data.humidity}%`, true)
      .setDescription(weatherConfig.icons[data.icon]);
  }

  return embed;
}

module.exports = {
  usage: [
    'weather <address> - brings current weather info for given address',
    'weather -v <address> - brings additional weather info for given address',
  ],
  run: (bot, message, cmdArgs) => {
    if (!cmdArgs) return true;

    let args = cmdArgs.split(' ');
    const verbose = args[0] === '-v';
    args = verbose ? args.slice(1) : args;

    getGeocodeData(args).then(getWeatherData)
                        .then(data => generateEmbed(data, verbose))
                        .then(embed => message.channel.sendEmbed(embed))
                        .catch(err => message.channel.sendMessage(err.toString()));
    return false;
  },
  init: (bot) => {
    weatherConfig = bot.settings.weather;
    tokens = bot.settings.tokens;
  },
};
<commit_msg>Maybe this actually fixes weather in undefined?<commit_after>const request = require('request-promise');
const discord = require('discord.js');

let weatherConfig;
let tokens;
const geocodeEndpoint = 'https://maps.googleapis.com/maps/api/geocode/json?key=gkey&address=input';
const darkskyEndpoint = 'https://api.darksky.net/forecast/key/lat,lng';

function fahrenheitToCelcius(degree) {
  return (((degree - 32) * 5) / 9).toFixed(0);
}

function getGeocodeData(address) {
  let requestURL = geocodeEndpoint
    .replace('gkey', tokens.google_geocode)
    .replace('input', address);
  requestURL = encodeURI(requestURL);

  return request(requestURL).then((body) => {
    const geocodeData = JSON.parse(body);

    if (geocodeData.status !== 'OK') {
      // eslint-disable-next-line no-throw-literal
      throw 'I\'m sorry, the address couldn\'t be detected.';
    }

    const result = {
      address: geocodeData.results[0].formatted_address,
      coordinate: geocodeData.results[0].geometry.location,
    };

    return result;
  });
}

function getWeatherData(location) {
  const requestURL = darkskyEndpoint
    .replace('key', tokens.darksky)
    .replace('lat', location.coordinate.lat)
    .replace('lng', location.coordinate.lng);

  return request(requestURL).then((body) => {
    const weatherData = JSON.parse(body);

    const offset = weatherData.offset;
    const utcTime = weatherData.currently.time;
    // datetime is weird in javascript, please do change this part if you can
    const localTime = new Date(utcTime * 1000);
    localTime.setHours(localTime.getHours() + offset);
    let dateString;
    // toGMTString prints out timezone of host so we slice it off
    if (offset > 0) {
      dateString = localTime.toUTCString() + ' +' + offset;
    } else {
      dateString = localTime.toUTCString() + ' ' + offset;
    }

    const temperatureF = weatherData.currently.temperature.toFixed(0);
    const temperatureC = fahrenheitToCelcius(temperatureF);
    const summary = weatherData.currently.summary;
    const humidity = (weatherData.currently.humidity * 100).toFixed(0);
    // convert speed to freedom units
    const windSpeed = (weatherData.currently.windSpeed * 1.61).toFixed(0);
    const pressure = weatherData.currently.pressure.toFixed(0);
    const icon = weatherData.currently.icon;
    const timezone = weatherData.timezone;

    const result = {
      location: location.address,
      offset,
      localTime,
      dateString,
      temperatureC,
      temperatureF,
      summary,
      humidity,
      windSpeed,
      pressure,
      icon,
      timezone,
    };

    return result;
  });
}

function generateEmbed(data, verbose) {
  const embed = new discord.RichEmbed();

  if (verbose) {
    embed.setColor('#4286f4')
      .setFooter(`Local Time: ${data.dateString}`)
      .setTitle(`Weather in ${data.location}`)
      .addField('Summary', data.summary)
      .addField('Temperature °C', `${data.temperatureC} °C`, true)
      .addField('Temperature °F', `${data.temperatureF} °F`, true)
      .addField('Timezone', data.timezone, true)
      .addField('Humidity', `${data.humidity}%`, true)
      .addField('Wind Speed', `${data.windSpeed} km/h`, true)
      .addField('Air Pressure', `${data.pressure} mbar`, true)
      .setDescription(weatherConfig.icons[data.icon]);
  } else {
    embed.setColor('#4286f4')
      .setFooter(`Local Time: ${data.dateString}`)
      .setTitle(`Weather in ${data.address}`)
      .addField('Summary', data.summary)
      .addField('Temperature', `${data.temperatureC} °C / ${data.temperatureF} °F`, true)
      .addField('Humidity', `${data.humidity}%`, true)
      .setDescription(weatherConfig.icons[data.icon]);
  }

  return embed;
}

module.exports = {
  usage: [
    'weather <address> - brings current weather info for given address',
    'weather -v <address> - brings additional weather info for given address',
  ],
  run: (bot, message, cmdArgs) => {
    if (!cmdArgs) return true;

    let args = cmdArgs.split(' ');
    const verbose = args[0] === '-v';
    args = verbose ? args.slice(1) : args;

    getGeocodeData(args).then(getWeatherData)
                        .then(data => generateEmbed(data, verbose))
                        .then(embed => message.channel.sendEmbed(embed))
                        .catch(err => message.channel.sendMessage(err.toString()));
    return false;
  },
  init: (bot) => {
    weatherConfig = bot.settings.weather;
    tokens = bot.settings.tokens;
  },
};
<|endoftext|>