<commit_before>/**
 * Stampit
 **
 * Create objects from reusable, composable behaviors.
 **
 * Copyright (c) 2013 Eric Elliott
 * http://opensource.org/licenses/MIT
 **/
'use strict';
var forEach = require('lodash/collection/forEach');
var map = require('lodash/collection/map');
var forOwn = require('lodash/object/forOwn');
var deepClone = require('lodash/lang/cloneDeep');
var isFunction = require('lodash/lang/isFunction');
var isArray = require('lodash/lang/isArray');
var isObject = require('lodash/lang/isObject');
var create = require('lodash/object/create');
var slice = require('lodash/array/slice');

var mixer = require('./mixer');

// Avoiding JSHist W003 violations.
var stampit;

function extractFunctions(arg) {
  if (isFunction(arg)) {
    return map(slice(arguments), function (fn) {
      if (isFunction(fn)) {
        return fn;
      }
    });
  } else if (isObject(arg)) {
    var arr = [];
    forEach(slice(arguments), function (obj) {
      forOwn(obj, function (fn) {
        arr.push(fn);
      });
    });
    return arr;
  } else if (isArray(arg)) {
    return slice(arg);
  }
  return [];
}

function addMethods(fixed, methods) {
  var args = [fixed.methods].concat(methods);
  mixer.mixinFunctions.apply(null, args);
  return fixed.methods;
}
function addRefs(fixed, states) {
  var args = [fixed.refs || fixed.state].concat(states);
  fixed.refs = fixed.state = mixer.mixin.apply(null, args);
  return fixed.refs;
}
function addInit(fixed, inits) {
  inits = isArray(inits) ? extractFunctions.apply(null, inits) : extractFunctions(inits);
  fixed.init = fixed.enclose = (fixed.init || fixed.enclose).concat(inits);
  return fixed.init;
}
function addProps(fixed, propses) {
  var args = [fixed.props].concat(propses);
  fixed.props = mixer.merge.apply(null, args);
  return fixed.props;
}

function cloneAndExtend(fixed, extensionFunction, args) {
  args = arguments.length > 3 ? slice(arguments, 2, arguments.length) : args;
  // We might end up having two different stampit modules loaded and used in conjunction.
  // These || operators ensure that old stamps could be combined with the current version stamps.
  var stamp = stampit(fixed);
  extensionFunction(stamp.fixed, args);
  return stamp;
}

function compose(factories) {
  factories = isArray(factories) ? factories : slice(arguments);
  var result = stampit();
  forEach(factories, function (source) {
    if (source && source.fixed) {
      addMethods(result.fixed, source.fixed.methods);
      addRefs(result.fixed, source.fixed.refs || source.fixed.state); // 'state' is the old name for 'refs'
      addInit(result.fixed, source.fixed.init || source.fixed.enclose); // 'enclose' is the old name for 'init'
      addProps(result.fixed, source.fixed.props);
    }
  });
  return result;
}

/**
 * Return a factory function that will produce new objects using the
 * prototypes that are passed in or composed.
 *
 * @param  {Object} [options] Options to build stamp from: `{ methods, refs, init, props }`
 * @return {Function} factory A factory to produce objects using the given prototypes.
 * @return {Function} factory.create Just like calling the factory function.
 * @return {Object} factory.fixed An object map containing the fixed prototypes.
 * @return {Function} factory.methods Add methods to the prototype. Chainable.
 * @return {Function} factory.refs Add references to the prototype. Chainable.
 * @return {Function} factory.state Alias to refs(). Deprecated.
 * @return {Function} factory.init Add a closure which called on object instantiation. Chainable.
 * @return {Function} factory.enclose Alias to init(). Deprecated.
 * @return {Function} factory.props Add deeply cloned properties to the produced objects. Chainable.
 */
stampit = function stampit(options) {
  var fixed = {methods: {}, refs: {}, init: [], props: {}};
  fixed.state = fixed.refs; // Backward compatibility. 'state' is the old name for 'refs'.
  fixed.enclose = fixed.init; // Backward compatibility. 'enclose' is the old name for 'init'.
  if (options) {
    addMethods(fixed, options.methods);
    addRefs(fixed, options.refs);
    addInit(fixed, options.init);
    addProps(fixed, options.props);
  }

  var factory = function Factory(properties, args) {
    properties = properties ? mixer.merge({}, fixed.props, properties) : deepClone(fixed.props);
    var instance = mixer.mixin(create(fixed.methods), fixed.refs, properties); // props are taking over refs

    if (fixed.init.length > 0) {
      args = slice(arguments, 1, arguments.length);
      forEach(fixed.init, function (fn) {
        if (isFunction(fn)) {
          instance = fn.call(instance, { args: args, instance: instance, stamp: factory }) || instance;
        }
      });
    }

    return instance;
  };

  var refsMethod = cloneAndExtend.bind(null, fixed, addRefs);
  var initMethod = cloneAndExtend.bind(null, fixed, addInit);
  return mixer.mixin(factory, {
    create: factory,
    fixed: fixed,

    /**
     * Take n objects and add them to the methods prototype.
     * @return {Object} stamp  The factory in question (`this`).
     */
    methods: cloneAndExtend.bind(null, fixed, addMethods),

    /**
     * Take n objects and add them to the newly stamped objects.
     * @return {Object} stamp  The factory in question (`this`).
     */
    refs: refsMethod,

    /**
     * Alias to refs(). Deprecated.
     * @return {Object} stamp  The factory in question (`this`).
     */
    state: refsMethod,

    /**
     * Take n functions, an array of functions, or n objects and add
     * the functions to the enclose prototype.
     * @return {Object} The factory in question (`this`).
     */
    init: initMethod,

    /**
     * Alias to init(). Deprecated.
     * @return {Object} The factory in question (`this`).
     */
    enclose: initMethod,

    /**
     * Take n objects and add deep clone them to the instantiated object.
     * @return {Object} stamp  The factory in question (`this`).
     */
    props: cloneAndExtend.bind(null, fixed, addProps),

    /**
     * Take one or more factories produced from stampit() and
     * combine them with `this` to produce and return a new factory.
     * Combining overrides properties with last-in priority.
     * @param {[Function]|...Function} factories Stampit factories.
     * @return {Function} A new stampit factory composed from arguments.
     */
    compose: function (factories) {
      var args = isArray(factories) ? factories : slice(arguments);
      args = [this].concat(args);
      return compose(args);
    }
  });
};

// Static methods

function isStamp(obj) {
  return (
  isFunction(obj) &&
  isFunction(obj.methods) &&
  // isStamp can be called for old stampit factory object. We should check old names (state and enclose) too.
  (isFunction(obj.refs) || isFunction(obj.state)) &&
  (isFunction(obj.init) || isFunction(obj.enclose)) &&
  isFunction(obj.props) &&
  isObject(obj.fixed)
  );
}

function convertConstructor(Constructor) {
  var stamp = stampit();
  mixer.mixinChainFunctions(stamp.fixed.methods, Constructor.prototype);
  stamp.fixed.refs = stamp.fixed.state = mixer.mergeChainNonFunctions(stamp.fixed.refs, Constructor.prototype);
  addInit(stamp.fixed, function (opts) {
    return Constructor.apply(opts.instance, opts.args);
  });
  return stamp;
}

function shortcutMethod(extensionFunction) {
  var stamp = stampit();
  extensionFunction(stamp.fixed, slice(arguments, 1));
  return stamp;
}

module.exports = mixer.mixin(stampit, {

  methods: shortcutMethod.bind(null, addMethods),

  refs: shortcutMethod.bind(null, addRefs),

  init: shortcutMethod.bind(null, addInit),

  props: shortcutMethod.bind(null, addProps),

  /**
   * Take two or more factories produced from stampit() and
   * combine them to produce a new factory.
   * Combining overrides properties with last-in priority.
   * @param {[Function]|...Function} factories Stamps produced by stampit().
   * @return {Function} A new stampit factory composed from arguments.
   */
  compose: compose,

  /**
   * Alias for mixin
   */
  extend: mixer.mixin,
  /**
   * Alias for mixin
   */
  mixIn: mixer.mixin,
  /**
   * Alias for mixin
   */
  assign: mixer.mixin,
  /**
   * Take a destination object followed by one or more source objects,
   * and copy the source object properties to the destination object,
   * with last in priority overrides.
   * @param {Object} destination An object to copy properties to.
   * @param {...Object} source An object to copy properties from.
   * @returns {Object}
   */
  mixin: mixer.mixin,

  /**
   * Check if an object is a stamp.
   * @param {Object} obj An object to check.
   * @returns {Boolean}
   */
  isStamp: isStamp,

  /**
   * Take an old-fashioned JS constructor and return a stampit stamp
   * that you can freely compose with other stamps.
   * @param  {Function} Constructor
   * @return {Function}             A composable stampit factory
   *                                (aka stamp).
   */
  convertConstructor: convertConstructor
});
<commit_msg>More IE8 support dropped. :)<commit_after>/**
 * Stampit
 **
 * Create objects from reusable, composable behaviors.
 **
 * Copyright (c) 2013 Eric Elliott
 * http://opensource.org/licenses/MIT
 **/
'use strict';
var forEach = require('lodash/collection/forEach');
var map = require('lodash/collection/map');
var forOwn = require('lodash/object/forOwn');
var deepClone = require('lodash/lang/cloneDeep');
var isFunction = require('lodash/lang/isFunction');
var isArray = Array.isArray;
var isObject = require('lodash/lang/isObject');
var create = Object.create;
var slice = require('lodash/array/slice');

var mixer = require('./mixer');

// Avoiding JSHist W003 violations.
var stampit;

function extractFunctions(arg) {
  if (isFunction(arg)) {
    return map(slice(arguments), function (fn) {
      if (isFunction(fn)) {
        return fn;
      }
    });
  } else if (isObject(arg)) {
    var arr = [];
    forEach(slice(arguments), function (obj) {
      forOwn(obj, function (fn) {
        arr.push(fn);
      });
    });
    return arr;
  } else if (isArray(arg)) {
    return slice(arg);
  }
  return [];
}

