<commit_before>/*
Copyright (c) 2015 Simon Cullen, http://github.com/cullens

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

$thing.WAKE_MIN_PERIOD = 500000;

/** @namespace $thing */

$thing.Mash = function() {
    // Mash by Johannes Baagoe <baagoe@baagoe.com>
    var n = 0xefc8249d;
    var mash = function(data) {
        data = data.toString();
        for (var i = 0; i < data.length; i++) {
            n += data.charCodeAt(i);
            var h = 0.02519603282416938 * n;
            n = h >>> 0;
            h -= n;
            h *= n;
            n = h >>> 0;
            h -= n;
            n += h * 0x100000000;
        }
        return (n >>> 0) * 2.3283064365386963e-10;
    };
    return mash;
};

/**
 * @memberOf $thing
 * @method create64BitId
 */
$thing.create64BitId = function() {
    var h1 = new $thing.Mash(),
        h2 = new $thing.Mash()
        ;

    for (var i = 0; i < arguments.length; i++)
        h1(arguments[i] || '');

    return  h1('').toString(16).split('.')[1] +
            h2($thing.getMicroTime()).toString(16).split('.')[1]
            ;
};

/**
 * @memberOf $thing
 * @method merge
 */
$thing.merge = function() {
    var args = $thing.arrayDup(arguments),
        obj = args[0],
        i = 1
        ;

    for(; i < args.length; i++)
        if (args[i] !== undefined)
            for(var k in args[i])
                (obj[k] === undefined)
                    ? obj[k] = args[i][k]
                    : undefined
                    ;

    return obj;
};

/**
 * @memberOf $thing
 * @method arrayDup
 */

$thing.arrayDup = function(src, length, destroySrc) {
    var i,
        l = src.length,
        dest = new Array(length || src.length)
        ;

    if (!destroySrc)
        for (i = 0; i < l; i++)
            dest[i] = src[i];
    else {

        for (i = 0; i < l; i++) {
            dest[i] = src[i];
            src[i] = undefined;
        }

        destroySrc.length = 0;

    }

    return dest;
};

/**
 * @memberOf $thing
 * @method arrayAppend
 */

$thing.arrayAppend = function(src, value) {
    var l = src.length,
        dest = new Array(l + 1)
        ;

    for (var i = 0; i < l; i++)
        dest[i] = src[i];

    dest[l] = value;

    return dest;
};

/**
 * @memberOf $thing
 * @method arrayToObject
 */

$thing.arrayToObject = function(values, predicates, cbTestFunc) {
    var obj = {};

    predicates = predicates || [];

    for (var i in values)
        if (!cbTestFunc || cbTestFunc(values[i]))
            obj[predicates[i] || i] = values[i];

    return obj;
};

$thing.containers = {
    main: {
        source: '$thing',
        heap: []
    }
};

/**
 * @memberOf $thing
 * @method $container
 */
$thing.$container = function(cb) {
    $thing.getContainer($thing.getThreadId(1));
    cb();
};

/**
 * @memberOf $thing
 * @method getContainer
 */
$thing.getContainer = function(threadId) {
    var container = $thing.containers[threadId[1]],
        parent = $thing.containers[threadId[2]]
        ;

    if (container === undefined) {

        container = $thing.containers[threadId[1]] = {
            heap: []
        };

        if (threadId[1] !== threadId[2] && parent !== undefined)
            for (var k in parent.heap)
                if (parent.heap[k].isAbstract)
                    container.heap.push(parent.heap[k]);

    }

    return container;
};

/**
 * @memberOf $thing
 * @method attach
 */
$thing.attach = function(def, heap) {

    if (def._id !== undefined)
        return def._id;
    else {
        var length = heap.length;

        while(heap.length !== 0 &&
            heap[heap.length - 1]._refCount === 0
        )
            (heap.pop())._id = undefined;

        if (!heap.length || heap.length !== length)
            def._id = heap.push(def) - 1;
        else {
            def._id = undefined;

            for(var i = heap.length - 1;
                i > -1 && def._id === undefined;
                i--
            )
                if (heap[i]._refCount === 0) {
                    heap[i]._id = undefined;
                    heap[def._id = i] = def;
                }

            if (def._id === undefined)
                def._id = heap.push(def) - 1;
        }

        return def._id;
    }
};

/**
 * @memberOf $thing
 * @method search
 */
$thing.search = function(obj, heap) {
    var match;

    for(var i = heap.length - 1; i > -1; i--) {
        if (heap[i]._refCount > 0) {
            for(var k in obj)
                if (!(match = obj[k] === heap[i][k]))
                    break;

                if (match)
                    return heap[i];
            }
        }

    return undefined;
};

/**
 * @memberOf $thing
 * @method searchMeta
 */
$thing.searchMeta = function(obj, predicate) {
    var type = 'string',
        cb = arguments[2],
        meta = (obj.getMeta !== undefined)
            ? obj.getMeta()
            : obj._meta
        ;

    switch(arguments[2]) {
        case 'int':
        case 'boolean':
        case 'string':
            type = arguments[2];
            cb = arguments[3];
    }

    meta.forEach(function(item) {
        item = item.match(/\S+/g);
        if (item !== null && item[0] === predicate) {
            item = item.slice(1);

            switch(type) {
                case 'int':
                    if (!isNaN(item[0] = parseInt(item[0])))
                        cb.apply(obj, item);
                    break;

                case 'boolean':
                    switch(item[0].toLowerCase()) {
                        case 'true':
                            item[0] = true;
                            cb.apply(obj, item);
                            break;

                        case 'false':
                            item[0] = false;
                            cb.apply(obj, item);
                            break;
                    }
                    break;

                default:
                    cb.apply(obj, item);
            }
        }
    });
};

/**
 * @memberOf $thing
 * @method cbBuilder
 */
$thing.cbBuilder = function(threadId, self, args, cbDone) {
    cbDone = cbDone || function(){};

    $thing.Tasker.thread(threadId);

    if (args.length === 0) cbDone();
    else {

        return function() {

            $thing.agent(self)
                .apply($thing, args)
                .apply($thing, arguments.length ? arguments : [$thing.Container]);

            cbDone();
        };

    }

};

/**
 * @method agent
 * @param {*}
 */
$thing.agent = function() {
    var cb,
        threadId,
        selector,
        filter,
        pattern,
        selects,
        callChain,
        refCount = 0
        ;

    switch(arguments.length) {
        case 0:
            return $thing.Tasker.thread($thing.getThreadId(1));

        case 2:
            if (typeof arguments[1] === 'function')
                cb = arguments[1];

            /* falls through */
        case 1:
            if (arguments[0] instanceof $thing.Pattern) {
                pattern = arguments[0];
                threadId = pattern.getThreadId();
                selector = new $thing.Selector(threadId, pattern, true);
                break;
            }
            else if (   typeof arguments[0] === 'object' &&
                        arguments[0].getInterfaces !== undefined
            ) {
                selector = arguments[0];
                threadId = selector.getThreadId();
                break;
            }

            /* falls through */
        default:
            var def = new $thing.Definition(
                $thing.Container,
                $thing.Agent,
                threadId = $thing.getThreadId(1),
                $thing.arrayDup(arguments)
            );

            if (def.class !== undefined)
                return def.refObject(function(obj, cbRelease) {
                    cbRelease();
                });
            else {
                selects = [];

                $thing.searchMeta(def, 'select', function() {
                    selects.push($thing.arrayDup(arguments));
                });

                selector = new $thing.Selector(
                    threadId,
                    pattern = (selects.length) ? selects : def.name,
                    true
                );
            }
    }

    filter = function(filters, callArgs) {

        return function() {
            var obj;

            switch(arguments.length) {
                case 0:
                    obj = $thing.Container;
                    break;

                case 1:
                    if (typeof arguments[0] === 'object' &&
                        arguments[0].getInterfaces !== undefined
                    ) {
                        obj = arguments[0];
                        break;
                    }

                    /* falls through */
                default:
                    var def = new $thing.Definition(
                            $thing.Container,
                            $thing.Agent,
                            $thing.getThreadId(1),
                            $thing.arrayDup(arguments)
                        )
                        ;

                    if (def.class !== undefined)
                        obj = def;
                    else {
                        selects = [];

                        $thing.searchMeta(def, 'select', function() {
                            selects.push($thing.arrayDup(arguments));
                        });

                        obj = new $thing.Pattern(
                            threadId,
                            (selects.length) ? selects : def.name
                        );
                    }

                    break;
            }

            obj.refObject(function(obj, cbRelease) {

                refCount++;

                if (pattern === undefined) {

                    selector.dispatch(
                        {   filters: filters,
                            method: callArgs[0],
                            args: callArgs.slice(1)
                        },
                        function() {

                            return $thing.cbBuilder(
                                threadId,
                                obj,
                                arguments,
                                function() {

                                    if (--refCount === 0) {

                                        if (cb !== undefined) cb();

                                        cbRelease();

                                    }

                                }
                            );
                        }
                    );

                }
                else {

                    selector.select();

                    selector.schedule();

                    selector.dispatch(
                        {   filters: filters,
                            method: callArgs[0],
                            args: callArgs.slice(1)
                        },
                        function() {

                            return $thing.cbBuilder(
                                threadId,
                                obj,
                                Array.prototype.slice.call(
                                    arguments,
                                    0,
                                    arguments.length - 1
                                ),
                                arguments[arguments.length - 1]
                            );
                        },
                        function() {

                            if (refCount > 1) refCount--;
                            else {

                                $thing.async.setImmediate(function() {

                                    if (--refCount === 0) {

                                        if (cb !== undefined) cb();

                                        cbRelease();

                                        selector.release();

                                    }

                                });

                            }

                        }
                    );

                }

            });

            return callChain;
        };
    };

    callChain = function() {

        return filter($thing.Filter.ALL, $thing.arrayDup(arguments));
    };

    callChain.all = callChain;

    callChain.first = function() {

        return filter($thing.Filter.FIRST, $thing.arrayDup(arguments));
    };

    callChain.last = function() {

        return filter($thing.Filter.LAST, $thing.arrayDup(arguments));
    };

    return callChain;
};<commit_msg>Added retainLength to arrayDup<commit_after>/*
Copyright (c) 2015 Simon Cullen, http://github.com/cullens

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

/** @namespace $thing */

