<commit_before>'use strict';

let canvas = new fabric.Canvas('c', {'selection' : false});

let view = new View(canvas);
let defs = new Definitions(); // Node definitions
let graph = new Graph({defs : defs});

//=======//
// TOOLS //
//=======//

let canvas_resize_tool = new CanvasResizeTool(canvas);
canvas_resize_tool.activate();
window.dispatchEvent(new Event('resize'));

let gui = new GUI(graph, view);
let server_ip = _.getURLParameter('server');
let commlink = new CommLink(view, gui, graph,
                            server_ip ? server_ip : 'localhost');
graph.commlink = commlink;

new RightClickDisableTool();

let gui_tool = new GUITool(gui);
let pan_tool = new PanningTool(canvas);
let highlight_tool = new HighlightTool(canvas);
let marker_tool = new MarkerTool(gui, highlight_tool);
let zoom_tool = new ZoomTool(canvas);
let motion_tool = new ConnectorMotionTool(graph, view);
let connection_tool = new ConnectionTool(canvas, graph, view, marker_tool);

let keypress_tool = new KeyPressTool(graph, view, canvas,
                                     highlight_tool, zoom_tool, marker_tool);

keypress_tool.listen(); // Start listening for keystrokes
zoom_tool.mousezoom();  // Start zooming behavior

// Update GUI on select and highlight
canvas.on('object:selected', function(e) {
    gui_tool.object_selected(e);
    marker_tool.object_selected(e);
});

canvas.on('selection:cleared', function(e) {
    marker_tool.selection_cleared();
});

// Object move with connector update
canvas.on('object:moving', function(e) {
    motion_tool.object_moving(e);
});

canvas.on('object:scaling', function(e) {
    motion_tool.object_scaling(e);
});

// Hover selection
canvas.on('mouse:over', function(e) {
    highlight_tool.mouse_over(e);
});

canvas.on('mouse:out', function(e) {
    highlight_tool.mouse_out(e);
});

// Panning
canvas.on('mouse:up', function (e) {
    pan_tool.mouse_up();
    connection_tool.mouse_up(e);
});
canvas.on('mouse:down', function (e) {
    pan_tool.mouse_down(e);
    connection_tool.mouse_down(e);
});
canvas.on('mouse:move', function (e) {
    pan_tool.mouse_move(e);
    connection_tool.mouse_move(e);
});
<commit_msg>Updated docs in main.js<commit_after>'use strict';
// ### Introduction
//
// In this file, instances of ``View``, ``Definitions``, ``Graph``,
// ``Commlink`` and ``GUI`` are created and linked up appropriately.
//
// Once these are created, the tools are also instantiated and hooked up
// to the appropriate events.

let canvas = new fabric.Canvas('c', {'selection' : false});

let view = new View(canvas);
let defs = new Definitions(); // Start with empty definitions
let graph = new Graph({defs : defs});

let canvas_resize_tool = new CanvasResizeTool(canvas);
canvas_resize_tool.activate();
window.dispatchEvent(new Event('resize'));

let gui = new GUI(graph, view);
let server_ip = _.getURLParameter('server');
let commlink = new CommLink(view, gui, graph,
                            server_ip ? server_ip : 'localhost');
graph.commlink = commlink;

// ### Tools
//
// Some of these tools are linked: for instance KeyPressTool needs to
// know what is highlighted to delete the right thing on 'Backspace'/'d'

new RightClickDisableTool();

let gui_tool = new GUITool(gui);
let pan_tool = new PanningTool(canvas);
let highlight_tool = new HighlightTool(canvas);
let marker_tool = new MarkerTool(gui, highlight_tool);
let zoom_tool = new ZoomTool(canvas);
let motion_tool = new ConnectorMotionTool(graph, view);
let connection_tool = new ConnectionTool(canvas, graph, view, marker_tool);

let keypress_tool = new KeyPressTool(graph, view, canvas,
                                     highlight_tool, zoom_tool, marker_tool);

keypress_tool.listen(); // Start listening for keystrokes
zoom_tool.mousezoom();  // Start zooming behavior

canvas.on('object:selected', function(e) {
    gui_tool.object_selected(e);
    marker_tool.object_selected(e);
});

canvas.on('selection:cleared', function(e) {
    marker_tool.selection_cleared();
});

canvas.on('object:moving', function(e) {
    motion_tool.object_moving(e);
});

canvas.on('object:scaling', function(e) {
    motion_tool.object_scaling(e);
});

canvas.on('mouse:over', function(e) {
    highlight_tool.mouse_over(e);
});

canvas.on('mouse:out', function(e) {
    highlight_tool.mouse_out(e);
});

canvas.on('mouse:up', function (e) {
    pan_tool.mouse_up();
    connection_tool.mouse_up(e);
});

canvas.on('mouse:down', function (e) {
    pan_tool.mouse_down(e);
    connection_tool.mouse_down(e);
});

canvas.on('mouse:move', function (e) {
    pan_tool.mouse_move(e);
    connection_tool.mouse_move(e);
});
<|endoftext|>


<commit_before>const HTTP = require("./http");
const create = Object.create;
const define = Object.defineProperties;
const GitHub$internal = new WeakMap();

/**
 * Connection to GitHub repository.
 * @param {string} repo
 * @param {Credentials} creds
 * @returns {GitHub}
 */
function github(repo, creds) {
    var github = create(GitHub);

    GitHub$internal.set(github, {
        repo: repo,
        creds: creds
    });
}

/**
 * Read response body.
 * @param {object} res
 * @returns {object}
 */
function readbody(res) {
    if (res.status === 200) return res.body;
    if (res.status === 404) return null;
    throw new Error(`unexpected ${res.status} status`);
}

const GitHub = {
    /**
     * Return full URI for GitHub resource URI.
     * @param {string} uri
     * @returns {string}
     */
    url: function(uri) {
        return /^https?:/.test(uri) ? uri : `${this.endpoint}/${uri}`;
    },

    /**
     * Lookup branch info.
     * @param {string} branch
     * @returns {Promise}
     */
    branch: function(branch) {
        var url = this.url(`branches/${branch}`),
            headers = this.headers();

        return HTTP.get(url, headers).then(readbody);
    },

    /**
     * Compare references.
     * @param {string} refa
     * @param {string} refb
     */
    compare: function(refa, refb) {
        var url = this.url(`compare/${refa}...${refb}`),
            headers = this.headers();

        return HTTP.get(url, headers).then(readbody);
    }
};

define(GitHub, {
    /**
     * GitHub owner/repo.
     * @name GitHub#repo
     * @type {string}
     * @readonly
     */
    repo: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).repo;}
    },

    /**
     * GitHub credentials.
     * @name GitHub#creds
     * @type {Credentials}
     * @readonly
     */
    creds: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).creds;}
    },

    /**
     * GitHub API endpoint for repo.
     * @name GitHub#endpoint
     * @type {string}
     * @readonly
     */
    endpoint: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).endpoint;}
    }
});

module.exports = github;
module.exports.GitHub = GitHub;
<commit_msg>github base and build options<commit_after>const HTTP = require("./http");
const create = Object.create;
const define = Object.defineProperties;
const GitHub$internal = new WeakMap();

/**
 * Create GitHub API object.
 * @param {string} repo
 * @param {Credentials} creds
 * @param {string} [base="master"]
 * @param {string} [build="jitrub"]
 * @returns {GitHub}
 */
function github(repo, creds, base, build) {
    var github = create(GitHub);

    GitHub$internal.set(github, {
        repo: repo,
        creds: creds,
        base: base ? String(base) : "master",
        build: build ? String(build) : "jitrub"
    });
}

/**
 * Return HTTP headers to send with GitHub API requests.
 * @param {GitHub} github
 * @returns {object}
 */
function headers(github) {
    var creds = GitHub$internal.get(github).creds,
        auth = HTTP.auth(creds.ident, creds.secret),
        ua = HTTP.ua(creds.ident);

    return assign(ua, auth);
}

/**
 * Read response body.
 * @param {object} res
 * @returns {object}
 */
function readbody(res) {
    if (res.status === 200) return res.body;
    if (res.status === 404) return null;
    throw new Error(`unexpected ${res.status} status`);
}

const GitHub = {
    /**
     * Return full URI for GitHub resource URI.
     * @param {string} uri
     * @returns {string}
     */
    url: function(uri) {
        return /^https?:/.test(uri) ? uri : `${this.endpoint}/${uri}`;
    },

    /**
     * Lookup branch info.
     * @param {string} branch
     * @returns {Promise}
     */
    branch: function(branch) {
        var url = this.url(`branches/${branch}`);
        return HTTP.get(url, headers(this)).then(readbody);
    },

    /**
     * Compare references.
     * @param {string} refa
     * @param {string} refb
     */
    compare: function(refa, refb) {
        var url = this.url(`compare/${refa}...${refb}`);
        return HTTP.get(url, headers(this)).then(readbody);
    }
};

define(GitHub, {
    /**
     * GitHub owner/repo.
     * @name GitHub#repo
     * @type {string}
     * @readonly
     */
    repo: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).repo;}
    },

    /**
     * GitHub credentials.
     * @name GitHub#creds
     * @type {Credentials}
     * @readonly
     */
    creds: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).creds;}
    },

    /**
     * Base branch at which to start builds.
     * @name GitHub#base
     * @type {string}
     * @readonly
     */
    base: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).base;}
    },

    /**
     * Build branch which will be set to latest build.
     * @name GitHub#build
     * @type {string}
     * @readonly
     */
    build: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).build;}
    },

    /**
     * GitHub API endpoint for repo.
     * @name GitHub#endpoint
     * @type {string}
     * @readonly
     */
    endpoint: {
        configurable: true,
        enumerable: true,
        get: function() {return GitHub$internal.get(this).endpoint;}
    }
});

module.exports = github;
module.exports.GitHub = GitHub;
<|endoftext|>


<commit_before>/*
 * openi_data_api
 * openi-ict.eu
 *
 * Copyright (c) 2013 dmccarthy
 */

'use strict';

var openiLogger  = require('openi-logger');
var openiUtils   = require('openi-cloudlet-utils');
var zmq          = require('m2nodehandler');
var querystring  = require('querystring');
var https        = require('https');
var loglet      = require('loglet');
loglet = loglet.child({component: 'type-api'});

var allowedTypes = ['boolean', 'int', 'float', 'string', 'url', 'attachment', 'date', 'timestamp', 'hexadecimal', 'base64'];

var init = function(logger_params) {
   this.logger = openiLogger(logger_params);
};