function addMethods(fixed, methods) {
  var args = [fixed.methods].concat(methods);
  mixer.mixinFunctions.apply(null, args);
  return fixed.methods;
}
function addRefs(fixed, states) {
  var args = [fixed.refs || fixed.state].concat(states);
  fixed.refs = fixed.state = mixer.mixin.apply(null, args);
  return fixed.refs;
}
function addInit(fixed, inits) {
  inits = isArray(inits) ? extractFunctions.apply(null, inits) : extractFunctions(inits);
  fixed.init = fixed.enclose = (fixed.init || fixed.enclose).concat(inits);
  return fixed.init;
}
function addProps(fixed, propses) {
  var args = [fixed.props].concat(propses);
  fixed.props = mixer.merge.apply(null, args);
  return fixed.props;
}

function cloneAndExtend(fixed, extensionFunction, args) {
  args = arguments.length > 3 ? slice(arguments, 2, arguments.length) : args;
  // We might end up having two different stampit modules loaded and used in conjunction.
  // These || operators ensure that old stamps could be combined with the current version stamps.
  var stamp = stampit(fixed);
  extensionFunction(stamp.fixed, args);
  return stamp;
}

function compose(factories) {
  factories = isArray(factories) ? factories : slice(arguments);
  var result = stampit();
  forEach(factories, function (source) {
    if (source && source.fixed) {
      addMethods(result.fixed, source.fixed.methods);
      addRefs(result.fixed, source.fixed.refs || source.fixed.state); // 'state' is the old name for 'refs'
      addInit(result.fixed, source.fixed.init || source.fixed.enclose); // 'enclose' is the old name for 'init'
      addProps(result.fixed, source.fixed.props);
    }
  });
  return result;
}

/**
 * Return a factory function that will produce new objects using the
 * prototypes that are passed in or composed.
 *
 * @param  {Object} [options] Options to build stamp from: `{ methods, refs, init, props }`
 * @return {Function} factory A factory to produce objects using the given prototypes.
 * @return {Function} factory.create Just like calling the factory function.
 * @return {Object} factory.fixed An object map containing the fixed prototypes.
 * @return {Function} factory.methods Add methods to the prototype. Chainable.
 * @return {Function} factory.refs Add references to the prototype. Chainable.
 * @return {Function} factory.state Alias to refs(). Deprecated.
 * @return {Function} factory.init Add a closure which called on object instantiation. Chainable.
 * @return {Function} factory.enclose Alias to init(). Deprecated.
 * @return {Function} factory.props Add deeply cloned properties to the produced objects. Chainable.
 */
stampit = function stampit(options) {
  var fixed = {methods: {}, refs: {}, init: [], props: {}};
  fixed.state = fixed.refs; // Backward compatibility. 'state' is the old name for 'refs'.
  fixed.enclose = fixed.init; // Backward compatibility. 'enclose' is the old name for 'init'.
  if (options) {
    addMethods(fixed, options.methods);
    addRefs(fixed, options.refs);
    addInit(fixed, options.init);
    addProps(fixed, options.props);
  }

  var factory = function Factory(properties, args) {
    properties = properties ? mixer.merge({}, fixed.props, properties) : deepClone(fixed.props);
    var instance = mixer.mixin(create(fixed.methods), fixed.refs, properties); // props are taking over refs

    if (fixed.init.length > 0) {
      args = slice(arguments, 1, arguments.length);
      forEach(fixed.init, function (fn) {
        if (isFunction(fn)) {
          instance = fn.call(instance, { args: args, instance: instance, stamp: factory }) || instance;
        }
      });
    }

    return instance;
  };

  var refsMethod = cloneAndExtend.bind(null, fixed, addRefs);
  var initMethod = cloneAndExtend.bind(null, fixed, addInit);
  return mixer.mixin(factory, {
    create: factory,
    fixed: fixed,

    /**
     * Take n objects and add them to the methods prototype.
     * @return {Object} stamp  The factory in question (`this`).
     */
    methods: cloneAndExtend.bind(null, fixed, addMethods),

    /**
     * Take n objects and add them to the newly stamped objects.
     * @return {Object} stamp  The factory in question (`this`).
     */
    refs: refsMethod,

    /**
     * Alias to refs(). Deprecated.
     * @return {Object} stamp  The factory in question (`this`).
     */
    state: refsMethod,

    /**
     * Take n functions, an array of functions, or n objects and add
     * the functions to the enclose prototype.
     * @return {Object} The factory in question (`this`).
     */
    init: initMethod,

    /**
     * Alias to init(). Deprecated.
     * @return {Object} The factory in question (`this`).
     */
    enclose: initMethod,

    /**
     * Take n objects and add deep clone them to the instantiated object.
     * @return {Object} stamp  The factory in question (`this`).
     */
    props: cloneAndExtend.bind(null, fixed, addProps),

    /**
     * Take one or more factories produced from stampit() and
     * combine them with `this` to produce and return a new factory.
     * Combining overrides properties with last-in priority.
     * @param {[Function]|...Function} factories Stampit factories.
     * @return {Function} A new stampit factory composed from arguments.
     */
    compose: function (factories) {
      var args = isArray(factories) ? factories : slice(arguments);
      args = [this].concat(args);
      return compose(args);
    }
  });
};

// Static methods

function isStamp(obj) {
  return (
  isFunction(obj) &&
  isFunction(obj.methods) &&
  // isStamp can be called for old stampit factory object. We should check old names (state and enclose) too.
  (isFunction(obj.refs) || isFunction(obj.state)) &&
  (isFunction(obj.init) || isFunction(obj.enclose)) &&
  isFunction(obj.props) &&
  isObject(obj.fixed)
  );
}

function convertConstructor(Constructor) {
  var stamp = stampit();
  mixer.mixinChainFunctions(stamp.fixed.methods, Constructor.prototype);
  stamp.fixed.refs = stamp.fixed.state = mixer.mergeChainNonFunctions(stamp.fixed.refs, Constructor.prototype);
  addInit(stamp.fixed, function (opts) {
    return Constructor.apply(opts.instance, opts.args);
  });
  return stamp;
}

function shortcutMethod(extensionFunction) {
  var stamp = stampit();
  extensionFunction(stamp.fixed, slice(arguments, 1));
  return stamp;
}

module.exports = mixer.mixin(stampit, {

  methods: shortcutMethod.bind(null, addMethods),

  refs: shortcutMethod.bind(null, addRefs),

  init: shortcutMethod.bind(null, addInit),

  props: shortcutMethod.bind(null, addProps),

  /**
   * Take two or more factories produced from stampit() and
   * combine them to produce a new factory.
   * Combining overrides properties with last-in priority.
   * @param {[Function]|...Function} factories Stamps produced by stampit().
   * @return {Function} A new stampit factory composed from arguments.
   */
  compose: compose,

  /**
   * Alias for mixin
   */
  extend: mixer.mixin,
  /**
   * Alias for mixin
   */
  mixIn: mixer.mixin,
  /**
   * Alias for mixin
   */
  assign: mixer.mixin,
  /**
   * Take a destination object followed by one or more source objects,
   * and copy the source object properties to the destination object,
   * with last in priority overrides.
   * @param {Object} destination An object to copy properties to.
   * @param {...Object} source An object to copy properties from.
   * @returns {Object}
   */
  mixin: mixer.mixin,

  /**
   * Check if an object is a stamp.
   * @param {Object} obj An object to check.
   * @returns {Boolean}
   */
  isStamp: isStamp,

  /**
   * Take an old-fashioned JS constructor and return a stampit stamp
   * that you can freely compose with other stamps.
   * @param  {Function} Constructor
   * @return {Function}             A composable stampit factory
   *                                (aka stamp).
   */
  convertConstructor: convertConstructor
});
<|endoftext|>


<commit_before>(function () {
    "use strict";
    let express = require('express'),
        bodyParser = require('body-parser'),
        cors = require('cors'),
        config = require('./config');

    module.exports = {
        start: function (done) {
            logger.success('Application started successfully');

            // set the database
            database.connect(function(db){
                /*The DB connection is open*/
                db.on('open', function () {
                    /*Perform operations that require DB connection*/
                });
            });

            //Setup application
            var app = express();

            // Add parser to get the data from a POST
            app.use(bodyParser.urlencoded({extended: true}));
            app.use(bodyParser.json());

            //router setup
            var router = express.Router();

            // for every request
            router.use(function (req, res, next) {
                logger.info('Request incoming: ' + req.url);

                //Allow all GET requests as these do not modify data and we want users to be able to see that basic stuff
                if (req.method === 'GET') {
                    return next();
                }
            });

            //cors support for all routes
            app.use(cors({
                "origin": "*",
                "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
            }));

            //routes inclusion
            require(__base + 'routes')(app, router);

            // Redirect default route / to the API documentation
            app.get('/', function (req, res) {
                return res.redirect('/doc');
            });

            // prefix for all routes
            app.use('/api', router);

            // Render the api documentation
            app.use('/doc', express.static('apidoc'));

            //listening for requests
            var port = config.server.port || 8080; //a default port if the config file does not contain it
            app.listen(port);
            logger.info('Listening on port ' + port);

        },
        stop: function (done) {
            logger.info('Application stopped');
        }
    };
}());
<commit_msg>Integrated hashPokemonGo so it gets started with "npm start" port is still 3322<commit_after>(function () {
    "use strict";
    let express = require('express'),
        bodyParser = require('body-parser'),
        cors = require('cors'),
        config = require('./config');

    module.exports = {
        start: function (done) {
            logger.success('Application started successfully');

            // set the database
            database.connect(function(db){
                /*The DB connection is open*/
                db.on('open', function () {
                    /*Perform operations that require DB connection*/
                    //start hashPokemonGo module
                    const listener = require(__base + 'app/controllers/filler/hashPokemonGo');
                    listener.insertToDb(function () {
                        return;
                    });
                });
            });

            //Setup application
            var app = express();

            // Add parser to get the data from a POST
            app.use(bodyParser.urlencoded({extended: true}));
            app.use(bodyParser.json());

            //router setup
            var router = express.Router();

            // for every request
            router.use(function (req, res, next) {
                logger.info('Request incoming: ' + req.url);

                //Allow all GET requests as these do not modify data and we want users to be able to see that basic stuff
                if (req.method === 'GET') {
                    return next();
                }
            });

            //cors support for all routes
            app.use(cors({
                "origin": "*",
                "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
            }));

            //routes inclusion
            require(__base + 'routes')(app, router);

            // Redirect default route / to the API documentation
            app.get('/', function (req, res) {
                return res.redirect('/doc');
            });

            // prefix for all routes
            app.use('/api', router);

            // Render the api documentation
            app.use('/doc', express.static('apidoc'));

            //listening for requests
            var port = config.server.port || 8080; //a default port if the config file does not contain it
            app.listen(port);
            logger.info('Listening on port ' + port);

        },
        stop: function (done) {
            logger.info('Application stopped');
        }
    };
}());
<|endoftext|>


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

