<commit_before>"use strict";

var express   = require('express');
var tinycolor = require('tinycolor2');

var config = require('../configuration');
var log = require('../logger');
var Eventer = require('../eventer');

var Blink1Service = require('./blink1Service');
var PatternsService = require('./patternsService');

var app = express();
app.set('json spaces', 2);
var myLogger = function (req, res, next) {
  // log.msg("ApiServer", req.url);
  Eventer.addStatus( {type:'info', source:'api', id:req.ip, text:req.url} );
  next();
};
app.use(myLogger);

app.get('/', function (req, res) {
    res.send("Blink1Control2 API server\n\n");
});
app.get('/blink1(/id)?', function(req,res) {
    res.json({
        blink1_serialnums: Blink1Service.getAllSerials(),
        blink1_id: Blink1Service.getIftttKey(),
        status: "blink1 id"
    });
});
app.get('/blink1/off', function(req,res) {
    var blink1_id = Number(req.query.blink1_id);
    PatternsService.stopAllPatterns();
    Blink1Service.fadeToColor(0.1, '#000000', 0, blink1_id); // turn off everyone
    res.json({
        status: "blink1 off"
    });
});
app.get('/blink1/on', function(req,res) {
    var blink1_id = Number(req.query.blink1_id);
    PatternsService.stopAllPatterns();
    Blink1Service.fadeToColor(0.1, '#ffffff', 0, blink1_id); // turn off everyone
    res.json({
        status: "blink1 on"
    });
});
app.get('/blink1/fadeToRGB', function(req, res) {
    var color = tinycolor(req.query.rgb);
    var secs = Number(req.query.time) || 0.1;
    var ledn = Number(req.query.ledn) || 0;
    var blink1_id = Number(req.query.blink1_id) || 0;

    // var blink1_id = req.query.blink1_id || '';
    var status = "success";

    if( color.isValid() ) {
        status = Blink1Service.fadeToColor( secs*1000, color, ledn, blink1_id );
    }
    else {
        status = "bad hex color specified " + req.query.rgb;
    }
    res.json( {
        // blink1Connected: blink1 !== null,
        blink1Serials: Blink1Service.getAllSerials(),
        lastColor: color.toHexString(),
        lastTime: secs,
        lastLedn: ledn,
        cmd: "fadeToRGB",
        status: status
    });
});

app.get('/blink1/pattern(s)?', function(req,res) {
    res.json({
        status: "pattern results",
        patterns: PatternsService.getAllPatternsForOutput()
    });
});
app.get('/blink1/pattern/queue', function(req,res) {
    res.json({
        status: "pattern queue results",
        // patterns: PatternsService.getAllPatternsForOutput()
        queue: PatternsService.getPlayingQueueForOutput()
    });
});

app.get('/blink1/pattern/:type(play|stop)', function(req,res) {
    var status = 'pattern '+req.params.type+': no pattern with that name';
    var patt_name = req.query.pname || req.query.name || '';
    var blink1id = req.query.blink1id || 0;

    if( req.params.type === 'play' ) {
        if( patt_name ) {
            // returns true on found pattern // FIXME: go back to using 'findPattern'
            if( PatternsService.playPatternFrom( 'api', patt_name, blink1id ) ) {
                status = 'pattern play: playing ' +patt_name;
            }
        }
    }
    else { // stop
        if( !patt_name ) {
            PatternsService.stopAllPatterns();
            status = 'pattern stop: stopping all patterns';
        }
        else {
            var id = PatternsService.getIdForName( patt_name );
            if( !id ) { id = patt_name; }

            if( PatternsService.stopPattern( id ) ) {
                status = 'pattern stop: stopping ' +patt_name;
            }
        }
    }

    res.json({
        // id: patt_id,
        status: status,
        pname: patt_name,
        blink1id: blink1id
    });
});
app.get('/blink1/pattern/add', function(req,res) {
    var status = 'pattern add: no pattern added';
    var patt_name = req.query.pname || req.query.name || '';
    var pattout = '';
    if( ! patt_name && ! req.query.pattern ) {
        status = "must specify 'name' and 'pattern' string";
    }
    else {
        var patt = PatternsService.newPatternFromString( patt_name, req.query.pattern);
        if( patt ) { PatternsService.savePattern(patt); }
        pattout = PatternsService.formatPatternForOutput(patt);
        status = "pattern add: pattern '"+patt_name+"' added";
    }
    res.json({
        pattern: pattout,
        status: status
    });
});
app.get('/blink1/pattern/del', function(req,res) {
    var status = 'pattern del: no pattern deleted';
    var patt_name = req.query.pname || req.query.name || ''; // hmmmm
    var id = req.query.id || '';
    if( patt_name ) {
        id = PatternsService.getIdForName( patt_name );
        if( !id ) { id = patt_name; }
    }
    if( id ) {
        PatternsService.deletePattern( id );
        status = "pattern '"+id+"' deleted";
    }
    else {
        status = "must specify 'name' or 'id'";
    }
    res.json({
        status: status
    });
});
//
app.get('/blink1/input', function(req,res) {
    var status = 'event inputs';
    var rules = config.readSettings('eventRules');
    res.json({
        status: status,
        inputs: rules
    });
});

var apiServer = {
    server: null,
    config: {},
    // init: function() { // FIXME: bad name
    // 	// config.saveSettings("apiServer:port",8934);
    // 	// config.saveSettings("apiServer:enabled", false);
    // 	// config.saveSettings("apiServer:host", 'localhost');
    // },

    reloadConfig: function() {
        this.stop();
        this.start();
    },

    start: function() {
        this.config = config.readSettings('apiServer');
        if( !this.config ) { // if no config, make sensible defaults & save them
            this.config = {};
            this.config.port = 8934;
            this.config.host = 'localhost';
            this.config.enabled = false;
            config.saveSettings('apiServer', this.config);
        }
        if( !this.config.enabled ) {
            return;
        }
        var port = this.config.port || 8934;
        var host = this.config.host || 'localhost';
        if( host === 'any' ) {
            this.server = app.listen(port);
        }
        else {
            this.server = app.listen( port, host );
        }
    },

    stop: function() {
        if( this.server ) {
            this.server.close();
        }
        // config.saveSettings("apiServer:enabled", false);
    },

};

module.exports = apiServer;
<commit_msg>fix API /blink1/fadeToRGB similar to fix for issue #104<commit_after>"use strict";

var express   = require('express');
var tinycolor = require('tinycolor2');

var config = require('../configuration');
var log = require('../logger');
var Eventer = require('../eventer');

var Blink1Service = require('./blink1Service');
var PatternsService = require('./patternsService');

var app = express();
app.set('json spaces', 2);
var myLogger = function (req, res, next) {
  // log.msg("ApiServer", req.url);
  Eventer.addStatus( {type:'info', source:'api', id:req.ip, text:req.url} );
  next();
};
app.use(myLogger);

app.get('/', function (req, res) {
    res.send("Blink1Control2 API server\n\n");
});
app.get('/blink1(/id)?', function(req,res) {
    res.json({
        blink1_serialnums: Blink1Service.getAllSerials(),
        blink1_id: Blink1Service.getIftttKey(),
        status: "blink1 id"
    });
});
app.get('/blink1/off', function(req,res) {
    var blink1_id = Number(req.query.blink1_id);
    PatternsService.stopAllPatterns();
    Blink1Service.fadeToColor(0.1, '#000000', 0, blink1_id); // turn off everyone
    res.json({
        status: "blink1 off"
    });
});
app.get('/blink1/on', function(req,res) {
    var blink1_id = Number(req.query.blink1_id);
    PatternsService.stopAllPatterns();
    Blink1Service.fadeToColor(0.1, '#ffffff', 0, blink1_id); // turn off everyone
    res.json({
        status: "blink1 on"
    });
});
app.get('/blink1/fadeToRGB', function(req, res) {
    var color = tinycolor(req.query.rgb);
    var secs = Number(req.query.time) || 0.1;
    var ledn = Number(req.query.ledn) || 0;
    var blink1_id = Number(req.query.blink1_id);  // undefined means all blink1 devices

    // var blink1_id = req.query.blink1_id || '';
    var status = "success";

    if( color.isValid() ) {
        status = Blink1Service.fadeToColor( secs*1000, color, ledn, blink1_id );
    }
    else {
        status = "bad hex color specified " + req.query.rgb;
    }
    res.json( {
        // blink1Connected: blink1 !== null,
        blink1Serials: Blink1Service.getAllSerials(),
        lastColor: color.toHexString(),
        lastTime: secs,
        lastLedn: ledn,
        cmd: "fadeToRGB",
        status: status
    });
});

app.get('/blink1/pattern(s)?', function(req,res) {
    res.json({
        status: "pattern results",
        patterns: PatternsService.getAllPatternsForOutput()
    });
});
app.get('/blink1/pattern/queue', function(req,res) {
    res.json({
        status: "pattern queue results",
        // patterns: PatternsService.getAllPatternsForOutput()
        queue: PatternsService.getPlayingQueueForOutput()
    });
});

app.get('/blink1/pattern/:type(play|stop)', function(req,res) {
    var status = 'pattern '+req.params.type+': no pattern with that name';
    var patt_name = req.query.pname || req.query.name || '';
    var blink1id = req.query.blink1id || 0;

    if( req.params.type === 'play' ) {
        if( patt_name ) {
            // returns true on found pattern // FIXME: go back to using 'findPattern'
            if( PatternsService.playPatternFrom( 'api', patt_name, blink1id ) ) {
                status = 'pattern play: playing ' +patt_name;
            }
        }
    }
    else { // stop
        if( !patt_name ) {
            PatternsService.stopAllPatterns();
            status = 'pattern stop: stopping all patterns';
        }
        else {
            var id = PatternsService.getIdForName( patt_name );
            if( !id ) { id = patt_name; }

            if( PatternsService.stopPattern( id ) ) {
                status = 'pattern stop: stopping ' +patt_name;
            }
        }
    }

    res.json({
        // id: patt_id,
        status: status,
        pname: patt_name,
        blink1id: blink1id
    });
});
app.get('/blink1/pattern/add', function(req,res) {
    var status = 'pattern add: no pattern added';
    var patt_name = req.query.pname || req.query.name || '';
    var pattout = '';
    if( ! patt_name && ! req.query.pattern ) {
        status = "must specify 'name' and 'pattern' string";
    }
    else {
        var patt = PatternsService.newPatternFromString( patt_name, req.query.pattern);
        if( patt ) { PatternsService.savePattern(patt); }
        pattout = PatternsService.formatPatternForOutput(patt);
        status = "pattern add: pattern '"+patt_name+"' added";
    }
    res.json({
        pattern: pattout,
        status: status
    });
});
app.get('/blink1/pattern/del', function(req,res) {
    var status = 'pattern del: no pattern deleted';
    var patt_name = req.query.pname || req.query.name || ''; // hmmmm
    var id = req.query.id || '';
    if( patt_name ) {
        id = PatternsService.getIdForName( patt_name );
        if( !id ) { id = patt_name; }
    }
    if( id ) {
        PatternsService.deletePattern( id );
        status = "pattern '"+id+"' deleted";
    }
    else {
        status = "must specify 'name' or 'id'";
    }
    res.json({
        status: status
    });
});
//
app.get('/blink1/input', function(req,res) {
    var status = 'event inputs';
    var rules = config.readSettings('eventRules');
    res.json({
        status: status,
        inputs: rules
    });
});