$thing.Mash = function() {
    // Mash by Johannes Baagoe <baagoe@baagoe.com>
    var n = 0xefc8249d;
    var mash = function(data) {
        data = data.toString();
        for (var i = 0; i < data.length; i++) {
            n += data.charCodeAt(i);
            var h = 0.02519603282416938 * n;
            n = h >>> 0;
            h -= n;
            h *= n;
            n = h >>> 0;
            h -= n;
            n += h * 0x100000000;
        }
        return (n >>> 0) * 2.3283064365386963e-10;
    };
    return mash;
};

/**
 * @memberOf $thing
 * @method create64BitId
 */
$thing.create64BitId = function() {
    var h1 = new $thing.Mash(),
        h2 = new $thing.Mash()
        ;

    for (var i = 0; i < arguments.length; i++)
        h1(arguments[i] || '');

    return  h1('').toString(16).split('.')[1] +
            h2($thing.getMicroTime()).toString(16).split('.')[1]
            ;
};

/**
 * @memberOf $thing
 * @method merge
 */
$thing.merge = function() {
    var args = $thing.arrayDup(arguments),
        obj = args[0],
        i = 1
        ;

    for(; i < args.length; i++)
        if (args[i] !== undefined)
            for(var k in args[i])
                (obj[k] === undefined)
                    ? obj[k] = args[i][k]
                    : undefined
                    ;

    return obj;
};

/**
 * @memberOf $thing
 * @method arrayDup
 */

$thing.arrayDup = function(src, length, destroySrc, retainLength) {
    var i,
        l = length || src.length,
        dest = new Array(length || src.length)
        ;

    if (destroySrc === undefined || destroySrc === false)
        for (i = 0; i < l; i++)
            dest[i] = src[i];
    else {

        for (i = 0; i < l; i++) {
            dest[i] = src[i];
            src[i] = undefined;
        }

        if (retainLength === undefined)
            src.length = 0;
        else if (src.length > retainLength)
            src.length = retainLength;

    }

    return dest;
};

/**
 * @memberOf $thing
 * @method arrayAppend
 */

$thing.arrayAppend = function(src, value) {
    var l = src.length,
        dest = new Array(l + 1)
        ;

    for (var i = 0; i < l; i++)
        dest[i] = src[i];

    dest[l] = value;

    return dest;
};

/**
 * @memberOf $thing
 * @method arrayToObject
 */

$thing.arrayToObject = function(values, predicates, cbTestFunc) {
    var obj = {};

    predicates = predicates || [];

    for (var i in values)
        if (!cbTestFunc || cbTestFunc(values[i]))
            obj[predicates[i] || i] = values[i];

    return obj;
};

$thing.containers = {
    main: {
        source: '$thing',
        heap: []
    }
};

/**
 * @memberOf $thing
 * @method $container
 */
$thing.$container = function(cb) {
    $thing.getContainer($thing.getThreadId(1));
    cb();
};

/**
 * @memberOf $thing
 * @method getContainer
 */
$thing.getContainer = function(threadId) {
    var container = $thing.containers[threadId[1]],
        parent = $thing.containers[threadId[2]]
        ;

    if (container === undefined) {

        container = $thing.containers[threadId[1]] = {
            heap: []
        };

        if (threadId[1] !== threadId[2] && parent !== undefined)
            for (var k in parent.heap)
                if (parent.heap[k].isAbstract)
                    container.heap.push(parent.heap[k]);

    }

    return container;
};

/**
 * @memberOf $thing
 * @method attach
 */
$thing.attach = function(def, heap) {

    if (def._id !== undefined)
        return def._id;
    else {
        var length = heap.length;

        while(heap.length !== 0 &&
            heap[heap.length - 1]._refCount === 0
        )
            (heap.pop())._id = undefined;

        if (!heap.length || heap.length !== length)
            def._id = heap.push(def) - 1;
        else {
            def._id = undefined;

            for(var i = heap.length - 1;
                i > -1 && def._id === undefined;
                i--
            )
                if (heap[i]._refCount === 0) {
                    heap[i]._id = undefined;
                    heap[def._id = i] = def;
                }

            if (def._id === undefined)
                def._id = heap.push(def) - 1;
        }

        return def._id;
    }
};

/**
 * @memberOf $thing
 * @method search
 */
$thing.search = function(obj, heap) {
    var match;

    for(var i = heap.length - 1; i > -1; i--) {
        if (heap[i]._refCount > 0) {
            for(var k in obj)
                if (!(match = obj[k] === heap[i][k]))
                    break;

                if (match)
                    return heap[i];
            }
        }

    return undefined;
};

/**
 * @memberOf $thing
 * @method searchMeta
 */
$thing.searchMeta = function(obj, predicate) {
    var type = 'string',
        cb = arguments[2],
        meta = (obj.getMeta !== undefined)
            ? obj.getMeta()
            : obj._meta
        ;

    switch(arguments[2]) {
        case 'int':
        case 'boolean':
        case 'string':
            type = arguments[2];
            cb = arguments[3];
    }

    meta.forEach(function(item) {
        item = item.match(/\S+/g);
        if (item !== null && item[0] === predicate) {
            item = item.slice(1);

            switch(type) {
                case 'int':
                    if (!isNaN(item[0] = parseInt(item[0])))
                        cb.apply(obj, item);
                    break;

                case 'boolean':
                    switch(item[0].toLowerCase()) {
                        case 'true':
                            item[0] = true;
                            cb.apply(obj, item);
                            break;

                        case 'false':
                            item[0] = false;
                            cb.apply(obj, item);
                            break;
                    }
                    break;

                default:
                    cb.apply(obj, item);
            }
        }
    });
};

/**
 * @memberOf $thing
 * @method cbBuilder
 */
$thing.cbBuilder = function(threadId, self, args, cbDone) {
    cbDone = cbDone || function(){};

    $thing.Tasker.thread(threadId);

    if (args.length === 0) cbDone();
    else {

        return function() {

            $thing.agent(self)
                .apply($thing, args)
                .apply($thing, arguments.length ? arguments : [$thing.Container]);

            cbDone();
        };

    }

};

/**
 * @method agent
 * @param {*}
 */
$thing.agent = function() {
    var cb,
        threadId,
        selector,
        filter,
        pattern,
        selects,
        callChain,
        refCount = 0
        ;

    switch(arguments.length) {
        case 0:
            return $thing.Tasker.thread($thing.getThreadId(1));

        case 2:
            if (typeof arguments[1] === 'function')
                cb = arguments[1];

            /* falls through */
        case 1:
            if (arguments[0] instanceof $thing.Pattern) {
                pattern = arguments[0];
                threadId = pattern.getThreadId();
                selector = new $thing.Selector(threadId, pattern, true);
                break;
            }
            else if (   typeof arguments[0] === 'object' &&
                        arguments[0].getInterfaces !== undefined
            ) {
                selector = arguments[0];
                threadId = selector.getThreadId();
                break;
            }

            /* falls through */
        default:
            var def = new $thing.Definition(
                $thing.Container,
                $thing.Agent,
                threadId = $thing.getThreadId(1),
                $thing.arrayDup(arguments)
            );

            if (def.class !== undefined)
                return def.refObject(function(obj, cbRelease) {
                    cbRelease();
                });
            else {
                selects = [];

                $thing.searchMeta(def, 'select', function() {
                    selects.push($thing.arrayDup(arguments));
                });

                selector = new $thing.Selector(
                    threadId,
                    pattern = (selects.length) ? selects : def.name,
                    true
                );
            }
    }

    filter = function(filters, callArgs) {

        return function() {
            var obj;

            switch(arguments.length) {
                case 0:
                    obj = $thing.Container;
                    break;

                case 1:
                    if (typeof arguments[0] === 'object' &&
                        arguments[0].getInterfaces !== undefined
                    ) {
                        obj = arguments[0];
                        break;
                    }

                    /* falls through */
                default:
                    var def = new $thing.Definition(
                            $thing.Container,
                            $thing.Agent,
                            $thing.getThreadId(1),
                            $thing.arrayDup(arguments)
                        )
                        ;

                    if (def.class !== undefined)
                        obj = def;
                    else {
                        selects = [];

                        $thing.searchMeta(def, 'select', function() {
                            selects.push($thing.arrayDup(arguments));
                        });

                        obj = new $thing.Pattern(
                            threadId,
                            (selects.length) ? selects : def.name
                        );
                    }

                    break;
            }

            obj.refObject(function(obj, cbRelease) {

                refCount++;

                if (pattern === undefined) {

                    selector.dispatch(
                        {   filters: filters,
                            method: callArgs[0],
                            args: callArgs.slice(1)
                        },
                        function() {

                            return $thing.cbBuilder(
                                threadId,
                                obj,
                                arguments,
                                function() {

                                    if (--refCount === 0) {

                                        if (cb !== undefined) cb();

                                        cbRelease();

                                    }

                                }
                            );
                        }
                    );

                }
                else {

                    selector.select();

                    selector.schedule();

                    selector.dispatch(
                        {   filters: filters,
                            method: callArgs[0],
                            args: callArgs.slice(1)
                        },
                        function() {

                            return $thing.cbBuilder(
                                threadId,
                                obj,
                                Array.prototype.slice.call(
                                    arguments,
                                    0,
                                    arguments.length - 1
                                ),
                                arguments[arguments.length - 1]
                            );
                        },
                        function() {

                            if (refCount > 1) refCount--;
                            else {

                                $thing.async.setImmediate(function() {

                                    if (--refCount === 0) {

                                        if (cb !== undefined) cb();

                                        cbRelease();

                                        selector.release();

                                    }

                                });

                            }

                        }
                    );

                }

            });

            return callChain;
        };
    };

    callChain = function() {

        return filter($thing.Filter.ALL, $thing.arrayDup(arguments));
    };

    callChain.all = callChain;

    callChain.first = function() {

        return filter($thing.Filter.FIRST, $thing.arrayDup(arguments));
    };

    callChain.last = function() {

        return filter($thing.Filter.LAST, $thing.arrayDup(arguments));
    };

    return callChain;
};<|endoftext|>