var ScrapedProduct = require('../../../models/Scrapedprodcut');
var random = require('mongoose-random');

exports.CommonFixer = class CommonFixer {
    constructor() {
    }

    fixProductsInScrapedProductsDB(){
        return setInterval(function() {
                // ScrapedProduct.findOne({'product_url' : {$regex : ".*657622412782*"}}).skip(0).exec(function (err, productToScrape) {
                ScrapedProduct.findOne({ barcode_id: { $exists: true } , $where: "this.barcode_id.length < 13"}).exec(function (err, productToFix) {
                    try {
                        if (productToFix && productToFix.barcode_id) {
                            productToFix.barcode_id = fixBarcode(productToFix);
                            ScrapedProduct.update({_id: productToFix.id}, {
                                barcode_id: productToFix.barcode_id
                            }, function(err, affected, resp) {
                                console.log('SAVED ' + productToFix.barcode_id);
                            })
                        } else {
                            console.log('no products');
                        }
                    }catch (err){
                        console.log('Error ' + err);
                    }
                });
        }, 2000);
    }
};

fixBarcode = function(product){
    let newBarcode = '';
    if(product.barcode_id) {
        newBarcode = product.barcode_id;
        while (newBarcode.length < 13){
            newBarcode = '0'+newBarcode;
        }
    }
    return newBarcode;
};<commit_msg>Adding db fixer<commit_after>const request = require('request');

var ScrapedProduct = require('../../../models/Scrapedprodcut');
var random = require('mongoose-random');

exports.CommonFixer = class CommonFixer {
    constructor() {
    }

    fixProductsInScrapedProductsDB(){
        return setInterval(function() {
                // ScrapedProduct.findOne({'product_url' : {$regex : ".*657622412782*"}}).skip(0).exec(function (err, productToScrape) {
                ScrapedProduct.findOne({ barcode_id: { $exists: true } , $where: "this.barcode_id.length < 13"},function(err,productToFix) {
                    try {
                        if (productToFix && productToFix.barcode_id && productToFix.barcode_id.length < 13) {
                            productToFix.barcode_id = fixBarcode(productToFix);
                            ScrapedProduct.update({_id: productToFix.id}, {
                                barcode_id: productToFix.barcode_id
                            }, function(err, affected, resp) {
                                console.log('SAVED ' + productToFix.barcode_id);
                            })
                        } else {
                            console.log('no products');
                        }
                    }catch (err){
                        console.log('Error ' + err);
                    }
                });
        }, 2000);
    }
};

fixBarcode = function(product){
    let newBarcode = '';
    if(product.barcode_id) {
        newBarcode = product.barcode_id;
        while (newBarcode.length < 13){
            newBarcode = '0'+newBarcode;
        }
    }
    return newBarcode;
};<|endoftext|>


<commit_before>//used by jjmenu
function getId() {
	var tr_id =  $(this.triggerElement).attr("id");
	tr_id = tr_id.split("_");

	return tr_id[1];
}

function getType() {
	var tr_id =  $(this.triggerElement).attr("id");
	tr_id = tr_id.split("_");

	return tr_id[0];
}
//end functions used by jjmenu

function deleteItem(type, id) {
	var tr_id, tr, dt;

	tr_id = type+"_"+id;
	tr = $("#"+tr_id);

	dt = $("#library_display").dataTable();
	dt.fnDeleteRow( tr );
}

function deleteAudioClip(json) {
	if(json.message) {
		alert(json.message);
		return;
	}

	deleteItem("au", json.id);
	location.reload(true);
}

//callbacks called by jjmenu
function confirmDeleteAudioClip(params){
    if(confirm('The file will be deleted from disk, are you sure you want to delete?')){
        var url = '/Library/delete' + params;
        $.ajax({
          url: url,
          success: deleteAudioClip
        });
    }
}

//callbacks called by jjmenu
function confirmDeletePlaylist(params){
    if(confirm('Are you sure you want to delete?')){
        var url = '/Playlist/delete' + params;
        $.ajax({
          url: url,
          success: deletePlaylist
        });
    }
}

function checkImportStatus(){
    $.getJSON('/Preference/is-import-in-progress', function(data){
        var div = $('#import_status');
        if(data == true){
            div.css('visibility', 'visible');
        }else{
            div.css('visibility', 'hidden');
        }
    })
}

function deletePlaylist(json) {
	if(json.message) {
		alert(json.message);
		return;
	}

	deleteItem("pl", json.id);
	window.location.reload();
}
//end callbacks called by jjmenu

function addLibraryItemEvents() {

	$('#library_display tr[id ^= "au"]')
		.draggable({
			helper: 'clone',
			cursor: 'pointer'
		});

	$('#library_display tbody tr')
		.jjmenu("click",
			[{get:"/Library/context-menu/format/json/id/#id#/type/#type#"}],
			{id: getId, type: getType},
			{xposition: "mouse", yposition: "mouse"});

}

function dtRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
	var id, type, once;

    type = aData[6].substring(0,2);
    id = aData[0];

    if(type == "au") {
        $('td:eq(5)', nRow).html( '' );
    }
    else if(type == "pl") {
        $('td:eq(5)', nRow).html( '' );
    }

	$(nRow).attr("id", type+'_'+id);

	// insert id on lenth field
	$('td:eq(4)', nRow).attr("id", "length");

	$('td:gt(0)', nRow).qtip({
            content: {
	            text: "Loading...",
                title: {
                    text: aData[1] + " MetaData"
                },
                ajax: {
                    url: "/Library/get-file-meta-data",
                    type: "post",
                    data: ({format: "html", id : id, type: type}),
                    success: function(data, status){
                        this.set('content.text', data)
                    }
                }
            },
            position: {
                adjust: {
                    resize: true,
                    method: "flip flip"
                },
                at: "right center",
                my: "left top",
                viewport: $(window)
            },
            style: {
                width: 570,
                classes: "ui-tooltip-dark"
            },
            show: {
                delay: 700
            }
        }
    );

	return nRow;
}

function dtDrawCallback() {
	addLibraryItemEvents();
}

function addProgressIcon(id) {
    if($("#au_"+id).find("td:eq(0)").find("span").length > 0){
        $("#au_"+id).find("td:eq(0)").find("span").removeClass();
        $("span[id="+id+"]").addClass("small-icon progress");
    }else{
        $("#au_"+id).find("td:eq(0)").append('')
    }
}

function checkSCUploadStatus(){
    var url = '/Library/get-upload-to-soundcloud-status/format/json';
    $("span[class*=progress]").each(function(){
        var id = $(this).attr("id");
        $.post(url, {format: "json", id: id, type:"file"}, function(json){
            if(json.sc_id > 0){
                $("span[id="+id+"]").removeClass("progress").addClass("soundcloud");
            }else if(json.sc_id == "-3"){
                $("span[id="+id+"]").removeClass("progress").addClass("sc-error");
            }
        });
    })
}

