<commit_before>#!/usr/bin/env node

var util = require('util');
var net = require('net');
var assert = require('assert');
var errors = require('../lib/jet/errors');

var MessageSocket = require('../lib/jet/message-socket.js').MessageSocket;

var peers = {};
var nodes = {};
var leaves = {};
var routes = {};

var routeResponse = function(peer, message) {
    var route = routes[message.id];
    if (route) {
        delete routes[message.id];
        message.id = route.id;
        route.receiver.sendMessage(message);
    }
    else {
        console.log('cannot router message', message);
    }
};

/* publishes a notification to all subsbribers / fetchers */
var publish = function(notification) {
    var path = notification.path;
    for (var peerId in peers) {
        var peer = peers[peerId];
        var fetchers = peer.fetchers;
        for (var fetchId in fetchers) {
            if (fetchers[fetchId](path)) {
                peer.sendMessage({
                    method: fetchId,
                    params: notification
                });
            }
        }
    }
};

/* creates a match function from an array of match and unmatch
   expressions.
*/
var matcher = function(match, unmatch) {
    return function(path) {
        for (var i = 0; i < unmatch.length; ++i) {
            if (path.match(unmatch[i])) {
                return false;
            }
        }
        for (i = 0; i < match.length; ++i) {
            if (path.match(match[i])) {
                return true;
            }
        }
        return false;
    }
};

var post = function(peer, message) {
    var notification = message.params;
    var path = notification.path;
    var event = notification.event;
    var data = notification.data;
    var leave = leaves[path];
    if (leave) {
        if (event === 'change') {
            if (data.value) {
                leave.element.value = data.value;
            }
            if (data.schema) {
                leave.element.schema = data.schema;
            }
        }
        publish(notification);
    }
    else {
        var error = errors.invalidParams({
            invalidPath: path
        });
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        else {
            console.log('post failed with invalid path', message);
        }
    }
};

var fetch = function(peer, message) {
    var params = message.params;
    var fetchId = params.id;
    var match = params.match;
    var unmatch = params.unmatch || [];
    var matchf = matcher(match, unmatch);
    if (!peer.fetchers[fetchId]) {
        var nodeNotifications = [];
        for (var path in nodes) {
            if (matchf(path)) {
                var notification = {
                    method: fetchId,
                    params: {
                        path: path,
                        event: 'add',
                        data: {
                            type: 'node'
                        }
                    }
                };
                nodeNotifications.push(notification);
            }
        }
        nodeNotifications.sort(function(a, b) {
            return a.length - b.length;
        });
        nodeNotifications.forEach(function(nodeNotification) {
            peer.sendMessage(nodeNotification);
        });
        for (path in leaves) {
            if (matchf(path)) {
                var leave = leaves[path];
                peer.sendMessage({
                    method: fetchId,
                    params: {
                        path: path,
                        event: 'add',
                        data: leave.element
                    }
                });
            }
        }
    }
    peer.fetchers[fetchId] = matchf;
    if (message.id) {
        peer.sendMessage({
            id: message.id,
            result: true
        });
    }
};

var set = function(peer, message) {
    var params = message.params;
    var path = params.path;
    var value = params.value;
    var leave = leaves[path];
    if (leave && leave.element.type === 'state') {
        var id;
        if (message.id) {
            id = message.id + '_' + peer.id;
            assert.equal(routes[id], null);
            routes[id] = {
                receiver: peer,
                id: message.id
            };
        }
        peer.sendMessage({
            id: id, // maybe null
            method: path,
            params: {
                value: value
            }
        });
    }
    else {
        var error;
        if (leave) {
            error = errors.invalidParams({
                pathIsNotState: path
            });
        }
        else {
            error = errors.invalidParams({
                invalidPath: path
            });
        }
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        console.log('set failed', error);
    }
};

var call = function(peer, message) {
    var params = message.params;
    var path = params.path;
    var args = params.args;
    var leave = leaves[path];
    if (leave && leave.element.type === 'method') {
        var id;
        if (message.id) {
            id = message.id + '_' + peer.id;
            assert.equal(routes[id], null);
            routes[id] = {
                receiver: peer,
                id: message.id
            };
        }
        peer.sendMessage({
            id: id, // maybe null
            method: path,
            params: args
        });
    }
    else {
        var error;
        if (leave) {
            error = errors.invalidParams({
                pathIsNotMethod: path
            });
        }
        else {
            error = errors.invalidParams({
                invalidPath: path
            });
        }
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        console.log('call failed', error);
    }
};

var incrementNodes = function(path) {
    var parts = path.split('/');
    for (var i = 1; i < parts.length; ++i) {
        path = parts.slice(0, i).join('/');
        var count = nodes[path];
        if (count) {
            ++nodes[path];
        }
        else {
            nodes[path] = 1;
            publish({
                event: 'add',
                path: path,
                data: {
                    type: 'node'
                }
            });
        }
    }
};

var decrementNodes = function(path) {
    var parts = path.split('/');
    for (var i = parts.length-1; i > 0; --i) {
        path = parts.slice(0, i).join('/');
        var count = nodes[path];
        assert.ok(count > 0);
        if (count > 1) {
            --nodes[path];
        }
        else {
            delete nodes[path];
            publish({
                event: 'remove',
                path: path,
                data: {
                    type: 'node'
                }
            });
        }
    }
};

var add = function(peer, message) {
    var params = message.params;
    var path = params.path;
    if (nodes[path] || leaves[path]) {
        throw errors.invalidParams({
            occupiedPath: path
        });
    }
    incrementNodes(path);
    var element = params.element;
    if (element.type !== 'state' && element.type !== 'method') {
        throw errors.invalidParams({
            missingParam: 'element.type',
            got: params
        });
    }
    leaves[path] = {
        peer: peer,
        element: element
    };
    publish({
        path: path,
        event: 'add',
        data: element
    });
};

var remove = function(peer, message) {
    var params = message.params;
    var path = params.path;
    if (!leaves[path]) {
        throw errors.invalidParams({
            invalidPath: path
        });
    }
    var element = leaves[path].element;
    assert.ok(element);
    delete leaves[path];
    publish({
        path: path,
        event: 'remove',
        data: element
    });
    decrementNodes(path);
};

var safe = function(f) {
    return function(peer, message) {
        try {
            var result = f(peer, message) || true;
            if (message.id) {
                peer.sendMessage({
                    id: message.id,
                    result: result
                });
            }
        }
        catch (err) {
            console.log('jetd.safe failed', err, message);
            if (message.id) {
                if (typeof(err) === 'object') {
                    assert.ok(err.code && err.message, err);
                    peer.sendMessage({
                        id: message.id,
                        error: err
                    });
                }
                else {
                    peer.sendMessage({
                        id: message.id,
                        error: {
                            code: -32603,
                            message: 'Internal error',
                            data: err
                        }
                    });
                }
            }
        }
    };
};

var safeForward = function(f) {
    return function(peer, message) {
        try {
            f(peer, message);
        }
        catch (err) {
            console.log('jetd.safeForward failed', err, message);
            if (message.id) {
                if (typeof(err) === 'object') {
                    assert.ok(err.code && err.message, err);
                    peer.sendMessage({
                        id: message.id,
                        error: err
                    });
                }
                else {
                    peer.sendMessage({
                        id: message.id,
                        error: {
                            code: -32603,
                            message: 'Internal error',
                            data: err
                        }
                    });
                }
            }
        }
    };
};

var services = {
    add: safe(add),
    remove: safe(remove),
    call: safeForward(call),
    set: safeForward(set),
    fetch: safeForward(fetch),
    post: safe(post),
    echo: safe(function(peer, message) {
        return message.params;
    })
};

var dispatchRequest = function(peer,message) {
    assert.ok(message.method);
    var service = services[message.method];
    if (service) {
        service(peer,message);
    }
    else {
        var error = errors.methodNotFound(message.method);
        peer.sendMessage({
            id: message.id,
            error: error
        });
    }
};

var dispatchNotification = function(peer,message) {
    assert.ok(message.method);
    var service = services[message.method];
    if (service) {
        service(peer,message);
    }
};

var listener = net.createServer(function(peerSocket) {
    var peer;
    var releasePeer = function() {
        if (peer) {
            peer.fetchers = {};
            for (var path in leaves) {
                var leave = leaves[path];
                if (leave.peer == peer) {
                    publish({
                        event: 'remove',
                        path: path,
                        data: {
                            type: leave.element.type
                        }
                    });
                    decrementNodes(path);
                    delete leaves[path];
                }
            }
        }
    };
    peer = new MessageSocket(peerSocket);
    var dispatchMessage = function(message){
        if (message.id) {
            if (message.method) {
            } else if (message.result !== null || message.error !== null) {
                routeResponse(peer,message);
            } else {
                var error = errors.invalidRequest(message);
                peer.sendMessage({
                    id: message.id,
                    error: error
                });
                console.log('invalid request',message);
            }
        } else if (message.method) {
            dispatchNotification(peer,message);
        } else {
            console.log('invalid message',message);
        }
    };
    peer.on('message',function(message){
        if (util.isArray(message)) {
            var batch = message;
            batch.forEach(function(message) {
                dispatchMessage(message);
            });
        }
        else {
            dispatchMessage(message);
        }
    });
    var peerId = peerSocket.remoteAddress + peerSocket.remotePort;
    peer.id = peerId;
    peer.fetchers = {}
    peers[peerId] = peer;
    peerSocket.on('close', releasePeer);
    peerSocket.on('error', releasePeer);
});