<commit_before>'use strict';
var core = {};
var util = require('./util.js');
var fs = require('fs');
var mkdirp = require('mkdirp');
var config = require('nconf');
var winston = require('winston');
var CronJob = require('cron').CronJob;
var getLoggerSettings = function(consoleLog) {
  var settings = {
    transports: [
      new winston.transports.File({ filename: process.env.HOME + "/.evac/evac.log", json: false})
    ],
    exceptionHandlers: [
      new winston.transports.File({ filename: process.env.HOME + "/.evac/evac.log", json: false})
    ]
  };

  if (consoleLog) {
    settings.transports.push(new winston.transports.Console({colorize: true, timestamp: true}));
    settings.exceptionHandlers.push(new winston.transports.Console({colorize: true, timestamp: true}));
  }

  return settings;
};

var logger = new (winston.Logger)(getLoggerSettings(false));
var pluginPaths = [__dirname + '/plugin'];

var parseRecipeFile = function(path) {
  util.parseSettingFile(path, function(err, config){
    if (err) {
      logger.error("Error parsing your evac recipe file.");
      process.exit(1);
    }

    core.parseRecipeJson(config, function(err, message){
      if (err) {
        logger.error(message + " plugin - raise error.");
        logger.error(err);
        process.exit(1);
      }
    });
  });
};

var parseCronFile = function(path) {
  util.parseSettingFile(path, function(err, cronConfig){
    if (err) {
      logger.error("Error parsing your cron configuration file.");
      process.exit(1);
    }

    var jobs = [];

    for(var config in cronConfig) {
      var oneConfig = cronConfig[config];

      for (var schedule in oneConfig) {
        var job = new CronJob({
          cronTime: schedule,
          onTick: function() {
            parseRecipeFile(oneConfig[schedule]);
          },
          start: true
        });
      }
    }
  });
};

core.parseRecipeJson = function(recipe, callback) {
  if (!recipe.filter) {
    recipe.filter = {
      "through": {}
    };
  }

  var pluginType = ['out', 'filter', 'in'];
  var plugins = {};
  var args = {};

  pluginType.forEach(function(type) {
    for (var plugin in recipe[type]) {
      pluginPaths.forEach(function(path) {
        var pluginFileName = path + '/' + type + '/' + plugin.toLowerCase() + '.js';
        logger.debug("Search plugin : " + pluginFileName);

        if (fs.existsSync(pluginFileName)) {
          plugins[type] = require(pluginFileName);
          args[type] = recipe[type][plugin];
        }
      });
    }

    if (!plugins[type]) {
      callback("Plugin not found.", "Not defined.");
      return;
    }
  });

  try {
    plugins['in'].load(args['in'], function(err, outputs){
      if (err) {
        callback(err, "input");
        return;
      }

      logger.info("Input plugin called.");

      var filtering = function() {
        var passedWord = outputs.shift();

        plugins['filter'].filter(args['filter'], passedWord, function(err, output){
          logger.info("Filter plugin received: " + passedWord);

          if (err) {
            callback(err, "filter");
            return;
          }

          logger.info("Filter plugin called.");

          if (output == "") {
            logger.info("Filter plugin no output.");

            if (outputs.length == 0) {
              callback(false, null);
            } else {
              filtering();
            }
          } else {
            plugins['out'].output(args['out'], output, function(err, output){
              if (err) {
                callback(err, "output");
                return;
              }

              logger.info("Output plugin received: " + output);
              logger.info("Output finished.");

              if (outputs.length == 0) {
                callback(false, null);
              } else {
                filtering();
              }

              return;
            });
          }
        });
      };

      logger.info("Input filter passed %d words.", outputs.length);

      if (outputs.length == 0) {
        return;
      }

      filtering();
    });
  } catch(e) {
    logger.error(e.message);
    callback(e, e.message);
    return;
  }
};

core.start = function(program, args) {
  mkdirp.sync(process.env.HOME + "/.evac");

  logger = new (winston.Logger)(getLoggerSettings(program.verbose));

  if (program.path) {
    pluginPaths.push(program.path);
  }

  if (program.cron) {
    // cron mode
    parseCronFile(args[0]);
  } else {
    // normal mode
    logger.info('Settings are loaded from a file :' + args[0]);
    parseRecipeFile(args[0]);
  }
}

module.exports = core;
<commit_msg>ログ出力追加<commit_after>'use strict';
var core = {};
var util = require('./util.js');
var fs = require('fs');
var mkdirp = require('mkdirp');
var config = require('nconf');
var winston = require('winston');
var CronJob = require('cron').CronJob;
var getLoggerSettings = function(consoleLog) {
  var settings = {
    transports: [
      new winston.transports.File({ filename: process.env.HOME + "/.evac/evac.log", json: false})
    ],
    exceptionHandlers: [
      new winston.transports.File({ filename: process.env.HOME + "/.evac/evac.log", json: false})
    ]
  };

  if (consoleLog) {
    settings.transports.push(new winston.transports.Console({colorize: true, timestamp: true}));
    settings.exceptionHandlers.push(new winston.transports.Console({colorize: true, timestamp: true}));
  }

  return settings;
};

var logger = new (winston.Logger)(getLoggerSettings(false));
var pluginPaths = [__dirname + '/plugin'];

var parseRecipeFile = function(path) {
  util.parseSettingFile(path, function(err, config){
    if (err) {
      logger.error("Error parsing your evac recipe file.");
      process.exit(1);
    }

    core.parseRecipeJson(config, function(err, message){
      if (err) {
        logger.error(message + " plugin - raise error.");
        logger.error(err);
        process.exit(1);
      }
    });
  });
};

var parseCronFile = function(path) {
  util.parseSettingFile(path, function(err, cronConfig){
    if (err) {
      logger.error("Error parsing your cron configuration file.");
      process.exit(1);
    }

    var jobs = [];

    for(var config in cronConfig) {
      var oneConfig = cronConfig[config];

      for (var schedule in oneConfig) {
        var job = new CronJob({
          cronTime: schedule,
          onTick: function() {
            parseRecipeFile(oneConfig[schedule]);
          },
          start: true
        });
      }
    }
  });
};

core.parseRecipeJson = function(recipe, callback) {
  if (!recipe.filter) {
    recipe.filter = {
      "through": {}
    };
  }

  var pluginType = ['out', 'filter', 'in'];
  var plugins = {};
  var args = {};

  pluginType.forEach(function(type) {
    for (var plugin in recipe[type]) {
      pluginPaths.forEach(function(path) {
        var pluginFileName = path + '/' + type + '/' + plugin.toLowerCase() + '.js';
        logger.debug("Search plugin : " + pluginFileName);

        if (fs.existsSync(pluginFileName)) {
          plugins[type] = require(pluginFileName);
          args[type] = recipe[type][plugin];
        }
      });
    }

    if (!plugins[type]) {
      callback("Plugin not found.", "Not defined.");
      return;
    }
  });

  try {
    plugins['in'].load(args['in'], function(err, outputs){
      if (err) {
        callback(err, "input");
        return;
      }

      logger.info("Input plugin called.");

      var filtering = function() {
        var passedWord = outputs.shift();

        plugins['filter'].filter(args['filter'], passedWord, function(err, output){
          logger.info("Filter plugin received: " + passedWord);

          if (err) {
            callback(err, "filter");
            return;
          }

          logger.info("Filter plugin called.");

          if (output == "") {
            logger.info("Filter plugin no output.");
            logger.info("COMPLETE:\t" + passedWord + "\t" + output);

            if (outputs.length == 0) {
              callback(false, null);
            } else {
              filtering();
            }
          } else {
            plugins['out'].output(args['out'], output, function(err, output){
              if (err) {
                callback(err, "output");
                return;
              }

              logger.info("Output plugin received: " + output);
              logger.info("Output finished.");
              logger.info("COMPLETE:\t" + passedWord + "\t" + output);

              if (outputs.length == 0) {
                callback(false, null);
              } else {
                filtering();
              }

              return;
            });
          }
        });
      };

      logger.info("Input filter passed %d words.", outputs.length);

      if (outputs.length == 0) {
        return;
      }

      filtering();
    });
  } catch(e) {
    logger.error(e.message);
    callback(e, e.message);
    return;
  }
};