var apiServer = {
    server: null,
    config: {},
    // init: function() { // FIXME: bad name
    // 	// config.saveSettings("apiServer:port",8934);
    // 	// config.saveSettings("apiServer:enabled", false);
    // 	// config.saveSettings("apiServer:host", 'localhost');
    // },

    reloadConfig: function() {
        this.stop();
        this.start();
    },

    start: function() {
        this.config = config.readSettings('apiServer');
        if( !this.config ) { // if no config, make sensible defaults & save them
            this.config = {};
            this.config.port = 8934;
            this.config.host = 'localhost';
            this.config.enabled = false;
            config.saveSettings('apiServer', this.config);
        }
        if( !this.config.enabled ) {
            return;
        }
        var port = this.config.port || 8934;
        var host = this.config.host || 'localhost';
        if( host === 'any' ) {
            this.server = app.listen(port);
        }
        else {
            this.server = app.listen( port, host );
        }
    },

    stop: function() {
        if( this.server ) {
            this.server.close();
        }
        // config.saveSettings("apiServer:enabled", false);
    },

};

module.exports = apiServer;
<|endoftext|>


<commit_before>var Utils         = require("../../utils")
  , AbstractQuery = require('../abstract/query')

module.exports = (function() {
  var Query = function(client, sequelize, callee, options) {
    this.client    = client
    this.callee    = callee
    this.sequelize = sequelize
    this.options   = Utils._.extend({
      logging: console.log,
      plain: false,
      raw: false
    }, options || {})

    this.checkLoggingOption()
    this.bindClientFunction = function(err) { onFailure.call(this, err) }.bind(this)
  }

  Utils.inherit(Query, AbstractQuery)

  Query.prototype.run = function(sql) {
    this.sql = sql

    bindClient.call(this)

    if(this.options.logging !== false) {
      this.options.logging('Executing: ' + this.sql)
    }

    this.client.query({ sql: this.sql, nestTables: true }, function(err, results, fields) {
      this.emit('sql', this.sql)

      if (err) {
        onFailure.call(this, err)
      } else {
        if (Array.isArray(results) && !!results[0] && Utils._.keys(results[0]).length === 1) {
          results = results.map(function(result){ return Utils._.values(result)[0] })
        }

        onSuccess.call(this, results, fields)
      }
    }.bind(this)).setMaxListeners(100)

    return this
  }

  //private

  var bindClient = function() {
    this.client.on('error', this.bindClientFunction)
  }

  var unbindClient = function() {
    this.client.removeListener('error', this.bindClientFunction)
  }

  var onSuccess = function(results, fields) {
    unbindClient.call(this)
    this.emit('success', this.formatResults(results))

  }

  var onFailure = function(err) {
    unbindClient.call(this)
    this.emit('error', err, this.callee)
  }

  return Query
})()
<commit_msg>don't nest the tables with the mysql connector<commit_after>var Utils         = require("../../utils")
  , AbstractQuery = require('../abstract/query')

module.exports = (function() {
  var Query = function(client, sequelize, callee, options) {
    this.client    = client
    this.callee    = callee
    this.sequelize = sequelize
    this.options   = Utils._.extend({
      logging: console.log,
      plain: false,
      raw: false
    }, options || {})

    this.checkLoggingOption()
    this.bindClientFunction = function(err) { onFailure.call(this, err) }.bind(this)
  }

  Utils.inherit(Query, AbstractQuery)

  Query.prototype.run = function(sql) {
    this.sql = sql

    bindClient.call(this)

    if(this.options.logging !== false) {
      this.options.logging('Executing: ' + this.sql)
    }

    this.client.query(this.sql, function(err, results, fields) {
      this.emit('sql', this.sql)

      if (err) {
        onFailure.call(this, err)
      } else {
        if (Array.isArray(results) && !!results[0] && Utils._.keys(results[0]).length === 1) {
          results = results.map(function(result){ return Utils._.values(result)[0] })
        }

        onSuccess.call(this, results, fields)
      }
    }.bind(this)).setMaxListeners(100)

    return this
  }

  //private

  var bindClient = function() {
    this.client.on('error', this.bindClientFunction)
  }

  var unbindClient = function() {
    this.client.removeListener('error', this.bindClientFunction)
  }

  var onSuccess = function(results, fields) {
    unbindClient.call(this)
    this.emit('success', this.formatResults(results))
  }

  var onFailure = function(err) {
    unbindClient.call(this)
    this.emit('error', err, this.callee)
  }

  return Query
})()
<|endoftext|>


<commit_before>var cdb = require('cartodb.js');

/**
 * View to select one or multiple columns.
 *  - For only allowing selecting one set selectorType to 'radio'
 *  - For allowing multiple selections set selectorType to 'switch'
 */
module.exports = cdb.core.View.extend({

  className: 'List-row',

  events: {
    'click': '_onClick'
  },

  initialize: function() {
    if (!this.options.selectorType) throw new Error('selectorType is required');
    this.elder('initialize');

    this.model = new cdb.core.Model({
      type: this.options.selectorType
    });

    this.column = this.options.column;
    this.add_related_model(this.column);

    this._initBinds();
  },

  render: function() {
    this.$el.html(
      this.getTemplate('common/dialogs/merge_datasets/column_selector')({
        selectorType: this.model.get('type'),
        isSelected: this.column.get('selected'),
        columnName: this.column.get('name'),
        columnType: this.column.get('type')
      })
    );

    var isDisabled = this.column.get('disabled');
    if (isDisabled) {
      this.undelegateEvents();
      this.$el.toggleClass('is-disabled', isDisabled);
    }

    return this;
  },

  _initBinds: function() {
    this.column.bind('change:selected', this._onChangeSelected, this);
  },

  _onChangeSelected: function(column, isSelected) {
    if (this.model.get('type') === 'radio') {
      this.$el.toggleClass('is-selected', isSelected);
    }
    this.$('.js-radio').toggleClass('is-checked', isSelected);
    this.$('.js-switch').prop('checked', isSelected);
  },

  _onClick: function(ev) {
    this.killEvent(ev);

    var inverseSelectedVal = !this.column.get('selected');

    // radio buttons can only be selected, unselection of other items should be handled by collection/parent
    if (inverseSelectedVal || this.model.get('type') !== 'radio') {
      this.column.set('selected', inverseSelectedVal);
    }
  }

});
<commit_msg>Move add_related_model to _initBinds instead<commit_after>var cdb = require('cartodb.js');

/**
 * View to select one or multiple columns.
 *  - For only allowing selecting one set selectorType to 'radio'
 *  - For allowing multiple selections set selectorType to 'switch'
 */
module.exports = cdb.core.View.extend({

  className: 'List-row',

  events: {
    'click': '_onClick'
  },

  initialize: function() {
    if (!this.options.selectorType) throw new Error('selectorType is required');
    this.elder('initialize');

    this.model = new cdb.core.Model({
      type: this.options.selectorType
    });

    this.column = this.options.column;

    this._initBinds();
  },

  render: function() {
    this.$el.html(
      this.getTemplate('common/dialogs/merge_datasets/column_selector')({
        selectorType: this.model.get('type'),
        isSelected: this.column.get('selected'),
        columnName: this.column.get('name'),
        columnType: this.column.get('type')
      })
    );

    var isDisabled = this.column.get('disabled');
    if (isDisabled) {
      this.undelegateEvents();
      this.$el.toggleClass('is-disabled', isDisabled);
    }

    return this;
  },

  _initBinds: function() {
    this.column.bind('change:selected', this._onChangeSelected, this);
    this.add_related_model(this.column);
  },

  _onChangeSelected: function(column, isSelected) {
    if (this.model.get('type') === 'radio') {
      this.$el.toggleClass('is-selected', isSelected);
    }
    this.$('.js-radio').toggleClass('is-checked', isSelected);
    this.$('.js-switch').prop('checked', isSelected);
  },

  _onClick: function(ev) {
    this.killEvent(ev);

    var inverseSelectedVal = !this.column.get('selected');

    // radio buttons can only be selected, unselection of other items should be handled by collection/parent
    if (inverseSelectedVal || this.model.get('type') !== 'radio') {
      this.column.set('selected', inverseSelectedVal);
    }
  }

});
<|endoftext|>


<commit_before>import _ from 'lodash';
import Moment from 'moment';

const initialUploadState = {
	state: 'empty',
	id: null,
		meta: {
			agency: 'Broadcasting Board of Governors',
        	startDate: Moment('2016-01-01','YYYY-MM-DD'),
        	endDate: Moment('2016-04-01','YYYY-MM-DD')
	},
	files: {},
	validation: {
	}
}