var validateType = function(msg, callback) {

   var type     = msg.json
   var subTypes = []
   var errs     = []

   if ( !('@reference' in  type) || '' === type['@reference']) {
      errs.push('Required property @reference is missing.')
   }
   if ( !('@context' in  type) || !Array.isArray(type['@context']) || 0 === type['@context'].length ){
      errs.push('Required property @context is missing.')
   }

   for ( var i in type['@context']) {

      if(type['@context'].hasOwnProperty(i)) {
         var entry = type['@context'][i];
         var name  = entry['@property_name']

         if ( !('@property_name' in  entry) || '' === entry['@property_name']) {
            errs.push('In \'' + name + '\' required parameter @property_name is missing.')
         }

         if ( !('@context_id' in  entry) || '' === entry['@context_id']) {
            errs.push('In \'' + name + '\' required parameter @context_id is missing.')
         }

         if ( !( '@openi_type' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @openi_type is missing.')
         }

         if ( !( '@required' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @required is missing.')
         }

         if ( !( '@multiple' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @multiple is missing.')
         }

         if ( '@allowed_values' in entry ) {
            if ( Object.prototype.toString.call( entry['@allowed_values'] ) !== '[object Array]' || 0 === entry['@allowed_values'].length ){
               errs.push('In \'' + name + '\' @allowed_values array is empty')
            }
            else{
               var type = entry['@openi_type']
               for (var allowed_entry in entry['@allowed_values']){
                  //use validator to check that allowed_entry is of apt type
               }
            }
         }

         if (undefined === entry['@openi_type'] || -1 === allowedTypes.indexOf(entry['@openi_type'].toLowerCase())) {

            var type_val = entry['@openi_type']

            if ( openiUtils.isTypeId(type_val) ){
               subTypes.push(type_val)
            }
            else{
               errs.push(entry['@openi_type'].toLowerCase() + ' is not a valid type.')
            }
         }
      }
   }

   if (errs.length > 0){
      callback( {valid:false, errors:errs});
      loglet.error(errs);
   }
   else if (0 === subTypes.length){
      callback( {valid:true})
   }
   else{
      var type_val = subTypes.pop()
      validateSubType(msg, type_val, subTypes, callback)
   }
};

var validateSubType = function(msg, type_id, subTypes, callback){

   var type = "https://" + msg.headers.host + "/api/v1/types/" + type_id

   var request = https.get(type, function(res) {

      var typeStr2 = '';

      res.on('data', function (chunk) {
         typeStr2 += chunk;
      });

      res.on('end', function () {

         var type_json = {}

         try{
            type_json = JSON.parse(typeStr2);
         }
         catch(e){
            loglet.error(e);
            return callback( {valid:false, error:[ type + ' cannot be found.']});
         }

         if (type_json["@id"] == type_id ){
            if (subTypes.length > 0){
               var new_type = subTypes.pop()
               validateSubType(msg, new_type, subTypes, callback)
            }
            else{
               return callback( {valid:true})
            }
         }
         else{
            return callback( {valid:false, error:[ type + ' is not a valid type.']});
         }
      });

   }).on('error', function(e) {
         loglet.error(e);
         return  callback( {valid:false, error:[ type + ' is not a valid type.' ]});
      }).setTimeout( 5000, function( ) {
         return callback( {valid:false, error:[ type + ' could not be found.']});
      });
}

var genPostMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   if (undefined === msg.json || null === msg.json){

      senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Empty body.' });

      return;
   }

   var typeId = 't_' + openiUtils.hash(msg.json);

   var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + typeId;

   msg.json['@id']            = typeId;
   msg.json['@location']      = typeRestUrl;
   msg.json['_date_created'] = new Date().toJSON();

   validateType(msg, function(validCheck){

      if (!validCheck.valid) {

         var errorString = (undefined === validCheck.errors)  ? "" : validCheck.errors.join(" ")

         senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type object isn\'t properly structured : ' + errorString});

         return;
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'POST',
               'database'    : typeId,
               'object_name' : 'meta',
               'object_data' : msg.json,
               'id'          : typeId
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   });

};

var genGetMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   var query = querystring.parse(msg.headers.QUERY);

   if ( msg.path === '/api/v1/types' ) {

      var limit  = (undefined !== query.limit)  ? Number(query.limit)   : 30
      var offset = (undefined !== query.offset) ? Number(query.offset)  :  0
      var prev   = msg.headers.URI.replace("offset="+offset, "offset="+ (((offset - limit) < 0) ? 0 : (offset - limit)))
      var next   = msg.headers.URI.replace("offset="+offset, "offset="+ (offset + limit))

      var meta = {
         "limit"       : limit,
         "offset"      : offset,
         "total_count" : 0,
         "prev"        : (0 === offset)? null : prev,
         "next"        : next
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_list',
               'meta'         : meta,
               'filter_show'  : query['only_show_properties'],
               'content-type' : query['content-type'],
               'resp_type'    : 'type',
               'id_only'      : ('true' === query.id_only)
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   } else if ( msg.path === '/api/v1/types/stats' ) {

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_usage',
               'group'        : true,
               'resp_type'    : 'type_stats'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   } else {

      var type =   openiUtils.extractTypeId(msg.path)

      var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + type;

      senderToDao.send({
         'dao_actions'      : [
            {
               'action' : 'GET',
               'database': type,
               'id' : type,
               'content-type' : query['content-type'],
               'resp_type'    : 'type'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   }
};

var genPatchMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   return senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Feature temporarily disabled' });

   if (undefined === msg.json || null === msg.json) {

      senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type array is empty' });

      return;
   }

   var actions = [];

   for ( var i =0; i < msg.json.length; i++) {
      var entry       = msg[i];
      var typeId      = 't_' + openiUtils.hash(entry);
      var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + typeId;

      if (!validateType(entry)) {

         senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type object isn\'t properly structured' });

         return;
      }

      entry['@id']            = typeId;
      entry['@location']      = typeRestUrl;
      entry['_date_created'] = new Date().toJSON();

      actions.push({
         'action'      : 'POST',
         'database'    : typeId,
         'object_name' : 'meta',
         'object_data' : entry,
         'id'          : typeId,
         'resp_type'   : 'type'
      });
   }

   senderToDao.send({
      'dao_actions'  : actions,
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {
            'uuid' : msg.uuid,
            'connId' : msg.connId
         }
      ]
   });
};

var processMongrel2Message = function (msg, senderToDao, senderToClient, terminal_handler) {

   this.logger.logMongrel2Message(msg);

   for(var key in msg.json) {
      if(msg.json.hasOwnProperty(key)) {
         if(msg.json[key] === null) {
            delete msg.json[key];
         }
      }
   }

   switch(msg.headers['METHOD']) {
      case 'POST':
         genPostMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      case 'GET':
         genGetMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      case 'PATCH':
         genPatchMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      default:
         break;
   }
};

module.exports.init                   = init;
module.exports.processMongrel2Message = processMongrel2Message;<commit_msg>Added permissions backend and refactored couchbase client code<commit_after>/*
 * openi_data_api
 * openi-ict.eu
 *
 * Copyright (c) 2013 dmccarthy
 */

'use strict';

var openiLogger  = require('openi-logger');
var openiUtils   = require('openi-cloudlet-utils');
var zmq          = require('m2nodehandler');
var querystring  = require('querystring');
var https        = require('https');
var loglet      = require('loglet');
loglet = loglet.child({component: 'type-api'});

var allowedTypes = ['boolean', 'int', 'float', 'string', 'url', 'attachment', 'date', 'timestamp', 'hexadecimal', 'base64'];

var init = function(logger_params) {
   this.logger = openiLogger(logger_params);
};

var validateType = function(msg, callback) {

   var type     = msg.json
   var subTypes = []
   var errs     = []

   if ( !('@reference' in  type) || '' === type['@reference']) {
      errs.push('Required property @reference is missing.')
   }
   if ( !('@context' in  type) || !Array.isArray(type['@context']) || 0 === type['@context'].length ){
      errs.push('Required property @context is missing.')
   }

   for ( var i in type['@context']) {

      if(type['@context'].hasOwnProperty(i)) {
         var entry = type['@context'][i];
         var name  = entry['@property_name']

         if ( !('@property_name' in  entry) || '' === entry['@property_name']) {
            errs.push('In \'' + name + '\' required parameter @property_name is missing.')
         }

         if ( !('@context_id' in  entry) || '' === entry['@context_id']) {
            errs.push('In \'' + name + '\' required parameter @context_id is missing.')
         }

         if ( !( '@openi_type' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @openi_type is missing.')
         }

         if ( !( '@required' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @required is missing.')
         }

         if ( !( '@multiple' in entry) ) {
            errs.push('In \'' + name + '\' required parameter @multiple is missing.')
         }

         if ( '@allowed_values' in entry ) {
            if ( Object.prototype.toString.call( entry['@allowed_values'] ) !== '[object Array]' || 0 === entry['@allowed_values'].length ){
               errs.push('In \'' + name + '\' @allowed_values array is empty')
            }
            else{
               var type = entry['@openi_type']
               for (var allowed_entry in entry['@allowed_values']){
                  //use validator to check that allowed_entry is of apt type
               }
            }
         }

         if (undefined === entry['@openi_type'] || -1 === allowedTypes.indexOf(entry['@openi_type'].toLowerCase())) {

            var type_val = entry['@openi_type']

            if ( openiUtils.isTypeId(type_val) ){
               subTypes.push(type_val)
            }
            else{
               errs.push(entry['@openi_type'].toLowerCase() + ' is not a valid type.')
            }
         }
      }
   }

   if (errs.length > 0){
      callback( {valid:false, errors:errs});
      loglet.error(errs);
   }
   else if (0 === subTypes.length){
      callback( {valid:true})
   }
   else{
      var type_val = subTypes.pop()
      validateSubType(msg, type_val, subTypes, callback)
   }
};

var validateSubType = function(msg, type_id, subTypes, callback){

   var type = "https://" + msg.headers.host + "/api/v1/types/" + type_id

   var request = https.get(type, function(res) {

      var typeStr2 = '';

      res.on('data', function (chunk) {
         typeStr2 += chunk;
      });

      res.on('end', function () {

         var type_json = {}

         try{
            type_json = JSON.parse(typeStr2);
         }
         catch(e){
            loglet.error(e);
            return callback( {valid:false, error:[ type + ' cannot be found.']});
         }

         if (type_json["@id"] == type_id ){
            if (subTypes.length > 0){
               var new_type = subTypes.pop()
               validateSubType(msg, new_type, subTypes, callback)
            }
            else{
               return callback( {valid:true})
            }
         }
         else{
            return callback( {valid:false, error:[ type + ' is not a valid type.']});
         }
      });

   }).on('error', function(e) {
         loglet.error(e);
         return  callback( {valid:false, error:[ type + ' is not a valid type.' ]});
      }).setTimeout( 5000, function( ) {
         return callback( {valid:false, error:[ type + ' could not be found.']});
      });
}

var genPostMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   if (undefined === msg.json || null === msg.json){

      senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Empty body.' });

      return;
   }

   var typeId = 't_' + openiUtils.hash(msg.json);

   var typeRestUrl = "/api/v1/types/" + typeId;

   msg.json['@id']            = typeId;
   msg.json['@location']      = typeRestUrl;
   msg.json['_date_created'] = new Date().toJSON();

   validateType(msg, function(validCheck){

      if (!validCheck.valid) {

         var errorString = (undefined === validCheck.errors)  ? "" : validCheck.errors.join(" ")

         senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type object isn\'t properly structured : ' + errorString});

         return;
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'      : 'POST',
               'database'    : typeId,
               'object_name' : 'meta',
               'object_data' : msg.json,
               'id'          : typeId,
               'bucket'      : 'types'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   });
};

var genGetMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   var query = querystring.parse(msg.headers.QUERY);

   if ( msg.path === '/api/v1/types' ) {

      var limit  = (undefined !== query.limit)  ? Number(query.limit)   : 30
      var offset = (undefined !== query.offset) ? Number(query.offset)  :  0
      var prev   = msg.headers.URI.replace("offset="+offset, "offset="+ (((offset - limit) < 0) ? 0 : (offset - limit)))
      var next   = msg.headers.URI.replace("offset="+offset, "offset="+ (offset + limit))

      var meta = {
         "limit"       : limit,
         "offset"      : offset,
         "total_count" : 0,
         "prev"        : (0 === offset)? null : prev,
         "next"        : next
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_list',
               'meta'         : meta,
               'filter_show'  : query['only_show_properties'],
               'content-type' : query['content-type'],
               'resp_type'    : 'type',
               'id_only'      : ('true' === query.id_only),
               'bucket'       : 'types'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   } else if ( msg.path === '/api/v1/types/stats' ) {

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_usage',
               'group'        : 0,
               'resp_type'    : 'type_stats',
               'bucket'       : 'types'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   } else {

      var type =   openiUtils.extractTypeId(msg.path)

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'GET',
               'database'     : type,
               'id'           : type,
               'content-type' : query['content-type'],
               'resp_type'    : 'type',
               'bucket'       : 'types'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {
               'uuid' : msg.uuid,
               'connId' : msg.connId
            }
         ]
      });
   }
};