core.start = function(program, args) {
  mkdirp.sync(process.env.HOME + "/.evac");

  logger = new (winston.Logger)(getLoggerSettings(program.verbose));

  if (program.path) {
    pluginPaths.push(program.path);
  }

  if (program.cron) {
    // cron mode
    parseCronFile(args[0]);
  } else {
    // normal mode
    logger.info('Settings are loaded from a file :' + args[0]);
    parseRecipeFile(args[0]);
  }
}

module.exports = core;
<|endoftext|>


<commit_before>var getTemplateFunction = function (template, defaultFn) {
  if (_.isFunction(template))
    return template;
  else if (Template[template])
    return Template[template];
  else if (defaultFn)
    return defaultFn;
  else
    throw new Error('Oops, no template found named "' + template + '"');
};

var assertTemplateExists = function (template) {
  if (_.isFunction(template))
    return true;
  else if (!Template[template])
    throw new Error('Uh oh, no template found named "' + template + '"');
};

var ReactiveVar = function (value) {
  this._dep = new Deps.Dependency;
  this._value = value || null;
};

ReactiveVar.prototype = {
  set: function (value) {
    if (EJSON.equals(value, this._value))
      return;

    this._value = value;
    this._dep.changed();
  },

  get: function () {
    this._dep.depend();
    return this._value;
  },

  equals: function (other) {
    this._dep.depend();
    return EJSON.equals(this._value, other);
  }
};

LayoutController = function () {
  this.templates = new ReactiveDict;
  this.layout = new ReactiveVar;
  this.data = new ReactiveVar({});
  this.layout.set('__defaultLayout__');
};

LayoutController.prototype = {
  setLayout: function (layout) {
    assertTemplateExists(layout);
    this.layout.set(layout);
  },

  setTemplate: function (template, to) {
    var self = this;

    to = to || '__main__';
    assertTemplateExists(template);

    Deps.nonreactive(function () {
      if (to !== '__main__' && self.templates.equals(to, undefined)) {
        throw new Error(
          "Sorry, couldn\'t find a yield named \"" + to + "\". Did you define a named yield in your layout like this: {{yield \"" + to + "\"}}?");
      }
    });

    this.templates.set(to, template);
  },

  setData: function (data) {
    this.data.set(data || {});
  },

  helpers: function () {
    var self = this;
    return {
      'yield': function (key, options) {
        var html;

        if (arguments.length < 2)
          key = '__main__';

        html = self.renderTemplate(key);
        return new Handlebars.SafeString(html);
      }
    };
  },

  renderTemplate: function (key) {
    // this makes sure to register a key in the ReactiveDict. When you later
    // call setTemplate('templateName', {to: 'someYield'}) this lets us check
    // whether the yield has been defined, otherwise give a helpful error
    // message
    this.templates.setDefault(key, '');

    // grab the template function from Template or just make the template
    // function return an empty string if no template found
    var template = getTemplateFunction(this.templates.get(key), function () {
      return '';
    });

    var data = this.data.get();
    var helpers = this.helpers();
    var dataContext = _.extend({}, data, helpers);

    return template(dataContext);
  },

  render: function () {
    var self = this;
    return Spark.render(function () {
      return Spark.isolate(function () {
        var layout = getTemplateFunction(self.layout.get());
        var data = self.data.get();
        var helpers = self.helpers();
        var dataContext = _.extend({}, data, helpers);
        return layout(dataContext);
      });
    });
  }
};
<commit_msg>WIP - Make named yield check async.<commit_after>var getTemplateFunction = function (template, defaultFn) {
  if (_.isFunction(template))
    return template;
  else if (Template[template])
    return Template[template];
  else if (defaultFn)
    return defaultFn;
  else
    throw new Error('Oops, no template found named "' + template + '"');
};

var assertTemplateExists = function (template) {
  if (_.isFunction(template))
    return true;
  else if (!Template[template])
    throw new Error('Uh oh, no template found named "' + template + '"');
};

var ReactiveVar = function (value) {
  this._dep = new Deps.Dependency;
  this._value = value || null;
};

ReactiveVar.prototype = {
  set: function (value) {
    if (EJSON.equals(value, this._value))
      return;

    this._value = value;
    this._dep.changed();
  },

  get: function () {
    this._dep.depend();
    return this._value;
  },

  equals: function (other) {
    this._dep.depend();
    return EJSON.equals(this._value, other);
  }
};

LayoutController = function () {
  this.templates = new ReactiveDict;
  this.layout = new ReactiveVar;
  this.data = new ReactiveVar({});
  this.layout.set('__defaultLayout__');
  this._yields = {};
};

LayoutController.prototype = {
  setLayout: function (layout) {
    assertTemplateExists(layout);
    // reset because we have a new layout now
    this._yields = {};
    this.layout.set(layout);
  },

  setTemplate: function (template, to) {
    var self = this;

    to = to || '__main__';
    assertTemplateExists(template);

    Deps.nonreactive(function () {
      // make sure the yield region was declared otherwise the user may have
      // tried to render into a named yield that was never declared in the
      // layout. Let's provide them a helpful warning if that happens.
      Deps.afterFlush(function () {
        var isYieldDeclared = self._yields[to];
        var help;

        if (!isYieldDeclared) {
          if (to == '__main__')
            help = 'Sorry, couldn\'t find the main yield. Did you define it in one of the rendered templates like this: {{yield}}?';
          else
            help = 'Sorry, couldn\'t find a yield named "' + to + '". Did you define it in one of the rendered templates like this: {{yield "' + to + '"}}?';

          if (console && console.warn)
            console.warn(help);
          else if (console && console.error)
            console.error(help);
          else
            throw new Error(help);
        }
      });
    });

    this.templates.set(to, template);
  },

  setData: function (data) {
    this.data.set(data || {});
  },

  helpers: function () {
    var self = this;
    return {
      'yield': function (key, options) {
        var html;

        if (arguments.length < 2)
          key = null;

        html = self.renderTemplate(key);
        return new Handlebars.SafeString(html);
      }
    };
  },

  renderTemplate: function (key) {
    key = key || '__main__';

    // register that this named yield was used so we can check later that all
    // setTemplate calls were for a yield region that exists.
    this._yields[key] = true;

    // grab the template function from Template or just make the template
    // function return an empty string if no template found
    var template = getTemplateFunction(this.templates.get(key), function () {
      return '';
    });

    var data = this.data.get();
    var helpers = this.helpers();
    var dataContext = _.extend({}, data, helpers);

    return template(dataContext);
  },

  render: function () {
    var self = this;
    return Spark.render(function () {
      return Spark.isolate(function () {
        var layout = getTemplateFunction(self.layout.get());
        var data = self.data.get();
        var helpers = self.helpers();
        var dataContext = _.extend({}, data, helpers);
        return layout(dataContext);
      });
    });
  }
};
<|endoftext|>


<commit_before>'use strict';

var semver = require('semver');

var data = module.exports = {
  google: {
    jquery: {
      versions: ['2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
      }
    },
    'jquery-ui': {
      versions: ['1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
      }
    }
  },
  cdnjs: {}
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-sanitize'
];