listener.listen(33326);
<commit_msg>use event 'messages' instead of 'message'<commit_after>#!/usr/bin/env node

var util = require('util');
var net = require('net');
var assert = require('assert');
var errors = require('../lib/jet/errors');

var MessageSocket = require('../lib/jet/message-socket.js').MessageSocket;

var peers = {};
var nodes = {};
var leaves = {};
var routes = {};

var routeResponse = function(peer, message) {
    var route = routes[message.id];
    if (route) {
        delete routes[message.id];
        message.id = route.id;
        route.receiver.sendMessage(message);
    }
    else {
        console.log('cannot router message', message);
    }
};

/* publishes a notification to all subsbribers / fetchers */
var publish = function(notification) {
    var path = notification.path;
    for (var peerId in peers) {
        var peer = peers[peerId];
        var fetchers = peer.fetchers;
        for (var fetchId in fetchers) {
            if (fetchers[fetchId](path)) {
                peer.sendMessage({
                    method: fetchId,
                    params: notification
                });
            }
        }
    }
};

/* creates a match function from an array of match and unmatch
   expressions.
*/
var matcher = function(match, unmatch) {
    return function(path) {
        for (var i = 0; i < unmatch.length; ++i) {
            if (path.match(unmatch[i])) {
                return false;
            }
        }
        for (i = 0; i < match.length; ++i) {
            if (path.match(match[i])) {
                return true;
            }
        }
        return false;
    }
};

var post = function(peer, message) {
    var notification = message.params;
    var path = notification.path;
    var event = notification.event;
    var data = notification.data;
    var leave = leaves[path];
    if (leave) {
        if (event === 'change') {
            if (data.value) {
                leave.element.value = data.value;
            }
            if (data.schema) {
                leave.element.schema = data.schema;
            }
        }
        publish(notification);
    }
    else {
        var error = errors.invalidParams({
            invalidPath: path
        });
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        else {
            console.log('post failed with invalid path', message);
        }
    }
};

var fetch = function(peer, message) {
    var params = message.params;
    var fetchId = params.id;
    var match = params.match;
    var unmatch = params.unmatch || [];
    var matchf = matcher(match, unmatch);
    if (!peer.fetchers[fetchId]) {
        var nodeNotifications = [];
        for (var path in nodes) {
            if (matchf(path)) {
                var notification = {
                    method: fetchId,
                    params: {
                        path: path,
                        event: 'add',
                        data: {
                            type: 'node'
                        }
                    }
                };
                nodeNotifications.push(notification);
            }
        }
        nodeNotifications.sort(function(a, b) {
            return a.length - b.length;
        });
        nodeNotifications.forEach(function(nodeNotification) {
            peer.sendMessage(nodeNotification);
        });
        for (path in leaves) {
            if (matchf(path)) {
                var leave = leaves[path];
                peer.sendMessage({
                    method: fetchId,
                    params: {
                        path: path,
                        event: 'add',
                        data: leave.element
                    }
                });
            }
        }
    }
    peer.fetchers[fetchId] = matchf;
    if (message.id) {
        peer.sendMessage({
            id: message.id,
            result: true
        });
    }
};

var set = function(peer, message) {
    var params = message.params;
    var path = params.path;
    var value = params.value;
    var leave = leaves[path];
    if (leave && leave.element.type === 'state') {
        var id;
        if (message.id) {
            id = message.id + '_' + peer.id;
            assert.equal(routes[id], null);
            routes[id] = {
                receiver: peer,
                id: message.id
            };
        }
        peer.sendMessage({
            id: id, // maybe null
            method: path,
            params: {
                value: value
            }
        });
    }
    else {
        var error;
        if (leave) {
            error = errors.invalidParams({
                pathIsNotState: path
            });
        }
        else {
            error = errors.invalidParams({
                invalidPath: path
            });
        }
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        console.log('set failed', error);
    }
};

var call = function(peer, message) {
    var params = message.params;
    var path = params.path;
    var args = params.args;
    var leave = leaves[path];
    if (leave && leave.element.type === 'method') {
        var id;
        if (message.id) {
            id = message.id + '_' + peer.id;
            assert.equal(routes[id], null);
            routes[id] = {
                receiver: peer,
                id: message.id
            };
        }
        peer.sendMessage({
            id: id, // maybe null
            method: path,
            params: args
        });
    }
    else {
        var error;
        if (leave) {
            error = errors.invalidParams({
                pathIsNotMethod: path
            });
        }
        else {
            error = errors.invalidParams({
                invalidPath: path
            });
        }
        if (message.id) {
            peer.sendMessage({
                id: message.id,
                error: error
            });
        }
        console.log('call failed', error);
    }
};

var incrementNodes = function(path) {
    var parts = path.split('/');
    for (var i = 1; i < parts.length; ++i) {
        path = parts.slice(0, i).join('/');
        var count = nodes[path];
        if (count) {
            ++nodes[path];
        }
        else {
            nodes[path] = 1;
            publish({
                event: 'add',
                path: path,
                data: {
                    type: 'node'
                }
            });
        }
    }
};

var decrementNodes = function(path) {
    var parts = path.split('/');
    for (var i = parts.length-1; i > 0; --i) {
        path = parts.slice(0, i).join('/');
        var count = nodes[path];
        assert.ok(count > 0);
        if (count > 1) {
            --nodes[path];
        }
        else {
            delete nodes[path];
            publish({
                event: 'remove',
                path: path,
                data: {
                    type: 'node'
                }
            });
        }
    }
};

var add = function(peer, message) {
    var params = message.params;
    var path = params.path;
    if (nodes[path] || leaves[path]) {
        throw errors.invalidParams({
            occupiedPath: path
        });
    }
    incrementNodes(path);
    var element = params.element;
    if (element.type !== 'state' && element.type !== 'method') {
        throw errors.invalidParams({
            missingParam: 'element.type',
            got: params
        });
    }
    leaves[path] = {
        peer: peer,
        element: element
    };
    publish({
        path: path,
        event: 'add',
        data: element
    });
};

var remove = function(peer, message) {
    var params = message.params;
    var path = params.path;
    if (!leaves[path]) {
        throw errors.invalidParams({
            invalidPath: path
        });
    }
    var element = leaves[path].element;
    assert.ok(element);
    delete leaves[path];
    publish({
        path: path,
        event: 'remove',
        data: element
    });
    decrementNodes(path);
};

var safe = function(f) {
    return function(peer, message) {
        try {
            var result = f(peer, message) || true;
            if (message.id) {
                peer.sendMessage({
                    id: message.id,
                    result: result
                });
            }
        }
        catch (err) {
            console.log('jetd.safe failed', err, message);
            if (message.id) {
                if (typeof(err) === 'object') {
                    assert.ok(err.code && err.message, err);
                    peer.sendMessage({
                        id: message.id,
                        error: err
                    });
                }
                else {
                    peer.sendMessage({
                        id: message.id,
                        error: {
                            code: -32603,
                            message: 'Internal error',
                            data: err
                        }
                    });
                }
            }
        }
    };
};

var safeForward = function(f) {
    return function(peer, message) {
        try {
            f(peer, message);
        }
        catch (err) {
            console.log('jetd.safeForward failed', err, message);
            if (message.id) {
                if (typeof(err) === 'object') {
                    assert.ok(err.code && err.message, err);
                    peer.sendMessage({
                        id: message.id,
                        error: err
                    });
                }
                else {
                    peer.sendMessage({
                        id: message.id,
                        error: {
                            code: -32603,
                            message: 'Internal error',
                            data: err
                        }
                    });
                }
            }
        }
    };
};

var services = {
    add: safe(add),
    remove: safe(remove),
    call: safeForward(call),
    set: safeForward(set),
    fetch: safeForward(fetch),
    post: safe(post),
    echo: safe(function(peer, message) {
        return message.params;
    })
};

var dispatchRequest = function(peer,message) {
    assert.ok(message.method);
    var service = services[message.method];
    if (service) {
        service(peer,message);
    }
    else {
        var error = errors.methodNotFound(message.method);
        peer.sendMessage({
            id: message.id,
            error: error
        });
    }
};

var dispatchNotification = function(peer,message) {
    assert.ok(message.method);
    var service = services[message.method];
    if (service) {
        service(peer,message);
    }
};