var genPatchMessage = function(msg, senderToDao, senderToClient, terminal_handler) {

   return senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Feature temporarily disabled' });

   if (undefined === msg.json || null === msg.json) {

      senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type array is empty' });

      return;
   }

   var actions = [];

   for ( var i =0; i < msg.json.length; i++) {
      var entry       = msg[i];
      var typeId      = 't_' + openiUtils.hash(entry);
      var typeRestUrl = "/api/v1/types/" + typeId;

      if (!validateType(entry)) {

         senderToClient.send(msg.uuid, msg.connId, zmq.status.BAD_REQUEST_400, zmq.standard_headers.json, {'error' : 'Type object isn\'t properly structured' });

         return;
      }

      entry['@id']            = typeId;
      entry['@location']      = typeRestUrl;
      entry['_date_created']  = new Date().toJSON();

      actions.push({
         'action'      : 'POST',
         'database'    : typeId,
         'object_name' : 'meta',
         'object_data' : entry,
         'id'          : typeId,
         'resp_type'   : 'type',
         'bucket'      : 'types'
      });
   }

   senderToDao.send({
      'dao_actions'  : actions,
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {
            'uuid' : msg.uuid,
            'connId' : msg.connId
         }
      ]
   });
};

var processMongrel2Message = function (msg, senderToDao, senderToClient, terminal_handler) {

   this.logger.logMongrel2Message(msg);

   for(var key in msg.json) {
      if(msg.json.hasOwnProperty(key)) {
         if(msg.json[key] === null) {
            delete msg.json[key];
         }
      }
   }

   switch(msg.headers['METHOD']) {
      case 'POST':
         genPostMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      case 'GET':
         genGetMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      case 'PATCH':
         genPatchMessage(msg, senderToDao, senderToClient, terminal_handler);
         break;
      default:
         break;
   }
};

module.exports.init                   = init;
module.exports.processMongrel2Message = processMongrel2Message;<|endoftext|>


<commit_before>var chalk              = require('chalk');
var log                = require('./utils/log');

var es                 = require('event-stream');
var vfs                = require('vinyl-fs');
var path               = require('path');
var EventEmitter       = require('event-emitter');

var Environment        = require('./environment');
var ExtensionRewriter    = require('./extensionRewriter');
var streamHelper       = require('./utils/stream');
var ProcessorStore     = require('./processorStore');

var defaultProcessors  = require('./defaultProcessors');
var defaultExtensionMap = require('./defaultExtensionMap');

var directiveStream    = require('./directiveStream');
var orderedMergeStream = require('./orderedMergeStream');

var help               = require('./utils/help');

var buildTask          = require('./tasks/build');
var cleanTask          = require('./tasks/clean');
var serverTask         = require('./tasks/server');

var Lingon = function(rootPath, argv) {
  this.eventEmitter = new EventEmitter();

  this.rootPath = rootPath;
  this.defaultTask = null;

  this.sourcePath = 'source';
  this.buildPath = 'build';

  //Expose the cli arguments to plugins
  this.argv = argv;

  this.server = null;

  // Backwards compatibility with old
  // lingon.js file formats.
  this.mode = this.task = null;

  this.taskCallbacks = {};
  this.taskQueue = [];

  this.global = {};

  // Keep a map of source => output files for the
  // server to use when requesting a certain URL.
  this.outputMap = [];

  this.validDirectiveFileTypes = ['.js', '.less', '.css', '.ejs', '.html', '.md'];

  this.preProcessor = new ProcessorStore(defaultProcessors.pre);
  this.postProcessor = new ProcessorStore(defaultProcessors.post);
  this.extensionRewriter = new ExtensionRewriter(defaultExtensionMap);

  // expose logger to plugins
  this.log = log;

  // Set up default tasks
  buildTask(this);
  serverTask(this);
  cleanTask(this);

  // Set up default help
  help.describe('help', {
    message: 'Shows this list'
  });

  help.describe('version', {
    message: 'Display Lingon version'
  });
};

Lingon.IGNORE_PREFIX_PATTERN = new RegExp('\/_');

Lingon.prototype.getEnvironment = function() {
  if(!this.__environment) {
    this.__environment = new Environment({
      rootPath: this.rootPath,
      sourcePath: this.sourcePath,
      ignorePrefixPattern: this.IGNORE_PREFIX_PATTERN
    });
  }

  return this.__environment;
};

Lingon.prototype.registerTask = function(task, callback, description) {
  help.describe(task, description);

  this.taskCallbacks[task] = function() {
    callback.call(this, function() {
      this.task = null;
      this.run();
    }.bind(this));
  }.bind(this);
};

Lingon.prototype.prepareOutputMap = function() {
  var _this = this;
  var sourceFiles = this.getEnvironment().getSourceFiles();

  sourceFiles.forEach(function(sourceFile){
    var sourceFilename = sourceFile.path.replace(_this.sourcePath + "/", "");
    var destFilename = _this.extensionRewriter.transform(sourceFilename, [_this.preProcessor, _this.postProcessor]);

    _this.outputMap[destFilename] = sourceFilename;
  });
};

Lingon.prototype.run = function(tasks) {
  if(tasks) {
    this.taskQueue = this.taskQueue.concat(tasks);
  }
  if(this.task) { return; }

  var task = this.taskQueue.shift();
  if(task) {
    var taskCallback = this.taskCallbacks[task];

    if(!taskCallback) {
      log(chalk.red('Error: Unknown task "' + task + '"'));
      return;
    }

    this.task = task;
    taskCallback.call(this);
  }
};

Lingon.prototype.build = function(callback, requestPaths) {
  var _this = this;
  requestPaths = requestPaths || [];

  this.trigger('beforeBuild');

  var sourceMappings = requestPaths.map(function(requestPath){
    return _this.outputMap[requestPath] || requestPath;
  });

  var sourceFiles = this.getEnvironment().getSourceFiles(sourceMappings);

  var cache = {};

  // Start a directiveStream for each sourceFile
  sourceFiles.forEach(function(sourceFile) {
    var vinylStream = vfs.src(sourceFile.path);

    sourceFile.stream = vinylStream.pipe(
      directiveStream({
        rootPath: _this.rootPath,
        sourcePath: _this.sourcePath,
        directiveFileTypes: _this.validDirectiveFileTypes,
        preProcessor: _this.preProcessor,
        global: _this.global,
        cache: cache,
        extensionRewriter: _this.extensionRewriter,
        directiveStream: directiveStream
      })
    );
  });

  // If no files are found, let's callback to allow the server
  // to process the next middleware (if the server is running).
  if(sourceFiles.length === 0) {
    if(!!callback) {
      var emptyFileBuffer = [];
      for(var i = requestPaths.length; i--;) {
        emptyFileBuffer.push(null);
      }
      callback( emptyFileBuffer );
    }

    return;
  }

  // If we have source files, let's create streams to process them.
  var outputStreams = sourceFiles.map(function(sourceFile) {
    return _this.postProcess(sourceFile);
  });

  var allStreams = es.concat.apply(_this, outputStreams);

  if(!!callback) {
    var fileBuffer = {};

    allStreams.on('data', function(file) {
      var buildPath = path.join(_this.rootPath, _this.buildPath);
      var relativePath = path.relative(buildPath, file.path);

      fileBuffer[relativePath] = file ;
    });
    allStreams.on('end', function() {
      var fileBufferSorted = [];
      for(var i = requestPaths.length; i--;) {
        fileBufferSorted[i] = fileBuffer[ requestPaths[i] ] || null;
      }

      callback( fileBufferSorted );
    });
  }

  this.trigger('afterBuild', { requestPaths: requestPaths });

};

Lingon.prototype.postProcess = function(sourceFile) {
  var _this = this;

  var sourcePath = sourceFile.path;
  var sourceFilename = path.basename(sourcePath);
  var destFilename = _this.extensionRewriter.transform(sourceFilename, [_this.preProcessor, _this.postProcessor]);

  var destFilePath = path.dirname(sourceFile.path.replace(_this.sourcePath, _this.buildPath));

  var stream = sourceFile.stream;
  var pipes = [];
  var postConcatPipes = [];

  postConcatPipes = postConcatPipes.concat(
    streamHelper.pipesForFileExtensions(
      sourceFile.name,
      _this.postProcessor,
      _this.global));

  // Queue the postConcatPipes (less, compression, etc)
  pipes = pipes.concat(postConcatPipes);

  // Queue the inspect pipe, rewrite the output filename
  var inspect = function(file, cb) {
    var filename = path.basename(file.path);
    file.path = file.path.replace(filename, destFilename);

    cb(null, file);
  };

  pipes.push(es.map(inspect));

  // Queue the output pipe
  pipes.push(vfs.dest(destFilePath));

  log(chalk.green(sourceFile.path, "->", path.join(destFilePath, destFilename)));

  // Apply all pipes to stream
  stream = streamHelper.applyPipes(stream, pipes);

  return stream;
};

