<commit_before>var express = require('express');
var router = express.Router();
var _ = require('lodash');
var common = require('./common');

// runs on all routes and checks password if one is setup
router.all('/document/*', common.checkLogin, function (req, res, next){
    next();
});

// Inserts a new document
router.post('/document/:conn/:db/:coll/insert_doc', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;
    var ejson = require('mongodb-extended-json');

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);

    try{
        var eJsonData = ejson.parse(req.body.objectData);
    }catch(e){
        console.error('Syntax error: ' + e);
        res.status(400).json({'msg': req.i18n.__('Syntax error. Please check the syntax')});
        return;
    }

    // adding a new doc
    mongo_db.collection(req.params.coll).save(eJsonData, function (err, docs){
        if(err){
            console.error('Error inserting document', err);
            res.status(400).json({'msg': req.i18n.__('Error inserting document') + ': ' + err});
        }else{
            res.status(200).json({'msg': req.i18n.__('Document successfully added'), 'doc_id': docs.ops[0]._id});
        }
    });
});

// Edits/updates an existing document
router.post('/document/:conn/:db/:coll/edit_doc', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;
    var ejson = require('mongodb-extended-json');

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB's form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);

    try{
        var eJsonData = ejson.parse(req.body.objectData);
    }catch(e){
        console.error('Syntax error: ' + e);
        res.status(400).json({'msg': req.i18n.__('Syntax error. Please check the syntax')});
        return;
    }

    mongo_db.collection(req.params.coll).save(eJsonData, function (err, doc, lastErrorObject){
        if(err){
            console.error('Error updating document: ' + err);
            res.status(400).json({'msg': req.i18n.__('Error updating document') + ': ' + err});
        }else{
            if(doc['nModified'] === 0){
                console.error('Error updating document: Document ID is incorrect');
                res.status(400).json({'msg': req.i18n.__('Error updating document: Syntax error')});
            }else{
                res.status(200).json({'msg': req.i18n.__('Document successfully updated')});
            }
        }
    });
});

// Deletes a document
router.post('/document/:conn/:db/:coll/doc_delete', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB's form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);
    common.get_id_type(mongo_db, req.params.coll, req.body.doc_id, function (err, result){
        if(result.doc){
            mongo_db.collection(req.params.coll).remove({_id: result.doc_id_type}, true, function (err, docs){
                if(err || docs.result.n === 0){
                    console.error('Error deleting document: ' + err);
                    res.status(400).json({'msg': req.i18n.__('Error deleting document') + ': ' + req.i18n.__('Cannot find document by Id')});
                }else{
                    res.status(200).json({'msg': req.i18n.__('Document successfully deleted')});
                }
            });
        }else{
            console.error('Error deleting document: ' + err);
            res.status(400).json({'msg': req.i18n.__('Cannot find document by Id')});
        }
    });
});

module.exports = router;
<commit_msg>Fix issue #97<commit_after>var express = require('express');
var router = express.Router();
var _ = require('lodash');
var common = require('./common');

// runs on all routes and checks password if one is setup
router.all('/document/*', common.checkLogin, function (req, res, next){
    next();
});

// Inserts a new document
router.post('/document/:conn/:db/:coll/insert_doc', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;
    var ejson = require('mongodb-extended-json');

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);

    try{
        var eJsonData = ejson.parse(req.body.objectData);
    }catch(e){
        console.error('Syntax error: ' + e);
        res.status(400).json({'msg': req.i18n.__('Syntax error. Please check the syntax')});
        return;
    }

    // adding a new doc
    mongo_db.collection(req.params.coll).save(eJsonData, function (err, docs){
        if(err){
            console.error('Error inserting document', err);
            res.status(400).json({'msg': req.i18n.__('Error inserting document') + ': ' + err});
        }else{
            var dataReturn = '';
            if(docs.ops){
                dataReturn = docs.ops[0]._id;
            }
            res.status(200).json({'msg': req.i18n.__('Document successfully added'), 'doc_id': dataReturn});
        }
    });
});

// Edits/updates an existing document
router.post('/document/:conn/:db/:coll/edit_doc', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;
    var ejson = require('mongodb-extended-json');

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB's form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);

    try{
        var eJsonData = ejson.parse(req.body.objectData);
    }catch(e){
        console.error('Syntax error: ' + e);
        res.status(400).json({'msg': req.i18n.__('Syntax error. Please check the syntax')});
        return;
    }

    mongo_db.collection(req.params.coll).save(eJsonData, function (err, doc, lastErrorObject){
        if(err){
            console.error('Error updating document: ' + err);
            res.status(400).json({'msg': req.i18n.__('Error updating document') + ': ' + err});
        }else{
            if(doc['nModified'] === 0){
                console.error('Error updating document: Document ID is incorrect');
                res.status(400).json({'msg': req.i18n.__('Error updating document: Syntax error')});
            }else{
                res.status(200).json({'msg': req.i18n.__('Document successfully updated')});
            }
        }
    });
});

// Deletes a document
router.post('/document/:conn/:db/:coll/doc_delete', function (req, res, next){
    var connection_list = req.app.locals.dbConnections;

    // Check for existance of connection
    if(connection_list[req.params.conn] === undefined){
        res.status(400).json({'msg': req.i18n.__('Invalid connection name')});
    }

    // Validate database name
    if(req.params.db.indexOf(' ') > -1){
        res.status(400).json({'msg': req.i18n.__('Invalid database name')});
    }

    // Get DB's form pool
    var mongo_db = connection_list[req.params.conn].native.db(req.params.db);
    common.get_id_type(mongo_db, req.params.coll, req.body.doc_id, function (err, result){
        if(result.doc){
            mongo_db.collection(req.params.coll).remove({_id: result.doc_id_type}, true, function (err, docs){
                if(err || docs.result.n === 0){
                    console.error('Error deleting document: ' + err);
                    res.status(400).json({'msg': req.i18n.__('Error deleting document') + ': ' + req.i18n.__('Cannot find document by Id')});
                }else{
                    res.status(200).json({'msg': req.i18n.__('Document successfully deleted')});
                }
            });
        }else{
            console.error('Error deleting document: ' + err);
            res.status(400).json({'msg': req.i18n.__('Cannot find document by Id')});
        }
    });
});

module.exports = router;
<|endoftext|>


<commit_before>/*
 * Back-end logic
 */

var fs   = require('fs');
var util = require('util');
var cv   = require('cloudcv-backend');
var async= require('async');

function exampleImages()
{
    this.items = new Array();

    this.addImage("Lena",       "/images/lena-128.png",     "/images/lena.png");
    this.addImage("Mandrill",   "/images/mandrill-128.png", "/images/mandrill.png");
    this.addImage("Sudoku",     "/images/sudoku-128.png",   "/images/sudoku.png");
    this.addImage("Kid",        "/images/kid-128.jpg",      "/images/kid.jpg");
}

exampleImages.prototype.addImage = function(key, thumbnail, source)
{
    var item =
    {
        key: key,
        thumbnailURL: thumbnail,
        sourceURL:    source,
        thumbnail:    __dirname + "/../public" + thumbnail,
        source:       __dirname + "/../public" + source,
    };

    this.items.push(item);
    this[key] = item;
}

exampleImages.prototype.isInputImageValid = function(img)
{
    return typeof (this[img]) != undefined;
}

exampleImages.prototype.getImagePath = function(img)
{
    return this[img].source;
}

var imgs = new exampleImages();

function processRequest(req, res, view, work)
{

    var img  = req.body.image;

    var renderDefaultPage = function() {
        res.render(view,
            {
                "example":  { "availableImages": imgs.items }
            });
    }

    var renderResultView = function(result) {
        res.render(view,
        {
            "result":   result,
            "example":  { "availableImages": imgs.items }
        });
    }

    var imageToLoad;
    if (img && imgs.isInputImageValid(img)) {
        imageToLoad = imgs[img].source;
    }
    else if (req.files && req.files.image) {
        imageToLoad = req.files.image;
    }

    if (!imageToLoad) {
        return renderDefaultPage();
    }

    console.log(imageToLoad);
    async.waterfall([
        function(callback){
            fs.readFile(imageToLoad, callback);
        },
        function(imageData, callback) {
            cv.loadImage(imageToLoad, function(error, imview) { callback(error, imageData, imview); });
        },
        function(imageData, imview, callback) {
            imview.thumbnail(128, 128, function(error, thumbnail) { callback(error, imageData, imview, thumbnail); });
        },
        function(imageData, imview, thumbnail, callback) {
            thumbnail.asJpegDataUri(function(error, thumbUri) { callback(error, imageData, imview, thumbUri); });
        },
        function(imageData, imview, thumbnail, callback) {
            work(imageData, function(error, workResult) { callback(error, { sourceImage:thumbnail, result:workResult }); });
        }
        ], function (err, result) {
        if (err) {
            console.error(err);
            return renderDefaultPage();
        }
        else {
            console.log(result);
            return renderResultView(result);
        }
    });
}