var listener = net.createServer(function(peerSocket) {
    var peer;
    var releasePeer = function() {
        if (peer) {
            peer.fetchers = {};
            for (var path in leaves) {
                var leave = leaves[path];
                if (leave.peer == peer) {
                    publish({
                        event: 'remove',
                        path: path,
                        data: {
                            type: leave.element.type
                        }
                    });
                    decrementNodes(path);
                    delete leaves[path];
                }
            }
        }
    };
    peer = new MessageSocket(peerSocket);
    var dispatchMessage = function(message){
        if (message.id) {
            if (message.method) {
            } else if (message.result !== null || message.error !== null) {
                routeResponse(peer,message);
            } else {
                var error = errors.invalidRequest(message);
                peer.sendMessage({
                    id: message.id,
                    error: error
                });
                console.log('invalid request',message);
            }
        } else if (message.method) {
            dispatchNotification(peer,message);
        } else {
            console.log('invalid message',message);
        }
    };
    peer.on('messages',function(batch){
        assert.equal(util.isArray(batch),true);
        batch.forEach(function(message) {
            dispatchMessage(message);
        });
    });
    var peerId = peerSocket.remoteAddress + peerSocket.remotePort;
    peer.id = peerId;
    peer.fetchers = {}
    peers[peerId] = peer;
    peerSocket.on('close', releasePeer);
    peerSocket.on('error', releasePeer);
});

listener.listen(33326);
<|endoftext|>


<commit_before>var TSV = {
  // Basic setup
  init: function() {
    // Plugins
    $('[data-toggle="tooltip"]').tooltip()
    $('.carousel').carousel({
      interval: 4000,
      keyboard: false,
      pause: "hover",
    });
    $('.counter').counterUp({
      delay: 25,
      time: 2500
    });
    moment.locale('es');

    // Set random hero image
    if( $('#hero') ) {
      var img = "url('images/hero_photo_"+ (Math.floor(Math.random() * 4) + 1) +".png')";
      $('#hero > div.photo').css( 'background-image', img );
    }

    if( $('form#preregister') ) {
      var form = $('form#preregister');
      form.on( 'submit', function( e ) {
        e.preventDefault();
        $.ajax({
          type: "POST",
          url: 'preregister',
          data: {
            email: form.find('input').val()
          },
          success: function( res ) {
            alert("Gracias por tu interés en Testigo Social 2.0. Pronto te informaremos cómo podrás participar en las compras públicas mediante esta nueva plataforma.");
          }
        });
      });
    }

    // Register form setup
    if( $('#setup') ) {
      this.registerSetup();
    }

    // Display main stats
    if( $('#highlights') ) {
      this.statsSetup();
    }

    // Query setup
    if( $('#queryForm') ) {
      this.querySetup();
    }
  },

  // Load main stats
  statsSetup: function() {
    var data = {}
    var charts = {}
    var ui = {
      totalContracts: $('span.totalContracts'),
      totalBudget: $('span#totalBudget'),
      totalAward: $('span#totalAward'),
      totalAmount: $('span#totalAmount'),
      firstDate: $('span#firstDate'),
      lastDate: $('span#lastDate')
    }

    // Dynamically set bucket used, default to 'gacm'
    var url = '/stats/gacm';
    if( getParameter('bucket') ) {
      url = '/stats/' + getParameter('bucket');
    }

    // Load stats
    $.ajax({
      type: "GET",
      url: url,
      success: function( res ) {
        data = JSON.parse(res);
      }
    }).done(function() {
      // Adjust labels
      ui.firstDate.text( moment( data.FirstDate ).format('LL') );
      ui.lastDate.text( moment( data.LastDate ).format('LL') );
      ui.totalContracts.text( data.contracts.total );
      ui.totalBudget.text((data.contracts.budget / 1000000).toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));
      ui.totalAward.text((data.contracts.awarded / 1000000).toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));
      ui.totalAmount.text( data.contracts.budget.toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));

      // Prepare chart data
      var directP = ((data.method['direct'].budget * 100) / data.contracts.budget).toFixed(2);
      var limitedP = ((data.method['limited'].budget * 100) / data.contracts.budget).toFixed(2);
      var publicP = ((data.method['public'].budget * 100) / data.contracts.budget).toFixed(2);
      var charts = {
        direct: {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Total Contratado (%)'
            ],
            datasets: [
              {
                data: [directP, (100 - directP).toFixed(2)],
                backgroundColor: ["#CCB3FF", "#EEEEEE"],
              }
            ]
          }
        },
        limited: {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Invitación a cuando menos 3 personas (%)',
              'Total Contratado (%)'
            ],
            datasets: [
              {
                data: [directP, limitedP, (100 - (Number(directP) + Number(limitedP))).toFixed(2)],
                backgroundColor: ["#CCB3FF", "#FF6384", "#EEEEEE"],
              }
            ]
          }
        },
        'public': {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Invitación a cuando menos 3 personas (%)',
              'Licitación Pública (%)'
            ],
            datasets: [
              {
                data: [directP, limitedP, publicP],
                backgroundColor: ["#CCB3FF", "#FF6384", "#7DE7CF"],
              }
            ]
          }
        }
      }

      // Configure data slider
      var slides = $('#content-slides');
      slides.on('slid.bs.carousel', function(){
        var active = slides.find('div.active');
        var method = active.data('section');
        if( method ) {
          active.find('span.contracts').text( data.method[method].total );
          active.find('span.amount').text( data.method[method].budget.toLocaleString({
            useGrouping: true
          }));

          if( !charts[method].c ) {
            charts[method].c = new Chart( active.find('canvas'), {
              type: "pie",
              data: charts[method].data,
              options: {
                responsive: true,
                responsiveAnimationDuration: 500,
                padding: 10
              }
            });
          }
        }
      });
    });
  },

  // Handler user registration process
  registerSetup: function() {
    var agencies = $('div.agency-grid div.item');
    var selectedAgencies = $('div.agency-grid input#selectedAgencies');
    agencies.click(function() {
      // Toggle state
      var a = $(this);
      var lbl = a.find('span.label');
      a.toggleClass('selected');
      if( lbl.text().toLowerCase() == 'seguir' ) {
        lbl.text( 'siguiendo' );
      } else {
        lbl.text( 'seguir' );
      }

      // Adjust result
      var res = [];
      agencies.each( function( i, v ) {
        if( $(v).hasClass( 'selected') ) {
          res.push( $(v).data('value') );
        }
      });
      selectedAgencies.val(JSON.stringify(res));
    });

    var projects = $('div.project-grid div.item');
    var selectedProjects = $('div.project-grid input#selectedProjects');
    projects.click(function() {
      // Toggle state
      var p = $(this);
      var lbl = p.find('span.label');
      p.toggleClass('selected');
      if( lbl.text().toLowerCase() == 'seguir' ) {
        lbl.text( 'siguiendo' );
      } else {
        lbl.text( 'seguir' );
      }

      // Adjust result
      var res = [];
      projects.each( function( i, v ) {
        if( $(v).hasClass( 'selected') ) {
          res.push( $(v).data('value') );
        }
      });
      selectedProjects.val(JSON.stringify(res));
    });

    var form = $('form#registerForm');
    form.pixativeFormValidator({
      msgHolder: 'title',
      errorMessages: {
        required: 'El campo es requerido',
        minlength: 'El valor proporcionado debe ser de al menos %s caracteres',
        maxlength: 'El valor proporcionado debe ser de máximo %s caracteres',
        email: 'El valor porporcionado no parece ser una dirección de correo valida',
        integer: 'El valor proporcionado debe ser un número',
        phone: 'El valor porporcionado no parece ser un número telefonico valido'
      },
      onError: function() {
        $('.validator-error').tooltip('destroy');
        $('.validator-error').tooltip();
      },
      onSuccess: function() {
        // Prepare data
        var data = {}
        form.serializeArray().forEach(function(el) {
          if( el.value == 'on' ) {
            el.value = true;
          }
          if( el.value == 'off' ) {
            el.value = false;
          }
          data[el.name] = el.value;
        });
        data.selectedAgencies = JSON.parse(data.selectedAgencies);
        data.selectedProjects = JSON.parse(data.selectedProjects);

        // Submit
        $.ajax({
          type: "POST",
          url: '/profile',
          data: {
            profile: JSON.stringify(data)
          },
          success: function( res ) {
            alert('Tu usuario ha quedado registrado exitosamente en Testigo Social Virtual 2.0');
          }
        })
      }
    });
  },

  // Contract query setup
  querySetup: function() {
    var ui = {}
    ui.form = $('form#queryForm');
    ui.bullets = ui.form.find('div.bullets span');
    ui.input = $( 'input#query' );
    ui.bullets.on( 'click', function( e ) {
      ui.bullets.removeClass( 'active' );
      var target = $( e.target );
      target.addClass( 'active' );

      switch (target.data( 'filter' )) {
        case 'date':
          if( ! target.data( 'pickerSetup' ) ) {
            target.data( 'pickerSetup', true );
            target.datepicker({
              clearBtn: true,
              assumeNearbyYear: true,
              format: 'mm/dd/yyyy',
              language: 'es',
              maxViewMode: 2,
              multidate: 2,
              todayHighlight: true
            }).on( 'hide', function( e ) {
              e.dates.sort(function(a, b) {
                return new Date(a).getTime() - new Date(b).getTime();
              });
              var lbl = moment(e.dates[0]).format('MMMM Do YYYY');
              var val = moment(e.dates[0]).format('MM-DD-YYYY');
              if( e.dates.length > 1 ) {
                lbl += ' a ' + moment(e.dates[1]).format('MMMM Do YYYY')
                val += '|' + moment(e.dates[1]).format('MM-DD-YYYY');
              }
              ui.input.data('value', val);
              ui.input.val( lbl );
              ui.input.focus();
            });
          }
          target.datepicker( 'show' );
          break;
        case 'amount':
          if( ! target.data( 'sliderSetup' ) ) {
            target.data( 'sliderSetup', true );
            target.popover({
              html: true,
              title: 'Seleccione el rango a utilizar como filtro (MXN)',
              content: '$0<input id="amountSlider" type="text" />$100,000,000',
              placement: 'bottom',
              trigger: 'focus'
            }).on( 'shown.bs.popover', function() {
              $("#amountSlider").slider({
                step: 50000,
                min: 0,
                max: 100000000,
                value: [20000000,80000000],
                formatter: function( value ) {
                  if( Array.isArray( value ) ) {
                    var lbl = '$' + value[0].toLocaleString() + ' a ' + '$' + value[1].toLocaleString();
                    return lbl;
                  }
                  return '';
                }
              }).on( 'slide', function( e ) {
                ui.input.data('value', e.value.join('|'));
                ui.input.val( '$' + e.value[0].toLocaleString() + ' a ' + '$' + e.value[1].toLocaleString() );
              });
            });
          }
          target.popover( 'toggle' );
          break;
        default:
          ui.input.data('value', false);
          break;
      }
    });
    ui.form.on( 'submit', function( e ) {
      e.preventDefault();
      var q = {
        value: ui.input.data('value') || ui.form.find('input').val(),
        filter: ui.bullets.filter('.active').data('filter'),
        limit: 20
      }
      if( q.value != "" ) {
        // Dynamically set bucket used, default to 'gacm'
        var url = '/query/gacm';
        if( getParameter('bucket') ) {
          url = '/query/' + getParameter('bucket');
        }

        // Submit query
        $.ajax({
          type: "POST",
          url: url,
          data: {
            query: JSON.stringify(q)
          },
          success: function( res ) {
            res = JSON.parse(res)
            console.log( res );
          }
        })
      }
    });
  }
}