Lingon.prototype.bind = Lingon.prototype.on = function() {
  this.eventEmitter.on.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.unbind = Lingon.prototype.off = function() {
  this.eventEmitter.off.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.one = function() {
  this.eventEmitter.once.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.trigger = function() {
  this.eventEmitter.emit.apply(this.eventEmitter, [].slice.call(arguments));
};

module.exports = Lingon;
<commit_msg>Core: Brought back the lingon.context object as an alias to the new lingon.global object.<commit_after>var chalk              = require('chalk');
var log                = require('./utils/log');

var es                 = require('event-stream');
var vfs                = require('vinyl-fs');
var path               = require('path');
var EventEmitter       = require('event-emitter');

var Environment        = require('./environment');
var ExtensionRewriter    = require('./extensionRewriter');
var streamHelper       = require('./utils/stream');
var ProcessorStore     = require('./processorStore');

var defaultProcessors  = require('./defaultProcessors');
var defaultExtensionMap = require('./defaultExtensionMap');

var directiveStream    = require('./directiveStream');
var orderedMergeStream = require('./orderedMergeStream');

var help               = require('./utils/help');

var buildTask          = require('./tasks/build');
var cleanTask          = require('./tasks/clean');
var serverTask         = require('./tasks/server');

var Lingon = function(rootPath, argv) {
  this.eventEmitter = new EventEmitter();

  this.rootPath = rootPath;
  this.defaultTask = null;

  this.sourcePath = 'source';
  this.buildPath = 'build';

  //Expose the cli arguments to plugins
  this.argv = argv;

  this.server = null;

  // Backwards compatibility with old
  // lingon.js file formats.
  this.mode = this.task = null;

  this.taskCallbacks = {};
  this.taskQueue = [];

  // TODO: Temporary - Remove in 2.0.0!
  // Temporary fix: context was renamed to global for the upcoming 2.0.0 release
  // but the commit ended up on master since other changes depended
  // on it. Remove this in 2.0.0
  this.context = {};

  this.global = {};

  // Keep a map of source => output files for the
  // server to use when requesting a certain URL.
  this.outputMap = [];

  this.validDirectiveFileTypes = ['.js', '.less', '.css', '.ejs', '.html', '.md'];

  this.preProcessor = new ProcessorStore(defaultProcessors.pre);
  this.postProcessor = new ProcessorStore(defaultProcessors.post);
  this.extensionRewriter = new ExtensionRewriter(defaultExtensionMap);

  // expose logger to plugins
  this.log = log;

  // Set up default tasks
  buildTask(this);
  serverTask(this);
  cleanTask(this);

  // Set up default help
  help.describe('help', {
    message: 'Shows this list'
  });

  help.describe('version', {
    message: 'Display Lingon version'
  });
};

Lingon.IGNORE_PREFIX_PATTERN = new RegExp('\/_');

Lingon.prototype.getEnvironment = function() {
  if(!this.__environment) {
    this.__environment = new Environment({
      rootPath: this.rootPath,
      sourcePath: this.sourcePath,
      ignorePrefixPattern: this.IGNORE_PREFIX_PATTERN
    });
  }

  return this.__environment;
};

Lingon.prototype.registerTask = function(task, callback, description) {
  help.describe(task, description);

  this.taskCallbacks[task] = function() {
    callback.call(this, function() {
      this.task = null;
      this.run();
    }.bind(this));
  }.bind(this);
};

Lingon.prototype.prepareOutputMap = function() {
  var _this = this;
  var sourceFiles = this.getEnvironment().getSourceFiles();

  sourceFiles.forEach(function(sourceFile){
    var sourceFilename = sourceFile.path.replace(_this.sourcePath + "/", "");
    var destFilename = _this.extensionRewriter.transform(sourceFilename, [_this.preProcessor, _this.postProcessor]);

    _this.outputMap[destFilename] = sourceFilename;
  });
};

Lingon.prototype.run = function(tasks) {
  if(tasks) {
    this.taskQueue = this.taskQueue.concat(tasks);
  }
  if(this.task) { return; }

  var task = this.taskQueue.shift();
  if(task) {
    var taskCallback = this.taskCallbacks[task];

    if(!taskCallback) {
      log(chalk.red('Error: Unknown task "' + task + '"'));
      return;
    }

    this.task = task;
    taskCallback.call(this);
  }
};

Lingon.prototype.build = function(callback, requestPaths) {
  var _this = this;
  requestPaths = requestPaths || [];

  this.trigger('beforeBuild');

  var sourceMappings = requestPaths.map(function(requestPath){
    return _this.outputMap[requestPath] || requestPath;
  });

  var sourceFiles = this.getEnvironment().getSourceFiles(sourceMappings);

  var cache = {};

  // TODO: Temporary - Remove in 2.0.0!
  // This should be removed when lingon.context
  // has been renamed to lingon.global.
  var merge = require('merge');
  var mergedContextGlobal = merge(this.context, this.global);

  // Start a directiveStream for each sourceFile
  sourceFiles.forEach(function(sourceFile) {
    var vinylStream = vfs.src(sourceFile.path);

    sourceFile.stream = vinylStream.pipe(
      directiveStream({
        rootPath: _this.rootPath,
        sourcePath: _this.sourcePath,
        directiveFileTypes: _this.validDirectiveFileTypes,
        preProcessor: _this.preProcessor,
        global: mergedContextGlobal,
        cache: cache,
        extensionRewriter: _this.extensionRewriter,
        directiveStream: directiveStream
      })
    );
  });

  // If no files are found, let's callback to allow the server
  // to process the next middleware (if the server is running).
  if(sourceFiles.length === 0) {
    if(!!callback) {
      var emptyFileBuffer = [];
      for(var i = requestPaths.length; i--;) {
        emptyFileBuffer.push(null);
      }
      callback( emptyFileBuffer );
    }

    return;
  }

  // If we have source files, let's create streams to process them.
  var outputStreams = sourceFiles.map(function(sourceFile) {
    return _this.postProcess(sourceFile);
  });

  var allStreams = es.concat.apply(_this, outputStreams);

  if(!!callback) {
    var fileBuffer = {};

    allStreams.on('data', function(file) {
      var buildPath = path.join(_this.rootPath, _this.buildPath);
      var relativePath = path.relative(buildPath, file.path);

      fileBuffer[relativePath] = file ;
    });
    allStreams.on('end', function() {
      var fileBufferSorted = [];
      for(var i = requestPaths.length; i--;) {
        fileBufferSorted[i] = fileBuffer[ requestPaths[i] ] || null;
      }

      callback( fileBufferSorted );
    });
  }

  this.trigger('afterBuild', { requestPaths: requestPaths });

};

Lingon.prototype.postProcess = function(sourceFile) {
  var _this = this;

  var sourcePath = sourceFile.path;
  var sourceFilename = path.basename(sourcePath);
  var destFilename = _this.extensionRewriter.transform(sourceFilename, [_this.preProcessor, _this.postProcessor]);

  var destFilePath = path.dirname(sourceFile.path.replace(_this.sourcePath, _this.buildPath));

  var stream = sourceFile.stream;
  var pipes = [];
  var postConcatPipes = [];

  postConcatPipes = postConcatPipes.concat(
    streamHelper.pipesForFileExtensions(
      sourceFile.name,
      _this.postProcessor,
      _this.global));

  // Queue the postConcatPipes (less, compression, etc)
  pipes = pipes.concat(postConcatPipes);

  // Queue the inspect pipe, rewrite the output filename
  var inspect = function(file, cb) {
    var filename = path.basename(file.path);
    file.path = file.path.replace(filename, destFilename);

    cb(null, file);
  };

  pipes.push(es.map(inspect));

  // Queue the output pipe
  pipes.push(vfs.dest(destFilePath));

  log(chalk.green(sourceFile.path, "->", path.join(destFilePath, destFilename)));

  // Apply all pipes to stream
  stream = streamHelper.applyPipes(stream, pipes);

  return stream;
};

Lingon.prototype.bind = Lingon.prototype.on = function() {
  this.eventEmitter.on.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.unbind = Lingon.prototype.off = function() {
  this.eventEmitter.off.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.one = function() {
  this.eventEmitter.once.apply(this.eventEmitter, [].slice.call(arguments));
};

Lingon.prototype.trigger = function() {
  this.eventEmitter.emit.apply(this.eventEmitter, [].slice.call(arguments));
};

module.exports = Lingon;
<|endoftext|>


<commit_before>'use strict';

var opentype = require('opentype.js');
var merge = require('webpack-merge');

var getDefaultOptions = require('./getDefaultOptions');
var getLoaderOptions = require('./getLoaderOptions');
var getOptionsFromQuery = require('./getOptionsFromQuery');
var getOptionsFromContent = require('./getOptionsFromContent');
var renderText = require('./renderText');

/**
 * @param {string} content
 */
module.exports = function opentypeSVGLoader(content) {
  if (this.cacheable) {
    this.cacheable();
  }

  var callback = this.async();

  var options = merge(
    getDefaultOptions(),
    getLoaderOptions(this),
    getOptionsFromQuery(this.resourceQuery),
    getOptionsFromContent(content)
  );

  if (!options.font) {
    if (options.fonts) {
      options.font = Object.keys(options.fonts)[0];
    }
  }

  opentype.load(options.fonts[options.font], function(error, font) {
    if (error) {
      callback(error);
    } else {
      var texts = renderText(options.text, options.data);

      var absoluteLineHeight = options.lineHeight * options.size;

      var firstBaseline = (font.ascender + font.descender / 2) /
        font.unitsPerEm *
        options.size;

      var bottomOffset = font.descender / font.unitsPerEm * options.size;

      var totalHeight = firstBaseline +
        (texts.length - 1) * absoluteLineHeight -
        bottomOffset;

      var paths = texts.map(function(tempText, index) {
        var y = firstBaseline + absoluteLineHeight * index;
        return font.getPath(tempText, 0, y, options.size, {
          kerning: options.kerning,
        });
      });

      var bounds = paths.map(function(tempPath) {
        return tempPath.getBoundingBox();
      });

      var widthValues = bounds.map(function(tempBounds) {
        return tempBounds.x2;
      });

      var totalWidth = Math.max.apply(null, widthValues);

      var viewBox = [0, 0, totalWidth, totalHeight];

      var attrsString = Object.keys(options.attrs).reduce(
        function(acc, tempKey) {
          return acc +
            tempKey +
            '=' +
            JSON.stringify(options.attrs[tempKey]) +
            ' ';
        },
        ''
      );

      var value = '<svg viewBox="' +
        viewBox.join(' ') +
        '" ' +
        attrsString +
        '>' +
        paths.reduce(
          function(acc, tempPath, index) {
            var tempBounds = bounds[index];
            var translateX = 0;
            var pathData = tempPath.toPathData(options.decimalPlaces);

            if (options.textAlign === 'right') {
              translateX = totalWidth - tempBounds.x2;
            } else if (options.textAlign === 'center') {
              translateX = (totalWidth - tempBounds.x2) * 0.5;
            }

            return acc +
              '<path id="line-' +
              index +
              '" transform="translate(' +
              translateX +
              ')" d="' +
              pathData +
              '"></path>';
          },
          ''
        ) +
        '</svg>';

      var result = 'module.exports = ' + JSON.stringify(value);
      callback(null, result);
    }
  });
};
<commit_msg>Refactored rendering. Reusing path data.<commit_after>'use strict';

var opentype = require('opentype.js');
var merge = require('webpack-merge');

var getDefaultOptions = require('./getDefaultOptions');
var getLoaderOptions = require('./getLoaderOptions');
var getOptionsFromQuery = require('./getOptionsFromQuery');
var getOptionsFromContent = require('./getOptionsFromContent');
var renderText = require('./renderText');

/**
 * @param {string} content
 */
module.exports = function opentypeSVGLoader(content) {
  if (this.cacheable) {
    this.cacheable();
  }

  var callback = this.async();

  var options = merge(
    getDefaultOptions(),
    getLoaderOptions(this),
    getOptionsFromQuery(this.resourceQuery),
    getOptionsFromContent(content)
  );

  if (!options.font) {
    if (options.fonts) {
      options.font = Object.keys(options.fonts)[0];
    }
  }

  opentype.load(options.fonts[options.font], function(error, font) {
    if (error) {
      callback(error);
    } else {
      var texts = renderText(options.text, options.data);

      var glyphs = {};

      var lines = texts.map(function(lineString) {
        var lineDescriptor = {
          glyphs: [],
          width: 0,
        };

        var lineChars = lineString.split('');
        var x = 0;

        lineChars.forEach(function(char, index) {
          var currentGlyph = glyphs[char];

          if (currentGlyph === void 0) {
            currentGlyph = font.charToGlyph(char);
            glyphs[char] = currentGlyph;
          }

          var glyphDescriptor = {
            name: currentGlyph.name,
            x: x,
          };

          var kerning = 0;

          if (options.kerning && index + 1 < lineChars.length) {
            var nextChar = lineChars[index + 1];
            var nextGlyph = glyphs[nextChar];

            if (nextGlyph === void 0) {
              nextGlyph = font.charToGlyph(nextChar);
              glyphs[nextChar] = nextGlyph;
            }
            kerning = font.getKerningValue(currentGlyph, nextGlyph) || 0;
          }

          x += currentGlyph.advanceWidth + kerning;

          lineDescriptor.width = glyphDescriptor.x +
            currentGlyph.leftSideBearing +
            (currentGlyph.xMax - currentGlyph.xMin);
          lineDescriptor.glyphs.push(glyphDescriptor);
        });

        return lineDescriptor;
      });

      var absoluteLineHeight = options.lineHeight * font.unitsPerEm;
      var firstBaseline = font.ascender + font.descender / 2;
      var bottomOffset = font.descender;
      var totalHeight = firstBaseline +
        (texts.length - 1) * absoluteLineHeight -
        bottomOffset;
      var totalWidth = lines.reduce(
        function(acc, line) {
          if (line.width > acc) {
            return line.width;
          } else {
            return acc;
          }
        },
        0
      );

      var viewBoxString = [0, 0, totalWidth, totalHeight].join(' ');

      var defsString = '<defs>' +
        Object.keys(glyphs).reduce(
          function(acc, key) {
            var glyph = glyphs[key];
            var path = glyph.getPath(0, 0, font.unitsPerEm);
            return acc +
              '<path id="' +
              glyph.name +
              '" d="' +
              path.toPathData(options.decimalPlaces) +
              '"/>';
          },
          ''
        ) +
        '</defs>';

      var linesString = lines.reduce(
        function(acc, line, index) {
          var y = firstBaseline + absoluteLineHeight * index;

          var xOffset = 0;

          if (options.textAlign === 'right') {
            xOffset = totalWidth - line.width;
          } else if (options.textAlign === 'center') {
            xOffset = (totalWidth - line.width) * 0.5;
          }

          acc += '<g id="line-' + index + '">';

          line.glyphs.forEach(function(glyph) {
            var x = glyph.x + xOffset;
            acc += '<use x="' +
              x +
              '" y="' +
              y +
              '" xlink:href="#' +
              glyph.name +
              '" />';
          });

          acc += '</g>';

          return acc;
        },
        ''
      );

      var fontSizeScale = 1 / font.unitsPerEm * options.size;

      var attrs = merge({}, options.attrs, {
        width: Math.round(fontSizeScale * totalWidth),
        height: Math.round(fontSizeScale * totalHeight),
      });

      var attrsString = Object.keys(attrs).reduce(
        function(acc, tempKey) {
          return acc + tempKey + '=' + JSON.stringify(attrs[tempKey]) + ' ';
        },
        ''
      );

      var value = '<svg viewBox="' +
        viewBoxString +
        '" ' +
        attrsString +
        '>' +
        defsString +
        linesString +
        '</svg>';

      var result = 'module.exports = ' + JSON.stringify(value);
      callback(null, result);
    }
  });
};
<|endoftext|>


<commit_before>var path = require('path');
var loaderUtils = require('loader-utils');
var extend = require('./utils/extend');
var Promise = require('bluebird');
var sprintf = require('sprintf');
var flatten = require('./utils/flatten');
var interpolateName = require('./utils/interpolateName');

var validateConfig = require('./utils/plugin/validateConfig');
var Example = require('./data/Example');
var ExampleFile = require('./data/ExampleFile');
var Asset = require('./data/Asset');
var createExamplesCompiler = require('./utils/compiler/examples/createCompiler');
var getAssetsByChunkName = require('./utils/compilation/getAssetsByChunkName');
var findFilesToCompile = require('./utils/compiler/examples/findFilesToCompile');
var findFilesToEmit = require('./utils/compiler/examples/findFilesToEmit');

var loaderPath = require('./plugin').loaderPath;

function PageIsNullException() {}

function callExtractor(extractor, data, options) {
  var extractor = typeof extractor === 'string' ? require(extractor) : extractor;
  return extractor.call(this, data, options);
}

module.exports = function () {
  this.cacheable && this.cacheable();
  var done = this.async();
  var loader = this;
  var plugin = this[loaderPath];
  if (plugin === undefined) {
    throw new Error(
      'webpack-docs-plugin loader is used without the corresponding plugin, ' +
      'refer to https://github.com/kisenka/webpack-docs-plugin for the usage example'
    );
  }

  var pluginConfig = plugin.config;
  var config = pluginConfig;
  var query = loaderUtils.parseQuery(loader.query);
  var isQueryEmpty = Object.keys(query).length == 0;
  if (!isQueryEmpty) {
    config = extend({}, pluginConfig, query);
    try {
      validateConfig(config);
    } catch (error) {
      return done(error);
    }
  }

  var compiler = loader._compiler;
  var compilation = loader._compilation;
  var fs = compiler.inputFileSystem;
  var contextPath = loader.options.context;
  var resourcePath = loader.resourcePath;
  var resourceRelativePath = path.relative(contextPath, resourcePath);
  var page, examples, files, source;
  var baseUrl = 'publicPath' in compiler.options.output ? compiler.options.output.publicPath : '/';

  new Promise(function(resolve, reject) {
    fs.readFile(resourcePath, function (err, result) {
      err ? reject(err) : resolve(result.toString('utf-8'));
    })
  })

  // Extractor
  .then(function (content) {
    source = content;
    page = callExtractor.call(
      loader, config.page.extractor,
      content, config.page.extractorOptions || undefined
    );
    if (!page)
      return Promise.reject(new PageIsNullException);

    page.source.path = resourceRelativePath;
    page.source.absolutePath = resourcePath;
    page.source.content = source;
    page.path = interpolateName(config.page.name, {
      path: resourcePath,
      context: contextPath
    });
    return Promise.resolve(page);
  })

  // lastModified
  .then(function (page) {
    return new Promise(function (resolve, reject) {
      fs.stat(resourcePath, function (err, result) {
        if (err)
          reject(err);
        else {
          page.source.lastModified = new Date(result.mtime);
          resolve(page);
        }
      });
    });
  })

  // Find assets to compile
  .then(function (page) {
    files = flatten(page.items, function (item) { return item instanceof ExampleFile });
    var filesToCompile = findFilesToCompile(files, config.example.files.compile);
    if (filesToCompile.length == 0)
      return;

    var webpackConfig = config.example.webpackConfig || compiler.options;
    var examplesCompiler = createExamplesCompiler(webpackConfig, filesToCompile, resourcePath);

    // Compile example assets
    return new Promise(function (resolve, reject) {
      examplesCompiler.run(function (err, stats) {
        err ? reject(err)
            : resolve(getAssetsByChunkName(stats.compilation));
      });
    })

    // Save assets info
    .then(function (assets) {
      for (var chunkName in assets) {
        var file = files.filter(function (file) { return file.id === chunkName })[0];

        assets[chunkName].forEach(function (assetInfo) {
          assetInfo.path = sprintf('%s.examples/%s', page.path, assetInfo.path);
          assetInfo.type = path.extname(assetInfo.path).substr(1);
          file.assets.push(new Asset(assetInfo));
        });
      }
    });

  })

  // Emit example assets
  .then(function () {
    findFilesToEmit(files, config.example.files.emit)
      .forEach(function (file) {
        file.emitAssets(compilation);
      });
  })

  // Render example pages
  .then(function () {
    if (!config.example.template)
      return;

    loader.addDependency(config.example.template);
    examples = flatten(page.items, function(item) { return item instanceof Example });

    return Promise
      .all(examples.map(function (example) {
        var templateContext = extend({}, config.templateEngine.context || {}, {
          example: example.serialize(),
          baseurl: baseUrl
        });

        return plugin
          .render(config.example.template, templateContext)
          .then(function (result) { example.content = result });
      }))
      .then(function() {
        return examples;
      });
  })

  // Emit example pages
  .then(function(examples) {
    if (!examples || !config.example.emit)
      return;

    examples.forEach(function (example) {
      example.path = sprintf('%s.examples/%s.html', page.path, example.id);
      loader.emitFile(example.path, example.content);
    });
  })

  // Render documentation page
  .then(function () {
    loader.addDependency(config.page.template);

    var templateContext = extend({}, config.templateEngine.context || {}, {
      page: page.serialize(),
      baseurl: baseUrl
    });

    return plugin
      .render(config.page.template, templateContext)
      .then(function (result) { loader.emitFile(page.path, result) })
  })

  // Save to plugin.pages
  .then(function() {
    var pages = plugin.pages;
    var alreadyAddedPage = pages.filter(function(p) { return p.path === page.path })[0];
    if (alreadyAddedPage)
      pages[pages.indexOf(alreadyAddedPage)] = page;
    else
      pages.push(page);
  })

  // All done
  .then(function() {
    done(null, source);
  })

  // Error handling
  .catch(function(err) {
    if (err instanceof PageIsNullException) {
      done(null, source);
    }
    else {
      compilation.errors.push(err);
      done(err);
    }
  });
};<commit_msg>Add error from child compiler<commit_after>var path = require('path');
var loaderUtils = require('loader-utils');
var extend = require('./utils/extend');
var Promise = require('bluebird');
var sprintf = require('sprintf');
var flatten = require('./utils/flatten');
var interpolateName = require('./utils/interpolateName');

var validateConfig = require('./utils/plugin/validateConfig');
var Example = require('./data/Example');
var ExampleFile = require('./data/ExampleFile');
var Asset = require('./data/Asset');
var createExamplesCompiler = require('./utils/compiler/examples/createCompiler');
var getAssetsByChunkName = require('./utils/compilation/getAssetsByChunkName');
var findFilesToCompile = require('./utils/compiler/examples/findFilesToCompile');
var findFilesToEmit = require('./utils/compiler/examples/findFilesToEmit');

var loaderPath = require('./plugin').loaderPath;

function PageIsNullException() {}

function callExtractor(extractor, data, options) {
  var extractor = typeof extractor === 'string' ? require(extractor) : extractor;
  return extractor.call(this, data, options);
}

module.exports = function () {
  this.cacheable && this.cacheable();
  var done = this.async();
  var loader = this;
  var plugin = this[loaderPath];
  if (plugin === undefined) {
    throw new Error(
      'webpack-docs-plugin loader is used without the corresponding plugin, ' +
      'refer to https://github.com/kisenka/webpack-docs-plugin for the usage example'
    );
  }

  var pluginConfig = plugin.config;
  var config = pluginConfig;
  var query = loaderUtils.parseQuery(loader.query);
  var isQueryEmpty = Object.keys(query).length == 0;
  if (!isQueryEmpty) {
    config = extend({}, pluginConfig, query);
    try {
      validateConfig(config);
    } catch (error) {
      return done(error);
    }
  }

  var compiler = loader._compiler;
  var compilation = loader._compilation;
  var fs = compiler.inputFileSystem;
  var contextPath = loader.options.context;
  var resourcePath = loader.resourcePath;
  var resourceRelativePath = path.relative(contextPath, resourcePath);
  var page, examples, files, source;
  var baseUrl = 'publicPath' in compiler.options.output ? compiler.options.output.publicPath : '/';

  new Promise(function(resolve, reject) {
    fs.readFile(resourcePath, function (err, result) {
      err ? reject(err) : resolve(result.toString('utf-8'));
    })
  })

  // Extractor
  .then(function (content) {
    source = content;
    page = callExtractor.call(
      loader, config.page.extractor,
      content, config.page.extractorOptions || undefined
    );
    if (!page)
      return Promise.reject(new PageIsNullException);

    page.source.path = resourceRelativePath;
    page.source.absolutePath = resourcePath;
    page.source.content = source;
    page.path = interpolateName(config.page.name, {
      path: resourcePath,
      context: contextPath
    });
    return Promise.resolve(page);
  })

  // lastModified
  .then(function (page) {
    return new Promise(function (resolve, reject) {
      fs.stat(resourcePath, function (err, result) {
        if (err)
          reject(err);
        else {
          page.source.lastModified = new Date(result.mtime);
          resolve(page);
        }
      });
    });
  })

  // Find assets to compile
  .then(function (page) {
    files = flatten(page.items, function (item) { return item instanceof ExampleFile });
    var filesToCompile = findFilesToCompile(files, config.example.files.compile);
    if (filesToCompile.length == 0)
      return;

    var webpackConfig = config.example.webpackConfig || compiler.options;
    var examplesCompiler = createExamplesCompiler(webpackConfig, filesToCompile, resourcePath);

    // Compile example assets
    return new Promise(function (resolve, reject) {
      examplesCompiler.run(function (err, stats) {
        var compilation = stats.compilation;
        var error = err || (compilation.errors.length > 0 && compilation.errors[0]);
        error ? reject(error)
              : resolve(getAssetsByChunkName(compilation));
      });
    })

    // Save assets info
    .then(function (assets) {
      for (var chunkName in assets) {
        var file = files.filter(function (file) { return file.id === chunkName })[0];

        assets[chunkName].forEach(function (assetInfo) {
          assetInfo.path = sprintf('%s.examples/%s', page.path, assetInfo.path);
          assetInfo.type = path.extname(assetInfo.path).substr(1);
          file.assets.push(new Asset(assetInfo));
        });
      }
    });

  })

  // Emit example assets
  .then(function () {
    findFilesToEmit(files, config.example.files.emit)
      .forEach(function (file) {
        file.emitAssets(compilation);
      });
  })

  // Render example pages
  .then(function () {
    if (!config.example.template)
      return;

    loader.addDependency(config.example.template);
    examples = flatten(page.items, function(item) { return item instanceof Example });

    return Promise
      .all(examples.map(function (example) {
        var templateContext = extend({}, config.templateEngine.context || {}, {
          example: example.serialize(),
          baseurl: baseUrl
        });

        return plugin
          .render(config.example.template, templateContext)
          .then(function (result) { example.content = result });
      }))
      .then(function() {
        return examples;
      });
  })

  // Emit example pages
  .then(function(examples) {
    if (!examples || !config.example.emit)
      return;

    examples.forEach(function (example) {
      example.path = sprintf('%s.examples/%s.html', page.path, example.id);
      loader.emitFile(example.path, example.content);
    });
  })

  // Render documentation page
  .then(function () {
    loader.addDependency(config.page.template);

    var templateContext = extend({}, config.templateEngine.context || {}, {
      page: page.serialize(),
      baseurl: baseUrl
    });

    return plugin
      .render(config.page.template, templateContext)
      .then(function (result) { loader.emitFile(page.path, result) })
  })

  // Save to plugin.pages
  .then(function() {
    var pages = plugin.pages;
    var alreadyAddedPage = pages.filter(function(p) { return p.path === page.path })[0];
    if (alreadyAddedPage)
      pages[pages.indexOf(alreadyAddedPage)] = page;
    else
      pages.push(page);
  })

  // All done
  .then(function() {
    done(null, source);
  })

  // Error handling
  .catch(function(err) {
    if (err instanceof PageIsNullException) {
      done(null, source);
    }
    else {
      compilation.errors.push(err);
      done(err);
    }
  });
};<|endoftext|>


<commit_before>//
// Copyright (c) Telefonica I+D. PDI  All rights reserved.
//
//

/*
 * Since Winston has a predefined log style define in 'common' module, it's necessary to modify this module
 * in order to accomplish TID Log Style guide. 'personalizedCommon.js' modifies that module and it's necessary
 * to be required even if not used.
 */

var util = require('util');
var common = require('./personalizedCommon.js');
var winston = require('winston');
var stackParser = require('stack-parser');
var os = require('os');
var logger = null;

var hostname = os.hostname();
var winstonLogger = null;

var config = {
  logLevel: 'debug',
  inspectDepth: 2,
  Console: {
    level: 'debug', timestamp: true
  },
  File: {
    //FIXME: Filename should be changed to meet PID requirements
    level: 'debug', filename: 'pditclogger.log', timestamp: true, json: false
  }
};

function createLogMessage(level, message, logObj) {

  var msg = '';

  var COMPONENT = 'component', LEVEL = 'level', CORRELATOR = 'correlator', OP = 'op', TRANSID = 'transid';
  var predefinedValues = [ COMPONENT, LEVEL, CORRELATOR, OP, TRANSID ];

  //Set default value
  logObj = logObj || {};

  //PDI Format
  msg += ' | lvl=' + level.toUpperCase();                                                          //Log level
  msg += ' | op=' + (logObj[OP] ? logObj[OP] : 'DEFAULT');                                        //Op Type
  msg += ' | msg=' + message;                                                                     //User message
  msg += ' | corr=' + (logObj[CORRELATOR] ? logObj[CORRELATOR] : 'N/A');                    //UNICA Correlator
  msg += ' | trans=' + (logObj[TRANSID] ? logObj[TRANSID] : 'N/A');                             //Transaction ID
  msg += ' | hostname=' + os.hostname();                                                          //Machine
  msg += ' | component=' + (logObj[COMPONENT] ? logObj[COMPONENT] : (this.prefix ? this.prefix : '?'));  //Component

  try {

    if (logObj !== null && logObj !== undefined) {

      if (util.isArray(logObj)) {
        msg += ' | Array=';
        if (logObj.length > 0) {
          msg += util.inspect(logObj[0], false, config.inspectDepth);
        }
        for (var ix = 1; ix < logObj.length; ix++) {
          msg += ', ' + util.inspect(logObj[ix], false, config.inspectDepth);
        }

      } else {
        for (var i in logObj) {
          if (predefinedValues.indexOf(i) === -1) {
            msg += ' | ' + i + '=' + util.inspect(logObj[i], false, config.inspectDepth);
          }
        }
      }
    }

  } catch (e) {
    //Nothing to do...
  }

  return msg;

}

function createWinston(cfg) {
  "use strict";

  /**
   * This function will be called when an error arises writing a log in a file
   * @param err The error
   * @returns {boolean} true (It forces to exit the application -due requirements-)
   */
  function exitOnError(err) {

    var component = null, component2;

    try {
      var items = stackParser.parse(err.stack);
      //component = items[0].file + ':' + items[0].line + ':' + items[0].column;
      component = items[0].file;
    } catch(e) {
      //Nothing to do...
    }

    var logMsg = createLogMessage('emerg', err+'('+err.stack+')', { component: component });

    //Use critical Winston to print the message
    winstonLogger.emerg(logMsg);

    //Exit (due requirements)
    return cfg.exitOnError || true;
  }

  winstonLogger = new (winston.Logger)({
    level: cfg.logLevel,
    exitOnError: exitOnError,
    transports: [
      new (winston.transports.Console)(cfg.Console),
      new (winston.transports.File)(cfg.File)
    ]
  });

  winstonLogger.setLevels(winston.config.syslog.levels);

}

function setConfig(newCfg) {
  "use strict";

  config = newCfg;
  config.File.handleExceptions = true;    //Necessary to handle file exceptions
  createWinston(config);

}

function newLogger() {
  "use strict";

  if (winstonLogger === null) {
    createWinston(config);
  }

  var logger = {};

  /**
   *
   * @param level Standard default values (DEBUG, INFO, NOTICE, WARNING, ERROR, CRIT, ALERT, EMERG)
   * @param message Log Message
   * @param logObj An object or an array that will be printed after the message
   * @returns {*}
   */
  logger.log = function (level, message, logObj) {

    if (winstonLogger.levels[level] < winstonLogger.levels[config.logLevel]) {
      return;
    }

    var message = createLogMessage.call(this, level, message, logObj).replace(/\n/g, '');

    return winstonLogger.log(level, message);
  };

  for (var lvl in winston.config.syslog.levels) {
    if (winston.config.syslog.levels.hasOwnProperty(lvl)) {
      logger[lvl] = function _block(aLevel) {
        return function (msg, obj) {
          return logger.log(aLevel, msg, obj);
        };
      }(lvl);
    }
  }
  // socket.io compatibility
  logger.warn = logger.warning;

  /*
   TODO: A log level for every logger? Each module could set its own filtering level
   logger.setLevel = function ...
   */

  return logger;
}

exports.newLogger = newLogger;
exports.setConfig = setConfig;
/*
 debug: 0,
 info: 1,
 notice: 2,
 warning: 3,
 error: 4,
 crit: 5,
 alert: 6,
 emerg: 7

 The list of syslog severity Levels:
 0 Emergency: system is unusable
 1 Alert: action must be taken immediately
 2 Critical: critical conditions
 3 Error: error conditions
 4 Warning: warning conditions
 5 Notice: normal but significant condition
 6 Informational: informational messages
 7 Debug: debug-level messages
 Recommended practice is to use the Notice or Informational level for normal messages.

 A detailed explanation of the severity Levels:
 DEBUG:
 Info useful to developers for debugging the application, not useful during operations
 INFORMATIONAL:
 Normal operational messages - may be harvested for reporting, measuring throughput, etc - no action required
 NOTICE:
 Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required
 WARNING:
 Warning messages - not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time
 ERROR:
 Non-urgent failures - these should be relayed to developers or admins; each item must be resolved within a given time
 ALERT:
 Should be corrected immediately - notify staff who can fix the problem - example is loss of backup ISP connection
 CRITICAL:
 Should be corrected immediately, but indicates failure in a primary system - fix CRITICAL problems before ALERT - example is loss of primary ISP connection
 EMERGENCY:
 A "panic" condition - notify all tech staff on call? (earthquake? tornado?) - affects multiple apps/servers/sites...

 */
<commit_msg>Log stack trace in JSON format for unexpected errors<commit_after>//
// Copyright (c) Telefonica I+D. PDI  All rights reserved.
//
//

/*
 * Since Winston has a predefined log style define in 'common' module, it's necessary to modify this module
 * in order to accomplish TID Log Style guide. 'personalizedCommon.js' modifies that module and it's necessary
 * to be required even if not used.
 */

var util = require('util');
var common = require('./personalizedCommon.js');
var winston = require('winston');
var stackParser = require('stack-parser');
var os = require('os');
var logger = null;

var hostname = os.hostname();
var winstonLogger = null;

var config = {
  logLevel: 'debug',
  inspectDepth: 2,
  Console: {
    level: 'debug', timestamp: true
  },
  File: {
    //FIXME: Filename should be changed to meet PID requirements
    level: 'debug', filename: 'pditclogger.log', timestamp: true, json: false
  }
};

function createLogMessage(level, message, logObj) {

  var msg = '';

  var COMPONENT = 'component', LEVEL = 'level', CORRELATOR = 'correlator', OP = 'op', TRANSID = 'transid';
  var predefinedValues = [ COMPONENT, LEVEL, CORRELATOR, OP, TRANSID ];

  //Set default value
  logObj = logObj || {};

  //PDI Format
  msg += ' | lvl=' + level.toUpperCase();                                                          //Log level
  msg += ' | op=' + (logObj[OP] ? logObj[OP] : 'DEFAULT');                                        //Op Type
  msg += ' | msg=' + message;                                                                     //User message
  msg += ' | corr=' + (logObj[CORRELATOR] ? logObj[CORRELATOR] : 'N/A');                    //UNICA Correlator
  msg += ' | trans=' + (logObj[TRANSID] ? logObj[TRANSID] : 'N/A');                             //Transaction ID
  msg += ' | hostname=' + os.hostname();                                                          //Machine
  msg += ' | component=' + (logObj[COMPONENT] ? logObj[COMPONENT] : (this.prefix ? this.prefix : '?'));  //Component

  try {

    if (logObj !== null && logObj !== undefined) {

      if (util.isArray(logObj)) {
        msg += ' | Array=';
        if (logObj.length > 0) {
          msg += util.inspect(logObj[0], false, config.inspectDepth);
        }
        for (var ix = 1; ix < logObj.length; ix++) {
          msg += ', ' + util.inspect(logObj[ix], false, config.inspectDepth);
        }

      } else {
        for (var i in logObj) {
          if (predefinedValues.indexOf(i) === -1) {
            msg += ' | ' + i + '=' + util.inspect(logObj[i], false, config.inspectDepth);
          }
        }
      }
    }

  } catch (e) {
    //Nothing to do...
  }

  return msg;

}

function createWinston(cfg) {
  "use strict";

  /**
   * This function will be called when an error arises writing a log in a file
   * @param err The error
   * @returns {boolean} true (It forces to exit the application -due requirements-)
   */
  function exitOnError(err) {

    var component = null, component2;

    try {
      var items = stackParser.parse(err.stack);
      //component = items[0].file + ':' + items[0].line + ':' + items[0].column;
      component = items[0].file;
    } catch(e) {
      //Nothing to do...
    }

    var logMsg = createLogMessage('emerg',JSON.stringify(items), { component: component });

    //Use critical Winston to print the message
    winstonLogger.emerg(logMsg);

    //Exit (due requirements)
    return cfg.exitOnError || true;
  }

  winstonLogger = new (winston.Logger)({
    level: cfg.logLevel,
    exitOnError: exitOnError,
    transports: [
      new (winston.transports.Console)(cfg.Console),
      new (winston.transports.File)(cfg.File)
    ]
  });

  winstonLogger.setLevels(winston.config.syslog.levels);

}

function setConfig(newCfg) {
  "use strict";

  config = newCfg;
  config.File.handleExceptions = true;    //Necessary to handle file exceptions
  createWinston(config);

}

function newLogger() {
  "use strict";

  if (winstonLogger === null) {
    createWinston(config);
  }

  var logger = {};

  /**
   *
   * @param level Standard default values (DEBUG, INFO, NOTICE, WARNING, ERROR, CRIT, ALERT, EMERG)
   * @param message Log Message
   * @param logObj An object or an array that will be printed after the message
   * @returns {*}
   */
  logger.log = function (level, message, logObj) {

    if (winstonLogger.levels[level] < winstonLogger.levels[config.logLevel]) {
      return;
    }

    var message = createLogMessage.call(this, level, message, logObj).replace(/\n/g, '');

    return winstonLogger.log(level, message);
  };

  for (var lvl in winston.config.syslog.levels) {
    if (winston.config.syslog.levels.hasOwnProperty(lvl)) {
      logger[lvl] = function _block(aLevel) {
        return function (msg, obj) {
          return logger.log(aLevel, msg, obj);
        };
      }(lvl);
    }
  }
  // socket.io compatibility
  logger.warn = logger.warning;

  /*
   TODO: A log level for every logger? Each module could set its own filtering level
   logger.setLevel = function ...
   */

  return logger;
}

exports.newLogger = newLogger;
exports.setConfig = setConfig;
/*
 debug: 0,
 info: 1,
 notice: 2,
 warning: 3,
 error: 4,
 crit: 5,
 alert: 6,
 emerg: 7

 The list of syslog severity Levels:
 0 Emergency: system is unusable
 1 Alert: action must be taken immediately
 2 Critical: critical conditions
 3 Error: error conditions
 4 Warning: warning conditions
 5 Notice: normal but significant condition
 6 Informational: informational messages
 7 Debug: debug-level messages
 Recommended practice is to use the Notice or Informational level for normal messages.

 A detailed explanation of the severity Levels:
 DEBUG:
 Info useful to developers for debugging the application, not useful during operations
 INFORMATIONAL:
 Normal operational messages - may be harvested for reporting, measuring throughput, etc - no action required
 NOTICE:
 Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required
 WARNING:
 Warning messages - not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time
 ERROR:
 Non-urgent failures - these should be relayed to developers or admins; each item must be resolved within a given time
 ALERT:
 Should be corrected immediately - notify staff who can fix the problem - example is loss of backup ISP connection
 CRITICAL:
 Should be corrected immediately, but indicates failure in a primary system - fix CRITICAL problems before ALERT - example is loss of primary ISP connection
 EMERGENCY:
 A "panic" condition - notify all tech staff on call? (earthquake? tornado?) - affects multiple apps/servers/sites...

 */
<|endoftext|>


<commit_before>var _ = require('underscore'),
    combine = require('./jsCombine'),
    config = require('./config'),
    fs = require('fs'),
    fu = require('./fileUtil'),
    plugin = require('./plugin'),
    watch = require('./watcher.js'),
    growl = require('growl');

function logError(err) {
    // TODO : Move this to the executable
    console.error(err.stack || err.message);
    growl.notify(err.message, { title: 'Lumbar error' });
}

var configCache;
function loadConfig(path) {
  try {
    configCache = {};
    config.load(path);
  } catch (err) {
    // Do not die a horrible death if this is just a syntax error
    logError(err);
  }
}

exports.plugin = plugin.plugin;
exports.init = function(configFile, options) {
    var outdir = options.outdir,
        minimize = options.minimize,
        plugins = plugin.create(options);

    function initPlatforms() {
        config.platformList().forEach(function(platform) {
            if (!platform) {
                return;
            }
            try {
                console.log("mkdir:\t\033[90mmaking directory\033[0m " + outdir + '/' + platform);
                fs.mkdirSync(outdir + '/' + platform, 0755);
            } catch (err) {
                if (err.code !== 'EEXIST') {
                    throw err;
                }
            }
        });
    }

    function buildPlatform(context, callback) {
      context.combined = config.combineModules(context.package);

      var modules = config.moduleList(context.package);
      modules.forEach(function(module) {
        context = _.clone(context);
        context.module = module;
        buildModule(context, callback)
      });

      if (context.combined) {
        combineResources(context, context.package, function(err, data) {
          if (data) {
            data.package = context.package;
          }
          callback(err, data);
        });
      }
    }
    function buildModule(context, callback) {
      context.platformPath = (context.platform ? context.platform + '/' : '');
      context.module = config.module(context.module);
      context.options = options;
      context.config = config;
      context.configCache = configCache;
      context.fileCache = context.fileCache || {};
      context.moduleCache = {};

      var fileList = config.fileList(plugins, context);

      var resources = fileList.map(function(resource) {
        context.resource = resource;
        return plugins.resource(context);
      }).filter(function(resource) { return resource; });

      context.moduleResources = resources;
      plugins.module(context);

      if (!context.combined) {
        context.resources = resources;
        combineResources(context, context.module.name, function(err, data) {
          if (data) {
            data.package = context.package;
            data.module = context.module.name;
          }
          callback(err, data);
        });
      } else {
        context.resources = context.resources || [];
        context.resources.push.apply(context.resources, resources);
      }
    }
    function combineResources(context, name, callback) {
      var fileName = outdir + '/' + context.platformPath + name + '.js';

      context.fileName = fileName;
      plugins.file(context);

      combine.combine(context.resources, fileName, options.minimize, function(err, data) {
        if (err) {
          fs.unlink(fileName);
        }

        context.fileCache = undefined;

        if (data) {
          data.platform = context.platform;
        }
        callback(err, data)
      });
    }

    loadConfig(configFile);
    initPlatforms();

    return {
        use: function(plugin) {
          plugins.use(plugin);
        },
        build: function(packageName, callback) {
            var packages = packageName ? [packageName] : config.packageList();
            packages.forEach(function(package) {
              var platforms = config.platformList(package);
              platforms.forEach(function(platform) {
                buildPlatform({package: package, platform: platform}, callback);
              });
            });
        },
        watch: function(packageName, callback) {
            var packages = packageName ? [packageName] : config.packageList(),
                self = this;

            // Watch for changes in the config file
            // WARN : This isn't really safe for multiple executions, this is a concious design decision
            watch.watchFile(configFile, [], function() {
                loadConfig(configFile);

                // Cleanup what we can, breaking things along the way
                watch.unwatchAll();
                fu.resetCache();

                // Give it a chance to cleanup before start recreating. Attempting to avoid the too many files error.
                setTimeout(function() {
                  initPlatforms();
                  self.watch(packageName, callback);
                }, 1000);
            });

            // Watch the individual components
            packages.forEach(function(name) {
                self.build(name, function(err, status) {
                    if (err) {
                        logError(err);
                        return;
                    }

                    callback(err, status);

                    if (status.fileName === 'module_map.json') {
                        return;
                    }
                    watch.watchFile("foo" + status.fileName + "foo", status.input, function() {
                      if (status.module) {
                        buildModule(_.clone(status), callback);
                      } else {
                        buildPlatform(_.clone(status), callback);
                      }
                    });
                });
            });
        }
    };
};
<commit_msg>Clone the watch context object<commit_after>var _ = require('underscore'),
    combine = require('./jsCombine'),
    config = require('./config'),
    fs = require('fs'),
    fu = require('./fileUtil'),
    plugin = require('./plugin'),
    watch = require('./watcher.js'),
    growl = require('growl');

function logError(err) {
    // TODO : Move this to the executable
    console.error(err.stack || err.message);
    growl.notify(err.message, { title: 'Lumbar error' });
}

var configCache;
function loadConfig(path) {
  try {
    configCache = {};
    config.load(path);
  } catch (err) {
    // Do not die a horrible death if this is just a syntax error
    logError(err);
  }
}

exports.plugin = plugin.plugin;
exports.init = function(configFile, options) {
    var outdir = options.outdir,
        minimize = options.minimize,
        plugins = plugin.create(options);

    function initPlatforms() {
        config.platformList().forEach(function(platform) {
            if (!platform) {
                return;
            }
            try {
                console.log("mkdir:\t\033[90mmaking directory\033[0m " + outdir + '/' + platform);
                fs.mkdirSync(outdir + '/' + platform, 0755);
            } catch (err) {
                if (err.code !== 'EEXIST') {
                    throw err;
                }
            }
        });
    }

    function buildPlatform(context, callback) {
      context.combined = config.combineModules(context.package);

      var modules = config.moduleList(context.package);
      modules.forEach(function(module) {
        context = _.clone(context);
        context.module = module;
        buildModule(context, callback)
      });

      if (context.combined) {
        combineResources(context, context.package, function(err, data) {
          if (data) {
            data.package = context.package;
          }
          callback(err, data);
        });
      }
    }
    function buildModule(context, callback) {
      context.platformPath = (context.platform ? context.platform + '/' : '');
      context.module = config.module(context.module);
      context.options = options;
      context.config = config;
      context.configCache = configCache;
      context.fileCache = context.fileCache || {};
      context.moduleCache = {};

      var fileList = config.fileList(plugins, context);

      var resources = fileList.map(function(resource) {
        context.resource = resource;
        return plugins.resource(context);
      }).filter(function(resource) { return resource; });

      context.moduleResources = resources;
      plugins.module(context);

      if (!context.combined) {
        context.resources = resources;
        combineResources(context, context.module.name, function(err, data) {
          if (data) {
            data.package = context.package;
            data.module = context.module.name;
          }
          callback(err, data);
        });
      } else {
        context.resources = context.resources || [];
        context.resources.push.apply(context.resources, resources);
      }
    }
    function combineResources(context, name, callback) {
      var fileName = outdir + '/' + context.platformPath + name + '.js';

      context.fileName = fileName;
      plugins.file(context);

      combine.combine(context.resources, fileName, options.minimize, function(err, data) {
        if (err) {
          fs.unlink(fileName);
        }

        context.fileCache = undefined;

        if (data) {
          data.platform = context.platform;
        }
        callback(err, data)
      });
    }

    loadConfig(configFile);
    initPlatforms();

    return {
        use: function(plugin) {
          plugins.use(plugin);
        },
        build: function(packageName, callback) {
            var packages = packageName ? [packageName] : config.packageList();
            packages.forEach(function(package) {
              var platforms = config.platformList(package);
              platforms.forEach(function(platform) {
                buildPlatform({package: package, platform: platform}, callback);
              });
            });
        },
        watch: function(packageName, callback) {
            var packages = packageName ? [packageName] : config.packageList(),
                self = this;

            // Watch for changes in the config file
            // WARN : This isn't really safe for multiple executions, this is a concious design decision
            watch.watchFile(configFile, [], function() {
                loadConfig(configFile);

                // Cleanup what we can, breaking things along the way
                watch.unwatchAll();
                fu.resetCache();

                // Give it a chance to cleanup before start recreating. Attempting to avoid the too many files error.
                setTimeout(function() {
                  initPlatforms();
                  self.watch(packageName, callback);
                }, 1000);
            });

            // Watch the individual components
            packages.forEach(function(name) {
                self.build(name, function(err, status) {
                    if (err) {
                        logError(err);
                        return;
                    }

                    callback(err, status);

                    var context = {package: status.package, platform: status.platform, module: status.module};
                    watch.watchFile("foo" + status.fileName + "foo", status.input, function() {
                      if (context.module) {
                        buildModule(_.clone(context), callback);
                      } else {
                        buildPlatform(_.clone(context), callback);
                      }
                    });
                });
            });
        }
    };
};
<|endoftext|>


<commit_before>'use strict';
var log = require('./log');
module.exports = function (workers, options) {
  var DEBUG = options.debug;
  var CONCURRENCY = options.concurrency;
  var PORT = options.port;
  var serverInstance;

  function serverCreate () {
    var hash = require('string-hash');
    return require('net')
      .createServer({ pauseOnConnect: true }, function (connection) {
        var index = hash(connection.remoteAddress) % CONCURRENCY;
        workers.entrust(index, connection);
      });
  }

  function serverStart (callback) {
    serverInstance = serverCreate();
    serverInstance.listen(PORT, callback);
  }

  function serverStop (callback) {
    serverInstance.close(function (err) {
      if (err) console.log(err);
      else return callback();
    });
  }

  function stop () {

    // stop proxy server
    if (DEBUG) log('MASTER  stop..');
    serverStop(function () {
      if (DEBUG) log('MASTER  ..stopped');

      // stop nodes
      if (DEBUG) log('WORKERS  stop..');
      workers.stop();

      // forced exit
      process.exit(0);
    });
  }

  function start () {

    // start proxy server
    if (DEBUG) log('MASTER  start..');
    serverStart(function () {
      if (DEBUG) log('MASTER  ..started at port %d', PORT);

      // start nodes
      if (DEBUG) log('WORKERS  start..');
      workers.start();

      // stop everything when requested
      process
        .on('SIGINT', stop)
        .on('SIGTERM', stop);
    });
  }

  return {
    start: start,
    stop: stop
  };
};
<commit_msg>replace forced exit to the once listener<commit_after>'use strict';
var log = require('./log');
module.exports = function (workers, options) {
  var DEBUG = options.debug;
  var CONCURRENCY = options.concurrency;
  var PORT = options.port;
  var serverInstance;

  function serverCreate () {
    var hash = require('string-hash');
    return require('net')
      .createServer({ pauseOnConnect: true }, function (connection) {
        var index = hash(connection.remoteAddress) % CONCURRENCY;
        workers.entrust(index, connection);
      });
  }

  function serverStart (callback) {
    serverInstance = serverCreate();
    serverInstance.listen(PORT, callback);
  }

  function serverStop (callback) {
    serverInstance.close(function (err) {
      if (err) console.log(err);
      else return callback();
    });
  }

  function stop () {

    // stop proxy server
    if (DEBUG) log('MASTER  stop..');
    serverStop(function () {
      if (DEBUG) log('MASTER  ..stopped');

      // stop nodes
      if (DEBUG) log('WORKERS  stop..');
      workers.stop();
    });
  }

  function start () {

    // start proxy server
    if (DEBUG) log('MASTER  start..');
    serverStart(function () {
      if (DEBUG) log('MASTER  ..started at port %d', PORT);

      // start nodes
      if (DEBUG) log('WORKERS  start..');
      workers.start();

      // stop everything when requested
      process.once('SIGINT', stop);
    });
  }

  return {
    start: start,
    stop: stop
  };
};
<|endoftext|>