exports.analysis = function(req, res)
{
    processRequest(req, res, 'demo-analysis', cv.analyzeImage);
};
<commit_msg>Fix image upload<commit_after>/*
 * Back-end logic
 */

var fs   = require('fs');
var util = require('util');
var cv   = require('cloudcv-backend');
var async= require('async');

function exampleImages()
{
    this.items = new Array();

    this.addImage("Lena",       "/images/lena-128.png",     "/images/lena.png");
    this.addImage("Mandrill",   "/images/mandrill-128.png", "/images/mandrill.png");
    this.addImage("Sudoku",     "/images/sudoku-128.png",   "/images/sudoku.png");
    this.addImage("Kid",        "/images/kid-128.jpg",      "/images/kid.jpg");
}

exampleImages.prototype.addImage = function(key, thumbnail, source)
{
    var item =
    {
        key: key,
        thumbnailURL: thumbnail,
        sourceURL:    source,
        thumbnail:    __dirname + "/../public" + thumbnail,
        source:       __dirname + "/../public" + source,
    };

    this.items.push(item);
    this[key] = item;
}

exampleImages.prototype.isInputImageValid = function(img)
{
    return typeof (this[img]) != undefined;
}

exampleImages.prototype.getImagePath = function(img)
{
    return this[img].source;
}

var imgs = new exampleImages();

function processRequest(req, res, view, work)
{

    var img  = req.body.image;

    var renderDefaultPage = function() {
        res.render(view,
            {
                "example":  { "availableImages": imgs.items }
            });
    }

    var renderResultView = function(result) {
        res.render(view,
        {
            "result":   result,
            "example":  { "availableImages": imgs.items }
        });
    }

    var imageToLoad;
    if (img && imgs.isInputImageValid(img)) {
        imageToLoad = imgs[img].source;
    }
    else if (req.files && req.files.image) {
        imageToLoad = req.files.image.path;
    }

    if (!imageToLoad) {
        return renderDefaultPage();
    }

    console.log(imageToLoad);
    async.waterfall([
        function(callback){
            fs.readFile(imageToLoad, callback);
        },
        function(imageData, callback) {
            cv.loadImage(imageToLoad, function(error, imview) { callback(error, imageData, imview); });
        },
        function(imageData, imview, callback) {
            imview.thumbnail(128, 128, function(error, thumbnail) { callback(error, imageData, imview, thumbnail); });
        },
        function(imageData, imview, thumbnail, callback) {
            thumbnail.asJpegDataUri(function(error, thumbUri) { callback(error, imageData, imview, thumbUri); });
        },
        function(imageData, imview, thumbnail, callback) {
            work(imageData, function(error, workResult) { callback(error, { sourceImage:thumbnail, result:workResult }); });
        }
        ], function (err, result) {
        if (err) {
            console.error(err);
            return renderDefaultPage();
        }
        else {
            console.log(result);
            return renderResultView(result);
        }
    });
}

exports.analysis = function(req, res)
{
    processRequest(req, res, 'demo-analysis', cv.analyzeImage);
};
<|endoftext|>


<commit_before>/*
 * Back-end logic
 */

var fs   = require('fs');
var util = require('util');
var cv   = require('cloudcv-backend');
var async= require('async');

function exampleImages()
{
    this.items = new Array();

    this.addImage("Lena",       "/images/lena-128.png",     "/images/lena.png");
    this.addImage("Mandrill",   "/images/mandrill-128.png", "/images/mandrill.png");
    this.addImage("Sudoku",     "/images/sudoku-128.png",   "/images/sudoku.png");
    this.addImage("Kid",        "/images/kid-128.jpg",      "/images/kid.jpg");
}

exampleImages.prototype.addImage = function(key, thumbnail, source)
{
    var item =
    {
        key: key,
        thumbnailURL: thumbnail,
        sourceURL:    source,
        thumbnail:    __dirname + "/../public" + thumbnail,
        source:       __dirname + "/../public" + source,
    };

    this.items.push(item);
    this[key] = item;
}

exampleImages.prototype.isInputImageValid = function(img)
{
    return typeof (this[img]) != undefined;
}

exampleImages.prototype.getImagePath = function(img)
{
    return this[img].source;
}

var imgs = new exampleImages();

function processRequest(req, res, view, work)
{

    var img  = req.body.image;

    var renderDefaultPage = function() {
        res.render(view,
            {
                "example":  { "availableImages": imgs.items }
            });
    }

    var renderResultView = function(result) {
        res.render(view,
        {
            "result":   result,
            "example":  { "availableImages": imgs.items }
        });
    }

    var imageToLoad;
    if (img && imgs.isInputImageValid(img)) {
        imageToLoad = imgs[img].source;
    }
    else if (req.files && req.files.image) {
        imageToLoad = req.files.image.path;
    }

    if (!imageToLoad) {
        return renderDefaultPage();
    }

    console.log(imageToLoad);
    async.waterfall([
        function(callback){
            fs.readFile(imageToLoad, callback);
        },
        function(imageData, callback) {
            cv.loadImage(imageToLoad, function(error, imview) { callback(error, imageData, imview); });
        },
        function(imageData, imview, callback) {
            imview.thumbnail(128, 128, function(error, thumbnail) { callback(error, imageData, imview, thumbnail); });
        },
        function(imageData, imview, thumbnail, callback) {
            thumbnail.asJpegDataUri(function(error, thumbUri) { callback(error, imageData, imview, thumbUri); });
        },
        function(imageData, imview, thumbnail, callback) {
            work(imageData, function(error, workResult) { callback(error, { sourceImage:thumbnail, result:workResult }); });
        }
        ], function (err, result) {
        if (err) {
            console.error(err);
            return renderDefaultPage();
        }
        else {
            console.log(result);
            return renderResultView(result);
        }
    });
}

exports.analysis = function(req, res)
{
    processRequest(req, res, 'demo-analysis', cv.analyzeImage);
};
<commit_msg>Tabs fixed.<commit_after>/*
 * Back-end logic
 */

var fs   = require('fs');
var util = require('util');
var cv   = require('cloudcv-backend');
var async= require('async');

function exampleImages()
{
    this.items = new Array();

    this.addImage("Lena",       "/images/lena-128.png",     "/images/lena.png");
    this.addImage("Mandrill",   "/images/mandrill-128.png", "/images/mandrill.png");
    this.addImage("Sudoku",     "/images/sudoku-128.png",   "/images/sudoku.png");
    this.addImage("Kid",        "/images/kid-128.jpg",      "/images/kid.jpg");
}

exampleImages.prototype.addImage = function(key, thumbnail, source)
{
    var item =
    {
        key: key,
        thumbnailURL: thumbnail,
        sourceURL:    source,
        thumbnail:    __dirname + "/../public" + thumbnail,
        source:       __dirname + "/../public" + source,
    };

    this.items.push(item);
    this[key] = item;
}

exampleImages.prototype.isInputImageValid = function(img)
{
    return typeof (this[img]) != undefined;
}

exampleImages.prototype.getImagePath = function(img)
{
    return this[img].source;
}

var imgs = new exampleImages();

function processRequest(req, res, view, work)
{

    var img  = req.body.image;

    var renderDefaultPage = function() {
        res.render(view,
            {
                "example":  { "availableImages": imgs.items }
            });
    }

    var renderResultView = function(result) {
        res.render(view,
        {
            "result":   result,
            "example":  { "availableImages": imgs.items }
        });
    }

    var imageToLoad;
    if (img && imgs.isInputImageValid(img)) {
        imageToLoad = imgs[img].source;
    }
    else if (req.files && req.files.image) {
        imageToLoad = req.files.image.path;
    }

    if (!imageToLoad) {
        return renderDefaultPage();
    }

    console.log(imageToLoad);
    async.waterfall([
        function(callback){
            fs.readFile(imageToLoad, callback);
        },
        function(imageData, callback) {
            cv.loadImage(imageToLoad, function(error, imview) { callback(error, imageData, imview); });
        },
        function(imageData, imview, callback) {
            imview.thumbnail(128, 128, function(error, thumbnail) { callback(error, imageData, imview, thumbnail); });
        },
        function(imageData, imview, thumbnail, callback) {
            thumbnail.asJpegDataUri(function(error, thumbUri) { callback(error, imageData, imview, thumbUri); });
        },
        function(imageData, imview, thumbnail, callback) {
            work(imageData, function(error, workResult) { callback(error, { sourceImage:thumbnail, result:workResult }); });
        }
        ], function (err, result) {
        if (err) {
            console.error(err);
            return renderDefaultPage();
        }
        else {
            console.log(result);
            return renderResultView(result);
        }
    });
}

exports.analysis = function(req, res)
{
    processRequest(req, res, 'demo-analysis', cv.analyzeImage);
};
<|endoftext|>


<commit_before>const _ = require('lodash');
const moment = require('moment');
const Promise = require('bluebird');
const debug = require('debug')('routes:personal');
const nconf = require('nconf');