// Helper method to retrieve a GET variable
function getParameter(name, url) {
  if (!url) {
    url = window.location.href;
  }
  name = name.replace(/[\[\]]/g, "\\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
  results = regex.exec(url);
  if (!results) return false;
  if (!results[2]) return false;
  return decodeURIComponent(results[2].replace(/\+/g, " "));
}
<commit_msg>Pre-Register email validation<commit_after>var TSV = {
  // Basic setup
  init: function() {
    // Plugins
    $('[data-toggle="tooltip"]').tooltip()
    $('.carousel').carousel({
      interval: 4000,
      keyboard: false,
      pause: "hover",
    });
    $('.counter').counterUp({
      delay: 25,
      time: 2500
    });
    moment.locale('es');

    // Set random hero image
    if( $('#hero') ) {
      var img = "url('images/hero_photo_"+ (Math.floor(Math.random() * 4) + 1) +".png')";
      $('#hero > div.photo').css( 'background-image', img );
    }

    // Pre-register form setup
    if( $('form#preregister') ) {
      this.preRegisterSetup();
    }

    // Register form setup
    if( $('#setup') ) {
      this.registerSetup();
    }

    // Display main stats
    if( $('#highlights') ) {
      this.statsSetup();
    }

    // Query setup
    if( $('#queryForm') ) {
      this.querySetup();
    }
  },

  // Load main stats
  statsSetup: function() {
    var data = {}
    var charts = {}
    var ui = {
      totalContracts: $('span.totalContracts'),
      totalBudget: $('span#totalBudget'),
      totalAward: $('span#totalAward'),
      totalAmount: $('span#totalAmount'),
      firstDate: $('span#firstDate'),
      lastDate: $('span#lastDate')
    }

    // Dynamically set bucket used, default to 'gacm'
    var url = '/stats/gacm';
    if( getParameter('bucket') ) {
      url = '/stats/' + getParameter('bucket');
    }

    // Load stats
    $.ajax({
      type: "GET",
      url: url,
      success: function( res ) {
        data = JSON.parse(res);
      }
    }).done(function() {
      // Adjust labels
      ui.firstDate.text( moment( data.FirstDate ).format('LL') );
      ui.lastDate.text( moment( data.LastDate ).format('LL') );
      ui.totalContracts.text( data.contracts.total );
      ui.totalBudget.text((data.contracts.budget / 1000000).toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));
      ui.totalAward.text((data.contracts.awarded / 1000000).toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));
      ui.totalAmount.text( data.contracts.budget.toLocaleString(undefined, {
        minimumFractionDigits: 1,
        maximumFractionDigits: 1
      }));

      // Prepare chart data
      var directP = ((data.method['direct'].budget * 100) / data.contracts.budget).toFixed(2);
      var limitedP = ((data.method['limited'].budget * 100) / data.contracts.budget).toFixed(2);
      var publicP = ((data.method['public'].budget * 100) / data.contracts.budget).toFixed(2);
      var charts = {
        direct: {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Total Contratado (%)'
            ],
            datasets: [
              {
                data: [directP, (100 - directP).toFixed(2)],
                backgroundColor: ["#CCB3FF", "#EEEEEE"],
              }
            ]
          }
        },
        limited: {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Invitación a cuando menos 3 personas (%)',
              'Total Contratado (%)'
            ],
            datasets: [
              {
                data: [directP, limitedP, (100 - (Number(directP) + Number(limitedP))).toFixed(2)],
                backgroundColor: ["#CCB3FF", "#FF6384", "#EEEEEE"],
              }
            ]
          }
        },
        'public': {
          c: false,
          data: {
            labels: [
              'Adjudicación Directa (%)',
              'Invitación a cuando menos 3 personas (%)',
              'Licitación Pública (%)'
            ],
            datasets: [
              {
                data: [directP, limitedP, publicP],
                backgroundColor: ["#CCB3FF", "#FF6384", "#7DE7CF"],
              }
            ]
          }
        }
      }

      // Configure data slider
      var slides = $('#content-slides');
      slides.on('slid.bs.carousel', function(){
        var active = slides.find('div.active');
        var method = active.data('section');
        if( method ) {
          active.find('span.contracts').text( data.method[method].total );
          active.find('span.amount').text( data.method[method].budget.toLocaleString({
            useGrouping: true
          }));

          if( !charts[method].c ) {
            charts[method].c = new Chart( active.find('canvas'), {
              type: "pie",
              data: charts[method].data,
              options: {
                responsive: true,
                responsiveAnimationDuration: 500,
                padding: 10
              }
            });
          }
        }
      });
    });
  },

  // Handler user registration process
  registerSetup: function() {
    var agencies = $('div.agency-grid div.item');
    var selectedAgencies = $('div.agency-grid input#selectedAgencies');
    agencies.click(function() {
      // Toggle state
      var a = $(this);
      var lbl = a.find('span.label');
      a.toggleClass('selected');
      if( lbl.text().toLowerCase() == 'seguir' ) {
        lbl.text( 'siguiendo' );
      } else {
        lbl.text( 'seguir' );
      }

      // Adjust result
      var res = [];
      agencies.each( function( i, v ) {
        if( $(v).hasClass( 'selected') ) {
          res.push( $(v).data('value') );
        }
      });
      selectedAgencies.val(JSON.stringify(res));
    });

    var projects = $('div.project-grid div.item');
    var selectedProjects = $('div.project-grid input#selectedProjects');
    projects.click(function() {
      // Toggle state
      var p = $(this);
      var lbl = p.find('span.label');
      p.toggleClass('selected');
      if( lbl.text().toLowerCase() == 'seguir' ) {
        lbl.text( 'siguiendo' );
      } else {
        lbl.text( 'seguir' );
      }

      // Adjust result
      var res = [];
      projects.each( function( i, v ) {
        if( $(v).hasClass( 'selected') ) {
          res.push( $(v).data('value') );
        }
      });
      selectedProjects.val(JSON.stringify(res));
    });

    var form = $('form#registerForm');
    form.pixativeFormValidator({
      msgHolder: 'title',
      errorMessages: {
        required: 'El campo es requerido',
        minlength: 'El valor proporcionado debe ser de al menos %s caracteres',
        maxlength: 'El valor proporcionado debe ser de máximo %s caracteres',
        email: 'El valor porporcionado no parece ser una dirección de correo valida',
        integer: 'El valor proporcionado debe ser un número',
        phone: 'El valor porporcionado no parece ser un número telefonico valido'
      },
      onError: function() {
        $('.validator-error').tooltip('destroy');
        $('.validator-error').tooltip();
      },
      onSuccess: function() {
        // Prepare data
        var data = {}
        form.serializeArray().forEach(function(el) {
          if( el.value == 'on' ) {
            el.value = true;
          }
          if( el.value == 'off' ) {
            el.value = false;
          }
          data[el.name] = el.value;
        });
        data.selectedAgencies = JSON.parse(data.selectedAgencies);
        data.selectedProjects = JSON.parse(data.selectedProjects);

        // Submit
        $.ajax({
          type: "POST",
          url: '/profile',
          data: {
            profile: JSON.stringify(data)
          },
          success: function( res ) {
            alert('Tu usuario ha quedado registrado exitosamente en Testigo Social Virtual 2.0');
          }
        })
      }
    });
  },

  // Pre-register process
  preRegisterSetup: function() {
    var regx = /^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$/;
    var form = $('form#preregister');
    form.on( 'submit', function( e ) {
      e.preventDefault();
      var email = form.find('input').val();
      if( regx.test(email) ) {
        $.ajax({
          type: "POST",
          url: 'preregister',
          data: {
            email: email
          },
          success: function( res ) {
            alert("Gracias por tu interés en Testigo Social 2.0. Pronto te informaremos cómo podrás participar en las compras públicas mediante esta nueva plataforma.");
          }
        });
      } else {
        alert("La dirección proporcionada no es una dirección de correo electrónico valida, favor de verificar!");
      }
    });
  },

  // Contract query setup
  querySetup: function() {
    var ui = {}
    ui.form = $('form#queryForm');
    ui.bullets = ui.form.find('div.bullets span');
    ui.input = $( 'input#query' );
    ui.bullets.on( 'click', function( e ) {
      ui.bullets.removeClass( 'active' );
      var target = $( e.target );
      target.addClass( 'active' );

      switch (target.data( 'filter' )) {
        case 'date':
          if( ! target.data( 'pickerSetup' ) ) {
            target.data( 'pickerSetup', true );
            target.datepicker({
              clearBtn: true,
              assumeNearbyYear: true,
              format: 'mm/dd/yyyy',
              language: 'es',
              maxViewMode: 2,
              multidate: 2,
              todayHighlight: true
            }).on( 'hide', function( e ) {
              e.dates.sort(function(a, b) {
                return new Date(a).getTime() - new Date(b).getTime();
              });
              var lbl = moment(e.dates[0]).format('MMMM Do YYYY');
              var val = moment(e.dates[0]).format('MM-DD-YYYY');
              if( e.dates.length > 1 ) {
                lbl += ' a ' + moment(e.dates[1]).format('MMMM Do YYYY')
                val += '|' + moment(e.dates[1]).format('MM-DD-YYYY');
              }
              ui.input.data('value', val);
              ui.input.val( lbl );
              ui.input.focus();
            });
          }
          target.datepicker( 'show' );
          break;
        case 'amount':
          if( ! target.data( 'sliderSetup' ) ) {
            target.data( 'sliderSetup', true );
            target.popover({
              html: true,
              title: 'Seleccione el rango a utilizar como filtro (MXN)',
              content: '$0<input id="amountSlider" type="text" />$100,000,000',
              placement: 'bottom',
              trigger: 'focus'
            }).on( 'shown.bs.popover', function() {
              $("#amountSlider").slider({
                step: 50000,
                min: 0,
                max: 100000000,
                value: [20000000,80000000],
                formatter: function( value ) {
                  if( Array.isArray( value ) ) {
                    var lbl = '$' + value[0].toLocaleString() + ' a ' + '$' + value[1].toLocaleString();
                    return lbl;
                  }
                  return '';
                }
              }).on( 'slide', function( e ) {
                ui.input.data('value', e.value.join('|'));
                ui.input.val( '$' + e.value[0].toLocaleString() + ' a ' + '$' + e.value[1].toLocaleString() );
              });
            });
          }
          target.popover( 'toggle' );
          break;
        default:
          ui.input.data('value', false);
          break;
      }
    });
    ui.form.on( 'submit', function( e ) {
      e.preventDefault();
      var q = {
        value: ui.input.data('value') || ui.form.find('input').val(),
        filter: ui.bullets.filter('.active').data('filter'),
        limit: 20
      }
      if( q.value != "" ) {
        // Dynamically set bucket used, default to 'gacm'
        var url = '/query/gacm';
        if( getParameter('bucket') ) {
          url = '/query/' + getParameter('bucket');
        }

        // Submit query
        $.ajax({
          type: "POST",
          url: url,
          data: {
            query: JSON.stringify(q)
          },
          success: function( res ) {
            res = JSON.parse(res)
            console.log( res );
          }
        })
      }
    });
  }
}