function addQtipToSCIcons(){
    $(".progress, .soundcloud, .sc-error").live('mouseover', function(){
        var id = $(this).attr("id");
        if($(this).hasClass("progress")){
            $(this).qtip({
                content: {
                    text: "Uploading in progress..."
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }else if($(this).hasClass("soundcloud")){
            $(this).qtip({
                content: {
                    text: "Retreiving data from the server...",
                    ajax: {
                        url: "/Library/get-upload-to-soundcloud-status",
                        type: "post",
                        data: ({format: "json", id : id, type: "file"}),
                        success: function(json, status){
                            this.set('content.text', "The soundcloud id for this file is: "+json.sc_id)
                        }
                    }
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }else if($(this).hasClass("sc-error")){
            $(this).qtip({
                content: {
                    text: "Retreiving data from the server...",
                    ajax: {
                        url: "/Library/get-upload-to-soundcloud-status",
                        type: "post",
                        data: ({format: "json", id : id, type: "file"}),
                        success: function(json, status){
                            this.set('content.text', "There was error while uploading to soundcloud.
"+"Error code: "+json.error_code+
                                    "
"+"Error msg: "+json.error_msg+"
")
                        }
                    }
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }
    });
}

$(document).ready(function() {

	$('.tabs').tabs();

	$('#library_display').dataTable( {
		"bProcessing": true,
		"bServerSide": true,
		"sAjaxSource": "/Library/contents/format/json",
		"fnServerData": function ( sSource, aoData, fnCallback ) {
			$.ajax( {
				"dataType": 'json',
				"type": "POST",
				"url": sSource,
				"data": aoData,
				"success": fnCallback
			} );
		},
		"fnRowCallback": dtRowCallback,
		"fnDrawCallback": dtDrawCallback,
		"aoColumns": [
			/* Id */		{ "sName": "id", "bSearchable": false, "bVisible": false },
			/* Title */		{ "sName": "track_title" },
			/* Creator */	{ "sName": "artist_name" },
			/* Album */		{ "sName": "album_title" },
			/* Track */		{ "sName": "track_number" },
			/* Length */	{ "sName": "length" },
			/* Type */		{ "sName": "ftype", "bSearchable": false }
		],
		"aaSorting": [[2,'asc']],
		"sPaginationType": "full_numbers",
		"bJQueryUI": true,
		"bAutoWidth": false,
        "oLanguage": {
            "sSearch": ""
        }
	}).fnSetFilteringDelay(350);

	checkImportStatus()
	setInterval( "checkImportStatus()", 5000 );
	setInterval( "checkSCUploadStatus()", 5000 );

	addQtipToSCIcons()
});
<commit_msg>CC-2937: Remove the word "Metadata" from metadata popup window<commit_after>//used by jjmenu
function getId() {
	var tr_id =  $(this.triggerElement).attr("id");
	tr_id = tr_id.split("_");

	return tr_id[1];
}

function getType() {
	var tr_id =  $(this.triggerElement).attr("id");
	tr_id = tr_id.split("_");

	return tr_id[0];
}
//end functions used by jjmenu

function deleteItem(type, id) {
	var tr_id, tr, dt;

	tr_id = type+"_"+id;
	tr = $("#"+tr_id);

	dt = $("#library_display").dataTable();
	dt.fnDeleteRow( tr );
}

function deleteAudioClip(json) {
	if(json.message) {
		alert(json.message);
		return;
	}

	deleteItem("au", json.id);
	location.reload(true);
}

//callbacks called by jjmenu
function confirmDeleteAudioClip(params){
    if(confirm('The file will be deleted from disk, are you sure you want to delete?')){
        var url = '/Library/delete' + params;
        $.ajax({
          url: url,
          success: deleteAudioClip
        });
    }
}

//callbacks called by jjmenu
function confirmDeletePlaylist(params){
    if(confirm('Are you sure you want to delete?')){
        var url = '/Playlist/delete' + params;
        $.ajax({
          url: url,
          success: deletePlaylist
        });
    }
}

function checkImportStatus(){
    $.getJSON('/Preference/is-import-in-progress', function(data){
        var div = $('#import_status');
        if(data == true){
            div.css('visibility', 'visible');
        }else{
            div.css('visibility', 'hidden');
        }
    })
}

function deletePlaylist(json) {
	if(json.message) {
		alert(json.message);
		return;
	}

	deleteItem("pl", json.id);
	window.location.reload();
}
//end callbacks called by jjmenu

function addLibraryItemEvents() {

	$('#library_display tr[id ^= "au"]')
		.draggable({
			helper: 'clone',
			cursor: 'pointer'
		});

	$('#library_display tbody tr')
		.jjmenu("click",
			[{get:"/Library/context-menu/format/json/id/#id#/type/#type#"}],
			{id: getId, type: getType},
			{xposition: "mouse", yposition: "mouse"});

}

function dtRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
	var id, type, once;

    type = aData[6].substring(0,2);
    id = aData[0];

    if(type == "au") {
        $('td:eq(5)', nRow).html( '' );
    }
    else if(type == "pl") {
        $('td:eq(5)', nRow).html( '' );
    }

	$(nRow).attr("id", type+'_'+id);

	// insert id on lenth field
	$('td:eq(4)', nRow).attr("id", "length");

	$('td:gt(0)', nRow).qtip({
            content: {
	            text: "Loading...",
                title: {
                    text: aData[1]
                },
                ajax: {
                    url: "/Library/get-file-meta-data",
                    type: "post",
                    data: ({format: "html", id : id, type: type}),
                    success: function(data, status){
                        this.set('content.text', data)
                    }
                }
            },
            position: {
                adjust: {
                    resize: true,
                    method: "flip flip"
                },
                at: "right center",
                my: "left top",
                viewport: $(window)
            },
            style: {
                width: 570,
                classes: "ui-tooltip-dark"
            },
            show: {
                delay: 700
            }
        }
    );

	return nRow;
}

function dtDrawCallback() {
	addLibraryItemEvents();
}

function addProgressIcon(id) {
    if($("#au_"+id).find("td:eq(0)").find("span").length > 0){
        $("#au_"+id).find("td:eq(0)").find("span").removeClass();
        $("span[id="+id+"]").addClass("small-icon progress");
    }else{
        $("#au_"+id).find("td:eq(0)").append('')
    }
}

function checkSCUploadStatus(){
    var url = '/Library/get-upload-to-soundcloud-status/format/json';
    $("span[class*=progress]").each(function(){
        var id = $(this).attr("id");
        $.post(url, {format: "json", id: id, type:"file"}, function(json){
            if(json.sc_id > 0){
                $("span[id="+id+"]").removeClass("progress").addClass("soundcloud");
            }else if(json.sc_id == "-3"){
                $("span[id="+id+"]").removeClass("progress").addClass("sc-error");
            }
        });
    })
}

function addQtipToSCIcons(){
    $(".progress, .soundcloud, .sc-error").live('mouseover', function(){
        var id = $(this).attr("id");
        if($(this).hasClass("progress")){
            $(this).qtip({
                content: {
                    text: "Uploading in progress..."
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }else if($(this).hasClass("soundcloud")){
            $(this).qtip({
                content: {
                    text: "Retreiving data from the server...",
                    ajax: {
                        url: "/Library/get-upload-to-soundcloud-status",
                        type: "post",
                        data: ({format: "json", id : id, type: "file"}),
                        success: function(json, status){
                            this.set('content.text', "The soundcloud id for this file is: "+json.sc_id)
                        }
                    }
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }else if($(this).hasClass("sc-error")){
            $(this).qtip({
                content: {
                    text: "Retreiving data from the server...",
                    ajax: {
                        url: "/Library/get-upload-to-soundcloud-status",
                        type: "post",
                        data: ({format: "json", id : id, type: "file"}),
                        success: function(json, status){
                            this.set('content.text', "There was error while uploading to soundcloud.
"+"Error code: "+json.error_code+
                                    "
"+"Error msg: "+json.error_msg+"
")
                        }
                    }
                },
                position:{
                    adjust: {
                    resize: true,
                    method: "flip flip"
                    },
                    at: "right center",
                    my: "left top",
                    viewport: $(window)
                },
                show: {
                    ready: true // Needed to make it show on first mouseover event
                }
            })
        }
    });
}

$(document).ready(function() {

	$('.tabs').tabs();

	$('#library_display').dataTable( {
		"bProcessing": true,
		"bServerSide": true,
		"sAjaxSource": "/Library/contents/format/json",
		"fnServerData": function ( sSource, aoData, fnCallback ) {
			$.ajax( {
				"dataType": 'json',
				"type": "POST",
				"url": sSource,
				"data": aoData,
				"success": fnCallback
			} );
		},
		"fnRowCallback": dtRowCallback,
		"fnDrawCallback": dtDrawCallback,
		"aoColumns": [
			/* Id */		{ "sName": "id", "bSearchable": false, "bVisible": false },
			/* Title */		{ "sName": "track_title" },
			/* Creator */	{ "sName": "artist_name" },
			/* Album */		{ "sName": "album_title" },
			/* Track */		{ "sName": "track_number" },
			/* Length */	{ "sName": "length" },
			/* Type */		{ "sName": "ftype", "bSearchable": false }
		],
		"aaSorting": [[2,'asc']],
		"sPaginationType": "full_numbers",
		"bJQueryUI": true,
		"bAutoWidth": false,
        "oLanguage": {
            "sSearch": ""
        }
	}).fnSetFilteringDelay(350);

	checkImportStatus()
	setInterval( "checkImportStatus()", 5000 );
	setInterval( "checkSCUploadStatus()", 5000 );

	addQtipToSCIcons()
});
<|endoftext|>


<commit_before>// Based off https://code.google.com/p/gaequery/source/browse/trunk/src/static/scripts/jquery.autogrow-textarea.js?r=2
// Modified by David Beck

( function( factory ) {
    // UMD wrapper
    if ( typeof define === 'function' && define.amd ) {
        // AMD
        define( [ 'jquery' ], factory );
    } else if ( typeof exports !== 'undefined' ) {
        // Node/CommonJS
        module.exports = factory( require( 'jquery' ) );
    } else {
        // Browser globals
        factory( jQuery );
    }
}( function( $ ) {

    /*
     * Auto-growing textareas; technique ripped from Facebook
     */
    $.fn.autogrow = function(options) {

		options = $.extend( {
			vertical: true,
			horizontal: false
		}, options);

		this.filter('textarea').each(function() {

            var $this       = $(this),
                minHeight   = $this.height(),
				maxHeight	= $this.attr( "maxHeight" ),
                lineHeight  = $this.css('lineHeight'),
				minWidth	= typeof( $this.attr( "minWidth" ) ) == "undefined" ? 0 : $this.attr( "minWidth" );

			if( typeof( maxHeight ) == "undefined" ) maxHeight = 1000000;

            var shadow = $('

').css({
                position:   'absolute',
                top:        -10000,
                left:       -10000,
                fontSize:   $this.css('fontSize'),
                fontFamily: $this.css('fontFamily'),
				fontWeight: $this.css('fontWeight'),
                lineHeight: $this.css('lineHeight'),
                resize:     'none'
            }).appendTo(document.body);

            var update = function() {

                var times = function(string, number) {
                    for (var i = 0, r = ''; i < number; i ++) r += string;
                    return r;
                };

                var val = this.value;

				if( options.vertical )
					val = val.replace(/</g, '<')
						.replace(/>/g, '>')
						.replace(/&/g, '&')
						.replace(/\n$/, '
 ')
						.replace(/\n/g, '
')
						.replace(/ {2,}/g, function(space) { return times(' ', space.length -1) + ' '; });

				//if( options.horizontal )
				//	val = $.trim( val );

                shadow.html(val).css( "width", "auto" );

				if( options.horizontal )
				{
					var maxWidth = options.maxWidth;
					if( typeof( maxWidth ) == "undefined" ) maxWidth = $this.parent().width() - 12;
					$(this).css( "width", Math.min( Math.max( shadow.width() + 9, minWidth ), maxWidth ) );
				}

				if( options.vertical )
				{
					shadow.css( "width", $(this).width() - parseInt($this.css('paddingLeft'),10) - parseInt($this.css('paddingRight'),10) );
					var shadowHeight = shadow.height();
					var newHeight = Math.min( Math.max( shadowHeight, minHeight ), maxHeight );
					$(this).css( "height", newHeight );
					$(this).css( "overflow", newHeight == maxHeight ? "auto" : "hidden" );
				}
            };

            $(this)
				.change(update)
				.keyup(update)
				.keydown(update)
				.bind( "update.autogrow", update )
				.bind( "remove.autogrow", function() {
					shadow.remove();
				} );

            update.apply(this);

        });

        return this;
    };

} ) );
<commit_msg>small tweaks and fixes<commit_after>// Based off https://code.google.com/p/gaequery/source/browse/trunk/src/static/scripts/jquery.autogrow-textarea.js?r=2
// Modified by David Beck

( function( factory ) {
    // UMD wrapper
    if ( typeof define === 'function' && define.amd ) {
        // AMD
        define( [ 'jquery' ], factory );
    } else if ( typeof exports !== 'undefined' ) {
        // Node/CommonJS
        module.exports = factory( require( 'jquery' ) );
    } else {
        // Browser globals
        factory( jQuery );
    }
}( function( $ ) {

    /*
     * Auto-growing textareas; technique ripped from Facebook
     */
    $.fn.autogrow = function(options) {

		options = $.extend( {
			vertical: true,
			horizontal: false
		}, options);

		this.filter('textarea,input').each(function() {

            var $this       = $(this),
                minHeight   = $this.height(),
				maxHeight	= $this.attr( "maxHeight" ),
                lineHeight  = $this.css('lineHeight'),
				minWidth	= typeof( $this.attr( "minWidth" ) ) == "undefined" ? 0 : $this.attr( "minWidth" );

			if( typeof( maxHeight ) == "undefined" ) maxHeight = 1000000;

            var shadow = $('

').css( {
                position:   'absolute',
                top:        -10000,
                left:       -10000,
                fontSize:   $this.css('fontSize'),
                fontFamily: $this.css('fontFamily'),
				fontWeight: $this.css('fontWeight'),
                lineHeight: $this.css('lineHeight'),
                resize:     'none'
            } ).appendTo(document.body);

            shadow.html( 'a' );
            var characterWidth = shadow.width();
            shadow.html( '' );

            var update = function() {

                var times = function(string, number) {
                    for (var i = 0, r = ''; i < number; i ++) r += string;
                    return r;
                };

                var val = this.value;

				if( options.vertical )
					val = val.replace(/</g, '<')
						.replace(/>/g, '>')
						.replace(/&/g, '&')
						.replace(/\n$/, '
 ')
						.replace(/\n/g, '
')
						.replace(/ {2,}/g, function(space) { return times(' ', space.length -1) + ' '; });

				//if( options.horizontal )
				//	val = $.trim( val );

                shadow.html(val).css( "width", "auto" );

				if( options.horizontal )
				{
					var newWidth = Math.max( shadow.width() + characterWidth * 3, minWidth );
					var maxWidth = options.maxWidth;
					//if( typeof( maxWidth ) === "undefined" ) maxWidth = $this.parent().width() - 12; // not sure why we were doing this but seems like a bad idea. doesn't work with inline-block parents for one thing, since it is the text area that should be "pushing" them to be wider
					if( maxWidth ) newWidth = Math.min( newWidth, maxWidth );
					$(this).css( "width", newWidth );
				}

				if( options.vertical )
				{
					shadow.css( "width", $(this).width() - parseInt($this.css('paddingLeft'),10) - parseInt($this.css('paddingRight'),10) );
					var shadowHeight = shadow.height();
					var newHeight = Math.min( Math.max( shadowHeight, minHeight ), maxHeight );
					$(this).css( "height", newHeight );
					$(this).css( "overflow", newHeight == maxHeight ? "auto" : "hidden" );
				}
            };

            $(this)
				.change(update)
				.keyup(update)
				.keydown(update)
				.bind( "update.autogrow", update )
				.bind( "remove.autogrow", function() {
					shadow.remove();
				} );

            update.apply(this);

        });

        return this;
    };

} ) );
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const has = require('has');
const { Status } = require('flora-cluster');

const cast = require('./cast');
const Profiler = require('./profiler');

/**
 * Execute all DataSources.
 *
 * Executes all subFilters, the main request and the subRequests, and may be
 * recursively called by the subRequests.
 *
 * @param {Api}    api
 * @param {flora.Request} request
 * @param {Object} dst DataSourceTree
 * @return {Promise}
 * @private
 */
function executeDst(api, request, dst) {
    let globalResults;

    return (new Promise(resolve => resolve()))

    // Execute subFilters
    .then(() => {
        let subFilters = [];
        if (dst.subFilters) {
            subFilters = dst.subFilters.map((subFilter) => {
                subFilter._profiler = dst._profiler;
                return executeDst(api, request, subFilter);
            });
        }

        return Promise.all(subFilters);
    })

    // Adjust the main request's filter to include the results from the subFilters
    .then((allSubFilterResults) => {
        /*
            * allSubFilterResults:
            * Results from all subFilters.
            * - Outer array: foreach subFilter
            * - Inner array: list of results per subFilter request.
            *   As there are no subRequests in subFilters, the length is 1
            */

        if (!dst.request.filter) return true;

        // Build filter array for the main request
        const parentValues = {};
        /*
            * parentValues:
            * case 1: combined key:
            *   indexed by concatenated filter field:
            *   Example:
            *     {
            *       'instrumentId-exchangeId': [
            *         [133962, 12],
            *         [134000, 12]
            *       ]
            *     }
            * case 2: single key:
            *    Example:
            *     {
            *       'instrumentId': [133962, 134000]
            *     }
            */

        allSubFilterResults.forEach((subFilterResults) => {
            const subFilterResult = subFilterResults[0]; // only main result from each subFilter
            const parentKey = subFilterResult.parentKey.join('-');
            parentValues[parentKey] = parentValues[parentKey] || [];

            const pvs = [];
            for (let i = 0; i < subFilterResult.data.length; i++) {
                if (subFilterResult.parentKey.length === 1) {
                    if (has(subFilterResult.data[i], subFilterResult.childKey[0])) {
                        pvs.push(subFilterResult.data[i][subFilterResult.childKey[0]]);
                    }
                } else {
                    let partEmpty = false;
                    const part = subFilterResult.childKey.map((childKeyPart) => {
                        if (!has(subFilterResult.data[i], childKeyPart)) {
                            partEmpty = true;
                            return null;
                        }
                        return subFilterResult.data[i][childKeyPart];
                    });
                    if (!partEmpty) pvs.push(part);
                }
            }
            parentValues[parentKey].push(pvs);
        });

        // Prevent duplicates for all parentValues properties
        for (const parentKeyIdx in parentValues) {
            for (let i = 0; i < parentValues[parentKeyIdx].length; i++) {
                parentValues[parentKeyIdx][i] = _.uniqWith(parentValues[parentKeyIdx][i], _.isEqual);
            }
        }

        // Replace "valueFromSubFilter" properties for the main resource
        // by the values from the parentValues object
        const requestFilter = [];
        dst.request.filter.forEach((filter) => {
            const filterNew = [];
            filter.forEach((filterPart) => {
                if (dst._isEmpty) return;

                if (!filterPart.valueFromSubFilter) {
                    filterNew.push(filterPart);
                    return;
                }

                const attributeIdx = Array.isArray(filterPart.attribute)
                    ? filterPart.attribute.join('-')
                    : filterPart.attribute;

                if (!parentValues[attributeIdx]) {
                    throw new Error('Missing subFilter for attribute "' + filterPart.attribute + '"');
                }

                parentValues[attributeIdx].forEach((pv) => {
                    if (dst._isEmpty) return;

                    if (pv.length === 0) {
                        // One of the subFilters return an empty result,
                        // so the main results will also be empty, no need to execute
                        dst._isEmpty = true;
                        filterNew.push(filterPart);
                        return;
                    }

                    const filterPartNew = _.clone(filterPart);

                    if (!Array.isArray(filterPart.attribute)) {
                        filterPartNew.value = pv;
                    } else {
                        filterPartNew.value = [];
                        for (let j = 0; j < filterPart.attribute.length; j++) {
                            filterPartNew.value[j] = pv[j];
                        }
                    }

                    filterNew.push(filterPartNew);
                });
            });
            requestFilter.push(filterNew);
        });

        dst.request.filter = requestFilter;
    })

    // Cast filter values to their storedType
    .then(() => {
        if (dst._isEmpty) return;
        if (!dst.request.filter) return;
        if (!dst.attributeOptions) return;

        dst.request.filter.forEach((filter) => {
            if (!filter) return;

            filter.forEach((filterPart) => {
                let storedType;

                if (Array.isArray(filterPart.attribute)) {
                    for (let j = 0; j < filterPart.attribute.length; j++) {
                        storedType = (dst.attributeOptions[filterPart.attribute[j]]) ?
                            dst.attributeOptions[filterPart.attribute[j]].storedType : null;
                        if (!storedType) continue;
                        if (Array.isArray(filterPart.value[j])) {
                            filterPart.value[j] = filterPart.value[j].map(valuePart =>
                                cast(valuePart, storedType));
                        } else {
                            filterPart.value[j] = cast(filterPart.value[j], storedType);
                        }
                    }
                } else {
                    storedType = (dst.attributeOptions[filterPart.attribute]) ?
                        dst.attributeOptions[filterPart.attribute].storedType : null;
                    if (!storedType) return;
                    if (Array.isArray(filterPart.value)) {
                        filterPart.value = filterPart.value.map(valuePart =>
                            cast(valuePart, storedType));
                    } else {
                        filterPart.value = cast(filterPart.value, storedType);
                    }
                }
            });
        });
    })

    // extension: "preExecute" (resource)
    .then(() => {
        if (!dst.resourceName) return;
        const resource = api.getResource(dst.resourceName);
        if (resource && resource.extensions && resource.extensions.preExecute) {
            api.log.trace('handle: "preExecute" extension (%s)', dst.resourceName);
            resource.extensions.preExecute({
                name: dst.dataSourceName,
                request: dst.request,
                dataSourceTree: dst,
                floraRequest: request
            });
        }
    })

    // Execute the main request
    .then(() => {
        const result = {
            data: [],
            totalCount: 0
        };
        [
            'attributePath', 'dataSourceName', 'childKey', 'parentKey',
            'multiValuedParentKey', 'uniqueChildKey'
        ].forEach((key) => {
            if (has(dst, key)) result[key] = dst[key];
        });

        return new Promise((resolve, reject) => {
            if (dst._isEmpty) return resolve(result);

            const ds = api.dataSources[dst.request.type];
            if (!ds) return reject(new Error('Unknown DataSource type "' + dst.request.type + '"'));

            // TODO: Move requestName generation into request-resolver:
            let requestName = 'unnamedRequest';
            if (dst.attributePath) {
                requestName = (dst.attributePath.length > 0 ? dst.attributePath.join('.') : '{root}') +
                    ':' + dst.dataSourceName;
            }

            const status = request._status ? request._status.addChild('dataSourceRequests') : new Status();
            dst.request._status = status;
            status.set('requestName', requestName);
            status.set('type', dst.request.type);

            if (request._explain) dst.request._explain = {};

            const profiler = dst._profiler.child(requestName);
            dst.request._profiler = profiler;

            return ds.process(dst.request, (err, rows) => {
                profiler.end();
                status.close();
                if (dst.request._explain) {
                    if (!err && Array.isArray(rows.data)) {
                        dst.request._explain.countRows = rows.data.length;
                    }
                    if (err) dst.request._explain.error = '' + err;
                    if (!dst.request._explain.duration) {
                        dst.request._explain.duration = profiler.getDuration();
                    }
                }
                if (err) {
                    err.info = err.info || {};
                    err.info.dataSource = requestName;
                    return reject(err);
                }

                result.data = rows.data;
                result.totalCount = rows.totalCount;
                resolve(result);
            });
        });
    })

    // Transform the main results, do type casting
    .then((mainResults) => {
        /*
            * mainResults:
            * {
            *   "data": [
            *      {id: 1, firstname: "Alice"},
            *      {id: 3, firstname: "Bob"}, ...
            *   ]
            *   "totalCount": null // or the real count
            * }
            */
        if (!dst.attributeOptions) return mainResults;
        if (typeof dst.attributeOptions !== 'object') return mainResults;

        for (var idx in mainResults.data) {
            if (typeof mainResults.data[idx] !== 'object') continue;
            for (var key in mainResults.data[idx]) {
                if (!dst.attributeOptions[key] || !dst.attributeOptions[key].type) continue;
                mainResults.data[idx][key] =
                    cast(mainResults.data[idx][key], dst.attributeOptions[key]);
            }
        }

        return mainResults;
    })

    // extension: "postExecute" (resource)
    .then((mainResults) => {
        if (!dst.resourceName) return mainResults;
        const resource = api.getResource(dst.resourceName);
        if (resource && resource.extensions && resource.extensions.postExecute) {
            api.log.trace('handle: "postExecute" extension (%s)', dst.resourceName);
            resource.extensions.postExecute({
                name: dst.dataSourceName,
                request: dst.request,
                floraRequest: request,
                rawResults: mainResults
            });
        }

        return mainResults;
    })

    // Add the main results to our global results array
    .then((mainResults) => {
        /*
         * globalResults
         * This is whats is being returned by executeDst:
         * [
         *    {data: ...}, // results of the main request
         *    {data: ...}, // results of the first subRequest
         *    {data: ...}, // results of the second subRequest
         *    ...
         * ]
         */
        globalResults = [mainResults];
        return mainResults;
    })

    // Execute the subRequests
    .then((mainResults) => {
        if (!dst.subRequests) return [];
        if (!mainResults || mainResults.data.length === 0) return [];

        // Prepare the subRequests that may be dependent from the main results.
        // "valueFromParentKey" properties are replaced by the appropriate values.
        const subRequests = dst.subRequests.map((subRequest) => {
            let parentValues = [];

            const flatten = (subRequest.parentKey.length === 1 &&
                dst.attributeOptions &&
                dst.attributeOptions[subRequest.parentKey[0]] &&
                dst.attributeOptions[subRequest.parentKey[0]].multiValued);

            mainResults.data.forEach((mainResult) => {
                let isNull = true;
                let value;
                if (subRequest.parentKey.length === 1) {
                    value = mainResult[subRequest.parentKey[0]];
                    if (value !== null && typeof value !== 'undefined') isNull = false;
                } else {
                    value = subRequest.parentKey.map((m) => {
                        if (mainResult[m] !== null && typeof mainResult[m] !== 'undefined') isNull = false;
                        return mainResult[m];
                    });
                }
                if (isNull) return;

                if (flatten) {
                    if (Array.isArray(value)) Array.prototype.push.apply(parentValues, value);
                } else {
                    parentValues.push(value);
                }
            });

            if (parentValues.length === 0) subRequest._isEmpty = true;
            parentValues = (subRequest.parentKey.length === 1)
                ? _.uniq(parentValues)
                : _.uniqWith(parentValues, _.isEqual);

            subRequest.request.filter.forEach((filters) => {
                filters.forEach((filter) => {
                    if (!filter.valueFromParentKey) return;
                    filter.value = parentValues;
                });
            });

            subRequest._profiler = dst._profiler;
            return executeDst(api, request, subRequest);
        });

        return Promise.all(subRequests);
    })

    // Add the subRequest results to the global results array
    .then((subResults) => {
        delete dst._isEmpty; // clean up

        subResults.forEach((subResult) => {
            globalResults = globalResults.concat(subResult);
        });
        return globalResults;
    });
}

/**
 * Actually execute a resolved request and call the DataSources.
 *
 * @param {Api}     api
 * @param {flora.Request} request
 * @param {Object}  dst         - DataSourceTree
 * @param {Function}callback
 */
module.exports = function execute(api, request, dst, callback) {
    dst._profiler = dst._profiler || new Profiler();
    executeDst(api, request, dst)
    .then(results => callback(null, results), callback);
};
<commit_msg>ES6: datasource-executor<commit_after>'use strict';

const _ = require('lodash');
const has = require('has');
const { Status } = require('flora-cluster');

const cast = require('./cast');
const Profiler = require('./profiler');

/**
 * Execute all DataSources.
 *
 * Executes all subFilters, the main request and the subRequests, and may be
 * recursively called by the subRequests.
 *
 * @param {Api}    api
 * @param {flora.Request} request
 * @param {Object} dst DataSourceTree
 * @return {Promise}
 * @private
 */
function executeDst(api, request, dst) {
    let globalResults;

    return (new Promise(resolve => resolve()))

    // Execute subFilters
    .then(() => {
        let subFilters = [];
        if (dst.subFilters) {
            subFilters = dst.subFilters.map((subFilter) => {
                subFilter._profiler = dst._profiler;
                return executeDst(api, request, subFilter);
            });
        }

        return Promise.all(subFilters);
    })

    // Adjust the main request's filter to include the results from the subFilters
    .then((allSubFilterResults) => {
        /*
         * allSubFilterResults:
         * Results from all subFilters.
         * - Outer array: foreach subFilter
         * - Inner array: list of results per subFilter request.
         *   As there are no subRequests in subFilters, the length is 1
         */

        if (!dst.request.filter) return;

        // Build filter array for the main request
        const parentValues = {};
        /*
         * parentValues:
         * case 1: combined key:
         *   indexed by concatenated filter field:
         *   Example:
         *     {
         *       'instrumentId-exchangeId': [
         *         [133962, 12],
         *         [134000, 12]
         *       ]
         *     }
         * case 2: single key:
         *    Example:
         *     {
         *       'instrumentId': [133962, 134000]
         *     }
         */

        allSubFilterResults.forEach((subFilterResults) => {
            const subFilterResult = subFilterResults[0]; // only main result from each subFilter
            const parentKey = subFilterResult.parentKey.join('-');
            parentValues[parentKey] = parentValues[parentKey] || [];

            const pvs = [];
            for (let i = 0; i < subFilterResult.data.length; i++) {
                if (subFilterResult.parentKey.length === 1) {
                    if (has(subFilterResult.data[i], subFilterResult.childKey[0])) {
                        pvs.push(subFilterResult.data[i][subFilterResult.childKey[0]]);
                    }
                } else {
                    let partEmpty = false;
                    const part = subFilterResult.childKey.map((childKeyPart) => {
                        if (!has(subFilterResult.data[i], childKeyPart)) {
                            partEmpty = true;
                            return null;
                        }
                        return subFilterResult.data[i][childKeyPart];
                    });
                    if (!partEmpty) pvs.push(part);
                }
            }
            parentValues[parentKey].push(pvs);
        });

        // Prevent duplicates for all parentValues properties

        Object.keys(parentValues).forEach((parentKeyIdx) => {
            parentValues[parentKeyIdx] =
                parentValues[parentKeyIdx].map(parentValue => _.uniqWith(parentValue, _.isEqual));
        });

        // Replace "valueFromSubFilter" properties for the main resource
        // by the values from the parentValues object
        const requestFilter = [];
        dst.request.filter.forEach((filter) => {
            const filterNew = [];
            filter.forEach((filterPart) => {
                if (dst._isEmpty) return;

                if (!filterPart.valueFromSubFilter) {
                    filterNew.push(filterPart);
                    return;
                }

                const attributeIdx = Array.isArray(filterPart.attribute)
                    ? filterPart.attribute.join('-')
                    : filterPart.attribute;

                if (!parentValues[attributeIdx]) {
                    throw new Error('Missing subFilter for attribute "' + filterPart.attribute + '"');
                }

                parentValues[attributeIdx].forEach((pv) => {
                    if (dst._isEmpty) return;

                    if (pv.length === 0) {
                        // One of the subFilters return an empty result,
                        // so the main results will also be empty, no need to execute
                        dst._isEmpty = true;
                        filterNew.push(filterPart);
                        return;
                    }

                    const filterPartNew = _.clone(filterPart);

                    if (!Array.isArray(filterPart.attribute)) {
                        filterPartNew.value = pv;
                    } else {
                        filterPartNew.value = [];
                        for (let j = 0; j < filterPart.attribute.length; j++) {
                            filterPartNew.value[j] = pv[j];
                        }
                    }

                    filterNew.push(filterPartNew);
                });
            });
            requestFilter.push(filterNew);
        });

        dst.request.filter = requestFilter;
    })

    // Cast filter values to their storedType
    .then(() => {
        if (dst._isEmpty) return;
        if (!dst.request.filter) return;
        if (!dst.attributeOptions) return;

        dst.request.filter.forEach((filter) => {
            if (!filter) return;

            filter.forEach((filterPart) => {
                if (Array.isArray(filterPart.attribute)) {
                    filterPart.attribute.forEach((attrPart, index) => {
                        const storedType = (dst.attributeOptions[attrPart]) ?
                            dst.attributeOptions[attrPart].storedType : null;
                        if (!storedType) return;
                        if (Array.isArray(filterPart.value[index])) {
                            filterPart.value[index] = filterPart.value[index].map(valuePart =>
                                cast(valuePart, storedType));
                        } else {
                            filterPart.value[index] = cast(filterPart.value[index], storedType);
                        }
                    });
                } else {
                    const storedType = (dst.attributeOptions[filterPart.attribute]) ?
                        dst.attributeOptions[filterPart.attribute].storedType : null;
                    if (!storedType) return;
                    if (Array.isArray(filterPart.value)) {
                        filterPart.value = filterPart.value.map(valuePart =>
                            cast(valuePart, storedType));
                    } else {
                        filterPart.value = cast(filterPart.value, storedType);
                    }
                }
            });
        });
    })

    // extension: "preExecute" (resource)
    .then(() => {
        if (!dst.resourceName) return;
        const resource = api.getResource(dst.resourceName);
        if (resource && resource.extensions && resource.extensions.preExecute) {
            api.log.trace('handle: "preExecute" extension (%s)', dst.resourceName);
            resource.extensions.preExecute({
                name: dst.dataSourceName,
                request: dst.request,
                dataSourceTree: dst,
                floraRequest: request
            });
        }
    })

    // Execute the main request
    .then(() => {
        const result = {
            data: [],
            totalCount: 0
        };
        [
            'attributePath', 'dataSourceName', 'childKey', 'parentKey',
            'multiValuedParentKey', 'uniqueChildKey'
        ].forEach((key) => {
            if (has(dst, key)) result[key] = dst[key];
        });

        return new Promise((resolve, reject) => {
            if (dst._isEmpty) return resolve(result);

            const ds = api.dataSources[dst.request.type];
            if (!ds) return reject(new Error('Unknown DataSource type "' + dst.request.type + '"'));

            // TODO: Move requestName generation into request-resolver:
            let requestName = 'unnamedRequest';
            if (dst.attributePath) {
                requestName = (dst.attributePath.length > 0 ? dst.attributePath.join('.') : '{root}') +
                    ':' + dst.dataSourceName;
            }

            const status = request._status ? request._status.addChild('dataSourceRequests') : new Status();
            dst.request._status = status;
            status.set('requestName', requestName);
            status.set('type', dst.request.type);

            if (request._explain) dst.request._explain = {};

            const profiler = dst._profiler.child(requestName);
            dst.request._profiler = profiler;

            return ds.process(dst.request, (err, rows) => {
                profiler.end();
                status.close();
                if (dst.request._explain) {
                    if (!err && Array.isArray(rows.data)) {
                        dst.request._explain.countRows = rows.data.length;
                    }
                    if (err) dst.request._explain.error = '' + err;
                    if (!dst.request._explain.duration) {
                        dst.request._explain.duration = profiler.getDuration();
                    }
                }
                if (err) {
                    err.info = err.info || {};
                    err.info.dataSource = requestName;
                    return reject(err);
                }

                result.data = rows.data;
                result.totalCount = rows.totalCount;
                return resolve(result);
            });
        });
    })

    // Transform the main results, do type casting
    .then((mainResults) => {
        /*
            * mainResults:
            * {
            *   "data": [
            *      {id: 1, firstname: "Alice"},
            *      {id: 3, firstname: "Bob"}, ...
            *   ]
            *   "totalCount": null // or the real count
            * }
            */
        if (!dst.attributeOptions) return mainResults;
        if (typeof dst.attributeOptions !== 'object') return mainResults;

        mainResults.data.forEach((result) => {
            if (typeof result !== 'object') return;
            Object.keys(result).forEach((key) => {
                if (!dst.attributeOptions[key] || !dst.attributeOptions[key].type) return;
                result[key] =
                    cast(result[key], dst.attributeOptions[key]);
            });
        });

        return mainResults;
    })

    // extension: "postExecute" (resource)
    .then((mainResults) => {
        if (!dst.resourceName) return mainResults;
        const resource = api.getResource(dst.resourceName);
        if (resource && resource.extensions && resource.extensions.postExecute) {
            api.log.trace('handle: "postExecute" extension (%s)', dst.resourceName);
            resource.extensions.postExecute({
                name: dst.dataSourceName,
                request: dst.request,
                floraRequest: request,
                rawResults: mainResults
            });
        }

        return mainResults;
    })

    // Add the main results to our global results array
    .then((mainResults) => {
        /*
         * globalResults
         * This is whats is being returned by executeDst:
         * [
         *    {data: ...}, // results of the main request
         *    {data: ...}, // results of the first subRequest
         *    {data: ...}, // results of the second subRequest
         *    ...
         * ]
         */
        globalResults = [mainResults];
        return mainResults;
    })

    // Execute the subRequests
    .then((mainResults) => {
        if (!dst.subRequests) return [];
        if (!mainResults || mainResults.data.length === 0) return [];

        // Prepare the subRequests that may be dependent from the main results.
        // "valueFromParentKey" properties are replaced by the appropriate values.
        const subRequests = dst.subRequests.map((subRequest) => {
            let parentValues = [];

            const flatten = (subRequest.parentKey.length === 1 &&
                dst.attributeOptions &&
                dst.attributeOptions[subRequest.parentKey[0]] &&
                dst.attributeOptions[subRequest.parentKey[0]].multiValued);

            mainResults.data.forEach((mainResult) => {
                let isNull = true;
                let value;
                if (subRequest.parentKey.length === 1) {
                    value = mainResult[subRequest.parentKey[0]];
                    if (value !== null && typeof value !== 'undefined') isNull = false;
                } else {
                    value = subRequest.parentKey.map((m) => {
                        if (mainResult[m] !== null && typeof mainResult[m] !== 'undefined') isNull = false;
                        return mainResult[m];
                    });
                }
                if (isNull) return;

                if (flatten) {
                    if (Array.isArray(value)) Array.prototype.push.apply(parentValues, value);
                } else {
                    parentValues.push(value);
                }
            });

            if (parentValues.length === 0) subRequest._isEmpty = true;
            parentValues = (subRequest.parentKey.length === 1)
                ? _.uniq(parentValues)
                : _.uniqWith(parentValues, _.isEqual);

            subRequest.request.filter.forEach((filters) => {
                filters.forEach((filter) => {
                    if (!filter.valueFromParentKey) return;
                    filter.value = parentValues;
                });
            });

            subRequest._profiler = dst._profiler;
            return executeDst(api, request, subRequest);
        });

        return Promise.all(subRequests);
    })

    // Add the subRequest results to the global results array
    .then((subResults) => {
        delete dst._isEmpty; // clean up

        subResults.forEach((subResult) => {
            globalResults = globalResults.concat(subResult);
        });
        return globalResults;
    });
}

/**
 * Actually execute a resolved request and call the DataSources.
 *
 * @param {Api}     api
 * @param {flora.Request} request
 * @param {Object}  dst         - DataSourceTree
 * @param {Function}callback
 */
module.exports = function execute(api, request, dst, callback) {
    dst._profiler = dst._profiler || new Profiler();
    executeDst(api, request, dst)
    .then(results => callback(null, results), callback);
};
<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  BarChart.js
* Module : FrontEnd::Model::GraphsModel
* Location : /frontend/app/Model/GraphsModel
*
* History :
* Version       Date        Programmer                  Description
* ===============================================================================================================
* 0.3.0         2015-05-18  Francesco Rossetto          Modified general structure, some fixes
*
* 0.2.1         2015-05-15  Francesco Rossetto          Various fixes, insert inzializeData
*
* 0.2.0         2015-05-14  Maria Giovanna Chinellato   Add all methods and fix class
*
* 0.1.0         2015-05-14  Maria Giovanna Chinellato   Add all attributes, add methods split and updateParameter
*
* 0.0.1         2015-05-14  Maria Giovanna Chinellato   Initial code
* ===============================================================================================================
*
*/

angular.module('services')
.factory('BarChart', ['Graph', 'Axis', 'BarChartFlow', function(Graph, Axis, BarChartFlow){

    var axisX = null;
    var axisY = null;
    var barOrientation = 'vertical';
    var background = '#FFF';
    var sortable = true;
    var barsGrouping = 'grouped';

    BarChart.prototype = Object.create(Graph.prototype);
    BarChart.prototype.constructor = BarChart;
    BarChart.prototype.parent = Graph.prototype;

    function split(json) {
        var graphJson = {};
        if (json.title !== undefined) {
            graphJson.title = json.title;
        }
        if (json.height !== undefined) {
            graphJson.height = json.height;
        }
        if (json.width !== undefined) {
            graphJson.width = json.width;
        }
        if (json.enabledLegend !== undefined) {
            graphJson.enabledLegend = json.enabledLegend;
            if (graphJson.enabledLegend && json.legend !== undefined) {
                graphJson.legend = json.legend;
            }
        }
        if (json.horizontalGrid !== undefined) {
            graphJson.horizontalGrid = json.horizontalGrid;
        }
        if (json.verticalGrid !== undefined) {
            graphJson.verticalGrid = json.verticalGrid;
        }

        var barJson = {};
        if (json.axisX !== undefined) {
            barJson.axisX = json.axisX;
        }
        if (json.axisY !== undefined) {
            barJson.axisY = json.axisY;
        }
        if (json.barOrientation !== undefined) {
            barJson.barOrientation = json.barOrientation;
        }
        if (json.background !== undefined) {
            barJson.background = json.background;
        }
        if (json.sortable !== undefined) {
            barJson.sortable = json.sortable;
        }
        if (json.barsGrouping !== undefined) {
            barJson.barsGrouping = json.barsGrouping;
        }

        return {
            'graphJson' : graphJson,
            'barJson' : barJson
        };
    }

    //BarChart.prototype.test = function _Test(expressionStr) { return eval(expressionStr); };

    // create our new custom object that reuse the original object constructor
    function BarChart(info) {
        this.parent.constructor.call(this, info);
    }

    BarChart.prototype.updateParameters = function(info) {
        if (info !== undefined) {
            var json = split(info);
            var gJson = json.graphJson;
            var bJson = json.barJson;
            if (Object.keys(gJson).length !== 0) {
                this.parent.updateParameters.call(this, gJson);
            }
            if (Object.keys(bJson).length !== 0) {
                if (bJson.axisX !== undefined) {
                    axisX = new Axis(bJson.axisX);
                }
                if (bJson.axisY !== undefined) {
                    axisY = new Axis(bJson.axisY);
                }
                if (bJson.barOrientation !== undefined) {
                    barOrientation = bJson.barOrientation;
                }
                if (bJson.background !== undefined) {
                    background = bJson.background;
                }
                if (bJson.sortable !== undefined) {
                    sortable = bJson.sortable;
                }
                if (bJson.barsGrouping !== undefined) {
                    barsGrouping = bJson.barsGrouping;
                }
            }
            if (info.flows !== undefined) {
                for (var i=0; i<info.flows.length; i++) {
                    var newflow = new BarChartFlow(info.flows[i]);
                    this.addFlow(info.flows[i].ID, newflow);
                }
            }
        }
        return this;
    };

    BarChart.prototype.addFlow = function(newId, newFlow) {
        if (newFlow instanceof BarChartFlow) {
            console.log('bar chart add flow');
            this.parent.addFlow.call(this, newId, newFlow);
        }
        return this;
    };

    BarChart.prototype.initializeData = function(newData) {  //inizialization data of flows
        if (newData !== undefined) {
            var flowList = this.parent.getFlowList();
            console.log('flowlist length ' + flowList.length + 'newData length ' + newData.length);
            for (var i=0; i<newData.length; i++) {
                for (var j=0; j<flowList.length; j++) {
                    if (flowList[j].id === newData[i].ID) {
                        console.log('flowlist[j].id ' + flowList[j].id);
                        console.log('low list stampa ' + flowList[j]);
                        flowList[j].initializeData(newData[i]);
                    }
                }
            }
        }
        return this;
    };

    // update data
    BarChart.prototype.inPlaceUpdate = function(newData) {
        if (newData !== undefined) {
            var flowList = this.parent.getFlowList();
            for (var j=0; j<flowList.length; j++) {
                if (flowList[j].id === newData.ID) {
                    flowList[j].inPlaceUpdate(newData);
                }
            }
        }
        return this;
    };

    // get method
    BarChart.prototype.getX = function() {
        return axisX;
    };
    BarChart.prototype.getY = function() {
        return axisY;
    };
    BarChart.prototype.getBarOrientation = function() {
        return barOrientation;
    };
    BarChart.prototype.getBackground = function() {
        return background;
    };
    BarChart.prototype.getSortable = function() {
        return sortable;
    };
    BarChart.prototype.getBarsGrouping = function() {
        return barsGrouping;
    };

    return BarChart;

}]);<commit_msg>some fixes<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  BarChart.js
* Module : FrontEnd::Model::GraphsModel
* Location : /frontend/app/Model/GraphsModel
*
* History :
* Version       Date        Programmer                  Description
* ===============================================================================================================
* 0.3.0         2015-05-18  Francesco Rossetto          Modified general structure, some fixes
*
* 0.2.1         2015-05-15  Francesco Rossetto          Various fixes, insert inzializeData
*
* 0.2.0         2015-05-14  Maria Giovanna Chinellato   Add all methods and fix class
*
* 0.1.0         2015-05-14  Maria Giovanna Chinellato   Add all attributes, add methods split and updateParameter
*
* 0.0.1         2015-05-14  Maria Giovanna Chinellato   Initial code
* ===============================================================================================================
*
*/

angular.module('services')
.factory('BarChart', ['Graph', 'Axis', 'BarChartFlow', function(Graph, Axis, BarChartFlow){

    var axisX = null;
    var axisY = null;
    var barOrientation = 'vertical';
    var background = '#FFF';
    var sortable = true;
    var barsGrouping = 'grouped';

    BarChart.prototype = Object.create(Graph.prototype);
    BarChart.prototype.constructor = BarChart;
    BarChart.prototype.parent = Graph.prototype;

    function split(json) {
        var graphJson = {};
        if (json.title !== undefined) {
            graphJson.title = json.title;
        }
        if (json.height !== undefined) {
            graphJson.height = json.height;
        }
        if (json.width !== undefined) {
            graphJson.width = json.width;
        }
        if (json.enabledLegend !== undefined) {
            graphJson.enabledLegend = json.enabledLegend;
            if (graphJson.enabledLegend && json.legend !== undefined) {
                graphJson.legend = json.legend;
            }
        }
        if (json.horizontalGrid !== undefined) {
            graphJson.horizontalGrid = json.horizontalGrid;
        }
        if (json.verticalGrid !== undefined) {
            graphJson.verticalGrid = json.verticalGrid;
        }

        var barJson = {};
        if (json.axisX !== undefined) {
            barJson.axisX = json.axisX;
        }
        if (json.axisY !== undefined) {
            barJson.axisY = json.axisY;
        }
        if (json.barOrientation !== undefined) {
            barJson.barOrientation = json.barOrientation;
        }
        if (json.background !== undefined) {
            barJson.background = json.background;
        }
        if (json.sortable !== undefined) {
            barJson.sortable = json.sortable;
        }
        if (json.barsGrouping !== undefined) {
            barJson.barsGrouping = json.barsGrouping;
        }

        return {
            'graphJson' : graphJson,
            'barJson' : barJson
        };
    }

    //BarChart.prototype.test = function _Test(expressionStr) { return eval(expressionStr); };

    // create our new custom object that reuse the original object constructor
    function BarChart(info) {
        this.parent.constructor.call(this, info);
    }

    BarChart.prototype.updateParameters = function(info) {
        if (info !== undefined) {
            var json = split(info);
            var gJson = json.graphJson;
            var bJson = json.barJson;
            if (Object.keys(gJson).length !== 0) {
                this.parent.updateParameters.call(this, gJson);
            }
            if (Object.keys(bJson).length !== 0) {
                if (bJson.axisX !== undefined) {
                    axisX = new Axis(bJson.axisX);
                }
                if (bJson.axisY !== undefined) {
                    axisY = new Axis(bJson.axisY);
                }
                if (bJson.barOrientation !== undefined) {
                    barOrientation = bJson.barOrientation;
                }
                if (bJson.background !== undefined) {
                    background = bJson.background;
                }
                if (bJson.sortable !== undefined) {
                    sortable = bJson.sortable;
                }
                if (bJson.barsGrouping !== undefined) {
                    barsGrouping = bJson.barsGrouping;
                }
            }
            if (info.flows !== undefined) {
                for (var i=0; i<info.flows.length; i++) {
                    var newflow = new BarChartFlow(info.flows[i]);
                    this.addFlow(info.flows[i].ID, newflow);
                }
            }
        }
        return this;
    };

    BarChart.prototype.addFlow = function(newId, newFlow) {
        if (newFlow instanceof BarChartFlow) {
            console.log('bar chart add flow');
            this.parent.addFlow.call(this, newId, newFlow);
        }
        return this;
    };

    BarChart.prototype.initializeData = function(newData) {  //inizialization data of flows
        if (newData !== undefined) {
            var flowList = this.parent.getFlowList();
            console.log('flowlist length ' + flowList.length + 'newData length ' + newData.length);
            for (var i=0; i<newData.length; i++) {
                for (var j=0; j<flowList.length; j++) {
                    if (flowList[j].id === newData[i].ID) {
                        console.log('flowlist[j].id ' + flowList[j].id);
                        flowList[j].initializeData(newData[i]);
                        console.log('flow list stampa ' + flowList[j].toString());
                    }
                }
            }
        }
        return this;
    };

    // update data
    BarChart.prototype.inPlaceUpdate = function(newData) {
        if (newData !== undefined) {
            var flowList = this.parent.getFlowList();
            for (var j=0; j<flowList.length; j++) {
                if (flowList[j].id === newData.ID) {
                    flowList[j].inPlaceUpdate(newData);
                }
            }
        }
        return this;
    };

    // get method
    BarChart.prototype.getX = function() {
        return axisX;
    };
    BarChart.prototype.getY = function() {
        return axisY;
    };
    BarChart.prototype.getBarOrientation = function() {
        return barOrientation;
    };
    BarChart.prototype.getBackground = function() {
        return background;
    };
    BarChart.prototype.getSortable = function() {
        return sortable;
    };
    BarChart.prototype.getBarsGrouping = function() {
        return barsGrouping;
    };

    return BarChart;

}]);<|endoftext|>