angularFiles.forEach(function (item) {
  data.google[item] = {
    versions: ['1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});

// CDNJS

var cdnjs = require('./external/cdnjs.json').packages;

cdnjs.forEach(function (item) {
  data.cdnjs[item.name] = {
    versions: item.assets.map(function (asset) {
      return asset.version;
    }).filter(function (version) {
      return semver.valid(version);
    }),
    url: function (version) {
      return ['//cdnjs.cloudflare.com/ajax/libs', item.name, version,
        item.filename].join('/');
    }
  };
});
<commit_msg>feat(data): dojo, swfobject for google CDN<commit_after>'use strict';

var semver = require('semver');

var data = module.exports = {
  google: {
    jquery: {
      versions: ['2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
      }
    },
    'jquery-ui': {
      versions: ['1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
      }
    },
    dojo: {
      versions: ['1.9.1', '1.9.0', '1.8.5', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.3', '1.2.0', '1.1.1'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/dojo/' + version + '/dojo.js';
      }
    },
    swfobject: {
      versions: ['2.2', '2.1'],
      url: function (version) {
        return '//ajax.googleapis.com/ajax/libs/swfobject/' + version + '/swfobject.js';
      }
    }
  },
  cdnjs: {}
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-sanitize'
];

angularFiles.forEach(function (item) {
  data.google[item] = {
    versions: ['1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});

// CDNJS

var cdnjs = require('./external/cdnjs.json').packages;

cdnjs.forEach(function (item) {
  data.cdnjs[item.name] = {
    versions: item.assets.map(function (asset) {
      return asset.version;
    }).filter(function (version) {
      return semver.valid(version);
    }),
    url: function (version) {
      return ['//cdnjs.cloudflare.com/ajax/libs', item.name, version,
        item.filename].join('/');
    }
  };
});
<|endoftext|>


<commit_before>/*
 * NTwitBot - data.js
 * Copyright (C) 2016-2017 Jordan Sne
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

const fs = require('fs');

/**
 * Database & IO handler class.
 */
module.exports = class Data {

    /**
     * Initialize the class.
     * After instantiating, call init().
     * @param {Util} utils - The utilities object needed for logging, etc.
     */
    constructor(utils) {
        this.DATA_DIR = './data';
        this.DATABASE_FILE = this.DATA_DIR + '/db.json';
        this.STATE_FILE = this.DATA_DIR + '/state.json';

        this.utils = utils;
    }

    /**
     * Sets up the environment for proper data actions.
     * @return {Promise} Resolves when done setting up.
     */
    init() {
        return new Promise((resolve, reject) => {
            fs.mkdir(this.DATA_DIR, (error) => {
                if (error) {
                    if (error.code !== 'EEXIST') {
                        reject(error);
                        return;
                    }
                }

                resolve();
            });
        });
    }

    /**
     * Saves new tweet data into the database.
     * @param {Object} newData - The new tweet data to be saved.
     * @return {Promise} Resolves when done saving data
     */
    saveTweetData(newData) {
        return new Promise((resolve, reject) => {
            fs.readFile(this.DATABASE_FILE, (error, data) => {
                if (error) {
                    if (error.code === 'ENOENT') {
                        // Resolve with new data if a database doesn't exist
                        resolve(newData);
                    } else {
                        reject(error);
                    }
                    return;
                }

                // Otherwise insert new data into existing data:
                // For each key in the new data..
                for (let key in newData) {
                    // If the it exists in existing data
                    if (key in data) {
                        // Push (append), new data to exist array
                        for (let i = 0; i < newData[key].length; i++) {
                            data[key].push(newData[key][i]);
                        }
                    // .. else declare new array in existing data
                    } else {
                        data[key] = newData[key];
                    }
                }

                resolve(data);
            });
        }).then((dataToSave) => {
            return new Promise((resolve, reject) => {
                fs.writeFile(this.DATABASE_FILE, JSON.stringify(dataToSave), (error) => {
                    if (error) {
                        this.utils.logError("I/O: Failed to write data to database file (" + this.DATABASE_FILE + ")");
                        reject(error);
                        return;
                    }

                    this.utils.log("I/O: Saved tweet data to database");
                    resolve();
                });
            });
        });
    }

    /**
     * Reads the tweet data from the database.
     * @return {Object} The tweet data object from the database.
     */
    readTweetData() {
        return this.readFile(this.DATABASE_FILE).then((data) => {
            try {
                return JSON.parse(data);
            } catch (error) {
                this.utils.logError("I/O: Failed to parse database data");
                throw error;
            }
        }, (error) => {
            if (error.code === 'ENOENT') {
                this.utils.logError("I/O: No database file found");
            }
            throw error;
        });
    }

    /**
     * Saves the state in file.
     * @param {Object} state - The bot's state object.
     * @return {Promise} Resolves when done saving.
     */
    saveState(state) {
        return new Promise((resolve, reject) => {
            fs.writeFile(this.STATE_FILE, JSON.stringify(state), (error) => {
                if (error) {
                    this.utils.logError("I/O: Failed to save bot state to file");
                    reject(error);
                    return;
                }

                this.utils.log("I/O: Saved bot state to database");
                resolve();
            });
        });
    }

    /**
     * Gets the state from the saved state.
     * @return {Promise} Resolves with the read state object.
     */
    readState() {
        return this.readFile(this.STATE_FILE).then((data) => {
            try {
                return JSON.parse(data);
            } catch (error) {
                this.utils.logError("I/O: Failed to parse state data");
                throw error;
            }
        }, (error) => {
            // If no state file exists..
            if (error.code === 'ENOENT') {
                return null;
            } else {
                this.utils.logError("I/O: Failed to read data from state file");
                throw error;
            }
        });
    }
    /**
     * Reads data from a file.
     * @private
     * @param {string} filePath - The path to the file.
     * @return {Promise} Resolves with data read from the file.
     */
    readFile(filePath) {
        return new Promise((resolve, reject) => {
            // Check that file exists..
            fs.stat(filePath, (error, stats) => {
                if (error) {
                    reject(error);
                    return;
                }

                // .. then read
                fs.readFile(filePath, 'utf8', (error, data) => {
                    if (error) {
                        reject(error);
                        return;
                    }

                    resolve(data);
                });
            });
        });
    }

};
<commit_msg>Use helper method for saveTweetData()<commit_after>/*
 * NTwitBot - data.js
 * Copyright (C) 2016-2017 Jordan Sne
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

const fs = require('fs');

/**
 * Database & IO handler class.
 */
module.exports = class Data {

    /**
     * Initialize the class.
     * After instantiating, call init().
     * @param {Util} utils - The utilities object needed for logging, etc.
     */
    constructor(utils) {
        this.DATA_DIR = './data';
        this.DATABASE_FILE = this.DATA_DIR + '/db.json';
        this.STATE_FILE = this.DATA_DIR + '/state.json';

        this.utils = utils;
    }

    /**
     * Sets up the environment for proper data actions.
     * @return {Promise} Resolves when done setting up.
     */
    init() {
        return new Promise((resolve, reject) => {
            fs.mkdir(this.DATA_DIR, (error) => {
                if (error) {
                    if (error.code !== 'EEXIST') {
                        reject(error);
                        return;
                    }
                }

                resolve();
            });
        });
    }

    /**
     * Saves new tweet data into the database.
     * @param {Object} newData - The new tweet data to be saved.
     * @return {Promise} Resolves when done saving data
     */
    saveTweetData(newData) {
        return this.readFile(this.DATABASE_FILE).then((rawData) => {
            let data;

            try {
                data = JSON.parse(rawData);
            } catch (error) {
                this.utils.logError("I/O: Failed to parse state data");
                throw error;
            }

            // Insert new data into existing data:
            // For each key in the new data..
            for (let key in newData) {
                // If the it exists in existing data
                if (key in data) {
                    // Push (append), new data to exist array
                    for (let i = 0; i < newData[key].length; i++) {
                        data[key].push(newData[key][i]);
                    }
                // .. else declare new array in existing data
                } else {
                    data[key] = newData[key];
                }
            }

            return data;
        }, (error) => {
            if (error.code === 'ENOENT') {
                // Resolve with new data if a database doesn't exist
                return newData;
            } else {
                throw error;
            }
        }).then((dataToSave) => {
            return new Promise((resolve, reject) => {
                fs.writeFile(this.DATABASE_FILE, JSON.stringify(dataToSave), (error) => {
                    if (error) {
                        this.utils.logError("I/O: Failed to write data to database file (" + this.DATABASE_FILE + ")");
                        reject(error);
                        return;
                    }

                    this.utils.log("I/O: Saved tweet data to database");
                    resolve();
                });
            });
        });
    }

    /**
     * Reads the tweet data from the database.
     * @return {Object} The tweet data object from the database.
     */
    readTweetData() {
        return this.readFile(this.DATABASE_FILE).then((data) => {
            try {
                return JSON.parse(data);
            } catch (error) {
                this.utils.logError("I/O: Failed to parse database data");
                throw error;
            }
        }, (error) => {
            if (error.code === 'ENOENT') {
                this.utils.logError("I/O: No database file found");
            }
            throw error;
        });
    }

    /**
     * Saves the state in file.
     * @param {Object} state - The bot's state object.
     * @return {Promise} Resolves when done saving.
     */
    saveState(state) {
        return new Promise((resolve, reject) => {
            fs.writeFile(this.STATE_FILE, JSON.stringify(state), (error) => {
                if (error) {
                    this.utils.logError("I/O: Failed to save bot state to file");
                    reject(error);
                    return;
                }

                this.utils.log("I/O: Saved bot state to database");
                resolve();
            });
        });
    }

    /**
     * Gets the state from the saved state.
     * @return {Promise} Resolves with the read state object.
     */
    readState() {
        return this.readFile(this.STATE_FILE).then((data) => {
            try {
                return JSON.parse(data);
            } catch (error) {
                this.utils.logError("I/O: Failed to parse state data");
                throw error;
            }
        }, (error) => {
            // If no state file exists..
            if (error.code === 'ENOENT') {
                return null;
            } else {
                this.utils.logError("I/O: Failed to read data from state file");
                throw error;
            }
        });
    }
    /**
     * Reads data from a file.
     * @private
     * @param {string} filePath - The path to the file.
     * @return {Promise} Resolves with data read from the file.
     */
    readFile(filePath) {
        return new Promise((resolve, reject) => {
            // Check that file exists..
            fs.stat(filePath, (error, stats) => {
                if (error) {
                    reject(error);
                    return;
                }

                // .. then read
                fs.readFile(filePath, 'utf8', (error, data) => {
                    if (error) {
                        reject(error);
                        return;
                    }

                    resolve(data);
                });
            });
        });
    }

};
<|endoftext|>


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

var _ = require('lodash');
var async = require('async');

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

var actions = utils.getActions();

module.exports = function(program) {
	program
		.command('group-users [quantityOfUsers]')
		.alias('gu')
		.description('Create a group (site) populated with users.')
		.action(function(number) {
			number = !_.isNaN(Number(number)) ? Number(number) : 1;

			var groupId;
			var tasks = [];
			var userIds = [];

			function addGroup(asyncCallback) {
				actions.addGroup(1, function(error, results) {
					var group = JSON.parse(results[0]);

					console.log('');
					utils.printJSON(group);
					console.log('');

					groupId = group.groupId;
					asyncCallback();
				});
			}

			tasks.push(addGroup);

			function addUser(asyncCallback) {
				actions.addUser(number, function(error, results) {
					_.forEach(results, function(user) {
						userIds.push(JSON.parse(user).userId);
					});

					asyncCallback();
				});
			}

			tasks.push(addUser);

			async.series(tasks, function() {
				actions.addGroupUsers(groupId, userIds, function(error, response) {
					if (!error) {
						console.log('Users added to site!');
					}
				});
			});
		});

	return program;
}
<commit_msg>Improve logging for 'add group-users' command<commit_after>#!/usr/bin/env node

var _ = require('lodash');
var async = require('async');

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

var actions = utils.getActions();

module.exports = function(program) {
	program
		.command('group-users [quantityOfUsers]')
		.alias('gu')
		.description('Create a group (site) populated with users.')
		.action(function(number) {
			number = !_.isNaN(Number(number)) ? Number(number) : 1;

			var groupId;
			var tasks = [];
			var userIds = [];

			function addGroup(asyncCallback) {
				actions.addGroup(1, function(error, results) {
					var group = JSON.parse(results[0]);

					console.log('');
					console.log('Added site:');
					utils.printJSON(group);
					console.log('');

					groupId = group.groupId;
					asyncCallback();
				});
			}

			tasks.push(addGroup);

			function addUser(asyncCallback) {
				actions.addUser(number, function(error, results) {
					_.forEach(results, function(user) {
						user = JSON.parse(user);

						console.log('');
						console.log('Added user:');
						utils.printJSON(user);
						console.log('');

						userIds.push(user.userId);
					});

					asyncCallback();
				});
			}

			tasks.push(addUser);

			async.series(tasks, function() {
				actions.addGroupUsers(groupId, userIds, function(error, response) {
					if (!error) {
						console.log('Users added to site!');
					}
				});
			});
		});

	return program;
}
<|endoftext|>


<commit_before>// fad distribute tool

// 'use strict';

var crypto = require('crypto');
var path = require('path');
var fs = require('fs');
var glob = require("glob")
var colors = require('colors');

colors.setTheme({
    silly: 'rainbow',
    input: 'grey',
    verbose: 'cyan',
    prompt: 'grey',
    info: 'green',
    data: 'grey',
    help: 'cyan',
    warn: 'yellow',
    debug: 'blue',
    error: 'red'
});

var options = {
    algorithm: 'md5',
    encoding: 'utf8',
    // IMG_exts: 'gif|png|jpg|jpeg|bmp|ico',
    exclude_path: ['http://', 'https://', 'lib/', 'seajs/'],
    res_re: {
        'html': /staticUrl\s*\(\s*'([^']+)'\s*,\s*'(?:\w{7})?'\s*\)/gi,
        'css': /\(['"]?([^\)]+\.(?:gif|png|jpg|css))['"]?\)/gi,
        'js': /['"]([^'"]+\.(?:css|gif|jpg|png))['"]/gi
    },
    html_hash_update_re: "(staticUrl\\s*\\(\\s*'RES'\\s*,\\s*')(?:\\w{7})?('\\s*\\))",

    seamod_id_deps_re: /define\("([^"]+)",\[([^\]]+)\]/
};

var project_dir = '/Users/hwp/Frontend/nodejs/shengyb/';
var static_dir = 'static';
var static_dist = 'static_dist';

var seamods_dir = 'static/dist'

var seamods_files = '**/*.js'

// TODO not full real path, like  'images/' + (flag ? 'a' : 'b') + '.gif' , need map to real path
var realpath_map = {};

var hash_map = {};

var seamods_hash_map = {};

var globOptions = {
    cwd: project_dir
};

exports = module.exports = function(src) {

    var exec = require('child_process').exec, child;
    child = exec('rm -rf /Users/hwp/Frontend/nodejs/shengyb/static_dist', function (error, stdout, stderr) {

        // console.log(src)
        // src.forEach(function(s) {
        //     var files = glob.sync(s, globOptions)
        //     files.map(function(f){
        //         distRes(f)
        //     })
        // })

        var seamods = glob.sync(seamods_files, {cwd: path.join(project_dir, seamods_dir)})
        // console.log(seamods)
        seamods.map(function(f){
            distRes(f, 'seamod')
        })

        //seamods process
        // gen hash map
        seamods.forEach(function(m){
            seamods_hash_map[m.slice(0, -3)] = sha(path.join(static_dist, m))
        })
        console.log(seamods_hash_map)

        seamods.forEach(function(m){
            var content = fs.readFileSync(realpath(path.join(static_dist,m)), options.encoding)
            var match = content.match(options.seamod_id_deps_re)
            if(match) {
                // change id
                var id = match[1];
                content = content.replace(id, suffixModId(id))
                // change dep
                var deps = match[2];
                deps.split(',').map(function(dep){
                    dep = dep.replace(/"/g,'');
                    if(/^\.{1,2}\//.test(dep)){
                        var new_dep = suffixModId(path.join(path.dirname(m), dep));
                        new_dep = path.dirname(dep) + '/' + path.basename(new_dep)
                        //change deps with append hash suffix
                        content = content.replace(new RegExp(dep, "g"), new_dep)
                    }
                })
                var file = realpath(path.join(static_dist, m));
                fs.writeFileSync(file, content);
                // rename mod with append hash suffix
                fs.renameSync(file, suffixHash(file, seamods_hash_map[m.slice(0, -3)]));
                console.info('Update and rename: '.info + m)
            }
        })

        //insert mod hash map into seajs-config.js

    });
};

function suffixModId(id){
    var new_id = id + '_' + seamods_hash_map[id]
    if(id.slice(-3) === '.js'){
        new_id = id.slice(0, -3) + '_' + seamods_hash_map[id.slice(0, -3)] + '.js';
    }
    return new_id;
}

function distRes(file, is_res){

    var dist_file = file;
    if(is_res){
        console.info('DIST-File: '.info + file)
        dist_file = copyRes(file, is_res)
        // res not exists
        if(!dist_file){
            return false;
        }
    }

    res = extractRes(dist_file);
    if(realpath_map[file]){
        res = res.concat(realpath_map[file])
    }
    var replace_list = [];
    res.forEach(function(r){
        if(hash_map[r]){
            replace_list.push([r, is_res && suffixHash(r, hash_map[r])])
            return;
        }
        var dist_r;
        if(Object.keys(options.res_re).indexOf(extname(r)) > -1){
            dist_r = distRes(r, true)
        } else {
            console.info('DIST-IMG: '.info + r)
            dist_r = copyRes(r, file)
        }
        // res not exists
        if(!dist_r){
            return;
        }
        hash_map[r] = sha(dist_r)
        var newPath = suffixHash(r, hash_map[r])
        fs.renameSync(realpath(dist_r), realpath(path.join(path.dirname(dist_r), path.basename(newPath))));

        replace_list.push([r, is_res && newPath])
    })
    if(replace_list.length){
        console.info('UPDATE-File: '.info + dist_file)
        updateFile(dist_file, replace_list)
    }

    return dist_file
}

function copyRes(file, ref){
    var src_dir = static_dir;
    if(ref === 'seamod'){
        src_dir = seamods_dir;
    } else if(ref &&  /^\.{1,2}\//.test(file)){
        file  = path.join(path.dirname(ref), file)
    }
    var src = path.join(src_dir, file)
    var dest = path.join(static_dist, file);
    if(fs.existsSync(realpath(src))){
        copy(src, dest);
        return dest;
    } else {
        console.warn('The resource is not exist: '.warn + src)
        return false;
    }
}

function updateFile(file, replace_list) {
    file = realpath(file)
    var contents = fs.readFileSync(file, options.encoding);

    replace_list.forEach(function(r){
        if(!r[1]){
            r[1] = '$1' + hash_map[r[0]] + '$2';
            r[0] = new RegExp(options.html_hash_update_re.replace('RES', r[0]), "g");
        }
        contents = contents.replace(r[0], r[1]);
    })
    fs.writeFileSync(file, contents);
}

function sha(file){
    console.info('HASH-File: '.info + file)
    var shasum = crypto.createHash(options.algorithm);
    shasum.update(fs.readFileSync(realpath(file), options.encoding));
    var d = shasum.digest('hex');
    return d.substr(0, 7);
}

function suffixHash(filepath, hash){
    return path.join(path.dirname(filepath), path.basename(filepath, path.extname(filepath)) + '_' + hash + path.extname(filepath))
}

function extractRes(filepath){
    // console.log(filepath)
    var res_list = [];
    var ext = extname(filepath);
    // var ext_re = options.ext_re_map[ext].join('|').replace('IMG', options.IMG_exts)
    var RES_RE = options.res_re[ext];
    var content = fs.readFileSync(realpath(filepath), options.encoding);
    while(match = RES_RE.exec(content)){
        // console.log(match)
        var r = match[1]
        if(options.exclude_path.some(function (element){return r.indexOf(element) > -1})){
            continue;
        }
        res_list.push(r)
    }
    return res_list;
}

function realpath(filepath) {
    return globOptions.cwd ? path.join(globOptions.cwd, filepath) : filepath;
}

function extname(filepath){
    return path.extname(filepath).substr(1);
}

function copy(src, dest){
    var contents = fs.readFileSync(realpath(src));
    dest = realpath(dest)
    mkdir(path.dirname(dest));
    fs.writeFileSync(dest, contents);
}

var pathSeparatorRe = /[\/\\]/g;
// Like mkdir -p. Create a directory and any intermediary directories. from grunt
function mkdir(dirpath, mode) {
  // Set directory mode in a strict-mode-friendly way.
    if (mode == null) {
        mode = parseInt('0777', 8) & (~process.umask());
    }
    dirpath.split(pathSeparatorRe).reduce(function(parts, part) {
        parts += part + '/';
        var subpath = path.resolve(parts);
        if (!fs.existsSync(subpath)) {
            fs.mkdirSync(subpath, mode);
        }
        return parts;
    }, '');
}
<commit_msg>implement insert sea modules hash map into seajs-config.js<commit_after>// fad distribute tool

// 'use strict';

var crypto = require('crypto');
var path = require('path');
var fs = require('fs');
var glob = require("glob")
var colors = require('colors');

colors.setTheme({
    silly: 'rainbow',
    input: 'grey',
    verbose: 'cyan',
    prompt: 'grey',
    info: 'green',
    data: 'grey',
    help: 'cyan',
    warn: 'yellow',
    debug: 'blue',
    error: 'red'
});

var options = {
    algorithm: 'md5',
    encoding: 'utf8',
    // IMG_exts: 'gif|png|jpg|jpeg|bmp|ico',
    exclude_path: ['http://', 'https://', 'lib/', 'seajs/'],
    res_re: {
        'html': /staticUrl\s*\(\s*'([^']+)'\s*,\s*'(?:\w{7})?'\s*\)/gi,
        'css': /\(['"]?([^\)]+\.(?:gif|png|jpg|css))['"]?\)/gi,
        'js': /['"]([^'"]+\.(?:css|gif|jpg|png))['"]/gi
    },
    html_hash_update_re: "(staticUrl\\s*\\(\\s*'RES'\\s*,\\s*')(?:\\w{7})?('\\s*\\))",

    seamod_id_deps_re: /define\("([^"]+)",\[([^\]]+)\]/
};

var project_dir = '/Users/hwp/Frontend/nodejs/shengyb/';
var static_dir = 'static';
var static_dist = 'static_dist';

var seamods_dir = 'static/dist'
var seajs_config = "seajs-config*.js"

var seamods_files = '**/*.js'

// TODO not full real path, like  'images/' + (flag ? 'a' : 'b') + '.gif' , need map to real path
var realpath_map = {};

var hash_map = {};

var seamods_hash_map = {};

var globOptions = {
    cwd: project_dir
};

exports = module.exports = function(src) {

    var exec = require('child_process').exec, child;
    child = exec('rm -rf /Users/hwp/Frontend/nodejs/shengyb/static_dist', function (error, stdout, stderr) {

        src.forEach(function(s) {
            var files = glob.sync(s, globOptions)
            files.map(function(f){
                distRes(f)
            })
        })

        //seamods process
        var seamods = glob.sync(seamods_files, {cwd: path.join(project_dir, seamods_dir)})
        seamods.map(function(f){
            distRes(f, 'seamod')
        })
        // gen hash map
        seamods.forEach(function(m){
            seamods_hash_map[m] = sha(path.join(static_dist, m))
        })
        // update sea modules
        seamods.forEach(function(m){
            var content = fs.readFileSync(realpath(path.join(static_dist, m)), options.encoding)
            var match = content.match(options.seamod_id_deps_re)
            if(match) {
                // change id
                var id = match[1];
                content = content.replace(id, suffixModId(id))
                // change dep
                var deps = match[2];
                deps.split(',').map(function(dep){
                    dep = dep.replace(/"/g,'');
                    if(/^\.{1,2}\//.test(dep)){
                        var new_dep = suffixModId(path.join(path.dirname(m), dep));
                        new_dep = path.dirname(dep) + '/' + path.basename(new_dep)
                        //change deps with hash suffix
                        content = content.replace(new RegExp(dep, "g"), new_dep)
                    }
                })
                var file = realpath(path.join(static_dist, m));
                fs.writeFileSync(file, content);
                // rename mod with hash suffix
                fs.renameSync(file, suffixHash(file, seamods_hash_map[m]));
                console.info('Update and rename: '.info + m)
            }
        })
        //insert sea modules hash map into seajs-config.js
        var seaconf =  glob.sync(seajs_config, {cwd: path.join(project_dir, static_dist)})
        if(seaconf.length){
            seaconf = realpath(path.join(static_dist, seaconf[0])) ;
            var content = fs.readFileSync(seaconf, options.encoding);
            var maps = JSON.stringify(seamods_hash_map, 'null', '\t');
            content = '// sea modules hash map \nseajs.hashmap = ' + maps + '\n\n' + content;
            fs.writeFileSync(seaconf, content);
            console.info('Write hash map of sea modules into: '.info + path.basename(seaconf))
        }
    });
};

function suffixModId(id){
    var new_id;
    if(id.slice(-3) === '.js'){
        new_id = id.slice(0, -3) + '_' + seamods_hash_map[id] + '.js';
    } else {
        new_id = id + '_' + seamods_hash_map[id + '.js']
    }
    return new_id;
}

function distRes(file, is_res){

    var dist_file = file;
    if(is_res){
        console.info('DIST-File: '.info + file)
        dist_file = copyRes(file, is_res)
        // res not exists
        if(!dist_file){
            return false;
        }
    }

    res = extractRes(dist_file);
    if(realpath_map[file]){
        res = res.concat(realpath_map[file])
    }
    var replace_list = [];
    res.forEach(function(r){
        if(hash_map[r]){
            replace_list.push([r, is_res && suffixHash(r, hash_map[r])])
            return;
        }
        var dist_r;
        if(Object.keys(options.res_re).indexOf(extname(r)) > -1){
            dist_r = distRes(r, true)
        } else {
            console.info('DIST-IMG: '.info + r)
            dist_r = copyRes(r, file)
        }
        // res not exists
        if(!dist_r){
            return;
        }
        hash_map[r] = sha(dist_r)
        var newPath = suffixHash(r, hash_map[r])
        fs.renameSync(realpath(dist_r), realpath(path.join(path.dirname(dist_r), path.basename(newPath))));

        replace_list.push([r, is_res && newPath])
    })
    if(replace_list.length){
        console.info('UPDATE-File: '.info + dist_file)
        updateFile(dist_file, replace_list)
    }

    return dist_file
}

function copyRes(file, ref){
    var src_dir = static_dir;
    if(ref === 'seamod'){
        src_dir = seamods_dir;
    } else if(ref &&  /^\.{1,2}\//.test(file)){
        file  = path.join(path.dirname(ref), file)
    }
    var src = path.join(src_dir, file)
    var dest = path.join(static_dist, file);
    if(fs.existsSync(realpath(src))){
        copy(src, dest);
        return dest;
    } else {
        console.warn('The resource is not exist: '.warn + src)
        return false;
    }
}

function updateFile(file, replace_list) {
    file = realpath(file)
    var contents = fs.readFileSync(file, options.encoding);

    replace_list.forEach(function(r){
        if(!r[1]){
            r[1] = '$1' + hash_map[r[0]] + '$2';
            r[0] = new RegExp(options.html_hash_update_re.replace('RES', r[0]), "g");
        }
        contents = contents.replace(r[0], r[1]);
    })
    fs.writeFileSync(file, contents);
}

function sha(file){
    console.info('HASH-File: '.info + file)
    var shasum = crypto.createHash(options.algorithm);
    shasum.update(fs.readFileSync(realpath(file), options.encoding));
    var d = shasum.digest('hex');
    return d.substr(0, 7);
}

function suffixHash(filepath, hash){
    return path.join(path.dirname(filepath), path.basename(filepath, path.extname(filepath)) + '_' + hash + path.extname(filepath))
}

function extractRes(filepath){
    // console.log(filepath)
    var res_list = [];
    var ext = extname(filepath);
    // var ext_re = options.ext_re_map[ext].join('|').replace('IMG', options.IMG_exts)
    var RES_RE = options.res_re[ext];
    var content = fs.readFileSync(realpath(filepath), options.encoding);
    while(match = RES_RE.exec(content)){
        // console.log(match)
        var r = match[1]
        if(options.exclude_path.some(function (element){return r.indexOf(element) > -1})){
            continue;
        }
        res_list.push(r)
    }
    return res_list;
}

function realpath(filepath) {
    return globOptions.cwd ? path.join(globOptions.cwd, filepath) : filepath;
}

function extname(filepath){
    return path.extname(filepath).substr(1);
}

function copy(src, dest){
    var contents = fs.readFileSync(realpath(src));
    dest = realpath(dest)
    mkdir(path.dirname(dest));
    fs.writeFileSync(dest, contents);
}

var pathSeparatorRe = /[\/\\]/g;
// Like mkdir -p. Create a directory and any intermediary directories. from grunt
function mkdir(dirpath, mode) {
  // Set directory mode in a strict-mode-friendly way.
    if (mode == null) {
        mode = parseInt('0777', 8) & (~process.umask());
    }
    dirpath.split(pathSeparatorRe).reduce(function(parts, part) {
        parts += part + '/';
        var subpath = path.resolve(parts);
        if (!fs.existsSync(subpath)) {
            fs.mkdirSync(subpath, mode);
        }
        return parts;
    }, '');
}
<|endoftext|>


<commit_before>module.exports = docs

docs.usage = "npm docs <pkgname>"

docs.completion = function (opts, cb) {
  if (opts.conf.argv.remain.length > 2) return cb()
  registry.get("/-/short", 60000, function (er, list) {
    return cb(null, list || [])
  })
}

var npm = require("./npm.js")
  , registry = npm.registry
  , log = require("npmlog")
  , opener = require("opener")

function docs (args, cb) {
  if (!args.length) return cb(docs.usage)
  var project = args[0]
  var npmName = project.split("@").shift()
  registry.get(project + "/latest", 3600, function (er, d) {
    if (er) {
      if (project.split("/").length !== 2) return cb(er)

      var url = "https://github.com/" + project + "#readme"
      return opener(url, { command: npm.config.get("browser") }, cb)
    }

    var homepage = d.homepage
      , repo = d.repository || d.repositories
      , url = homepage ? homepage
            : "https://npmjs.org/package/" + d.name
    opener(url, { command: npm.config.get("browser") }, cb)
  })
}
<commit_msg>`npm docs` without args uses project in cwd<commit_after>module.exports = docs

docs.usage  = "npm docs <pkgname>"
docs.usage += "\n"
docs.usage += "npm docs ."

docs.completion = function (opts, cb) {
  if (opts.conf.argv.remain.length > 2) return cb()
  registry.get("/-/short", 60000, function (er, list) {
    return cb(null, list || [])
  })
}

var npm = require("./npm.js")
  , registry = npm.registry
  , opener = require("opener")
  , path = require('path')
  , log = require('npmlog')

function url (json) {
  return json.homepage ? json.homepage : "https://npmjs.org/package/" + json.name
}

function docs (args, cb) {
  var project = args[0] || '.'
    , package = path.resolve(process.cwd(), "package.json")

  if (project === '.') {
    try {
      var json = require(package)
      if (!json.name) throw new Error('package.json does not have a valid "name" property')
      project = json.name
    } catch (e) {
      log.error(e.message)
      return cb(docs.usage)
    }

    return opener(url(json), { command: npm.config.get("browser") }, cb)
  }

  registry.get(project + "/latest", 3600, function (er, json) {
    var github = "https://github.com/" + project + "#readme"

    if (er) {
      if (project.split("/").length !== 2) return cb(er)
      return opener(github, { command: npm.config.get("browser") }, cb)
    }

    return opener(url(json), { command: npm.config.get("browser") }, cb)
  })
}
<|endoftext|>


<commit_before>var async = require('async');
var Web3 = require('web3');

var Deploy = require('./deploy.js');
var ContractsManager = require('./contracts.js');

var DeployManager = function(options) {
  this.config = options.config;
  this.logger = options.logger;
  this.blockchainConfig = this.config.blockchainConfig;
  this.plugins = options.plugins;
  this.events = options.events;
  this.web3 = options.web3;
  // TODO: lol, redo this
  if (options.trackContracts !== false) {
    this.chainConfig = this.config.chainTracker;
  } else {
    this.chainConfig = false;
  }
};

DeployManager.prototype.deployContracts = function(done) {
  var self = this;

  if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
    self.logger.info("Blockchain component is disabled in the config".underline);
    self.events.emit('blockchainDisabled', {});
    return done();
  }

  async.waterfall([
  function buildContracts(callback) {
    var contractsManager = new ContractsManager({
      contractFiles:  self.config.contractsFiles,
      contractsConfig: self.config.contractsConfig,
      logger: self.logger,
      plugins: self.plugins
    });
    contractsManager.build(callback);
  },
  function connectWithWeb3(contractsManager, callback) {
    var web3;
    if (self.web3) {
      web3 = self.web3;
    } else {
      web3 = new Web3();
      var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort;
      web3.setProvider(new web3.providers.HttpProvider(web3Endpoint));
      if (!web3.isConnected()) {
        self.logger.error(("Couldn't connect to " + web3Endpoint.underline + " are you sure it's on?").red);
        self.logger.info("make sure you have an ethereum node or simulator running. e.g 'embark blockchain'".magenta);
        return callback(Error("error connecting to blockchain node"));
      }
    }
    callback(null, contractsManager, web3);
  },
  function setDefaultAccount(contractsManager, web3, callback) {
    web3.eth.getAccounts(function(err, accounts) {
      if (err) {
        return callback(new Error(err));
      }
      var selectedAccount = self.config.blockchainConfig.account.address;
      web3.eth.defaultAccount = (selectedAccount || accounts[0]);
      callback(null, contractsManager, web3);
    });
  },
  function deployAllContracts(contractsManager, web3, callback) {
    var deploy = new Deploy({
      web3: web3,
      contractsManager: contractsManager,
      logger: self.logger,
      chainConfig: self.chainConfig,
      env: self.config.env
    });
    deploy.deployAll(function() {
      self.events.emit('contractsDeployed', contractsManager);
      callback(null, contractsManager);
    });
  }
  ], function(err, result) {
    if (err) {
      done(err, null);
    } else {
      done(null, result);
    }
  });
};

module.exports = DeployManager;

<commit_msg>refactor condition<commit_after>var async = require('async');
var Web3 = require('web3');

var Deploy = require('./deploy.js');
var ContractsManager = require('./contracts.js');

var DeployManager = function(options) {
  this.config = options.config;
  this.logger = options.logger;
  this.blockchainConfig = this.config.blockchainConfig;
  this.plugins = options.plugins;
  this.events = options.events;
  this.web3 = options.web3;
  this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false;
};

DeployManager.prototype.deployContracts = function(done) {
  var self = this;

  if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
    self.logger.info("Blockchain component is disabled in the config".underline);
    self.events.emit('blockchainDisabled', {});
    return done();
  }

  async.waterfall([
  function buildContracts(callback) {
    var contractsManager = new ContractsManager({
      contractFiles:  self.config.contractsFiles,
      contractsConfig: self.config.contractsConfig,
      logger: self.logger,
      plugins: self.plugins
    });
    contractsManager.build(callback);
  },
  function connectWithWeb3(contractsManager, callback) {
    var web3;
    if (self.web3) {
      web3 = self.web3;
    } else {
      web3 = new Web3();
      var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort;
      web3.setProvider(new web3.providers.HttpProvider(web3Endpoint));
      if (!web3.isConnected()) {
        self.logger.error(("Couldn't connect to " + web3Endpoint.underline + " are you sure it's on?").red);
        self.logger.info("make sure you have an ethereum node or simulator running. e.g 'embark blockchain'".magenta);
        return callback(Error("error connecting to blockchain node"));
      }
    }
    callback(null, contractsManager, web3);
  },
  function setDefaultAccount(contractsManager, web3, callback) {
    web3.eth.getAccounts(function(err, accounts) {
      if (err) {
        return callback(new Error(err));
      }
      var selectedAccount = self.config.blockchainConfig.account.address;
      web3.eth.defaultAccount = (selectedAccount || accounts[0]);
      callback(null, contractsManager, web3);
    });
  },
  function deployAllContracts(contractsManager, web3, callback) {
    var deploy = new Deploy({
      web3: web3,
      contractsManager: contractsManager,
      logger: self.logger,
      chainConfig: self.chainConfig,
      env: self.config.env
    });
    deploy.deployAll(function() {
      self.events.emit('contractsDeployed', contractsManager);
      callback(null, contractsManager);
    });
  }
  ], function(err, result) {
    if (err) {
      done(err, null);
    } else {
      done(null, result);
    }
  });
};

module.exports = DeployManager;
<|endoftext|>


<commit_before>const util = require('util'),
    glob = require('glob'),
    file = require('./file'),
    queue = require('./queue');

module.exports = function (root) {
    const path = function (string) {
            return util.format('%s/%s', root, string);
        },
        all = function (pattern) {
            return glob.sync(path(pattern), {nocase: true}).map(function (item) {
                return file(item);
            });
        },

        index = all('{ops,oebps}/*.opf'),
        files = all('**/*.{htm,html,xhtml}'),
        styles = all('**/*.css'),
        fonts = all('**/*.{ttf,otf,woff}');

    return {
        root: root,
        index: index,
        files: files,
        styles: styles,
        fonts: fonts,
        persist: function (done) {
            const q = queue();

            [].concat(index, files, styles).forEach(function (item) {
                q.push(function (next) {
                    item.persist(next);
                });
            });

            q.process(done);
        }
    };
};
<commit_msg>Changes glob for epub index.<commit_after>const util = require('util'),
    glob = require('glob'),
    file = require('./file'),
    queue = require('./queue');

module.exports = function (root) {
    const path = function (string) {
            return util.format('%s/%s', root, string);
        },
        all = function (pattern) {
            return glob.sync(path(pattern), {nocase: true}).map(function (item) {
                return file(item);
            });
        },

        index = all('**/*.opf'),
        files = all('**/*.{htm,html,xhtml}'),
        styles = all('**/*.css'),
        fonts = all('**/*.{ttf,otf,woff}');

    return {
        root: root,
        index: index,
        files: files,
        styles: styles,
        fonts: fonts,
        persist: function (done) {
            const q = queue();

            [].concat(index, files, styles).forEach(function (item) {
                q.push(function (next) {
                    item.persist(next);
                });
            });

            q.process(done);
        }
    };
};
<|endoftext|>