const mongo = require('../lib/mongo');
const params = require('../lib/params');
const adopters = require('../lib/adopters');
const csv = require('../lib/CSV');

function summary(req) {
    const { amount, skip } = params.optionParsing(req.params.paging, 200);
    debug("summary request, amount %d skip %d", amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').summary, { user: supporter.pseudo },
                    { impressionTime: -1}, amount, skip);
        })
        .map(function(e) {
            return _.omit(e, ['_id' ]);
        })
        .then(function(data) {
            debug("retrived %d objects, with amount %d skip %d", _.size(data), amount, skip);
            return { json: data };
        })
        .catch(function(e) {
            debug("Summary (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function personalCSV(req) {
    const { amount, skip } = params.optionParsing(req.params.paging, 1000);
    debug("CSV request by [%s], amount %d skip %d", req.params.userToken, amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').summary, { user: supporter.pseudo },
                    { impressionTime: -1}, amount, skip);
        })
        .tap(function(check) {
            if(!_.size(check)) throw new Error("Invalid token");
        })
        .then(csv.produceCSVv1)
        .then(function(structured) {
            debug("personalCSV produced %d bytes", _.size(structured));
            const fname=`summary-${skip}-${amount}.csv`;
            return {
                headers: { "Content-Type": "csv/text",
                           "content-disposition": `attachment; filename=${fname}` },
                text: structured,
            };
        })
        .catch(function(e) {
            debug("csv (error): %s", e.message);
            return {
                headers: { "Content-Type": "csv/text",
                           "content-disposition": `attachment; filename=error.csv` },
                text: `error: ${e.message}`
            };
        });
}