const setUploadItem = (state, action) => {
	let newFile = {
		[action.name]: {
			state: action.state,
			file: action.file,
			progress: 0
		}
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

const setUploadProgress = (state, action) => {
	let file = Object.assign({}, state.files[action.name]);
	file.progress = action.progress;

	let newFile = {
		[action.name]: file
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

const setUploadState = (state, action) => {
	let file = Object.assign({}, state.files[action.name]);
	file.state = action.state;

	let newFile = {
		[action.name]: file
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

export const uploadReducer = (state = initialUploadState, action) => {
	switch (action.type) {
		case 'SET_UPLOAD_ITEM':

			return Object.assign({}, state, {
				files: setUploadItem(state, action)
			});

		case 'SET_UPLOAD_PROGRESS':

			return Object.assign({}, state, {
				files: setUploadProgress(state, action)
			});

		case 'SET_UPLOAD_STATE':

			return Object.assign({}, state, {
				files: setUploadState(state, action)
			});

		case 'SET_SUBMISSION_STATE':
			return Object.assign({}, state, {
				state: action.state
			});

		case 'SET_META':
			return Object.assign({}, state, {
				meta: action.state
			});

		case 'SET_SUBMISSION_ID':
			return Object.assign({}, state, {
				id: action.state
			});

		case 'RESET_SUBMISSION':
			return Object.assign({}, initialUploadState);

		case 'SET_VALIDATION':
			return Object.assign({}, state, {
				validation: action.state
			});

		default:
			return state;
	}
}<commit_msg>Removed dummy data from the uploadReducer.js file<commit_after>import _ from 'lodash';
import Moment from 'moment';

const initialUploadState = {
	state: 'empty',
	id: null,
	meta: {
		agency: '',
		startDate: null,
		endDate: null
	},
	files: {},
	validation: {
	}
}

const setUploadItem = (state, action) => {
	let newFile = {
		[action.name]: {
			state: action.state,
			file: action.file,
			progress: 0
		}
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

const setUploadProgress = (state, action) => {
	let file = Object.assign({}, state.files[action.name]);
	file.progress = action.progress;

	let newFile = {
		[action.name]: file
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

const setUploadState = (state, action) => {
	let file = Object.assign({}, state.files[action.name]);
	file.state = action.state;

	let newFile = {
		[action.name]: file
	};

	const files = Object.assign({}, state.files, newFile);

	return files;
}

export const uploadReducer = (state = initialUploadState, action) => {
	switch (action.type) {
		case 'SET_UPLOAD_ITEM':

			return Object.assign({}, state, {
				files: setUploadItem(state, action)
			});

		case 'SET_UPLOAD_PROGRESS':

			return Object.assign({}, state, {
				files: setUploadProgress(state, action)
			});

		case 'SET_UPLOAD_STATE':

			return Object.assign({}, state, {
				files: setUploadState(state, action)
			});

		case 'SET_SUBMISSION_STATE':
			return Object.assign({}, state, {
				state: action.state
			});

		case 'SET_META':
			return Object.assign({}, state, {
				meta: action.state
			});

		case 'SET_SUBMISSION_ID':
			return Object.assign({}, state, {
				id: action.state
			});

		case 'RESET_SUBMISSION':
			return Object.assign({}, initialUploadState);

		case 'SET_VALIDATION':
			return Object.assign({}, state, {
				validation: action.state
			});

		default:
			return state;
	}
}<|endoftext|>


<commit_before>var _ = require('underscore-cdb-v3');
var Backbone = require('backbone');
var CustomBaselayerModel = require('../../../../data/custom-baselayer-model');

/**
 * Model for an individual WMS/WMTS layer.
 */

module.exports = Backbone.Model.extend({

  defaults: {
    selected: false,
    state: 'idle' // idle, saving, saveDone, saveFail
  },

  url: function () {
    return this._wmsService.saveLayerURL({
      title: this.get('title'),
      name: this.get('name'),
      layer: this.get('name'),
      srs: this.get('srs'),
      bounding_boxes: this.get('llbbox'),
      type: this._wmsType, // wms/wmts
      matrix_sets: this.get('matrix_sets')
    });
  },

  sync: function (method, model, options) {
    options = options || {};
    options.url = this.url(method.toLowerCase());
    options.dataType = 'jsonp';
    method = 'READ';

    return Backbone.sync.apply(this, arguments);
  },

  initialize: function (attrs, opts) {
    if (!opts.wmsService) throw new Error('wmsService is required');

    this._wmsService = opts.wmsService;
    this._wmsType = opts.wmsType;
  },

  canSave: function (customBaselayersCollection) {
    return !_.any(customBaselayersCollection.isCustomCategory(), function (customLayer) {
      return customLayer.get('name') === this.get('title');
    }, this);
  },

  createProxiedLayerOrCustomBaselayerModel: function () {
    this.set('state', 'saving');
    this._shouldBeProxied() ? this._createProxiedLayer() : this._newCustomBaselayerModel();
  },

  _shouldBeProxied: function () {
    if (this._wmsType === 'wmts') {
      var supportedMatrixSets = this._wmsService.supportedMatrixSets(this.get('matrix_sets') || []);

      return supportedMatrixSets.length > 0;
    }

    return true;
  },

  _createProxiedLayer: function () {
    var self = this;

    this.save({}, {
      success: function () {
        var proxiedBaselayerModel;

        try {
          proxiedBaselayerModel = self._newProxiedBaselayerModel();
        } catch (e) {
        }

        if (proxiedBaselayerModel) {
          self._setCustomBaselayerModel(proxiedBaselayerModel);
        } else {
          self.set('state', 'saveFail');
        }
      },
      error: function (e) {
        self.set('state', 'saveFail');
      }
    });
  },

  _newCustomBaselayerModel: function () {
    var customBaselayerModel = this._byCustomURL(this._xyzURLTemplate());

    customBaselayerModel.set({
      name: this.get('title') || this.get('name'),
      attribution: this.get('attribution'),
      bounding_boxes: this.get('llbbox')
    });
    this._setCustomBaselayerModel(customBaselayerModel);

    return customBaselayerModel;
  },

  _newProxiedBaselayerModel: function () {
    if (!this.get('mapproxy_id')) {
      throw new Error('mapproxy_id must be set');
    }

    var url = this._wmsService.getProxyTilesURL() + '/' + this.get('mapproxy_id') + '/wmts/map/webmercator/{z}/{x}/{y}.png';
    var proxiedBaselayerModel = this._generateCustomBaselayerModel(url);

    proxiedBaselayerModel.set({
      name: this.get('title') || this.get('name'),
      attribution: this.get('attribution'),
      proxy: true,
      bounding_boxes: this.get('bounding_boxes')
    });

    return proxiedBaselayerModel;
  },

  _generateCustomBaselayerModel: function (url) {
    var layer = new CustomBaselayerModel({
      urlTemplate: url,
      attribution: null,
      maxZoom: 21,
      minZoom: 0,
      name: '',
      tms: false
    });
    layer.set('className', layer._generateClassName(url));

    return layer
  },

  _byCustomURL: function (url) {
    // Minimal test for "valid URL" w/o having to complicate it with regex
    if (url && url.indexOf('/') === -1) throw new TypeError('invalid URL');

    // Only lowercase the placeholder variables, since the URL may contain case-sensitive data (e.g. API keys and such)
    url = url.replace(/\{S\}/g, '{s}')
      .replace(/\{X\}/g, '{x}')
      .replace(/\{Y\}/g, '{y}')
      .replace(/\{Z\}/g, '{z}');

    var layer = this._generateCustomBaselayerModel(url);

    return layer;
  },

  _xyzURLTemplate: function () {
    var urlTemplate = this.get('url_template') || '';
    // Convert the proxy template variables to XYZ format, http://foo.com/bar/%%(z)s/%%(x)s/%%(y)s.png"
    return urlTemplate.replace(/%%\((\w)\)s/g, '{$1}');
  },

  _setCustomBaselayerModel: function (customBaselayerModel) {
    this.set({
      state: 'saveDone',
      customBaselayerModel: customBaselayerModel
    });
  }

});
<commit_msg>basemaps: wms: refactor custombaselayermodel<commit_after>var _ = require('underscore-cdb-v3');
var Backbone = require('backbone');
var CustomBaselayerModel = require('../../../../data/custom-baselayer-model');

/**
 * Model for an individual WMS/WMTS layer.
 */

module.exports = Backbone.Model.extend({

  defaults: {
    selected: false,
    state: 'idle' // idle, saving, saveDone, saveFail
  },

  url: function () {
    return this._wmsService.saveLayerURL({
      title: this.get('title'),
      name: this.get('name'),
      layer: this.get('name'),
      srs: this.get('srs'),
      bounding_boxes: this.get('llbbox'),
      type: this._wmsType, // wms/wmts
      matrix_sets: this.get('matrix_sets')
    });
  },

  sync: function (method, model, options) {
    options = options || {};
    options.url = this.url(method.toLowerCase());
    options.dataType = 'jsonp';
    method = 'READ';

    return Backbone.sync.apply(this, arguments);
  },

  initialize: function (attrs, opts) {
    if (!opts.wmsService) throw new Error('wmsService is required');

    this._wmsService = opts.wmsService;
    this._wmsType = opts.wmsType;
  },

  canSave: function (customBaselayersCollection) {
    return !_.any(customBaselayersCollection.isCustomCategory(), function (customLayer) {
      return customLayer.get('name') === this.get('title');
    }, this);
  },

  createProxiedLayerOrCustomBaselayerModel: function () {
    this.set('state', 'saving');
    this._shouldBeProxied() ? this._createProxiedLayer() : this._newCustomBaselayerModel();
  },

  _shouldBeProxied: function () {
    if (this._wmsType === 'wmts') {
      var supportedMatrixSets = this._wmsService.supportedMatrixSets(this.get('matrix_sets') || []);

      return supportedMatrixSets.length > 0;
    }

    return true;
  },

  _createProxiedLayer: function () {
    var self = this;

    this.save({}, {
      success: function () {
        var proxiedBaselayerModel;

        try {
          proxiedBaselayerModel = self._newProxiedBaselayerModel();
        } catch (e) {
        }

        if (proxiedBaselayerModel) {
          self._setCustomBaselayerModel(proxiedBaselayerModel);
        } else {
          self.set('state', 'saveFail');
        }
      },
      error: function (e) {
        self.set('state', 'saveFail');
      }
    });
  },

  _newCustomBaselayerModel: function () {
    var customBaselayerModel = this._byCustomURL(this._xyzURLTemplate());

    customBaselayerModel.set({
      name: this.get('title') || this.get('name'),
      attribution: this.get('attribution'),
      bounding_boxes: this.get('llbbox')
    });
    this._setCustomBaselayerModel(customBaselayerModel);

    return customBaselayerModel;
  },

  _newProxiedBaselayerModel: function () {
    if (!this.get('mapproxy_id')) {
      throw new Error('mapproxy_id must be set');
    }

    var url = this._wmsService.getProxyTilesURL() + '/' + this.get('mapproxy_id') + '/wmts/map/webmercator/{z}/{x}/{y}.png';
    var proxiedBaselayerModel = this._generateCustomBaselayerModel(url);

    proxiedBaselayerModel.set({
      name: this.get('title') || this.get('name'),
      attribution: this.get('attribution'),
      proxy: true,
      bounding_boxes: this.get('bounding_boxes')
    });

    return proxiedBaselayerModel;
  },

  _generateCustomBaselayerModel: function (url) {
    var layer = new CustomBaselayerModel({
      urlTemplate: url,
      attribution: null,
      maxZoom: 21,
      minZoom: 0,
      name: '',
      category: 'WMS',
      tms: false,
      type: 'Tiled'
    });
    layer.set('className', layer._generateClassName(url));

    return layer
  },

  _byCustomURL: function (url) {
    // Minimal test for "valid URL" w/o having to complicate it with regex
    if (url && url.indexOf('/') === -1) throw new TypeError('invalid URL');

    // Only lowercase the placeholder variables, since the URL may contain case-sensitive data (e.g. API keys and such)
    url = url.replace(/\{S\}/g, '{s}')
      .replace(/\{X\}/g, '{x}')
      .replace(/\{Y\}/g, '{y}')
      .replace(/\{Z\}/g, '{z}');

    var layer = this._generateCustomBaselayerModel(url);

    return layer;
  },

  _xyzURLTemplate: function () {
    var urlTemplate = this.get('url_template') || '';
    // Convert the proxy template variables to XYZ format, http://foo.com/bar/%%(z)s/%%(x)s/%%(y)s.png"
    return urlTemplate.replace(/%%\((\w)\)s/g, '{$1}');
  },

  _setCustomBaselayerModel: function (customBaselayerModel) {
    this.set({
      state: 'saveDone',
      customBaselayerModel: customBaselayerModel
    });
  }

});
<|endoftext|>


<commit_before>const { HackerApplication, ApplicationResponse, Team, TeamMember, Hacker, db } = require('js/server/models');
const { sendEmail } = require('js/server/email');
const { response } = require('js/shared/status-constants');
const emailTemplates = require('./email-templates');

function isApplicationScoreValid(application) {
  // TODO: Make this work
  return Promise.resolve(false);
}

/**
 * Normalizes teams and non-teams into an array that either contains a
 * single application, or all applications from the team that the input
 * belongs to.
 */
function normalizeApplicationTeams(application) {
  return application.getHacker().then(hacker => {
    return TeamMember.findOne({
      where: {
        hackerId: hacker.id
      },
      // We're going deeper and deeper...
      include: [
        {
          model: Team,
          include: [
            {
              model: TeamMember,
              include: [
                {
                  model: Hacker,
                  include: [HackerApplication],
                },
              ],
            },
          ],
        },
      ],
    }).then(teamMember => {
      if (teamMember == null) {
        return [application];
      }

      return teamMember.team.teamMembers.map(member => member.hacker.hackerApplication);
    });
  });
}

/**
 * Returns a promise that resolves with the applications if all applications have been scored,
 * and rejects if any one of them have not been.
 */
function checkApplicationsAreScored(applications) {
  return Promise
    .all(applications.map(isApplicationScoreValid))
    .then(applicationValidities => applicationValidities.every(validity => validity))
    .then(areApplicationsValid => {
      if (!areApplicationsValid) {
        throw new Error('Not all applications have been scored fully');
      }

      return applications;
    })
}

/**
 * Sets a response for an individual application.
 *
 * Returns a promise that resolves with whether the application is new or not
 */
function setResponseForApplication(application, responseStatus, transaction) {
  console.log(`Setting response for application ${application.id} to "${responseStatus}"`);
  const responseContent = {
    response: responseStatus,
    hackerApplicationId: application.id,
  };

  return ApplicationResponse.findOne({
    where: {
      hackerApplicationId: application.id,
    },
    transaction,
  }).then((applicationResponse) => {
    if (applicationResponse != null) {
      return applicationResponse.update(responseContent, { transaction }).then(() => false);
    }

    return ApplicationResponse.create(responseContent, { transaction }).then(() => true);
  });
}

/**
 * Sets the response for a set of applications in an ACID-safe way
 */
function setResponseForApplications(applications, responseStatus) {
  return db.transaction(transaction =>
    Promise.all(
      applications.map(application =>
        Promise
          .all([application, setResponseForApplication(application, responseStatus, transaction)])
          .then(([ application, isApplicationNew ]) => ({ application, isApplicationNew }))
        )
    )
  );
}

function getEmailForApplicationResponse(hacker, responseStatus) {
  if (responseStatus === response.INVITED) {
    return emailTemplates.invited({ name: hacker.firstName });
  }

  if (responseStatus === response.REJECTED) {
    return emailTemplates.notInvited({ name: hacker.firstName });
  }

  throw new Error(`Could not find template for response "${responseStatus}"`);
}

function sendEmailForApplicationResponse(application, responseStatus) {
  console.log(`Sending response email for application ${application.id}`);

  return application.getHacker().then(hacker =>
    sendEmail({
      to: hacker.email,
      contents: getEmailForApplicationResponse(hacker, responseStatus),
    })
  );
}

/**
 * Sets the response to an application while enforcing our requirements:
 *
 * - An application must be validly scored
 * - Any applicants in the same team will receive the same status
 * - If this is the application's first response (99% of cases), an email will be sent
 */
exports.setResponseForApplicationWithChecks = function setResponseForApplicationWithChecks(originalApplication, responseStatus) {
  return normalizeApplicationTeams(originalApplication)
    .then(checkApplicationsAreScored)
    .then(applications => setResponseForApplications(applications, responseStatus))
    .then((applicationCreationStatuses) => {
      // We do not return these promises as they are just fire and forget
      // No way to recover on error
      applicationCreationStatuses
        .filter(({ isApplicationNew }) => isApplicationNew)
        .forEach(({ application }) => sendEmailForApplicationResponse(application, responseStatus))
    }).then(() => ({ response: responseStatus }));
};
<commit_msg>Hook up correct score checking<commit_after>const { HackerApplication, ApplicationResponse, Team, TeamMember, Hacker, db } = require('js/server/models');
const { sendEmail } = require('js/server/email');
const { response } = require('js/shared/status-constants');
const { applicationHasBeenIndividuallyScored } = require('./score-logic');
const emailTemplates = require('./email-templates');

function isApplicationScoreValid(application) {
  // TODO: Make this work
  return Promise.resolve(false);
}

/**
 * Normalizes teams and non-teams into an array that either contains a
 * single application, or all applications from the team that the input
 * belongs to.
 */
function normalizeApplicationTeams(application) {
  return application.getHacker().then(hacker => {
    return TeamMember.findOne({
      where: {
        hackerId: hacker.id
      },
      // We're going deeper and deeper...
      include: [
        {
          model: Team,
          include: [
            {
              model: TeamMember,
              include: [
                {
                  model: Hacker,
                  include: [HackerApplication],
                },
              ],
            },
          ],
        },
      ],
    }).then(teamMember => {
      if (teamMember == null) {
        return [application];
      }

      return teamMember.team.teamMembers.map(member => member.hacker.hackerApplication);
    });
  });
}

/**
 * Returns a promise that resolves with the applications if all applications have been scored,
 * and rejects if any one of them have not been.
 */
function checkApplicationsAreScored(applications) {
  return Promise
    .all(applications.map(applicationHasBeenIndividuallyScored))
    .then(applicationValidities => applicationValidities.every(validity => validity))
    .then(areApplicationsValid => {
      if (!areApplicationsValid) {
        throw new Error('Not all applications have been scored fully');
      }

      return applications;
    })
}

/**
 * Sets a response for an individual application.
 *
 * Returns a promise that resolves with whether the application is new or not
 */
function setResponseForApplication(application, responseStatus, transaction) {
  console.log(`Setting response for application ${application.id} to "${responseStatus}"`);
  const responseContent = {
    response: responseStatus,
    hackerApplicationId: application.id,
  };

  return ApplicationResponse.findOne({
    where: {
      hackerApplicationId: application.id,
    },
    transaction,
  }).then((applicationResponse) => {
    if (applicationResponse != null) {
      return applicationResponse.update(responseContent, { transaction }).then(() => false);
    }

    return ApplicationResponse.create(responseContent, { transaction }).then(() => true);
  });
}

/**
 * Sets the response for a set of applications in an ACID-safe way
 */
function setResponseForApplications(applications, responseStatus) {
  return db.transaction(transaction =>
    Promise.all(
      applications.map(application =>
        Promise
          .all([application, setResponseForApplication(application, responseStatus, transaction)])
          .then(([ application, isApplicationNew ]) => ({ application, isApplicationNew }))
        )
    )
  );
}

function getEmailForApplicationResponse(hacker, responseStatus) {
  if (responseStatus === response.INVITED) {
    return emailTemplates.invited({ name: hacker.firstName });
  }

  if (responseStatus === response.REJECTED) {
    return emailTemplates.notInvited({ name: hacker.firstName });
  }

  throw new Error(`Could not find template for response "${responseStatus}"`);
}

function sendEmailForApplicationResponse(application, responseStatus) {
  console.log(`Sending response email for application ${application.id}`);

  return application.getHacker().then(hacker =>
    sendEmail({
      to: hacker.email,
      contents: getEmailForApplicationResponse(hacker, responseStatus),
    })
  );
}

/**
 * Sets the response to an application while enforcing our requirements:
 *
 * - An application must be validly scored
 * - Any applicants in the same team will receive the same status
 * - If this is the application's first response (99% of cases), an email will be sent
 */
exports.setResponseForApplicationWithChecks = function setResponseForApplicationWithChecks(originalApplication, responseStatus) {
  return normalizeApplicationTeams(originalApplication)
    .then(checkApplicationsAreScored)
    .then(applications => setResponseForApplications(applications, responseStatus))
    .then((applicationCreationStatuses) => {
      // We do not return these promises as they are just fire and forget
      // No way to recover on error
      applicationCreationStatuses
        .filter(({ isApplicationNew }) => isApplicationNew)
        .forEach(({ application }) => sendEmailForApplicationResponse(application, responseStatus))
    }).then(() => ({ response: responseStatus }));
};
<|endoftext|>


<commit_before>(function($) {
    "use strict";

    var defaultOptions = {
        defaultText: 'Please Select...'
    };
    $.fn.fallzuSelectpicker = function(devOptions) {
        var options = $.extend(defaultOptions, devOptions);
        var skinRender = function(el, name, template) {
            el.after(
                '
' +
                    '<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">' +
                        '' + options.defaultText + '' +
                        '' +
                    '</button>' +
                    '
' + template + '
' +
                '
'
            );
        };

        var templateRender = function(el, labelStr, hrStr, isGroup) {
            var labelStr = labelStr || '';
            var hrStr = hrStr || '';
            var subtext = (el.data('subtext') === undefined)
                          ? ('')
                          : (' ' + el.data('subtext') + '');
            var subtextAttr = (el.data('subtext') === undefined)
                              ? ('')
                              : ('data-subtext="' + el.data('subtext') + '"');
            var group = (isGroup === true) ? ('opt') : ('');

            var template =
                '
' +
                    labelStr +
                    '' +
                        '' + el.text() + subtext + '' +
                        '' +
                    '' +
                    hrStr +
                '
';
            return template;
        };

        $(this).each(function() {
            var el = $(this);

            // Reset
            el.find('option:selected').prop('', false);

            // Check select element
            var elName = el.attr('name');
            if (el.is('select') && elName != undefined) {
                var template = '';
                var seletLength = el.children().length;
                el.children().each(function(optionIndex) {
                    var rootOption = $(this);

                    // Check isGroup
                    if (rootOption.is('optgroup')) {
                        rootOption.each(function() {
                            var optionGroup = $(this);
                            var label = optionGroup.attr('label');
                            var length = optionGroup.children().length;

                            optionGroup.children().each(function(index) {
                                var option = $(this);
                                // Label
                                var labelStr = (index === 0) ? ('
' + label + '
') : ('');
                                // hr line
                                var hrStr = (index === length - 1 && optionIndex != seletLength - 1)
                                            ? ('

')
                                            : ('');

                                template += templateRender(option, labelStr, hrStr, true);
                            });
                        });
                    } else {
                        template += templateRender(rootOption);
                    }

                });

                skinRender(el, elName, template);
                el.hide();

                // Binding event
                var dropdownDiv = el.next('.fallzu-select-dropdown[data-name=' + elName + ']').first();

                // Option Click
                dropdownDiv.find('.fallzu-select-option').on('click', function(e) {
                    e.preventDefault();
                    var ul = $(this).parents('ul');
                    var value = $(this).data('val');
                    var originalOption = el.find('option[value=' + value + ']');
                    // Without children element
                    var text = $(this).find('.fallzu-option-text').clone().children().remove().end().text();
                    var subtext = $(this).data('subtext');
                    var subtextStr = (subtext === undefined)
                                    ? ('')
                                    : (' ' + subtext + '');

                    // Multiple
                    if (el.prop('multiple')) {
                        var isSelect = originalOption.prop('selected');

                        if (isSelect) {
                            $(this).removeClass('fallzu-option-active');
                            originalOption.prop('selected', false);
                        } else {
                            $(this).addClass('fallzu-option-active');
                            originalOption.prop('selected', true);
                        }

                        var textArr = [];
                        el.find('option:selected').each(function() {
                            textArr.push($(this).text());
                        });

                        dropdownDiv.find('.fallzu-select-text').html(textArr.join());
                        return false;
                    } else {
                        originalOption.prop('selected', true);
                        ul.find('.fallzu-option-active').removeClass('fallzu-option-active');
                        $(this).addClass('fallzu-option-active');
                        dropdownDiv.find('.fallzu-select-text').html(text + subtextStr);
                        originalOption.prop('selected', true);
                    }
                });
            }
        });
    };
})(jQuery);
<commit_msg>fix multiple bug<commit_after>(function($) {
    "use strict";

    var defaultOptions = {
        defaultText: 'Please Select...'
    };
    $.fn.fallzuSelectpicker = function(devOptions) {
        var options = $.extend(defaultOptions, devOptions);
        var skinRender = function(el, name, template) {
            el.after(
                '
' +
                    '<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">' +
                        '' + options.defaultText + '' +
                        '' +
                    '</button>' +
                    '
' + template + '
' +
                '
'
            );
        };

        var templateRender = function(el, labelStr, hrStr, isGroup) {
            var labelStr = labelStr || '';
            var hrStr = hrStr || '';
            var subtext = (el.data('subtext') === undefined)
                          ? ('')
                          : (' ' + el.data('subtext') + '');
            var subtextAttr = (el.data('subtext') === undefined)
                              ? ('')
                              : ('data-subtext="' + el.data('subtext') + '"');
            var group = (isGroup === true) ? ('opt') : ('');

            var template =
                '
' +
                    labelStr +
                    '' +
                        '' + el.text() + subtext + '' +
                        '' +
                    '' +
                    hrStr +
                '
';
            return template;
        };

        $(this).each(function() {
            var el = $(this);

            // Reset
            el.find('option:selected').prop('', false);

            // Check select element
            var elName = el.attr('name');
            if (el.is('select') && elName != undefined) {
                var template = '';
                var seletLength = el.children().length;
                el.children().each(function(optionIndex) {
                    var rootOption = $(this);

                    // Check isGroup
                    if (rootOption.is('optgroup')) {
                        rootOption.each(function() {
                            var optionGroup = $(this);
                            var label = optionGroup.attr('label');
                            var length = optionGroup.children().length;

                            optionGroup.children().each(function(index) {
                                var option = $(this);
                                // Label
                                var labelStr = (index === 0) ? ('
' + label + '
') : ('');
                                // hr line
                                var hrStr = (index === length - 1 && optionIndex != seletLength - 1)
                                            ? ('

')
                                            : ('');

                                template += templateRender(option, labelStr, hrStr, true);
                            });
                        });
                    } else {
                        template += templateRender(rootOption);
                    }

                });

                skinRender(el, elName, template);
                el.hide();

                // Binding event
                var dropdownDiv = el.next('.fallzu-select-dropdown[data-name=' + elName + ']').first();

                // Option Click
                dropdownDiv.find('.fallzu-select-option').on('click', function(e) {
                    e.preventDefault();
                    var ul = $(this).parents('ul');
                    var value = $(this).data('val');
                    var originalOption = el.find('option[value=' + value + ']');
                    // Without children element
                    var text = $(this).find('.fallzu-option-text').clone().children().remove().end().text();
                    var subtext = $(this).data('subtext');
                    var subtextStr = (subtext === undefined)
                                    ? ('')
                                    : (' ' + subtext + '');

                    // Multiple
                    if (el.prop('multiple')) {
                        var isSelect = originalOption.prop('selected');

                        if (isSelect) {
                            $(this).removeClass('fallzu-option-active');
                            originalOption.prop('selected', false);
                        } else {
                            $(this).addClass('fallzu-option-active');
                            originalOption.prop('selected', true);
                        }

                        var textArr = [];
                        el.find('option:selected').each(function() {
                            textArr.push($(this).text());
                        });

                        var title = (textArr.length == 0) ? (options.defaultText) : (textArr.join());

                        dropdownDiv.find('.fallzu-select-text').html(title);
                        return false;
                    } else {
                        originalOption.prop('selected', true);
                        ul.find('.fallzu-option-active').removeClass('fallzu-option-active');
                        $(this).addClass('fallzu-option-active');
                        dropdownDiv.find('.fallzu-select-text').html(text + subtextStr);
                        originalOption.prop('selected', true);
                    }
                });
            }
        });
    };
})(jQuery);
<|endoftext|>


<commit_before>/* eslint-disable */
// https://github.com/karma-runner/karma/issues/1597
'use strict';

const path = require('path');
const webpackConfig = require('../webpack/base.webpack.conf');
webpackConfig.devtool = 'inline-source-map';
webpackConfig.module.preLoaders.push({
  test: /\.js$/,
  include: path.resolve(__dirname, '../src'),
  loader: 'babel-istanbul-loader',
});

module.exports = {
  frameworks: ['mocha'],
  files: [
    'node_modules/babel-polyfill/dist/polyfill.js',
    'test/index.spec.js',
    { pattern: 'test/resources/**/*', included: false },
  ],

  preprocessors: {
    'test/index.spec.js': ['webpack', 'sourcemap'],
  },

  proxies: {
    '/resources/': '/base/test/resources/'
  },

  basePath: '../',

  reporters: ['spec', 'coverage'],

  coverageReporter: {
    type: 'html',
    dir: 'coverage/',
  },

  webpack: webpackConfig,

  webpackMiddleware: {
    // webpack-dev-middleware configuration
    noInfo: true,
  },

  client: {
    mocha: {
      // change Karma's debug.html to the mocha web reporter
      reporter: 'html',

      // require specific files after Mocha is initialized
      require: [require.resolve('bdd-lazy-var/bdd_lazy_var_global')],

      // custom ui, defined in required file above
      ui: 'bdd-lazy-var/global',
    },
  },

  plugins: [
    require('karma-webpack'),
    require('istanbul-instrumenter-loader'),
    require('karma-mocha'),
    require('karma-coverage'),
    require('karma-spec-reporter'),
    require('karma-sourcemap-loader'),
  ],
};
<commit_msg>Move coverage folder<commit_after>/* eslint-disable */
// https://github.com/karma-runner/karma/issues/1597
'use strict';

const path = require('path');
const webpackConfig = require('../webpack/base.webpack.conf');
webpackConfig.devtool = 'inline-source-map';
webpackConfig.module.preLoaders.push({
  test: /\.js$/,
  include: path.resolve(__dirname, '../src'),
  loader: 'babel-istanbul-loader',
});

module.exports = {
  frameworks: ['mocha'],
  files: [
    'node_modules/babel-polyfill/dist/polyfill.js',
    'test/index.spec.js',
    { pattern: 'test/resources/**/*', included: false },
  ],

  preprocessors: {
    'test/index.spec.js': ['webpack', 'sourcemap'],
  },

  proxies: {
    '/resources/': '/base/test/resources/'
  },

  basePath: '../',

  reporters: ['spec', 'coverage'],

  coverageReporter: {
    type: 'html',
    dir: '../coverage/',
  },

  webpack: webpackConfig,

  webpackMiddleware: {
    // webpack-dev-middleware configuration
    noInfo: true,
  },

  client: {
    mocha: {
      // change Karma's debug.html to the mocha web reporter
      reporter: 'html',

      // require specific files after Mocha is initialized
      require: [require.resolve('bdd-lazy-var/bdd_lazy_var_global')],

      // custom ui, defined in required file above
      ui: 'bdd-lazy-var/global',
    },
  },

  plugins: [
    require('karma-webpack'),
    require('istanbul-instrumenter-loader'),
    require('karma-mocha'),
    require('karma-coverage'),
    require('karma-spec-reporter'),
    require('karma-sourcemap-loader'),
  ],
};
<|endoftext|>


<commit_before>/**
 * Created by diegob on 02.10.15.
 */
(function () {
  'use strict';

  window.kj = window.kj || {};
  var kj = window.kj;

  kj.Recorder = function($window, $rootScope, $document, $mdToast) {
    this.rec = new webkitSpeechRecognition();
    this.rec.continuous = true;
    this.rec.interimResults = true;
    this.rec.lang = 'en-IN';
    this.rec.onstart = this.onStart.bind(this);
    this.rec.onerror = this.onError.bind(this);
    this.rec.onresult = this.onResult.bind(this);
    this.rec.onend = this.onEnd.bind(this);
    this.rec.start();

    $window.setInterval(this.watchDog.bind(this), 1000);
    this.lastResultTime = 0;
    this.result = '';
    this.$scope_ = $rootScope;
    this.enabled_ = true;
    this.isRecording = false;
    this.$mdToast_ = $mdToast;
  };

  Object.defineProperty(kj.Recorder.prototype, 'enabled', {
    get: function() {
      return this.enabled_;
    },
    set: function(value) {
      this.enabled_ = value;
      if (this.enabled_) {
        this.rec.start();
      } else {
        this.rec.stop();
      }
    }
  });

  kj.Recorder.prototype.showMessage = function(message) {
    this.$mdToast_.show(
        this.$mdToast_.simple()
            .content(message)
            .position('bottom right')
            .hideDelay(50000)
    );
  };

  kj.Recorder.prototype.onStart = function(event) {
    console.log('Started listening.');
    console.log(event);
    this.showMessage('Now listening...');
    this.lastResultTime = Date.now();
    this.isRecording = true;
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.onEnd = function(event) {
    console.log('Listening ended.');
    console.log(event);
    this.isRecording = false;
    this.showMessage('Stopped listening.');
    if (this.enabled_) {
      this.rec.start();
    }
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.onError = function(event) {
    console.log('Oops, an error.');
    console.log(event);
    if (event.error === 'aborted') {
      this.enabled_ = false;
      this.showMessage('Disabling because the microphone is busy.');
    } else {
      this.showMessage('Found error while recording, restarting...');
    }
    this.rec.stop();
  };

  kj.Recorder.prototype.onResult = function(event) {
    console.log('Received a result.');
    console.log(event);
    console.log(Date.now());
    var found = false;
    this.lastResultTime = Date.now();
    for (var i = event.resultIndex; i < event.results.length; i++) {
      if (event.results[i].isFinal) {
        var result = event.results[i][0].transcript;
        result = result.trim().toLowerCase();
        console.log('Checking result...');
        console.log(result);
        this.showMessage('Detected speech: ' + result + '.Still listening...');
        found = true;
        for (var j = 0; j < kj.VoiceService.VOICES.length; j++) {
          var helper = kj.VoiceService.VOICES[j];
          var helperIndex = result.indexOf(helper.name.toLowerCase());
          if (helperIndex > -1) {
            result = result.substring(helperIndex + helper.name.length);
            this.$scope_.$broadcast('speechResult', {
              text: result,
              voiceModel: helper.value,
              swear: helper.name === 'Gordon' || helper.name === 'Garden'
            });
            break;
          }
        }
      }
    }
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.watchDog = function() {
    var now = Date.now();
    if (this.enabled_ && now - this.lastResultTime > 10000) {
      console.log('Timed out.');
      this.rec.stop();
    }
  };

  kj.module.service('Recorder', kj.Recorder);
})();<commit_msg>Latest<commit_after>/**
 * Created by diegob on 02.10.15.
 */
(function () {
  'use strict';

  window.kj = window.kj || {};
  var kj = window.kj;

  kj.Recorder = function($window, $rootScope, $document, $mdToast) {
    this.rec = new webkitSpeechRecognition();
    this.rec.continuous = true;
    this.rec.interimResults = true;
    this.rec.lang = 'en-IN';
    this.rec.onstart = this.onStart.bind(this);
    this.rec.onerror = this.onError.bind(this);
    this.rec.onresult = this.onResult.bind(this);
    this.rec.onend = this.onEnd.bind(this);
    this.rec.start();

    $window.setInterval(this.watchDog.bind(this), 1000);
    this.lastResultTime = 0;
    this.result = '';
    this.$scope_ = $rootScope;
    this.enabled_ = true;
    this.isRecording = false;
    this.$mdToast_ = $mdToast;
  };

  Object.defineProperty(kj.Recorder.prototype, 'enabled', {
    get: function() {
      return this.enabled_;
    },
    set: function(value) {
      this.enabled_ = value;
      if (this.enabled_) {
        this.rec.start();
      } else {
        this.rec.stop();
      }
    }
  });

  kj.Recorder.prototype.showMessage = function(message) {
    this.$mdToast_.show(
        this.$mdToast_.simple()
            .content(message)
            .position('bottom right')
            .hideDelay(50000)
    );
  };

  kj.Recorder.prototype.onStart = function(event) {
    console.log('Started listening.');
    console.log(event);
    this.showMessage('Now listening...');
    this.lastResultTime = Date.now();
    this.isRecording = true;
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.onEnd = function(event) {
    console.log('Listening ended.');
    console.log(event);
    this.isRecording = false;
    this.showMessage('Stopped listening.');
    if (this.enabled_) {
      this.rec.start();
    }
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.onError = function(event) {
    console.log('Oops, an error.');
    console.log(event);
    if (event.error === 'aborted') {
      this.enabled_ = false;
      this.showMessage('Disabling because the microphone is busy.');
    } else {
      this.showMessage('Found error while recording, restarting...');
    }
    this.rec.stop();
  };

  kj.Recorder.prototype.onResult = function(event) {
    console.log('Received a result.');
    console.log(event);
    console.log(Date.now());
    var found = false;
    this.lastResultTime = Date.now();
    for (var i = event.resultIndex; i < event.results.length; i++) {
      if (event.results[i].isFinal) {
        var result = event.results[i][0].transcript;
        result = result.trim().toLowerCase();
        console.log('Checking result...');
        console.log(result);
        this.showMessage('Detected speech: ' + result + '.Still listening...');
        found = true;
        for (var j = 0; j < kj.VoiceService.VOICES.length; j++) {
          var helper = kj.VoiceService.VOICES[j];
          var helperIndex = result.indexOf(helper.name.toLowerCase());
          if (helperIndex > -1) {
            result = result.substring(helperIndex + helper.name.length);
            this.$scope_.$broadcast('speechResult', {
              text: result,
              voiceModel: helper.value,
              swear: helper.name === 'Gordon' || helper.name === 'Garden'
            });
            break;
          }
        }
      }
    }
    if (!found) {
      this.showMessage('Listening...');
    }
    this.$scope_.$apply();
  };

  kj.Recorder.prototype.watchDog = function() {
    var now = Date.now();
    if (this.enabled_ && now - this.lastResultTime > 10000) {
      console.log('Timed out.');
      this.rec.stop();
    }
  };

  kj.module.service('Recorder', kj.Recorder);
})();<|endoftext|>


<commit_before>/*****************************************************************************/
/* ImportEmployeesModal: Event Handlers */
/*****************************************************************************/
import Ladda from 'ladda';

Template.ImportEmployeesModal.events({
    "click #employeesFileUpload": function (e, tmpl) {
        e.preventDefault();

        let file = $("#fileInput")[0].files[0];
        if (!file){
            swal('No File to Import', 'Please specify file to import', 'error');
            return
        }
        $('#employeesFileUpload').text('Uploading. Please wait ...')
        tmpl.$('#employeesFileUpload').attr('disabled', true);
        //--
        if (file.type !== "text/csv") {
            try {
                let l = Ladda.create(tmpl.$('#employeesFileUpload')[0]);
                l.stop();
                l.remove();
            } catch(e) {
                console.log(e);
            }
            return
        }

        tmpl.isUploading.set(true)

        Papa.parse( file, {
            header: true,
            complete( results, file ) {
                Meteor.call('parseEmployeesUpload', results.data, Session.get('context'), ( error, response ) => {
                    $('#employeesFileUpload').text('Upload File')
                    tmpl.$('#employeesFileUpload').attr('disabled', false);
                    tmpl.isUploading.set(false)

                    if ( error ) {
                        console.log(error.reason)
                        swal('Server Error!', 'Sorry, a server error has occurred. Please try again later.', 'error');
                    } else {
                        tmpl.response.set('response', response);    // For some weird reason Template.instance() doesn't work
                    }
                });
            }
        });
    },
    "click .uploadIcon": function (e, tmpl) {
        e.preventDefault();
        tmpl.$("#fileInput").trigger('click');
    },
    "change #fileInput": function (e) {
        let file =  e.target.files[0];
        if (file) {
            $(".file-info").text(file.name);
            if (file.type !== "text/csv") {
                swal('Invalid file', "Only csv files allowed", 'error');
            }
        } else {
            $(".file-info").text("No file chosen")
        }
    },
    'click #recordsWithError': function(e, tmpl) {
        e.preventDefault()

        let fields = ['ErrorLine', 'FirstName','LastName','OtherNames','Email','EmployeeId','Address','DateOfBirth',
          'Gender','MaritalStatus','Phone','State','GuarantorFullName','GuarantorEmail','GuarantorPhone',
          'GuarantorAddress','GuarantorCity','GuarantorState','EmploymentHireDate',
          'EmploymentConfirmationDate','EmploymentTerminationDate','Status',
          'EmergencyContactFullName','EmergencyContactEmail','EmergencyContactPhone',
          'EmergencyContactAddress','EmergencyContactCity','EmergencyContactState','PaymentMethod',
          'Bank','AccountNumber','AccountName','Pensionmanager','RSANumber','TaxPayerId']

        let uploadResponse = tmpl.response.get('response'); // For some weird reason Template.instance() doesn't work
        let skippedAndErrors = Array.prototype.concat(uploadResponse.skipped, uploadResponse.errors)

        BulkpayExplorer.exportAllData({fields: fields, data: skippedAndErrors}, "Employee records with error");
    }
});

/*****************************************************************************/
/* ImportEmployeesModal: Helpers */
/*****************************************************************************/
Template.ImportEmployeesModal.helpers({
    'response': () => {
        return Template.instance().response.get('response');
    },
    'error': () => {
        let uploadResponse = Template.instance().response.get('response');
        if(uploadResponse) {
            let skippedCount = uploadResponse.skippedCount
            let errorCount = uploadResponse.failed

            if((skippedCount + errorCount) > 0) {
                return true
            }
        } else {

        }
    },
    'isUploading': () => {
        return Template.instance().isUploading.get()
    }
});

/*****************************************************************************/
/* ImportEmployeesModal: Lifecycle Hooks */
/*****************************************************************************/
Template.ImportEmployeesModal.onCreated(function () {
    let self = this
    self.response = new ReactiveDict()

    self.isUploading = new ReactiveVar()
    self.isUploading.set(false)
});

Template.ImportEmployeesModal.onRendered(function () {
    $('select.dropdown').dropdown();
});

Template.ImportEmployeesModal.onDestroyed(function () {
});
<commit_msg>Trying to see the ACTUAL file type for selected files on windows systems<commit_after>/*****************************************************************************/
/* ImportEmployeesModal: Event Handlers */
/*****************************************************************************/
import Ladda from 'ladda';

Template.ImportEmployeesModal.events({
    "click #employeesFileUpload": function (e, tmpl) {
        e.preventDefault();

        let file = $("#fileInput")[0].files[0];
        console.log(`File type: ${file.type}`)

        if (!file){
            swal('No File to Import', 'Please specify file to import', 'error');
            return
        }
        //--

        if (file.type !== "text/csv") {
            swal('Invalid file', "Only csv files allowed", 'error');
            return
        }
        $('#employeesFileUpload').text('Uploading. Please wait ...')
        tmpl.$('#employeesFileUpload').attr('disabled', true);
        tmpl.isUploading.set(true)

        Papa.parse( file, {
            header: true,
            complete( results, file ) {
                Meteor.call('parseEmployeesUpload', results.data, Session.get('context'), ( error, response ) => {
                    $('#employeesFileUpload').text('Upload File')
                    tmpl.$('#employeesFileUpload').attr('disabled', false);
                    tmpl.isUploading.set(false)

                    if ( error ) {
                        console.log(error.reason)
                        swal('Server Error!', 'Sorry, a server error has occurred. Please try again later.', 'error');
                    } else {
                        tmpl.response.set('response', response);    // For some weird reason Template.instance() doesn't work
                    }
                });
            }
        });
    },
    "click .uploadIcon": function (e, tmpl) {
        e.preventDefault();
        tmpl.$("#fileInput").trigger('click');
    },
    "change #fileInput": function (e) {
        let file =  e.target.files[0];
        if (file) {
            $(".file-info").text(file.name);
            console.log(`File type: ${file.type}`)

            if (file.type !== "text/csv") {
                swal('Invalid file', "Only csv files allowed", 'error');
            }
        } else {
            $(".file-info").text("No file chosen")
        }
    },
    'click #recordsWithError': function(e, tmpl) {
        e.preventDefault()

        let fields = ['ErrorLine', 'FirstName','LastName','OtherNames','Email','EmployeeId','Address','DateOfBirth',
          'Gender','MaritalStatus','Phone','State','GuarantorFullName','GuarantorEmail','GuarantorPhone',
          'GuarantorAddress','GuarantorCity','GuarantorState','EmploymentHireDate',
          'EmploymentConfirmationDate','EmploymentTerminationDate','Status',
          'EmergencyContactFullName','EmergencyContactEmail','EmergencyContactPhone',
          'EmergencyContactAddress','EmergencyContactCity','EmergencyContactState','PaymentMethod',
          'Bank','AccountNumber','AccountName','Pensionmanager','RSANumber','TaxPayerId']

        let uploadResponse = tmpl.response.get('response'); // For some weird reason Template.instance() doesn't work
        let skippedAndErrors = Array.prototype.concat(uploadResponse.skipped, uploadResponse.errors)

        BulkpayExplorer.exportAllData({fields: fields, data: skippedAndErrors}, "Employee records with error");
    }
});

/*****************************************************************************/
/* ImportEmployeesModal: Helpers */
/*****************************************************************************/
Template.ImportEmployeesModal.helpers({
    'response': () => {
        return Template.instance().response.get('response');
    },
    'error': () => {
        let uploadResponse = Template.instance().response.get('response');
        if(uploadResponse) {
            let skippedCount = uploadResponse.skippedCount
            let errorCount = uploadResponse.failed

            if((skippedCount + errorCount) > 0) {
                return true
            }
        } else {

        }
    },
    'isUploading': () => {
        return Template.instance().isUploading.get()
    }
});

/*****************************************************************************/
/* ImportEmployeesModal: Lifecycle Hooks */
/*****************************************************************************/
Template.ImportEmployeesModal.onCreated(function () {
    let self = this
    self.response = new ReactiveDict()

    self.isUploading = new ReactiveVar()
    self.isUploading.set(false)
});

Template.ImportEmployeesModal.onRendered(function () {
    $('select.dropdown').dropdown();
});

Template.ImportEmployeesModal.onDestroyed(function () {
});
<|endoftext|>


<commit_before>define(['render', 'jquery', 'ajax', 'common'], function (render, $, ajax, common) {

    function loadingError(error) {
        ajax.elementErrorMessageFn($('#project-validation-stamp-mgt-error'))(error.responseText)
    }

    function sendUpdates(config, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        // 1 - collect the selected validation stamp names
        var names = $('.project-validation-stamp-mgt-chk').filter(':checked').map(function (i, e) {
            return $(e).attr('data-name')
        }).toArray();
        // 2 - collect the replacement expression
        var replacements = [];
        $('div.project-validation-stamp-mgt-property').each(function (i, div) {
            var extension = $(div).attr('data-extension');
            var name = $(div).attr('data-name');
            var oldRegex = $(div).find('.project-validation-stamp-mgt-property-old').val();
            var newRegex = $(div).find('.project-validation-stamp-mgt-property-new').val();
            if (oldRegex != '') {
                replacements.push({
                    extension: extension,
                    name: name,
                    regex: oldRegex,
                    replacement: newRegex
                })
            }
        });
        // Sends the update
        ajax.post({
            url: 'ui/manage/project/{0}/validation-stamp-mgt'.format(project),
            data: {
                branch1: branch1,
                branch2: branch2,
                stamps: names,
                replacements: replacements
            },
            loading: {
                el: $('#project-validation-stamp-mgt-submit')
            },
            successFn: function () {
                // Confirmation
                var message = 'validation_stamp.mgt.ack'.loc(names);
                $('#project-validation-stamp-mgt-ack').find('span').text(message);
                $('#project-validation-stamp-mgt-ack').show();
                // Reload
                loadBranches(config, target);
            }
        })
    }

    function loadValidationStamps(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/validation_stamp'.format(config.project, branch))
    }

    function loadEditableProperties(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/clone'.format(config.project, branch))
    }

    function prepareCommands(config, indexedStamps2, clone1, clone2, target) {
        // Select missing only
        $('#project-validation-stamp-mgt-select-missing').click(function () {
            $('.project-validation-stamp-mgt-chk').each(function (index, chk) {
                var name = $(chk).attr('data-name');
                var checked = indexedStamps2[name] ? false : true;
                $(chk).prop('checked', checked)
            })
        });
        // Select none
        $('#project-validation-stamp-mgt-select-none').click(function () {
            $('.project-validation-stamp-mgt-chk').prop('checked', false)
        });
        // Select all
        $('#project-validation-stamp-mgt-select-all').click(function () {
            $('.project-validation-stamp-mgt-chk').prop('checked', true)
        });
        // Shows the commands
        target.find('.commands').show();

        // Assemble the properties
        var propertiesIndex = {};
        for (var i = 0; i < clone1.validationStampProperties.length; i++) {
            var property = clone1.validationStampProperties[i];
            var key = property.extension + '-' + property.name;
            propertiesIndex[key] = property;
        }
        for (var i = 0; i < clone2.validationStampProperties.length; i++) {
            var property = clone2.validationStampProperties[i];
            var key = property.extension + '-' + property.name;
            propertiesIndex[key] = property;
        }

        // Gets the values only
        var properties = [];
        for (var key in propertiesIndex) {
            properties.push(propertiesIndex[key])
        }

        // Renders the properties
        render.renderInto(
            target.find('.project-validation-stamp-mgt-properties'),
            'project-validation-stamp-mgt-properties',
            {
                properties: properties
            }
        );

        // Submit button
        $('#project-validation-stamp-mgt-submit').click(function () {
            sendUpdates(config, target)
        });
    }

    function displayBranches(config, stamps1, stamps2, clone1, clone2, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;

        // Indexation of validation stamps by names
        var stampNameFn = function (stamp) {
            return stamp.name;
        }
        var indexedStamps1 = common.uniqueIndex(stamps1, stampNameFn);
        var indexedStamps2 = common.uniqueIndex(stamps2, stampNameFn);

        // Gets all names in a sorted list
        var names = [];
        for (var name in indexedStamps1) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        for (var name in indexedStamps2) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        names.sort();

        // Creating the model
        var model = {
            project: project,
            branch1: branch1,
            branch2: branch2,
            stamps: []
        };
        $.each(names, function (index, name) {
            var line = {
                name: name
            };
            var stamp1 = indexedStamps1[name];
            if (stamp1) {
                line.stamp1 = stamp1;
            }
            var stamp2 = indexedStamps2[name];
            if (stamp2) {
                line.stamp2 = stamp2;
            }
            model.stamps.push(line);
        });

        // Rendering
        render.renderInto(
            target.find('.content'),
            'project-validation-stamp-mgt-list',
            model,
            function () {
                prepareCommands(config, indexedStamps2, clone1, clone2, target)
            }
        )
    }

    function loadBranches(config, target) {
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        if (branch1 != '' && branch2 != '' && branch1 != branch2) {
            // Parallel AJAX calls
            var ajaxStamps1 = loadValidationStamps(config, branch1);
            var ajaxStamps2 = loadValidationStamps(config, branch2);
            var ajaxProperties1 = loadEditableProperties(config, branch1);
            var ajaxProperties2 = loadEditableProperties(config, branch2);
            // Loading...
            ajax.showLoading({
                mode: 'container',
                el: $('#project-validation-stamp-mgt-loading')
            }, true);
            // Completion
            $.when(ajaxStamps1, ajaxStamps2, ajaxProperties1, ajaxProperties2).then(
                function (resultStamps1, resultStamps2, resultProperties1, resultProperties2) {
                    displayBranches(config, resultStamps1[0], resultStamps2[0], resultProperties1[0], resultProperties2[0], target);
                },
                loadingError
            ).done(
                function () {
                    ajax.showLoading({
                        mode: 'container',
                        el: $('#project-validation-stamp-mgt-loading')
                    }, false);
                }
            )
        }
    }

    return {
        url: function (config) {
            return 'ui/manage/project/{0}/branch'.format(config.project)
        },
        render: render.asSimpleTemplate(
            'project-validation-stamp-mgt',
            render.sameDataFn,
            function (config, branches, target) {
                config.branch1 = '';
                config.branch2 = '';
                // On selection of a branch
                target.find('select.project-validation-stamp-mgt-branch').change(function (e) {
                    var branchTarget = $(this).attr('data-target');
                    var branch = $(this).val();
                    if (branchTarget == '1') {
                        config.branch1 = branch;
                    } else {
                        config.branch2 = branch;
                    }
                    loadBranches(config, target);
                })
            }
        )
    }

});<commit_msg>#220 Make to re-init the state of events<commit_after>define(['render', 'jquery', 'ajax', 'common'], function (render, $, ajax, common) {

    function loadingError(error) {
        ajax.elementErrorMessageFn($('#project-validation-stamp-mgt-error'))(error.responseText)
    }

    function sendUpdates(config, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        // 1 - collect the selected validation stamp names
        var names = $('.project-validation-stamp-mgt-chk').filter(':checked').map(function (i, e) {
            return $(e).attr('data-name')
        }).toArray();
        // 2 - collect the replacement expression
        var replacements = [];
        $('div.project-validation-stamp-mgt-property').each(function (i, div) {
            var extension = $(div).attr('data-extension');
            var name = $(div).attr('data-name');
            var oldRegex = $(div).find('.project-validation-stamp-mgt-property-old').val();
            var newRegex = $(div).find('.project-validation-stamp-mgt-property-new').val();
            if (oldRegex != '') {
                replacements.push({
                    extension: extension,
                    name: name,
                    regex: oldRegex,
                    replacement: newRegex
                })
            }
        });
        // Sends the update
        ajax.post({
            url: 'ui/manage/project/{0}/validation-stamp-mgt'.format(project),
            data: {
                branch1: branch1,
                branch2: branch2,
                stamps: names,
                replacements: replacements
            },
            loading: {
                el: $('#project-validation-stamp-mgt-submit')
            },
            successFn: function () {
                // Confirmation
                var message = 'validation_stamp.mgt.ack'.loc(names);
                $('#project-validation-stamp-mgt-ack').find('span').text(message);
                $('#project-validation-stamp-mgt-ack').show();
                // Reload
                loadBranches(config, target);
            }
        })
    }

    function loadValidationStamps(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/validation_stamp'.format(config.project, branch))
    }

    function loadEditableProperties(config, branch) {
        return $.get('ui/manage/project/{0}/branch/{1}/clone'.format(config.project, branch))
    }

    function prepareCommands(config, indexedStamps2, clone1, clone2, target) {
        // Clears previous state
        $('#project-validation-stamp-mgt-select-missing').unbind('click');
        $('#project-validation-stamp-mgt-select-none').unbind('click');
        $('#project-validation-stamp-mgt-select-all').unbind('click');
        $('#project-validation-stamp-mgt-submit').unbind('click');
        // Select missing only
        $('#project-validation-stamp-mgt-select-missing').click(function () {
            $('.project-validation-stamp-mgt-chk').each(function (index, chk) {
                var name = $(chk).attr('data-name');
                var checked = indexedStamps2[name] ? false : true;
                $(chk).prop('checked', checked)
            })
        });
        // Select none
        $('#project-validation-stamp-mgt-select-none').click(function () {
            $('.project-validation-stamp-mgt-chk').prop('checked', false)
        });
        // Select all
        $('#project-validation-stamp-mgt-select-all').click(function () {
            $('.project-validation-stamp-mgt-chk').prop('checked', true)
        });
        // Shows the commands
        target.find('.commands').show();

        // Assemble the properties
        var propertiesIndex = {};
        for (var i = 0; i < clone1.validationStampProperties.length; i++) {
            var property = clone1.validationStampProperties[i];
            var key = property.extension + '-' + property.name;
            propertiesIndex[key] = property;
        }
        for (var i = 0; i < clone2.validationStampProperties.length; i++) {
            var property = clone2.validationStampProperties[i];
            var key = property.extension + '-' + property.name;
            propertiesIndex[key] = property;
        }

        // Gets the values only
        var properties = [];
        for (var key in propertiesIndex) {
            properties.push(propertiesIndex[key])
        }

        // Renders the properties
        render.renderInto(
            target.find('.project-validation-stamp-mgt-properties'),
            'project-validation-stamp-mgt-properties',
            {
                properties: properties
            }
        );

        // Submit button
        $('#project-validation-stamp-mgt-submit').click(function () {
            sendUpdates(config, target)
        });
    }

    function displayBranches(config, stamps1, stamps2, clone1, clone2, target) {
        var project = config.project;
        var branch1 = config.branch1;
        var branch2 = config.branch2;

        // Indexation of validation stamps by names
        var stampNameFn = function (stamp) {
            return stamp.name;
        }
        var indexedStamps1 = common.uniqueIndex(stamps1, stampNameFn);
        var indexedStamps2 = common.uniqueIndex(stamps2, stampNameFn);

        // Gets all names in a sorted list
        var names = [];
        for (var name in indexedStamps1) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        for (var name in indexedStamps2) {
            if (names.indexOf(name) < 0) {
                names.push(name);
            }
        }
        names.sort();

        // Creating the model
        var model = {
            project: project,
            branch1: branch1,
            branch2: branch2,
            stamps: []
        };
        $.each(names, function (index, name) {
            var line = {
                name: name
            };
            var stamp1 = indexedStamps1[name];
            if (stamp1) {
                line.stamp1 = stamp1;
            }
            var stamp2 = indexedStamps2[name];
            if (stamp2) {
                line.stamp2 = stamp2;
            }
            model.stamps.push(line);
        });

        // Rendering
        render.renderInto(
            target.find('.content'),
            'project-validation-stamp-mgt-list',
            model,
            function () {
                prepareCommands(config, indexedStamps2, clone1, clone2, target)
            }
        )
    }

    function loadBranches(config, target) {
        var branch1 = config.branch1;
        var branch2 = config.branch2;
        if (branch1 != '' && branch2 != '' && branch1 != branch2) {
            // Parallel AJAX calls
            var ajaxStamps1 = loadValidationStamps(config, branch1);
            var ajaxStamps2 = loadValidationStamps(config, branch2);
            var ajaxProperties1 = loadEditableProperties(config, branch1);
            var ajaxProperties2 = loadEditableProperties(config, branch2);
            // Loading...
            ajax.showLoading({
                mode: 'container',
                el: $('#project-validation-stamp-mgt-loading')
            }, true);
            // Completion
            $.when(ajaxStamps1, ajaxStamps2, ajaxProperties1, ajaxProperties2).then(
                function (resultStamps1, resultStamps2, resultProperties1, resultProperties2) {
                    displayBranches(config, resultStamps1[0], resultStamps2[0], resultProperties1[0], resultProperties2[0], target);
                },
                loadingError
            ).done(
                function () {
                    ajax.showLoading({
                        mode: 'container',
                        el: $('#project-validation-stamp-mgt-loading')
                    }, false);
                }
            )
        }
    }

    return {
        url: function (config) {
            return 'ui/manage/project/{0}/branch'.format(config.project)
        },
        render: render.asSimpleTemplate(
            'project-validation-stamp-mgt',
            render.sameDataFn,
            function (config, branches, target) {
                config.branch1 = '';
                config.branch2 = '';
                // On selection of a branch
                target.find('select.project-validation-stamp-mgt-branch').change(function (e) {
                    var branchTarget = $(this).attr('data-target');
                    var branch = $(this).val();
                    if (branchTarget == '1') {
                        config.branch1 = branch;
                    } else {
                        config.branch2 = branch;
                    }
                    loadBranches(config, target);
                })
            }
        )
    }

});<|endoftext|>


<commit_before>'use strict';
const Promise = require('bluebird'),
    _ = require('lodash'),
    parseString = require('xml2js'),
    config = require('config'),
    collectionName = config.get('dbConfig.mongo.collections')[0].collection,
    xml2js = Promise.promisifyAll(parseString);

module.exports = {
    init: init,
    find: find
};

function init(env) {
    return new Promise((resolve, reject) => {
        resolve(env);
    });
}

function find(env, query, mongo, options) {
    // If listing query is not specified, return everything in scope.
    if (!query) {
        return Promise.resolve(options.scope);
    }
    else if (query) {
        const xmlQuery = '<root>' + query + '</root>'
        return xml2js.parseStringAsync(xmlQuery, { explicitArray: false }).
            then((queryObject) => {
                const queryObj = getQuery(queryObject.root);
                return mongo.find(collectionName, queryObj, { fields: { id: 1 } });
            }).then((cursor) => {
                // TODO: limit the cursor returned results
                cursor.toArrayAsync = Promise.promisify(cursor.toArray, cursor);
                return cursor.toArrayAsync();
            }).then((docs) => {
                return _.pluck(docs, 'id');
            });
    }
}

function getQuery(queryObject) {
    const fullTextFields = ['listing-details', 'new', 'desc'],
        query = {};
    _.forEach(queryObject, (value, key) => {
        // Extract the extra "( )" from the value
        const newValue = _ExtractReturnParameters(value);
        if (fullTextFields.indexOf(key) > -1) {
            query['$text'] = { $search: newValue };
        }
        else if (newValue) {
            query[key] = value;
        }
    });
    return query;
}

// e.g. <element>(app*)</element> and <element>(*)</element>
function _ExtractReturnParameters(value) {
    let newValue = value;
    if (value && value.trim().indexOf('(') === 0) {
        if (value.trim()[value.length - 1] === ')') {
            newValue = value.trim().substring(1, value.length - 1);
        }
    }
    if (newValue === '*') {
        return null;
    }
    return newValue;
}
<commit_msg>query Solr for listing details<commit_after>'use strict';
const Promise = require('bluebird'),
    _ = require('lodash'),
    parseString = require('xml2js'),
    solr = require('../../db/solr'),
    xml2js = Promise.promisifyAll(parseString);

module.exports = {
    init: init,
    find: find
};

function init(env) {
    return new Promise((resolve, reject) => {
        resolve(env);
    });
}

function find(env, query, options) {
    // If listing query is not specified, return everything in scope.
    if (!query) {
        return Promise.resolve(options.scope);
    }
    else if (query) {
        const xmlQuery = '<root>' + query + '</root>';
        return xml2js.parseStringAsync(xmlQuery, { explicitArray: false }).
            then((queryObject) => {
                const queryObj = getQuery(queryObject.root);
                return solr.findListing(queryObj, 'id');
            }).then((docs) => {
                return _.pluck(docs, 'id');
            });
    }
}

// Strip extra return parameters from query object
function getQuery(queryObject) {
    const query = {};
    _.forEach(queryObject, (value, key) => {
        // Extract the extra "( )" from the value
        const newValue = _ExtractReturnParameters(value);
        if (newValue) {
            query[key] = value;
        }
    });
    return query;
}

// e.g. <element>(app*)</element> and <element>(*)</element>
function _ExtractReturnParameters(value) {
    let newValue = value;
    if (value && value.trim().indexOf('(') === 0) {
        if (value.trim()[value.length - 1] === ')') {
            newValue = value.trim().substring(1, value.length - 1);
        }
    }
    if (newValue === '*') {
        return null;
    }
    return newValue;
}
<|endoftext|>