// Helper method to retrieve a GET variable
function getParameter(name, url) {
  if (!url) {
    url = window.location.href;
  }
  name = name.replace(/[\[\]]/g, "\\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
  results = regex.exec(url);
  if (!results) return false;
  if (!results[2]) return false;
  return decodeURIComponent(results[2].replace(/\+/g, " "));
}
<|endoftext|>


<commit_before>var MongoClient = require('../../').MongoClient,
  expect = require('chai').expect;

function connectToDb(url, db, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  MongoClient.connect(url, options || {}, function(err, client) {
    if (err) return callback(err);
    callback(null, client.db(db), client);
  });
}

function setupDatabase(configuration) {
  var dbName = configuration.db;
  var client = configuration.newClient(configuration.writeConcernMax(), {
    poolSize: 1
  });

  return client.connect().then(function() {
    var db = client.db(dbName);
    return db
      .command({
        dropAllUsersFromDatabase: 1,
        writeConcern: { w: 1 }
      })
      .then(function() {
        return db.dropDatabase();
      });
  });
}

var assert = {
  equal: function(a, b) {
    expect(a).to.equal(b);
  },

  deepEqual: function(a, b) {
    expect(a).to.eql(b);
  },

  strictEqual: function(a, b) {
    expect(a).to.eql(b);
  },

  notEqual: function(a, b) {
    expect(a).to.not.equal(b);
  },

  ok: function(a) {
    expect(a).to.be.ok;
  },

  throws: function(func) {
    expect(func).to.throw;
  }
};

module.exports = {
  connectToDb: connectToDb,
  setupDatabase: setupDatabase,
  assert: assert
};
<commit_msg>refactor(shared): support cleaning other databases in setup<commit_after>var MongoClient = require('../../').MongoClient,
  expect = require('chai').expect;

function connectToDb(url, db, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  MongoClient.connect(url, options || {}, function(err, client) {
    if (err) return callback(err);
    callback(null, client.db(db), client);
  });
}

function setupDatabase(configuration, dbsToClean) {
  dbsToClean = Array.isArray(dbsToClean) ? dbsToClean : [];
  var configDbName = configuration.db;
  var client = configuration.newClient(configuration.writeConcernMax(), {
    poolSize: 1
  });

  dbsToClean.push(configDbName);
  return client.connect().then(function() {
    var cleanPromises = [];
    dbsToClean.forEach(function(dbName) {
      var cleanPromise = client
        .db(dbName)
        .command({
          dropAllUsersFromDatabase: 1,
          writeConcern: { w: 1 }
        })
        .then(function() {
          return client.db(dbName).dropDatabase();
        });

      cleanPromises.push(cleanPromise);
    });

    return Promise.all(cleanPromises);
  });
}

var assert = {
  equal: function(a, b) {
    expect(a).to.equal(b);
  },

  deepEqual: function(a, b) {
    expect(a).to.eql(b);
  },

  strictEqual: function(a, b) {
    expect(a).to.eql(b);
  },

  notEqual: function(a, b) {
    expect(a).to.not.equal(b);
  },

  ok: function(a) {
    expect(a).to.be.ok;
  },

  throws: function(func) {
    expect(func).to.throw;
  }
};

module.exports = {
  connectToDb: connectToDb,
  setupDatabase: setupDatabase,
  assert: assert
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

var process = global.process;
var minimist = require('minimist');
var console = require('console');
var path = require('path');
var TermColor = require('term-color');

var TypeChecker = require('../type-checker/').TypeChecker;

/*eslint no-process-exit: 0*/
module.exports = main;

function main(args) {
    var fileName = args._[0];
    if (!fileName) {
        console.warn('WARN: unknown fileName');
        return shortHelp();
    }

    var sourceFile = path.resolve(process.cwd(), fileName);
    var checker = new TypeChecker(sourceFile, {
        definitions: args.definitions || null,
        globalsFile: args.globals || null
    });

    /* eslint-disable no-restricted-syntax */
    try {
        checker.checkProgram();
    } catch (error) {
    /* eslint-enable no-restricted-syntax */
        console.log(TermColor.red('Fatal Exception: '), {
            message: error.message,
            stackLine: error.stack && error.stack.split('\n')[1]
        });

        var currMeta = checker.currentMeta;
        console.log('was processing the following text: ');
        console.log();
        console.log(TermColor.red(
            currMeta.serializeAST(currMeta.currentNode)
        ));
        console.log();
        console.log('on: ' + currMeta.fileName + ':' +
            currMeta.currentNode.loc.start.line);

        return process.exit(1);
    }

    if (checker.errors.length === 0) {
        console.log('No type errors');
        return process.exit(0);
    }

    console.log(checker.prettyPrintAllErrors());
    process.exit(1);
}

function shortHelp() {
    console.log('jsig [fileName]');
}

if (require.main === module) {
    main(minimist(process.argv.slice(2)));
}
<commit_msg>also print raw stack<commit_after>#!/usr/bin/env node
'use strict';

var process = global.process;
var minimist = require('minimist');
var console = require('console');
var path = require('path');
var TermColor = require('term-color');

var TypeChecker = require('../type-checker/').TypeChecker;

/*eslint no-process-exit: 0*/
module.exports = main;

function main(args) {
    var fileName = args._[0];
    if (!fileName) {
        console.warn('WARN: unknown fileName');
        return shortHelp();
    }

    var sourceFile = path.resolve(process.cwd(), fileName);
    var checker = new TypeChecker(sourceFile, {
        definitions: args.definitions || null,
        globalsFile: args.globals || null
    });

    /* eslint-disable no-restricted-syntax */
    try {
        checker.checkProgram();
    } catch (error) {
    /* eslint-enable no-restricted-syntax */
        console.log(TermColor.red('Fatal Exception: '), {
            message: error.message,
            stackLine: error.stack && error.stack.split('\n')[1],
            rawStack: error.stack.split('\n')
        });

        var currMeta = checker.currentMeta;
        console.log('was processing the following text: ');
        console.log();
        console.log(TermColor.red(
            currMeta.serializeAST(currMeta.currentNode)
        ));
        console.log();
        console.log('on: ' + currMeta.fileName + ':' +
            currMeta.currentNode.loc.start.line);

        return process.exit(1);
    }

    if (checker.errors.length === 0) {
        console.log('No type errors');
        return process.exit(0);
    }

    console.log(checker.prettyPrintAllErrors());
    process.exit(1);
}

function shortHelp() {
    console.log('jsig [fileName]');
}

if (require.main === module) {
    main(minimist(process.argv.slice(2)));
}
<|endoftext|>


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

function captureStream(stream) {
    var oldWrite = stream.write;
    var buf = '';
    stream.write = function (chunk, encoding, callback) {
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
    }

    return {
        unhook: function unhook() {
            stream.write = oldWrite;
        },
        captured: function () {
            return buf;
        }
    };
}

describe('helpers/args.js (Args Parse):\n', function (){
    var args = require('../../src/helpers/args');
    var startRes = '';
    var srartContext = '';
    var startArguments = [];

    args.command('start', 'start server', function(){
        startRes = 'ok';
        startContext = this;
        startArguments = arguments;
    });

    args.option('one', {
        alias: 'o'
    });

    args.option('port', {
        alias: 'p'
    });

    args.option('t', {
        alias: 'two'
    });

    args.option('sub-domains', {
        alias: 's'
    });

    args.option('P', {
        alias: 'output-path'
    });

    var argv =
          '/path/to/node /path/to/file start '
        + 'subcmd '
        + '--https '
        + '--port 5525 '
        + '--middle-man-port 10010 '
        + '-a '
        + '-b val '
        + '-s *.a.com,*.a.cn '
        + '-P /file/path/xxx '
        + 'subcmd1 '
        + '-def '
        + '-ot two_val';

    var _args = args.parse(argv.split(' '));

    describe('#parse()', function (){
        describe('正确解析 long option:', function (){
            it('--https ==> {https:true}', function (){
                assert.equal(true, _args.https);
            });

            it('--port 5525 ==> {port: "5525"}', function (){
                assert.equal('5525', _args.port);
            });

            it('--middle-man-port 10010 ==> {middleManPort: 10010}', function (){
                assert.equal('10010', _args.middleManPort);
            });
        });

        describe('正确解析 short option:', function (){
            it('-a ==> {a: true}', function (){
                assert.equal(true, _args.a);
            });

            it('-b val ==> {b: "val"}', function (){
                assert.equal('val', _args.b);
            });

            it('-def ==> {d: true, e: true, f: true}', function (){
                assert.ok(_args.d === true && _args.e === true && _args.f === true);
            });

            it('-ot two_val ==> {o: true, t: "two_val"}', function (){
                assert.ok(_args.o === true && _args.t === 'two_val');
            });
        });

        describe('正确处理 alias: ', function (){
            it('"-o, --one" ==> -o ==> {o: true, one: true}', function(){
                assert.ok(_args.one === _args.o && _args.one === true)
            });

            it('"-p, --port" ==> --port 5525 ==> {p: "5525", port: "5525"}', function(){
                assert.ok(_args.port === _args.p && _args.port === '5525')
            });

            it('"-t, --two" ==> -ot two_val ==> {t: "two_val", two: "two_val"}', function(){
                assert.ok(_args.two === _args.t && _args.t === 'two_val')
            });

            it('"-s, --sub-domains" ==> --sub-domains *.a.com ==> {s: "*.a.com,*.a.cn", subDomains: "*.a.com,*.a.cn"}', function(){
                assert.ok(_args.subDomains === _args.s && _args.s === '*.a.com,*.a.cn')
            });

            it('"--output-path, -P" ==> -P /file/path/xxx ==> {P: "*.a.com,*.a.cn", outputPath: "/file/path/xxx"}', function(){
                assert.ok(_args.outputPath === _args.P && _args.P === '/file/path/xxx')
            });
        });
    });

    describe('#exec callback', function (){
        it('正确执行 callback', function (){
            assert.equal("ok", startRes);
        });

        it('传入正确的参数', function (){
            assert.ok(
                startArguments.length === 2 &&
                startArguments[0] === 'subcmd' &&
                startArguments[1] === 'subcmd1'
            );
        });

        it('设置正确的上下文(this)', function (){
            assert.ok(startContext === _args);
        });
    });

    describe('#other', function(){
        var hook;
        beforeEach(function () {
            hook = captureStream(process.stdout);
        });
        afterEach(function () {
            hook.unhook();
        });

        it('print full help info', function(){
            args.parse('node cli.js --help'.split(' '));

            assert.ok(hook.captured().indexOf('full help info') !== -1)
        });

        it('print version info', function(){
            args.parse('node clis.js --version'.split(' '));

            assert.ok(hook.captured().indexOf('版本') !== -1)
        });

        it('print error message when cmd not exists', function(){
            args.parse('node clis.js test-cmd'.split(' '));

            assert.ok(hook.captured().indexOf('命令`test-cmd`不存在') !== -1);
        });

        it('cmd args error: "what <name>" ==> "node clis.js test"', function(){
            var name = '';
            args.command('what <name>', 'what name', function(_name){
                name = _name;
            })
            args.parse('node clis.js what'.split(' '));

            assert.ok(hook.captured().indexOf('参数个数不对') !== -1 && name === '');
        });

        it('cmd args ok: "what <name>" ==> "node clis.js test zdying" callback get arg "name"', function(){
            var name = '';
            args.command('what <name>', 'what name', function(_name){
                name = _name;
            })
            args.parse('node clis.js what zdying'.split(' '));

            assert.ok(name === 'zdying');
        });
    });
});<commit_msg>fix test<commit_after>var assert = require('assert');

function captureStream(stream) {
    var oldWrite = stream.write;
    var buf = '';
    stream.write = function (chunk, encoding, callback) {
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
    }

    return {
        unhook: function unhook() {
            stream.write = oldWrite;
        },
        captured: function () {
            return buf;
        }
    };
}

describe('helpers/args.js (Args Parse):\n', function (){
    var args = require('../../src/helpers/args');
    var startRes = '';
    var srartContext = '';
    var startArguments = [];

    args.command('start', 'start server', function(){
        startRes = 'ok';
        startContext = this;
        startArguments = arguments;
    });

    args.option('one', {
        alias: 'o'
    });

    args.option('port', {
        alias: 'p'
    });

    args.option('t', {
        alias: 'two'
    });

    args.option('sub-domains', {
        alias: 's'
    });

    args.option('P', {
        alias: 'output-path'
    });

    var argv =
          '/path/to/node /path/to/file start '
        + 'subcmd '
        + '--https '
        + '--port 5525 '
        + '--middle-man-port 10010 '
        + '-a '
        + '-b val '
        + '-s *.a.com,*.a.cn '
        + '-P /file/path/xxx '
        + 'subcmd1 '
        + '-def '
        + '-ot two_val';

    var _args = args.parse(argv.split(' '));

    describe('#parse()', function (){
        describe('正确解析 long option:', function (){
            it('--https ==> {https:true}', function (){
                assert.equal(true, _args.https);
            });

            it('--port 5525 ==> {port: "5525"}', function (){
                assert.equal('5525', _args.port);
            });

            it('--middle-man-port 10010 ==> {middleManPort: 10010}', function (){
                assert.equal('10010', _args.middleManPort);
            });
        });

        describe('正确解析 short option:', function (){
            it('-a ==> {a: true}', function (){
                assert.equal(true, _args.a);
            });

            it('-b val ==> {b: "val"}', function (){
                assert.equal('val', _args.b);
            });

            it('-def ==> {d: true, e: true, f: true}', function (){
                assert.ok(_args.d === true && _args.e === true && _args.f === true);
            });

            it('-ot two_val ==> {o: true, t: "two_val"}', function (){
                assert.ok(_args.o === true && _args.t === 'two_val');
            });
        });

        describe('正确处理 alias: ', function (){
            it('"-o, --one" ==> -o ==> {o: true, one: true}', function(){
                assert.ok(_args.one === _args.o && _args.one === true)
            });

            it('"-p, --port" ==> --port 5525 ==> {p: "5525", port: "5525"}', function(){
                assert.ok(_args.port === _args.p && _args.port === '5525')
            });

            it('"-t, --two" ==> -ot two_val ==> {t: "two_val", two: "two_val"}', function(){
                assert.ok(_args.two === _args.t && _args.t === 'two_val')
            });

            it('"-s, --sub-domains" ==> --sub-domains *.a.com ==> {s: "*.a.com,*.a.cn", subDomains: "*.a.com,*.a.cn"}', function(){
                assert.ok(_args.subDomains === _args.s && _args.s === '*.a.com,*.a.cn')
            });

            it('"--output-path, -P" ==> -P /file/path/xxx ==> {P: "*.a.com,*.a.cn", outputPath: "/file/path/xxx"}', function(){
                assert.ok(_args.outputPath === _args.P && _args.P === '/file/path/xxx')
            });
        });
    });

    describe('#exec callback', function (){
        it('正确执行 callback', function (){
            assert.equal("ok", startRes);
        });

        it('传入正确的参数', function (){
            assert.ok(
                startArguments.length === 2 &&
                startArguments[0] === 'subcmd' &&
                startArguments[1] === 'subcmd1'
            );
        });

        it('设置正确的上下文(this)', function (){
            assert.ok(startContext === _args);
        });
    });

    describe('#other', function(){
        var hook;
        beforeEach(function () {
            hook = captureStream(process.stdout);
        });
        afterEach(function () {
            hook.unhook();
        });

        it('print full help info', function(){
            args.parse('node cli.js --help'.split(' '));

            assert.ok(hook.captured().indexOf('full help info') !== -1)
        });

        it('print help info for cmd', function(){
            args.parse('node cli.js start --help'.split(' '));

            assert.ok(hook.captured().indexOf('help info for `start`') !== -1)
        });

        it('print version info', function(){
            args.parse('node clis.js --version'.split(' '));

            assert.ok(hook.captured().indexOf('版本') !== -1)
        });

        it('print error message when cmd not exists', function(){
            args.parse('node clis.js test-cmd'.split(' '));

            assert.ok(hook.captured().indexOf('命令`test-cmd`不存在') !== -1);
        });

        it('cmd args error: "what <name>" ==> "node clis.js test"', function(){
            var name = '';
            args.command('what <name>', 'what name', function(_name){
                name = _name;
            })
            args.parse('node clis.js what'.split(' '));

            assert.ok(hook.captured().indexOf('参数个数不对') !== -1 && name === '');
        });

        it('cmd args ok: "what <name> [age]" ==> "node clis.js test zdying" callback get arg "name"', function(){
            var name = '', age = 0;
            args.command('what <name> [age]', 'what name', function(_name, _age){
                name = _name;
                age = _age;
            })
            args.parse('node clis.js what zdying 23'.split(' '));

            assert.ok(name === 'zdying' && age === '23');
        });
    });
});<|endoftext|>


<commit_before>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /* TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently edited books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}});
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$addToSet:set});
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<commit_msg>callback error<commit_after>var mongodb = require('mongodb'),
    MongoClient = require('mongodb').MongoClient,
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server,
    BSON = require('mongodb').BSON,
    ObjectID = require('mongodb').ObjectID;

BookProvider = function(uri) {

  var that = this;
  mongodb.MongoClient.connect(uri, { server: { auto_reconnect: true } }, function (error, database) {
    if (error) console.log(error);
    that.db = database;
  });

  /* TO DEVELOP LOCALLY
      uncomment the following two lines
      comment out the beginning of this function
  */

  //this.db = new Db('books', new Server('localhost', 27017, {safe: false}, {auto_reconnect: true}, {}));
  //this.db.open(function(){});
};

//initialize info values
BookProvider.prototype.init = function(info, callback) {
  this.getCollection(function(error, book_collection) {
    if ( error ) callback(error);
    else {
      book_collection.insert({info:info}, function(error){
        if (error) callback(error);
        else callback(null);
      });
    }
  });
};

//delete book
BookProvider.prototype.delete = function(bookId, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.remove(
      {_id: book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
      function(error, book){
        if(error) callback(error);
        else callback(null, book)
      });
    }
  });
};