function metadata(req) {
    const { amount, skip } = params.optionParsing(req.params.paging);
    debug("metadata request: %d skip %d", amount, skip);
    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').metadata, { userId: supporter.userId },
                    { impressionTime: -1}, amount, skip);
        })
        .then(function(data) {
            debug("retrived %d objects, with amount %d skip %d", _.size(data), amount, skip);
            return { json: data };
        })
        .catch(function(e) {
            debug("Metadata (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function enrich(req) {
    /* reminder: this API allow two different method of paging, for example
     * you can ask a specific day */

    var amount = 0, skip, pipeline, when = null;
    if(!req.params.paging || _.size(_.split(req.params.paging, '-')) == 2) {
        let paging = params.optionParsing(req.params.paging);
        amount = paging.amount;
        skip = paging.skip;
        debug("enrich with paging, looking for %d, skip %d", amount, skip);
    }
    else {
        when = moment(req.params.paging);
        amount = 100;
        debug("enrich by day: looking for %s forced limit at 100!", when);
    }

    if( (when != null && !when.isValid()) || (when == null && !amount) )
        throw new Error("Invalid parameter: $amount-$skip OR $(year-$month-day)")

    /* pipeline should be:
            match, limit, sort, lookup
       the match and limits are added below in the promise chain */
    let lookup = [
        { $lookup: {
            from: 'labels',
            localField: 'semanticId',
            foreignField: 'semanticId',
            as: 'labelcopy'
        }}
    ];

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {

            if(when) {
                const startOf = new Date(when.startOf('day').toISOString());
                const endOf = new Date(when.add(1, 'd').startOf('day').toISOString());
                pipeline = _.concat([
                    { $match: {
                        user: supporter.pseudo,
                        impressionTime: { $lt: endOf, $gt: startOf }
                    } },
                    { $sort: { impressionTime: -1 } },
                ], lookup);
            } else {
                pipeline = _.concat([
                    { $match: { user: supporter.pseudo } },
                    { $sort: { impressionTime: -1 } },
                    { $skip: skip },
                    { $limit: amount },
                ], lookup);
            }
            return mongo
                .aggregate(nconf.get('schema').summary, pipeline);
        })
        .map(function(e) {
            if(_.size(e.labelcopy)) {
                e.labels = _.get(e.labelcopy[0], 'l');
                e.lang = _.get(e.labelcopy[0], 'lang');
            }
            return _.omit(e, ['_id', 'id', 'labelcopy' ]);
        })
        .then(function(prod) {
            debug("Returning %d enriched entries, the most recent from %s",
                _.size(prod), prod[0].impressionTime);
            return { json: prod };
        })
        .catch(function(e) {
            debug("Enrich (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function byTimelineLookup(userId, amount, skipnum) {
    /* let me intrduce you to the bigger pipeline of this code iteration */

    const match = { $match: {userId: userId }};
    const sort = { $sort: { startTime: -1 }};
    const skip = { $skip: skipnum };
    const limit = { $limit: amount };
    const lookup = { $lookup: { from: 'impressions2', localField: 'id', foreignField: 'timelineId', as: 'impressions'}};
    const unwind = { $unwind: { path: "$impressions", preserveNullAndEmptyArrays: true } };
    const project = { $project: {
        _id: 0,
        "impressionOrder": "$impressions.impressionOrder",
        "impressionTime": "$impressions.impressionTime",
        "htmlId": "$impressions.htmlId",
        geoip: 1,
        startTime: 1,
        "timelineId": "$id"
    }};
    const summaryl = { $lookup: { from: 'summary', localField: 'htmlId', foreignField: 'id', as: 'summary'  }};

    return mongo
        .aggregate(nconf.get('schema').timelines, [ match, sort, skip, limit, lookup, unwind, project, summaryl ]);
};

function stats(req) {

    const DEFTIMLN = 20;
    const { amount, skip } = params.optionParsing(req.params.paging, DEFTIMLN);

    debug("Personal statistics requested, it process timelines: amount %d skip %d",
        amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return Promise.all([
                mongo.count(nconf.get('schema').timelines, { userId: supporter.userId }),
                byTimelineLookup(supporter.userId, amount, skip)
            ])
        })
        .then(function(result) {
            const timelines = _.countBy(result[1], 'timelineId')
            debug("Retrieved %d impressions in %d timelines, first %s, last %s",
                _.size(result[1]), _.size(timelines), _.first(result[1]).impressionTime, _.last(result[1]).impressionTime);

            /* order the timeline by startTime and impressionOrder */
            const orderedTimelines = _.map(_.map(_.groupBy(result[1], 'timelineId'), _.first), 'startTime');
            let sorted = [];
            _.each(_.orderBy(orderedTimelines, new Date), function(sT) {
                sorted = _.concat(sorted, _.orderBy(_.filter(result[1], { startTime: sT }), 'impressionOrder'));
            });

            return {
                json: {
                    storedTimelines: result[0],
                    served: { amount, skip },
                    content: sorted,
                    timelines,
                }
            };
        })
        .catch(function(e) {
            debug("Stats (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });

};

function daily(req) {

    const MINIMUM_AMOUNT = 3;
    const { amount, skip } = params.optionParsing(req.params.paging, 3);
    const dayamount = ( amount < MINIMUM_AMOUNT ) ? MINIMUM_AMOUNT : amount;

    debug("Personal daily statistics - skip %d amount %d [MIN %d]",
        skip, dayamount, MINIMUM_AMOUNT);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo.readLimit(nconf.get('schema').tmlnstats, {
                userId: supporter.userId,
                'nature.organic': { $exists: true },
                'nature.sponsored': { $exists: true }
            }, { dayTime: -1 }, dayamount, skip);
        })
        .map(function(e) {
            return _.omit(e, ['_id', 'userId']);
        })
        .then(function(stats) {
            debug("Retrieved daily stats: amount %d info: %j %j",
                _.size(stats), _.map(stats, 'duration'), _.map(stats, 'npost'));
            return { json: stats };
        })
        .catch(function(e) {
            debug("Daily (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

module.exports = {
    summary,
    metadata,
    personalCSV,
    enrich,
    daily,
    stats
};
<commit_msg>fixed personal.stats<commit_after>const _ = require('lodash');
const moment = require('moment');
const Promise = require('bluebird');
const debug = require('debug')('routes:personal');
const nconf = require('nconf');

const mongo = require('../lib/mongo');
const params = require('../lib/params');
const adopters = require('../lib/adopters');
const csv = require('../lib/CSV');

function summary(req) {
    const { amount, skip } = params.optionParsing(req.params.paging, 200);
    debug("summary request, amount %d skip %d", amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').summary, { user: supporter.pseudo },
                    { impressionTime: -1}, amount, skip);
        })
        .map(function(e) {
            return _.omit(e, ['_id' ]);
        })
        .then(function(data) {
            debug("retrived %d objects, with amount %d skip %d", _.size(data), amount, skip);
            return { json: data };
        })
        .catch(function(e) {
            debug("Summary (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function personalCSV(req) {
    const { amount, skip } = params.optionParsing(req.params.paging, 1000);
    debug("CSV request by [%s], amount %d skip %d", req.params.userToken, amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').summary, { user: supporter.pseudo },
                    { impressionTime: -1}, amount, skip);
        })
        .tap(function(check) {
            if(!_.size(check)) throw new Error("Invalid token");
        })
        .then(csv.produceCSVv1)
        .then(function(structured) {
            debug("personalCSV produced %d bytes", _.size(structured));
            const fname=`summary-${skip}-${amount}.csv`;
            return {
                headers: { "Content-Type": "csv/text",
                           "content-disposition": `attachment; filename=${fname}` },
                text: structured,
            };
        })
        .catch(function(e) {
            debug("csv (error): %s", e.message);
            return {
                headers: { "Content-Type": "csv/text",
                           "content-disposition": `attachment; filename=error.csv` },
                text: `error: ${e.message}`
            };
        });
}

function metadata(req) {
    const { amount, skip } = params.optionParsing(req.params.paging);
    debug("metadata request: %d skip %d", amount, skip);
    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo
                .readLimit(nconf.get('schema').metadata, { userId: supporter.userId },
                    { impressionTime: -1}, amount, skip);
        })
        .then(function(data) {
            debug("retrived %d objects, with amount %d skip %d", _.size(data), amount, skip);
            return { json: data };
        })
        .catch(function(e) {
            debug("Metadata (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function enrich(req) {
    /* reminder: this API allow two different method of paging, for example
     * you can ask a specific day */

    var amount = 0, skip, pipeline, when = null;
    if(!req.params.paging || _.size(_.split(req.params.paging, '-')) == 2) {
        let paging = params.optionParsing(req.params.paging);
        amount = paging.amount;
        skip = paging.skip;
        debug("enrich with paging, looking for %d, skip %d", amount, skip);
    }
    else {
        when = moment(req.params.paging);
        amount = 100;
        debug("enrich by day: looking for %s forced limit at 100!", when);
    }

    if( (when != null && !when.isValid()) || (when == null && !amount) )
        throw new Error("Invalid parameter: $amount-$skip OR $(year-$month-day)")

    /* pipeline should be:
            match, limit, sort, lookup
       the match and limits are added below in the promise chain */
    let lookup = [
        { $lookup: {
            from: 'labels',
            localField: 'semanticId',
            foreignField: 'semanticId',
            as: 'labelcopy'
        }}
    ];

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {

            if(when) {
                const startOf = new Date(when.startOf('day').toISOString());
                const endOf = new Date(when.add(1, 'd').startOf('day').toISOString());
                pipeline = _.concat([
                    { $match: {
                        user: supporter.pseudo,
                        impressionTime: { $lt: endOf, $gt: startOf }
                    } },
                    { $sort: { impressionTime: -1 } },
                ], lookup);
            } else {
                pipeline = _.concat([
                    { $match: { user: supporter.pseudo } },
                    { $sort: { impressionTime: -1 } },
                    { $skip: skip },
                    { $limit: amount },
                ], lookup);
            }
            return mongo
                .aggregate(nconf.get('schema').summary, pipeline);
        })
        .map(function(e) {
            if(_.size(e.labelcopy)) {
                e.labels = _.get(e.labelcopy[0], 'l');
                e.lang = _.get(e.labelcopy[0], 'lang');
            }
            return _.omit(e, ['_id', 'id', 'labelcopy' ]);
        })
        .then(function(prod) {
            debug("Returning %d enriched entries, the most recent from %s",
                _.size(prod), prod[0].impressionTime);
            return { json: prod };
        })
        .catch(function(e) {
            debug("Enrich (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

function byTimelineLookup(userId, amount, skipnum) {
    /* let me intrduce you to the bigger pipeline of this code iteration */

    const match = { $match: {userId: userId }};
    const sort = { $sort: { startTime: -1 }};
    const skip = { $skip: skipnum };
    const limit = { $limit: amount };
    const lookup = { $lookup: { from: 'impressions2', localField: 'id', foreignField: 'timelineId', as: 'impressions'}};
    const unwind = { $unwind: { path: "$impressions", preserveNullAndEmptyArrays: true } };
    const project = { $project: {
        _id: 0,
        "impressionOrder": "$impressions.impressionOrder",
        "impressionTime": "$impressions.impressionTime",
        "htmlId": "$impressions.htmlId",
        "visibility": "$impressions.visibility",
        geoip: 1,
        startTime: 1,
        "timelineId": "$id"
    }};

    return mongo
        .aggregate(nconf.get('schema').timelines, [ match, sort, skip, limit, lookup, unwind, project ]);
};

function stats(req) {

    const DEFTIMLN = 20;
    const { amount, skip } = params.optionParsing(req.params.paging, DEFTIMLN);

    debug("Personal statistics requested, it process timelines: amount %d skip %d",
        amount, skip);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return Promise.all([
                mongo.count(nconf.get('schema').timelines, { userId: supporter.userId }),
                byTimelineLookup(supporter.userId, amount, skip)
            ])
        })
        .then(function(result) {
            const timelines = _.countBy(result[1], 'timelineId')
            debug("Retrieved %d impressions in %d timelines, first %s, last %s",
                _.size(result[1]), _.size(timelines), _.first(result[1]).impressionTime, _.last(result[1]).impressionTime);

            /* order the timeline by startTime and impressionOrder */
            const orderedTimelines = _.map(_.map(_.groupBy(result[1], 'timelineId'), _.first), 'startTime');
            let sorted = [];
            _.each(_.orderBy(orderedTimelines, new Date), function(sT) {
                sorted = _.concat(sorted, _.orderBy(_.filter(result[1], { startTime: sT }), 'impressionOrder'));
            });

            return {
                json: {
                    storedTimelines: result[0],
                    served: { amount, skip },
                    content: sorted,
                    timelines,
                }
            };
        })
        .catch(function(e) {
            debug("Stats (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });

};

function daily(req) {

    const MINIMUM_AMOUNT = 3;
    const { amount, skip } = params.optionParsing(req.params.paging, 3);
    const dayamount = ( amount < MINIMUM_AMOUNT ) ? MINIMUM_AMOUNT : amount;

    debug("Personal daily statistics - skip %d amount %d [MIN %d]",
        skip, dayamount, MINIMUM_AMOUNT);

    return adopters
        .validateToken(req.params.userToken)
        .then(function(supporter) {
            return mongo.readLimit(nconf.get('schema').tmlnstats, {
                userId: supporter.userId,
                'nature.organic': { $exists: true },
                'nature.sponsored': { $exists: true }
            }, { dayTime: -1 }, dayamount, skip);
        })
        .map(function(e) {
            return _.omit(e, ['_id', 'userId']);
        })
        .then(function(stats) {
            debug("Retrieved daily stats: amount %d info: %j %j",
                _.size(stats), _.map(stats, 'duration'), _.map(stats, 'npost'));
            return { json: stats };
        })
        .catch(function(e) {
            debug("Daily (error): %s", e.message);
            return { json: { error: true, 'message': `error: ${e.message}` }};
        });
};

module.exports = {
    summary,
    metadata,
    personalCSV,
    enrich,
    daily,
    stats
};
<|endoftext|>


<commit_before>/**
*	//this object is dependent on the DynamicListHelper, included in the sidebar tile
*	// src='dwr/interface/DynamicListHelper.js'
*	// also dependent on browserSniff.js, SidebarHelper.js, and prototype.js 1.5.x
*/
	var ManageListHelper = {
		'getGenericLists' : function(listType)	{
			DynamicListHelper.getGenericLists(listType, ManageListHelper.getGenericLists_cb);
		},
		'getAllLists' : function()	{
			//assumes browserSniff.js has already been included and declared the browser specific vars
			DynamicListHelper.getAllLists(ManageListHelper.getGenericLists_cb);
		},
		'getGenericLists_cb' : function(txt)	{
			//accepts a JSON object	<- now accepts a json array
			// String listType : patient | gene | defaultPatient
			// Array<Object> listItems : { listName, listDate, itemCount, invalidItems }
			try	{
				var listContainerArray = eval('(' + txt + ')');
				for(var i=0; i<listContainerArray.length; i++)	{
					var listContainer = listContainerArray[i];
					var listType = listContainer.listType ? listContainer.listType : "none";
					if(listType == "none") {
						continue;
					}

					var lists = listContainer.listItems;

					//Note:  $('..'+"ListDiv") needs be be defined in the HTML src
					// ^ now, should be auto generated

					if(lists.length == 0)	{
						if($(listType+'ListDiv')){
							$(listType+'ListDiv').innerHTML = "No "+ listType + " lists currently saved

";
					    }
					    if($(listType+'UniteDiv')){
					    	$(listType+'UniteDiv').style.display = "none";
					    }
						continue;
					}

					if($(listType+'ListDiv'))
						$(listType+'ListDiv').innerHTML = "";  //clear it, and repopulate

					var tst = "";
					for(var t=0; t<lists.length; t++)	{

						var status = "";
						var shortName = lists[t].listName.length>25 ? lists[t].listName.substring(0,23) + "..." : lists[t].listName;
						var theName = lists[t].listName;
						var itemCount = lists[t].itemCount;

						var listSubTypes = (lists[t].listSubTypes && lists[t].listSubTypes.length > 0) ? lists[t].listSubTypes.join(",") : "";
						var lstyle = listSubTypes.indexOf(listContainer.highlightType)!= -1 ? "color:#000000;" : "";
						// += or =
						tst +=  "
"
		                    + "<input type='checkbox' style='border:0px;' id='' name='" + listType + "' value='" +theName+ "'/>"
		                    + ""
		                    + shortName + "

 Type: " + listSubTypes + " - "
		                    + "" + itemCount + " item(s)"
		                    + "
"
		                    + "details" + status + "
"
		                    + "
"
		                    + "delete
"
		                    + "

\n
\n";
					}
					if($(listType+'ListDiv'))
						$(listType+'ListDiv').innerHTML = tst;
				}
			}
			catch(err)	{
				//alert("ERR: " + err);
			}

		},
		'groupSelectedLists' : function(groupType, listGroup, groupName, action)	{
			//params:  String listType, DOM where the selected boxes are, new list name, action to perform
			var sLists = Array();
			try	{
				if(groupName == "")	{
					alert("Please Enter a name for the new group");
					throw("no name error");
				}
				var ls = $(listGroup) ? $(listGroup).getElementsByTagName('input') : Array();
				for(var i=0; i<ls.length; i++)	{
					if(ls[i].type=='checkbox' && (ls[i].selected || ls[i].checked))
						sLists.push(ls[i].value);
				}

				if(sLists.length < 1)	{
					alert("Please select some lists to " + action);
					throw("no lists selected");
				}
				if(sLists.length!=2 && action == "difference")	{
					alert("Please select only 2 groups");
					throw("incorrect amount of lists");
				}

				DynamicListHelper.uniteLists(sLists, groupName, groupType, action, ManageListHelper.groupSelectedLists_cb );
			}
			catch(err) {}
		},
		'groupSelectedLists_cb' : function(txt)	{
			//var res = txt.split(",");
			//accepts a comma sep string, should/could be json!
			//String results : pass | fail
			//String action
			//String groupType
			try	{
				var res = eval('(' + txt + ')');

				if(res.results.indexOf("pass")!=-1)	{
					$(res.groupType+'GroupName').value = "";

					var st = res.groupType+"GroupStatus";
					$(st).innerHTML = "Group Saved";
					setTimeout(function()	{ $(st).innerHTML = ""; }, 2000);
				}
				else {
					if(res.action == "join"){
						alert("List did not save, please try again.");
					}
					else{
						alert("The selected lists do not have any common entries.");
					}
				}

				ManageListHelper.getAllLists();
			   	SidebarHelper.loadSidebar();
			}
			catch(err)	{
				//alert(err);
			}
		},
		// ************* upload related **************** //
		//this function is called by upload.jsp sitting in an iframe
		//it is given an associative array (much like a paramMap) from
		// the validated list. The groupString variable(below) is inserted into the page
		// at the appropriate place.-KR...dont need the main argument anymore

		'handleResponse' : function(msg) {
			//optional arguments: 1-upload form id, 2-upload status id
			try	{
				ManageListHelper.getAllLists();
			   	SidebarHelper.loadSidebar();
			}
			catch(err)	{}

		   var uform = arguments.length > 1 && arguments[1]!= "" ? arguments[0] : "uploadForm";
		   var ustat = arguments.length > 2 ? arguments[2] : "uploadStatus";
			//reset the form
			Form.reset($(uform));
			//hide the indicator
			setTimeout(function(){$(ustat).style.display = "none";}, 500);

		},

		// this functions as a toggle for the details link next to a
		// list. If details are currently viewable, it removes the element
		// from the DOM. If the "list name + detailsDiv" element doesn't
		// exist, the AJAX call is made to retrieve the most current details
		// from the userListBean sitting in the session. -KR
		// requires name+"detailsDiv" and name+"status" elements(ids) to be in the HTML
		'getDetails' : function(name){

			if(document.getElementById(name+ "detailsDiv")==null){
				if($(name+"status"))
					$(name+"status").style.display = "";
		    	UserListHelper.getDetailsFromList(name,ManageListHelper.putDetailsIHTML);
		   	}
		   	else	{
		    	Element.remove(name+"detailsDiv");
		    }
		},
		 //function to make an AJAX call to the userListBean in the session
		 // and delete the list under the name it passes as a param. Then finds
		 // the div with an id matching this name and removes it from the DOM. -KR
		'deleteList' : function(name){
			if(confirm("Delete this List?"))
				UserListHelper.removeListFromAjax(name, ManageListHelper.generic_cb);
		},
		'generic_cb' : function(name)	{
			try	{
				SidebarHelper.loadSidebar();
			}
			catch(err)	{}
			ManageListHelper.getAllLists()
		},
		//function to make an AJAX call to the userListBean in the session
		// and delete the list item under the list name it passes as params. Then finds
		// the div with an id matching this item name and removes it from the DOM. -KR
		'deleteItem' : function (name, itemId){
			UserListHelper.removeItemFromList(name,itemId);
			Element.remove(name + itemId + "_div");
			try	{
				SidebarHelper.loadSidebar();
				//update the count
				if($(name+"_count"))	{
					var tmp = $(name+"_count").innerHTML;
					$(name+"_count").innerHTML = parseInt(tmp) - 1;
				}
			}
			catch(err){}
		},
		//this is the callback function from the getDetails AJAX function (above). This
		//function recieves a Document object back from the getDetails call and parses
		// the Document object. As it parses the Document (which is a UserList), it
		// dynamically creates DOM elements for each item in a particular list and adds
		// them to the page. The dynamically created nodes are created/deleted depending
		// on when the user toggles the "details" link next to a link. -KR

		// modded to use IHTML and JSON- rcl
		'putDetailsIHTML' : function(userList){
			//JSON: String listName
			// String listType
			// Array validItems
			// Array invalidItems
		 	try	{
				var list = eval('(' + userList + ')');
				listName = list.listName;
				listType = list.listType;
				listType = ""; //clear this for now

				var items = list.validItems ? list.validItems : Array();
				var invalidItems = list.invalidItems ? list.invalidItems : Array();

				var itemId;
		 		var value;
		 		var dDIV = document.createElement("div");
		 		dDIV.setAttribute("id",listName + "detailsDiv");
		 		dDIV.setAttribute("class", "listItemsDiv");

		 		//rcl - create and append our container
		 		 document.getElementById(listName + "details").appendChild(dDIV);
		 		//setup a handle to the working container
		 		var wDiv = $(listName + "detailsDiv");
		 		wDiv.style.borderLeft = "1px dashed red";
		 		wDiv.style.marginLeft = "20px";
				wDiv.style.width="300px";
		 		if(items.length > 0)	{
		 			var tmp = "";
					for(var i=0; i<items.length; i++)	{
						itemId = items[i];
						tmp += "
"+(i+1) +") " +listType + " " + itemId;
						var oc = new Function("deleteItem('"+listName+ "','" + itemId + "');return false;");
						tmp += "[delete]
";
					}
					wDiv.innerHTML += tmp;

					var eid = encodeURIComponent(listName);
					wDiv.innerHTML += "
export list
";
				}
				else{
			    	document.getElementById(listName + "details").appendChild(dDIV);
			    	wDiv.innerHTML = "No valid items found
";
				}

			    if(!invalidItems.length < 1)	{
					var intmp = "

Invalid or does not exist in the database:
 ";
					//wDiv.innerHTML += "
Invalid or does not exist in the database:
 ";
					for(var i=0; i<invalidItems.length; i++){
						invalidItemId = invalidItems[i];
						if((i+1) == invalidItems.length){
							//wDiv.innerHTML += invalidItemId;
							intmp += invalidItemId;
						}
						else{
							intmp += invalidItemId + ", ";
							//wDiv.innerHTML += invalidItemId + ", ";
						}
					}
					wDiv.innerHTML +=intmp;
					wDiv.innerHTML += "
";

				}
			}
			catch(err)	{
				if($('details'))	{
					$("details").innerHTML = err;
					$("details").style.display = "";
				}
			}

			if($(listName+"status"))	{
				setTimeout(function()	{$(listName+"status").style.display = "none";}, 500);
			}
		},
		//all form validation is done client side. The name and file fields are checked for null
		// and list name collisions are checked. If there is a collision the user can either
		//overwrite the stored list with the current list or cancel the action and rename it. -KR

		//never gets called if you click <enter> on the keyboard, hence the onSubmit = return false; - RL
		//moved here from inline - RL
     	'validateForm' : function()	{
			//optional args: listName, upload, uploadStatus
			//loosely checking for presence
			var listName = arguments.length>0 ? arguments[0] : 'listName';
			var upload = arguments.length>1 ? arguments[1] : 'upload';
			var uploadStatus = arguments.length> 2 ? arguments[2] : 'uploadStatus';
			var uploadForm = arguments.length>3 ? arguments[3] : 'uploadForm';

			$(uploadStatus).style.display = "";
	     	var thisListName = $(listName).value;

			var errors = "";
	     	if(thisListName == ""){
	     		errors += "please enter a name for this list. \n";
	     	}
	     	if($(upload).value==""){
	     		errors += "please enter a file for this list.";
			}
	     	if(errors != ""){
	     	    alert(errors);
	     	    $(uploadStatus).style.display = "none";
	     	    return false;
	     	}
	     	else {
		    	$(uploadForm).submit();
			}
	     }
	};
	<commit_msg>changed icons<commit_after>/**
*	//this object is dependent on the DynamicListHelper, included in the sidebar tile
*	// src='dwr/interface/DynamicListHelper.js'
*	// also dependent on browserSniff.js, SidebarHelper.js, and prototype.js 1.5.x
*/
	var ManageListHelper = {
		'getGenericLists' : function(listType)	{
			DynamicListHelper.getGenericLists(listType, ManageListHelper.getGenericLists_cb);
		},
		'getAllLists' : function()	{
			//assumes browserSniff.js has already been included and declared the browser specific vars
			DynamicListHelper.getAllLists(ManageListHelper.getGenericLists_cb);
		},
		'getGenericLists_cb' : function(txt)	{
			//accepts a JSON object	<- now accepts a json array
			// String listType : patient | gene | defaultPatient
			// Array<Object> listItems : { listName, listDate, itemCount, invalidItems }
			try	{
				var listContainerArray = eval('(' + txt + ')');
				for(var i=0; i<listContainerArray.length; i++)	{
					var listContainer = listContainerArray[i];
					var listType = listContainer.listType ? listContainer.listType : "none";
					if(listType == "none") {
						continue;
					}

					var lists = listContainer.listItems;

					//Note:  $('..'+"ListDiv") needs be be defined in the HTML src
					// ^ now, should be auto generated

					if(lists.length == 0)	{
						if($(listType+'ListDiv')){
							$(listType+'ListDiv').innerHTML = "No "+ listType + " lists currently saved

";
					    }
					    if($(listType+'UniteDiv')){
					    	$(listType+'UniteDiv').style.display = "none";
					    }
						continue;
					}

					if($(listType+'ListDiv'))
						$(listType+'ListDiv').innerHTML = "";  //clear it, and repopulate

					var tst = "";
					for(var t=0; t<lists.length; t++)	{

						var status = "";
						var shortName = lists[t].listName.length>25 ? lists[t].listName.substring(0,23) + "..." : lists[t].listName;
						var theName = lists[t].listName;
						var itemCount = lists[t].itemCount;

						var listSubTypes = (lists[t].listSubTypes && lists[t].listSubTypes.length > 0) ? lists[t].listSubTypes.join(",") : "";
						var lstyle = listSubTypes.indexOf(listContainer.highlightType)!= -1 ? "color:#000000;" : "";
						// += or =
						tst +=  "
"
		                    + "<input type='checkbox' style='border:0px;' id='' name='" + listType + "' value='" +theName+ "'/>"
		                    + ""
		                    + shortName + "

 Type: " + listSubTypes + " - "
		                    + "" + itemCount + " item(s)"
		                    + "
"
		                    + "details" + status + "
"
		                    + "
"
		                    + "delete
"
		                    + "

\n
\n";
					}
					if($(listType+'ListDiv'))
						$(listType+'ListDiv').innerHTML = tst;
				}
			}
			catch(err)	{
				//alert("ERR: " + err);
			}

		},
		'groupSelectedLists' : function(groupType, listGroup, groupName, action)	{
			//params:  String listType, DOM where the selected boxes are, new list name, action to perform
			var sLists = Array();
			try	{
				if(groupName == "")	{
					alert("Please Enter a name for the new group");
					throw("no name error");
				}
				var ls = $(listGroup) ? $(listGroup).getElementsByTagName('input') : Array();
				for(var i=0; i<ls.length; i++)	{
					if(ls[i].type=='checkbox' && (ls[i].selected || ls[i].checked))
						sLists.push(ls[i].value);
				}

				if(sLists.length < 1)	{
					alert("Please select some lists to " + action);
					throw("no lists selected");
				}
				if(sLists.length!=2 && action == "difference")	{
					alert("Please select only 2 groups");
					throw("incorrect amount of lists");
				}

				DynamicListHelper.uniteLists(sLists, groupName, groupType, action, ManageListHelper.groupSelectedLists_cb );
			}
			catch(err) {}
		},
		'groupSelectedLists_cb' : function(txt)	{
			//var res = txt.split(",");
			//accepts a comma sep string, should/could be json!
			//String results : pass | fail
			//String action
			//String groupType
			try	{
				var res = eval('(' + txt + ')');

				if(res.results.indexOf("pass")!=-1)	{
					$(res.groupType+'GroupName').value = "";

					var st = res.groupType+"GroupStatus";
					$(st).innerHTML = "Group Saved";
					setTimeout(function()	{ $(st).innerHTML = ""; }, 2000);
				}
				else {
					if(res.action == "join"){
						alert("List did not save, please try again.");
					}
					else{
						alert("The selected lists do not have any common entries.");
					}
				}

				ManageListHelper.getAllLists();
			   	SidebarHelper.loadSidebar();
			}
			catch(err)	{
				//alert(err);
			}
		},
		// ************* upload related **************** //
		//this function is called by upload.jsp sitting in an iframe
		//it is given an associative array (much like a paramMap) from
		// the validated list. The groupString variable(below) is inserted into the page
		// at the appropriate place.-KR...dont need the main argument anymore

		'handleResponse' : function(msg) {
			//optional arguments: 1-upload form id, 2-upload status id
			try	{
				ManageListHelper.getAllLists();
			   	SidebarHelper.loadSidebar();
			}
			catch(err)	{}

		   var uform = arguments.length > 1 && arguments[1]!= "" ? arguments[0] : "uploadForm";
		   var ustat = arguments.length > 2 ? arguments[2] : "uploadStatus";
			//reset the form
			Form.reset($(uform));
			//hide the indicator
			setTimeout(function(){$(ustat).style.display = "none";}, 500);

		},

		// this functions as a toggle for the details link next to a
		// list. If details are currently viewable, it removes the element
		// from the DOM. If the "list name + detailsDiv" element doesn't
		// exist, the AJAX call is made to retrieve the most current details
		// from the userListBean sitting in the session. -KR
		// requires name+"detailsDiv" and name+"status" elements(ids) to be in the HTML
		'getDetails' : function(name){

			if(document.getElementById(name+ "detailsDiv")==null){
				if($(name+"status"))
					$(name+"status").style.display = "";
		    	UserListHelper.getDetailsFromList(name,ManageListHelper.putDetailsIHTML);
		   	}
		   	else	{
		    	Element.remove(name+"detailsDiv");
		    }
		},
		 //function to make an AJAX call to the userListBean in the session
		 // and delete the list under the name it passes as a param. Then finds
		 // the div with an id matching this name and removes it from the DOM. -KR
		'deleteList' : function(name){
			if(confirm("Delete this List?"))
				UserListHelper.removeListFromAjax(name, ManageListHelper.generic_cb);
		},
		'generic_cb' : function(name)	{
			try	{
				SidebarHelper.loadSidebar();
			}
			catch(err)	{}
			ManageListHelper.getAllLists()
		},
		//function to make an AJAX call to the userListBean in the session
		// and delete the list item under the list name it passes as params. Then finds
		// the div with an id matching this item name and removes it from the DOM. -KR
		'deleteItem' : function (name, itemId){
			UserListHelper.removeItemFromList(name,itemId);
			Element.remove(name + itemId + "_div");
			try	{
				SidebarHelper.loadSidebar();
				//update the count
				if($(name+"_count"))	{
					var tmp = $(name+"_count").innerHTML;
					$(name+"_count").innerHTML = parseInt(tmp) - 1;
				}
			}
			catch(err){}
		},
		//this is the callback function from the getDetails AJAX function (above). This
		//function recieves a Document object back from the getDetails call and parses
		// the Document object. As it parses the Document (which is a UserList), it
		// dynamically creates DOM elements for each item in a particular list and adds
		// them to the page. The dynamically created nodes are created/deleted depending
		// on when the user toggles the "details" link next to a link. -KR

		// modded to use IHTML and JSON- rcl
		'putDetailsIHTML' : function(userList){
			//JSON: String listName
			// String listType
			// Array validItems
			// Array invalidItems
		 	try	{
				var list = eval('(' + userList + ')');
				listName = list.listName;
				listType = list.listType;
				listType = ""; //clear this for now

				var items = list.validItems ? list.validItems : Array();
				var invalidItems = list.invalidItems ? list.invalidItems : Array();

				var itemId;
		 		var value;
		 		var dDIV = document.createElement("div");
		 		dDIV.setAttribute("id",listName + "detailsDiv");
		 		dDIV.setAttribute("class", "listItemsDiv");

		 		//rcl - create and append our container
		 		 document.getElementById(listName + "details").appendChild(dDIV);
		 		//setup a handle to the working container
		 		var wDiv = $(listName + "detailsDiv");
		 		wDiv.style.borderLeft = "1px dashed red";
		 		wDiv.style.marginLeft = "20px";
				wDiv.style.width="300px";
		 		if(items.length > 0)	{
		 			var tmp = "";
					for(var i=0; i<items.length; i++)	{
						itemId = items[i];
						tmp += "
"+(i+1) +") " +listType + " " + itemId;
						var oc = new Function("deleteItem('"+listName+ "','" + itemId + "');return false;");
						tmp += "[delete]
";
					}
					wDiv.innerHTML += tmp;

					var eid = encodeURIComponent(listName);
					wDiv.innerHTML += "
export list
";
				}
				else{
			    	document.getElementById(listName + "details").appendChild(dDIV);
			    	wDiv.innerHTML = "No valid items found
";
				}

			    if(!invalidItems.length < 1)	{
					var intmp = "

Invalid or does not exist in the database:
 ";
					//wDiv.innerHTML += "
Invalid or does not exist in the database:
 ";
					for(var i=0; i<invalidItems.length; i++){
						invalidItemId = invalidItems[i];
						if((i+1) == invalidItems.length){
							//wDiv.innerHTML += invalidItemId;
							intmp += invalidItemId;
						}
						else{
							intmp += invalidItemId + ", ";
							//wDiv.innerHTML += invalidItemId + ", ";
						}
					}
					wDiv.innerHTML +=intmp;
					wDiv.innerHTML += "
";

				}
			}
			catch(err)	{
				if($('details'))	{
					$("details").innerHTML = err;
					$("details").style.display = "";
				}
			}

			if($(listName+"status"))	{
				setTimeout(function()	{$(listName+"status").style.display = "none";}, 500);
			}
		},
		//all form validation is done client side. The name and file fields are checked for null
		// and list name collisions are checked. If there is a collision the user can either
		//overwrite the stored list with the current list or cancel the action and rename it. -KR

		//never gets called if you click <enter> on the keyboard, hence the onSubmit = return false; - RL
		//moved here from inline - RL
     	'validateForm' : function()	{
			//optional args: listName, upload, uploadStatus
			//loosely checking for presence
			var listName = arguments.length>0 ? arguments[0] : 'listName';
			var upload = arguments.length>1 ? arguments[1] : 'upload';
			var uploadStatus = arguments.length> 2 ? arguments[2] : 'uploadStatus';
			var uploadForm = arguments.length>3 ? arguments[3] : 'uploadForm';

			$(uploadStatus).style.display = "";
	     	var thisListName = $(listName).value;

			var errors = "";
	     	if(thisListName == ""){
	     		errors += "please enter a name for this list. \n";
	     	}
	     	if($(upload).value==""){
	     		errors += "please enter a file for this list.";
			}
	     	if(errors != ""){
	     	    alert(errors);
	     	    $(uploadStatus).style.display = "none";
	     	    return false;
	     	}
	     	else {
		    	$(uploadForm).submit();
			}
	     }
	};
	<|endoftext|>


<commit_before>(function(cobalt){
    var plugin={
        name:"webservices",

        settings:{
            base:{
                url :"",
                params : {}
            },
            defaultParameters:{
                type : "GET",
                saveToStorage : true,
                filterData : undefined,
                sendCacheResult : true
            }
        },
        calls:{},

        init:function(options){
            cobalt.log('init webservices plugin with options', options)

            //create shortcuts
            cobalt.ws={
                call : this.call.bind(this),
                config : this.config.bind(this)
            }
            if (options){
                this.config(options);
            }

        },
        config:function(settings){
            if (settings){
                if (settings.base){
                    this.settings.base = cobalt.utils.extend(this.settings.base, settings.base);
                }
                if (settings.defaultParameters){
                    this.settings.defaultParameters = cobalt.utils.extend(this.settings.defaultParameters, settings.defaultParameters);
                }
            }
        },
        call:function(options){
            var self=this;
            var newCall = {
                url :           (options.url) ? self.settings.base.url + options.url : undefined,
                processData :    options.processData || this.settings.defaultParameters.processData,
                storageKey :    ( typeof options.storageKey =="string" && options.storageKey.length ) ? options.storageKey : undefined,

                successCallback : (typeof options.successCallback =="function") ?  options.successCallback : self.settings.defaultParameters.successCallback || undefined,
                errorCallback : (typeof options.errorCallback =="function") ?  options.errorCallback : self.settings.defaultParameters.errorCallback || undefined
            }
            if (newCall.storageKey){
                newCall.cacheCallback = (typeof options.cacheCallback =="function") ?  options.cacheCallback : self.settings.defaultParameters.cacheCallback || undefined;
                newCall.cacheError = (typeof options.cacheError =="function") ?  options.cacheError : self.settings.defaultParameters.cacheError || undefined;

                if (newCall.url){
                    newCall.params = cobalt.utils.extend( this.settings.base.params, options.params );
                    newCall.type = options.type || this.settings.defaultParameters.type;

                    newCall.saveToStorage = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }

                if (newCall.cacheCallback){
                    newCall.sendCacheResult = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }
            }

            self.send(newCall, function( data ){
                cobalt.log('WS call started with id = '+data.callId)
                newCall.callId = data.callId;
                self.calls[data.callId] = newCall;
            })

        },
        handleEvent:function(json){
            cobalt.log('received webservices plugin event', json)
            var data = ( json && json.data ) ? json.data : undefined;
            if (data && data.callId && this.calls[data.callId]){
                var concernedCall = this.calls[data.callId];
                switch (json.action){
                    case "onWSError":
                        if (concernedCall.errorCallback){
                            concernedCall.errorCallback( data.data || data.text, data.errorCode, concernedCall )
                        }else{
                            cobalt.log('WS error : No JS error callback for call ' + data.callId)
                        }
                        break;
                    case "onWSResult":
                        if (concernedCall.successCallback){
                            concernedCall.successCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('WS success but no JS callback for call ' + data.callId)
                        }
                        break;
                    case "onStorageResult":
                        if (concernedCall.cacheCallback){
                            concernedCall.cacheCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    case "onStorageError":
                        if (concernedCall.cacheError){
                            concernedCall.cacheError( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    default :
                        cobalt.log('WS unknown action received from native side for call '+ data.callId);

                }
            }else{
                cobalt.log('WS unknown call event for call ', json)
            }

        },
        send:function(data, callback){
            cobalt.send({ type : "plugin", name : "webservices", action : "call", data : data }, callback);
        }
    };
    cobalt.plugins.register(plugin);

})(cobalt || {});<commit_msg>small log change<commit_after>(function(cobalt){
    var plugin={
        name:"webservices",

        settings:{
            base:{
                url :"",
                params : {}
            },
            defaultParameters:{
                type : "GET",
                saveToStorage : true,
                filterData : undefined,
                sendCacheResult : true
            }
        },
        calls:{},

        init:function(options){
            //create shortcuts
            cobalt.ws={
                call : this.call.bind(this),
                config : this.config.bind(this)
            }
            if (options){
                this.config(options);
            }

        },
        config:function(settings){
            cobalt.log('config webservices plugin with settings', settings)
            if (settings){
                if (settings.base){
                    this.settings.base = cobalt.utils.extend(this.settings.base, settings.base);
                }
                if (settings.defaultParameters){
                    this.settings.defaultParameters = cobalt.utils.extend(this.settings.defaultParameters, settings.defaultParameters);
                }
            }
        },
        call:function(options){
            var self=this;
            var newCall = {
                url :           (options.url) ? self.settings.base.url + options.url : undefined,
                processData :    options.processData || this.settings.defaultParameters.processData,
                storageKey :    ( typeof options.storageKey =="string" && options.storageKey.length ) ? options.storageKey : undefined,

                successCallback : (typeof options.successCallback =="function") ?  options.successCallback : self.settings.defaultParameters.successCallback || undefined,
                errorCallback : (typeof options.errorCallback =="function") ?  options.errorCallback : self.settings.defaultParameters.errorCallback || undefined
            }
            if (newCall.storageKey){
                newCall.cacheCallback = (typeof options.cacheCallback =="function") ?  options.cacheCallback : self.settings.defaultParameters.cacheCallback || undefined;
                newCall.cacheError = (typeof options.cacheError =="function") ?  options.cacheError : self.settings.defaultParameters.cacheError || undefined;

                if (newCall.url){
                    newCall.params = cobalt.utils.extend( this.settings.base.params, options.params );
                    newCall.type = options.type || this.settings.defaultParameters.type;

                    newCall.saveToStorage = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }

                if (newCall.cacheCallback){
                    newCall.sendCacheResult = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }
            }

            self.send(newCall, function( data ){
                cobalt.log('WS call started with id = '+data.callId)
                newCall.callId = data.callId;
                self.calls[data.callId] = newCall;
            })

        },
        handleEvent:function(json){
            cobalt.log('received webservices plugin event', json)
            var data = ( json && json.data ) ? json.data : undefined;
            if (data && data.callId && this.calls[data.callId]){
                var concernedCall = this.calls[data.callId];
                switch (json.action){
                    case "onWSError":
                        if (concernedCall.errorCallback){
                            concernedCall.errorCallback( data.data || data.text, data.errorCode, concernedCall )
                        }else{
                            cobalt.log('WS error : No JS error callback for call ' + data.callId)
                        }
                        break;
                    case "onWSResult":
                        if (concernedCall.successCallback){
                            concernedCall.successCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('WS success but no JS callback for call ' + data.callId)
                        }
                        break;
                    case "onStorageResult":
                        if (concernedCall.cacheCallback){
                            concernedCall.cacheCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    case "onStorageError":
                        if (concernedCall.cacheError){
                            concernedCall.cacheError( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    default :
                        cobalt.log('WS unknown action received from native side for call '+ data.callId);

                }
            }else{
                cobalt.log('WS unknown call event for call ', json)
            }

        },
        send:function(data, callback){
            cobalt.send({ type : "plugin", name : "webservices", action : "call", data : data }, callback);
        }
    };
    cobalt.plugins.register(plugin);

})(cobalt || {});<|endoftext|>


<commit_before>(function(cobalt){
    var plugin={
        name:"webservices",

        settings:{
            base:{
                url :"",
                params : {}
            },
            defaultParameters:{
                type : "GET",
                saveToStorage : true,
                filterData : undefined,
                sendCacheResult : true
            }
        },
        calls:{},

        init:function(options){
            //create shortcuts
            cobalt.ws={
                call : this.call.bind(this),
                config : this.config.bind(this)
            }
            if (options){
                this.config(options);
            }

        },
        config:function(settings){
            cobalt.log('config webservices plugin with settings', settings)
            if (settings){
                if (settings.base){
                    this.settings.base = cobalt.utils.extend(this.settings.base, settings.base);
                }
                if (settings.defaultParameters){
                    this.settings.defaultParameters = cobalt.utils.extend(this.settings.defaultParameters, settings.defaultParameters);
                }
            }
        },
        call:function(options){
            var self=this;
            var newCall = {
                url :           (options.url) ? self.settings.base.url + options.url : undefined,
                processData :    options.processData || this.settings.defaultParameters.processData,
                storageKey :    ( typeof options.storageKey =="string" && options.storageKey.length ) ? options.storageKey : undefined,

                successCallback : (typeof options.successCallback =="function") ?  options.successCallback : self.settings.defaultParameters.successCallback || undefined,
                errorCallback : (typeof options.errorCallback =="function") ?  options.errorCallback : self.settings.defaultParameters.errorCallback || undefined
            }
            if (newCall.storageKey){
                newCall.cacheCallback = (typeof options.cacheCallback =="function") ?  options.cacheCallback : self.settings.defaultParameters.cacheCallback || undefined;
                newCall.cacheError = (typeof options.cacheError =="function") ?  options.cacheError : self.settings.defaultParameters.cacheError || undefined;

                if (newCall.url){
                    newCall.params = cobalt.utils.extend( this.settings.base.params, options.params );
                    newCall.type = options.type || this.settings.defaultParameters.type;

                    newCall.saveToStorage = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }

                if (newCall.cacheCallback){
                    newCall.sendCacheResult = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }
            }

            self.send(newCall, function( data ){
                cobalt.log('WS call started with id = '+data.callId)
                newCall.callId = data.callId;
                self.calls[data.callId] = newCall;
            })

        },
        handleEvent:function(json){
            cobalt.log('received webservices plugin event', json)
            var data = ( json && json.data ) ? json.data : undefined;
            if (data && data.callId && this.calls[data.callId]){
                var concernedCall = this.calls[data.callId];
                switch (json.action){
                    case "onWSError":
                        if (concernedCall.errorCallback){
                            concernedCall.errorCallback( data.data || data.text, data.errorCode, concernedCall )
                        }else{
                            cobalt.log('WS error : No JS error callback for call ' + data.callId)
                        }
                        break;
                    case "onWSResult":
                        if (concernedCall.successCallback){
                            concernedCall.successCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('WS success but no JS callback for call ' + data.callId)
                        }
                        break;
                    case "onStorageResult":
                        if (concernedCall.cacheCallback){
                            concernedCall.cacheCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    case "onStorageError":
                        if (concernedCall.cacheError){
                            concernedCall.cacheError( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    default :
                        cobalt.log('WS unknown action received from native side for call '+ data.callId);

                }
            }else{
                cobalt.log('WS unknown call event for call ', json)
            }

        },
        send:function(data, callback){
            cobalt.send({ type : "plugin", name : "webservices", action : "call", data : data }, callback);
        }
    };
    cobalt.plugins.register(plugin);

})(cobalt || {});<commit_msg>webservices plugin : escaping paramaters<commit_after>(function(cobalt){
    var plugin={
        name:"webservices",

        settings:{
            base:{
                url :"",
                params : {}
            },
            defaultParameters:{
                type : "GET",
                saveToStorage : true,
                filterData : undefined,
                sendCacheResult : true
            }
        },
        calls:{},

        init:function(options){
            //create shortcuts
            cobalt.ws={
                call : this.call.bind(this),
                config : this.config.bind(this)
            }
            if (options){
                this.config(options);
            }

        },
        config:function(settings){
            cobalt.log('config webservices plugin with settings', settings)
            if (settings){
                if (settings.base){
                    this.settings.base = cobalt.utils.extend(this.settings.base, settings.base);
                }
                if (settings.defaultParameters){
                    this.settings.defaultParameters = cobalt.utils.extend(this.settings.defaultParameters, settings.defaultParameters);
                }
            }
        },
        call:function(options){
            var self=this;
            var newCall = {
                processData :    options.processData || this.settings.defaultParameters.processData,
                storageKey :    ( typeof options.storageKey =="string" && options.storageKey.length ) ? options.storageKey : undefined
            }

            if (options.url){
                newCall.url = ((/^https?:/).test(options.url)) ? options.url : self.settings.base.url + options.url;
                newCall.successCallback = (typeof options.successCallback =="function") ?  options.successCallback : self.settings.defaultParameters.successCallback || undefined;
                newCall.errorCallback = (typeof options.errorCallback =="function") ?  options.errorCallback : self.settings.defaultParameters.errorCallback || undefine;

                var params = cobalt.utils.extend( this.settings.base.params, options.params );
                if (params){
                    newCall.params = cobalt.utils.param(params);
                }
                newCall.headers = cobalt.utils.extend( this.settings.base.headers, options.headers );
                newCall.type = options.type || this.settings.defaultParameters.type;
            }

            if (newCall.storageKey){
                newCall.cacheCallback = (typeof options.cacheCallback =="function") ?  options.cacheCallback : self.settings.defaultParameters.cacheCallback || undefined;
                newCall.cacheError = (typeof options.cacheError =="function") ?  options.cacheError : self.settings.defaultParameters.cacheError || undefined;

                if (newCall.url){
                    newCall.saveToStorage = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }

                if (newCall.cacheCallback){
                    newCall.sendCacheResult = options.saveToStorage || this.settings.defaultParameters.saveToStorage;
                }
            }
            self.send(newCall, function( data ){
                cobalt.log('WS call started with id = '+data.callId, newCall)
                newCall.callId = data.callId;
                self.calls[data.callId] = newCall;
            })

        },
        handleEvent:function(json){
            cobalt.log('received webservices plugin event', json)
            var data = ( json && json.data ) ? json.data : undefined;
            if (data && data.callId && this.calls[data.callId]){
                var concernedCall = this.calls[data.callId];
                switch (json.action){
                    case "onWSError":
                        if (concernedCall.errorCallback){
                            concernedCall.errorCallback( data.data || data.text, data.statusCode, concernedCall )
                        }else{
                            cobalt.log('WS error : No JS error callback for call ' + data.callId)
                        }
                        break;
                    case "onWSResult":
                        if (concernedCall.successCallback){
                            concernedCall.successCallback( data.data || data.text, data.statusCode, concernedCall )
                        }else{
                            cobalt.log('WS success but no JS callback for call ' + data.callId)
                        }
                        break;
                    case "onStorageResult":
                        if (concernedCall.cacheCallback){
                            concernedCall.cacheCallback( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    case "onStorageError":
                        if (concernedCall.cacheError){
                            concernedCall.cacheError( data.data || data.text, concernedCall )
                        }else{
                            cobalt.log('Some data in storage but no JS callback for call '+ data.callId)
                        }
                        break;
                    default :
                        cobalt.log('WS unknown action received from native side for call '+ data.callId);

                }
            }else{
                cobalt.log('WS unknown call event for call ', json)
            }

        },
        send:function(data, callback){
            cobalt.send({ type : "plugin", name : "webservices", action : "call", data : data }, callback);
        }
    };
    cobalt.plugins.register(plugin);

})(cobalt || {});<|endoftext|>


<commit_before><commit_msg>Subtraction test failed<commit_after><|endoftext|>


<commit_before><commit_msg>fix: ensure proper path format<commit_after><|endoftext|>


<commit_before><commit_msg>fix test<commit_after><|endoftext|>