BookProvider.prototype.getCollection = function(callback) {
  this.db.collection('bks', function(error, book_collection) {
    if( error ) callback(error);
    else callback(null, book_collection);
  });
};

//find all books
BookProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find recently edited books
BookProvider.prototype.findRecentEdits = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({last_edit:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};
//find recently edited books
BookProvider.prototype.findRecentLogs = function(callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error);
      else {
        book_collection.find().sort({created_at:-1}).limit(8).toArray(function(error, results) {
          if( error ) callback(error);
          else callback(null, results);
        });
      }
    });
};

//find subset of books with tag
BookProvider.prototype.findTag = function(tag, callback) {
  this.getCollection(function(error, book_collection) {
    if(error) callback(error);
    else {
      book_collection.find({tags:tag}).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
    }
  });
};

//search all books
BookProvider.prototype.search = function(query, callback) {
  var name = query._field;
  var value = query._query;
  var dbQuery = {};
  dbQuery[name] = {$regex:value, $options:"-i"};
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.searchRefs = function(query, callback) {
  var name = query._field;
  var value = query._ref;
  var dbQuery = {};
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  dbQuery[name] = {$regex:value, $options:"-i"};
  console.log(JSON.stringify(dbQuery));
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browseRefs = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  if (query._refs != undefined) {
    var exclude = query._refs;
    if (exclude.constructor == Array) {
      for (var i = 0; i < exclude.length; i++) {
        var obj = new ObjectID(exclude[i]);
        exclude[i] = obj;
      }
      dbQuery = {_id:{$nin:exclude}};
    } else {
      exclude = new ObjectID(exclude);
      dbQuery = {_id:{$ne:exclude}};
    }
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};
//search books and return subset based on a feild and query (_ref)
BookProvider.prototype.browse = function(query, callback) {
  var dbQuery = {};
  var f = query._field;
  var q = query[query._field];
  if (f == "_fields") {
      dbQuery[query[query._field]] = {$exists:true};
  } else if (query._field == "_types") {
    dbQuery = {type:q};
  } else if (f == "_tags") {
    dbQuery = {tags:{$in:[q]}};
  }
  console.log(dbQuery);
  this.getCollection(function(error, book_collection) {
      book_collection.find(dbQuery).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

// get references from single book to display query from id
BookProvider.prototype.getRefs = function(refs, callback) {
  var query = {_id:{$in:[]}};
  for (var i = 0; i < refs.length; i++) {
    var objId = new ObjectID(refs[i].refId);
    query._id["$in"].push(objId);
  }
  this.getCollection(function(error, book_collection) {
      book_collection.find(query).toArray(function(error, results){
        if (error) callback(error);
        else callback(null, results);
      });
  });
};

//save new book
BookProvider.prototype.save = function(books, callback) {
    this.getCollection(function(error, book_collection) {
      if( error ) callback(error)
      else {
        if( typeof(books.length)=="undefined")
          books = [books];

        for( var i =0;i< books.length;i++ ) {
          book = books[i];
          book.created_at = new Date();
        }

        book_collection.insert(books, function() {
          callback(null, books);
        });
      }
    });
};

BookProvider.prototype.addType = function(type, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.update({info:{$exists:true}}, {$addToSet:{"info._types":type}});
    }
  });
};

// find a book by id
BookProvider.prototype.findById = function(id, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          book_collection.findOne({_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
            if (error) callback(error);
            else callback(null, result, info);
        });
      });
    }
  });
};

// get info
BookProvider.prototype.getInfo = function(callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
      book_collection.findOne({info:{$exists:true}}, function(error, info) {
          if (error) callback(error);
          else callback(null, info);
      });
    }
  });
};

// add a tag
BookProvider.prototype.addTag = function(query, set) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else book_collection.update(query, set);
  });
};

// referenced by add note
BookProvider.prototype.addReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId)};
  var set = { referencedBy: {}};
  set["referencedBy"] = {id:id, note:note, title:title};
  this.getCollection(function(error, book_collection){
    if (error) console.log("WAS callback error" + error);
    else {
      book_collection.update(query, {$addToSet:set});
    }
  });
};
// edit referenced by
BookProvider.prototype.editReferencedBy = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), referencedBy:{$elemMatch:{id:id}}};
  var set = {};
  set["referencedBy.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};
// edit reference
BookProvider.prototype.editRef = function(refId, id, title, note) {
  var query = {_id:new ObjectID(refId), refs:{$elemMatch:{id:id}}};
  var set = {};
  set["refs.$.note"] = note;
  this.getCollection(function(error, book_collection){
    if (error) callback(error);
    else {
      book_collection.update(query, {$set:set});
    }
  });
};

// update a book
BookProvider.prototype.update = function(bookId, books, callback) {
  this.getCollection(function(error, book_collection) {
    if (error) callback(error);
    else {
       book_collection.update(
          {_id:book_collection.db.bson_serializer.ObjectID.createFromHexString(bookId)},
          books,
          function(error, books) {
            if (error) callback(error);
            else callback(null, books);
          });
    }
  });
};

exports.BookProvider = BookProvider;<|endoftext|>


<commit_before>//Recuperer le contenu d'un fichier XML
Webos.XMLFile = function WXMLFile(path, callback) {
	var xmlCallback = new W.Callback(function(response) {
		var xmlDoc = $.parseXML(response.getStandardChannel());
		var xml = $(xmlDoc);
		callback.success(xml, xmlDoc);
	}, function(error) {
		callback.error(error);
	});
	new W.ServerCall({
		'class': 'FileController',
		'method': 'getContents',
		'arguments': { 'filename': path }
	}).load(xmlCallback);
};<commit_msg>Annulation de la suppression de la classe gerant le XML (les tableaux de bord de gnome dependent de cette bibliotheque).<commit_after>//Recuperer le contenu d'un fichier XML
Webos.XMLFile = function WXMLFile(path, callback) {
	var xmlCallback = new W.Callback(function(response) {
		var xmlDoc = $.parseXML(response.getStandardChannel());
		var xml = $(xmlDoc);
		callback.success(xml, xmlDoc);
	}, function(error) {
		callback.error(error);
	});
	new W.ServerCall({
		'class': 'FileController',
		'method': 'getContents',
		'arguments': { 'filename': path }
	}).load(xmlCallback);
};<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var parseArgs = require('minimist');
var template = require('string-template');
var msee = require('msee');

var Template = require('../index.js');

function printHelp(opts) {
    opts = opts || {};

    var loc = path.join(__dirname, 'usage.md');
    var content = fs.readFileSync(loc, 'utf8');

    content = template(content, {
        cmd: opts.cmd || 'uber-ngen',
        template: opts.template || 'uber',
        options: opts.usageOptions || '',
        defaults: opts.usageDefaults || '',
        directoryName: opts.directoryName || 'uber-ngen/templates'
    });

    return console.log(msee.parse(content, {
        paragraphStart: '\n'
    }));
}

function main(opts, callback) {
    // parse arguments
    if (opts.h || opts.help) {
        printHelp(opts);
        return callback();
    }

    opts.template = opts.t || opts.template || 'uber';
    opts.templates = opts.d || opts.directory ||
        path.join(__dirname, '..', 'templates');
    opts.name = opts.name || opts._[0];
    opts.description = opts.description || opts._[1];

    opts.logger = console;

    // create template
    var tmpl = new Template(opts.template, opts);
    tmpl.init(opts.name, callback);
}

module.exports = main;

if (require.main === module) {
    main(parseArgs(process.argv.slice(2)), function (err) {
        if (err) {
            console.error(err.message);
            return process.exit(1);
        }

        process.stdin.destroy();
    });
}
<commit_msg>default the callback<commit_after>#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var parseArgs = require('minimist');
var template = require('string-template');
var msee = require('msee');

var Template = require('../index.js');

module.exports = main;

function printHelp(opts) {
    opts = opts || {};

    var loc = path.join(__dirname, 'usage.md');
    var content = fs.readFileSync(loc, 'utf8');

    content = template(content, {
        cmd: opts.cmd || 'uber-ngen',
        template: opts.template || 'uber',
        options: opts.usageOptions || '',
        defaults: opts.usageDefaults || '',
        directoryName: opts.directoryName || 'uber-ngen/templates'
    });

    return console.log(msee.parse(content, {
        paragraphStart: '\n'
    }));
}

function main(opts, callback) {
    callback = callback || defaultCallback;

    // parse arguments
    if (opts.h || opts.help) {
        printHelp(opts);
        return callback();
    }

    opts.template = opts.t || opts.template || 'uber';
    opts.templates = opts.d || opts.directory ||
        path.join(__dirname, '..', 'templates');
    opts.name = opts.name || opts._[0];
    opts.description = opts.description || opts._[1];

    opts.logger = console;

    // create template
    var tmpl = new Template(opts.template, opts);
    tmpl.init(opts.name, callback);
}

function defaultCallback(err) {
    if (err) {
        console.error(err.message);
        return process.exit(1);
    }

    process.stdin.destroy();
}

if (require.main === module) {
    main(parseArgs(process.argv.slice(2)), defaultCallback);
}
<|endoftext|>


<commit_before>;(function(window, document, undefined){

  'use strict';

  var DEFAULTS = {},
      arrowKeys = [37, 38, 39, 40];

  function _extend( a, b ) {
    for ( var prop in b ) {
      if( b.hasOwnProperty(prop) ){
        a[ prop ] = b[ prop ];
      }
    }
    return a;
  }

  function _attachEvts( elem ){
    elem.addEventListener('keyup', _addDots, false);
    elem.addEventListener('paste', _addDots, false);
  }

  // Compare the original string with the generated one.
  // If the 2 strings length are identical (hence no new dot was added)
  // place the cursor at the same position it was placed in the beginning.
  // If the new string is longer put the cursor one place forward.
  // if it's shorter put it one place backwards.
  function _getSelectionEnd(len, newLen, curPos){
    if(len === newLen){
      return curPos;
    } else if(newLen > len){
      return curPos + 1;
    } else {
      return curPos - 1;
    }
  }

  function _addDots( e ) {
    // Don't execute anything if the user is just moving the cursor around and
    // not really enetring anything new.
    if(arrowKeys.indexOf(e.keyCode) !== -1){ return; }
    // keep track of the cursor position for later
    var cursorPos = this.selectionEnd,
        len = this.value.length,
        newLen;

    // remove the dots (and any non-integer character),
    // split the string and reverse it
    var a = this.value.replace(/\D/g,'').split('').reverse();

    // start from 3 and as long as there's a number
    // add a dot every three digits.
    var pos = 3;
    while(a[pos] !== undefined){
      a.splice(pos,0,'.');
      pos = pos + 4;
    }
    newLen = a.length;
    // reverse, join and reassign the value
    this.value = a.reverse().join('');

    this.selectionEnd = _getSelectionEnd(len, newLen, cursorPos);
    this.focus();
  }

  var Dotdot = function( node, opts ){

    if(!node){
      throw new Error('Dotdot needs an input element to be passed as a parameter');
    }

    if(opts){
      DEFAULTS = _extend(DEFAULTS, opts);
    }

    if(node.length !== undefined){
      Array.prototype.forEach.call(node, _attachEvts);
    } else {
      _attachEvts(node);
    }
  };

  window.Dotdot = Dotdot;

})(window, document);<commit_msg>rename a variable<commit_after>;(function(window, document, undefined){

  'use strict';

  var DEFAULTS = {},
      arrowKeys = [37, 38, 39, 40];

  function _extend( a, b ) {
    for ( var prop in b ) {
      if( b.hasOwnProperty(prop) ){
        a[ prop ] = b[ prop ];
      }
    }
    return a;
  }

  function _attachEvts( elem ){
    elem.addEventListener('keyup', _addDots, false);
    elem.addEventListener('paste', _addDots, false);
  }

  // Compare the original string with the generated one.
  // If the 2 strings length are identical (hence no new dot was added)
  // place the cursor at the same position it was placed in the beginning.
  // If the new string is longer put the cursor one place forward.
  // if it's shorter put it one place backwards.
  function _getSelectionEnd(len, newLen, cursorPos){
    if(len === newLen){
      return cursorPos;
    } else if(newLen > len){
      return cursorPos + 1;
    } else {
      return cursorPos - 1;
    }
  }

  function _addDots( e ) {
    // Don't execute anything if the user is just moving the cursor around and
    // not really enetring anything new.
    if(arrowKeys.indexOf(e.keyCode) !== -1){ return; }
    // keep track of the cursor position for later
    var cursorPos = this.selectionEnd,
        len = this.value.length,
        newLen;

    // remove the dots (and any non-integer character),
    // split the string and reverse it
    var a = this.value.replace(/\D/g,'').split('').reverse();

    // start from 3 and as long as there's a number
    // add a dot every three digits.
    var pos = 3;
    while(a[pos] !== undefined){
      a.splice(pos,0,'.');
      pos = pos + 4;
    }
    newLen = a.length;
    // reverse, join and reassign the value
    this.value = a.reverse().join('');

    this.selectionEnd = _getSelectionEnd(len, newLen, cursorPos);
    this.focus();
  }

  var Dotdot = function( node, opts ){

    if(!node){
      throw new Error('Dotdot needs an input element to be passed as a parameter');
    }

    if(opts){
      DEFAULTS = _extend(DEFAULTS, opts);
    }

    if(node.length !== undefined){
      Array.prototype.forEach.call(node, _attachEvts);
    } else {
      _attachEvts(node);
    }
  };

  window.Dotdot = Dotdot;

})(window, document);<|endoftext|>