<commit_before>import constant from 'lodash/constant';
import noop from './internal/noop';
import wrapAsync from './internal/wrapAsync';

/**
 * Attempts to get a successful response from `task` no more than `times` times
 * before returning an error. If the task is successful, the `callback` will be
 * passed the result of the successful task. If all attempts fail, the callback
 * will be passed the error and result (if any) of the final attempt.
 *
 * @name retry
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @see [async.retryable]{@link module:ControlFlow.retryable}
 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
 * object with `times` and `interval` or a number.
 * * `times` - The number of attempts to make before giving up.  The default
 *   is `5`.
 * * `interval` - The time to wait between retries, in milliseconds.  The
 *   default is `0`. The interval may also be specified as a function of the
 *   retry count (see example).
 * * `errorFilter` - An optional synchronous function that is invoked on
 *   erroneous result. If it returns `true` the retry attempts will continue;
 *   if the function returns `false` the retry flow is aborted with the current
 *   attempt's error and result being returned to the final callback.
 *   Invoked with (err).
 * * If `opts` is a number, the number specifies the number of times to retry,
 *   with the default interval of `0`.
 * @param {AsyncFunction} task - An async function to retry.
 * Invoked with (callback).
 * @param {Function} [callback] - An optional callback which is called when the
 * task has succeeded, or after the final failed attempt. It receives the `err`
 * and `result` arguments of the last attempt at completing the `task`. Invoked
 * with (err, results).
 *
 * @example
 *
 * // The `retry` function can be used as a stand-alone control flow by passing
 * // a callback, as shown below:
 *
 * // try calling apiMethod 3 times
 * async.retry(3, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 3 times, waiting 200 ms between each retry
 * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 10 times with exponential backoff
 * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
 * async.retry({
 *   times: 10,
 *   interval: function(retryCount) {
 *     return 50 * Math.pow(2, retryCount);
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod the default 5 times no delay between each retry
 * async.retry(apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod only when error condition satisfies, all other
 * // errors will abort the retry control flow and return to final callback
 * async.retry({
 *   errorFilter: function(err) {
 *     return err.message === 'Temporary error'; // only retry on a specific error
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // to retry individual methods that are not as reliable within other
 * // control flow functions, use the `retryable` wrapper:
 * async.auto({
 *     users: api.getUsers.bind(api),
 *     payments: async.retryable(3, api.getPayments.bind(api))
 * }, function(err, results) {
 *     // do something with the results
 * });
 *
 */
export default function retry(opts, task, callback) {
    var DEFAULT_TIMES = 5;
    var DEFAULT_INTERVAL = 0;

    var options = {
        times: DEFAULT_TIMES,
        intervalFunc: constant(DEFAULT_INTERVAL)
    };

    function parseTimes(acc, t) {
        if (typeof t === 'object') {
            acc.times = +t.times || DEFAULT_TIMES;

            acc.intervalFunc = typeof t.interval === 'function' ?
                t.interval :
                constant(+t.interval || DEFAULT_INTERVAL);

            acc.errorFilter = t.errorFilter;
        } else if (typeof t === 'number' || typeof t === 'string') {
            acc.times = +t || DEFAULT_TIMES;
        } else {
            throw new Error("Invalid arguments for async.retry");
        }
    }

    if (arguments.length < 3 && typeof opts === 'function') {
        callback = task || noop;
        task = opts;
    } else {
        parseTimes(options, opts);
        callback = callback || noop;
    }

    if (typeof task !== 'function') {
        throw new Error("Invalid arguments for async.retry");
    }

    var _task = wrapAsync(task);

    var attempt = 1;
    function retryAttempt() {
        _task(function(err) {
            if (err && attempt++ < options.times &&
                (typeof options.errorFilter != 'function' ||
                    options.errorFilter(err))) {
                setTimeout(retryAttempt, options.intervalFunc(attempt));
            } else {
                callback.apply(null, arguments);
            }
        });
    }

    retryAttempt();
}
<commit_msg>Drop constant<commit_after>import noop from './internal/noop';
import wrapAsync from './internal/wrapAsync';

function constant(value) {
    return function () {
        return value;
    }
}

/**
 * Attempts to get a successful response from `task` no more than `times` times
 * before returning an error. If the task is successful, the `callback` will be
 * passed the result of the successful task. If all attempts fail, the callback
 * will be passed the error and result (if any) of the final attempt.
 *
 * @name retry
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @see [async.retryable]{@link module:ControlFlow.retryable}
 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
 * object with `times` and `interval` or a number.
 * * `times` - The number of attempts to make before giving up.  The default
 *   is `5`.
 * * `interval` - The time to wait between retries, in milliseconds.  The
 *   default is `0`. The interval may also be specified as a function of the
 *   retry count (see example).
 * * `errorFilter` - An optional synchronous function that is invoked on
 *   erroneous result. If it returns `true` the retry attempts will continue;
 *   if the function returns `false` the retry flow is aborted with the current
 *   attempt's error and result being returned to the final callback.
 *   Invoked with (err).
 * * If `opts` is a number, the number specifies the number of times to retry,
 *   with the default interval of `0`.
 * @param {AsyncFunction} task - An async function to retry.
 * Invoked with (callback).
 * @param {Function} [callback] - An optional callback which is called when the
 * task has succeeded, or after the final failed attempt. It receives the `err`
 * and `result` arguments of the last attempt at completing the `task`. Invoked
 * with (err, results).
 *
 * @example
 *
 * // The `retry` function can be used as a stand-alone control flow by passing
 * // a callback, as shown below:
 *
 * // try calling apiMethod 3 times
 * async.retry(3, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 3 times, waiting 200 ms between each retry
 * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 10 times with exponential backoff
 * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
 * async.retry({
 *   times: 10,
 *   interval: function(retryCount) {
 *     return 50 * Math.pow(2, retryCount);
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod the default 5 times no delay between each retry
 * async.retry(apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod only when error condition satisfies, all other
 * // errors will abort the retry control flow and return to final callback
 * async.retry({
 *   errorFilter: function(err) {
 *     return err.message === 'Temporary error'; // only retry on a specific error
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // to retry individual methods that are not as reliable within other
 * // control flow functions, use the `retryable` wrapper:
 * async.auto({
 *     users: api.getUsers.bind(api),
 *     payments: async.retryable(3, api.getPayments.bind(api))
 * }, function(err, results) {
 *     // do something with the results
 * });
 *
 */
export default function retry(opts, task, callback) {
    var DEFAULT_TIMES = 5;
    var DEFAULT_INTERVAL = 0;

    var options = {
        times: DEFAULT_TIMES,
        intervalFunc: constant(DEFAULT_INTERVAL)
    };

    function parseTimes(acc, t) {
        if (typeof t === 'object') {
            acc.times = +t.times || DEFAULT_TIMES;

            acc.intervalFunc = typeof t.interval === 'function' ?
                t.interval :
                constant(+t.interval || DEFAULT_INTERVAL);

            acc.errorFilter = t.errorFilter;
        } else if (typeof t === 'number' || typeof t === 'string') {
            acc.times = +t || DEFAULT_TIMES;
        } else {
            throw new Error("Invalid arguments for async.retry");
        }
    }

    if (arguments.length < 3 && typeof opts === 'function') {
        callback = task || noop;
        task = opts;
    } else {
        parseTimes(options, opts);
        callback = callback || noop;
    }

    if (typeof task !== 'function') {
        throw new Error("Invalid arguments for async.retry");
    }

    var _task = wrapAsync(task);

    var attempt = 1;
    function retryAttempt() {
        _task(function(err) {
            if (err && attempt++ < options.times &&
                (typeof options.errorFilter != 'function' ||
                    options.errorFilter(err))) {
                setTimeout(retryAttempt, options.intervalFunc(attempt));
            } else {
                callback.apply(null, arguments);
            }
        });
    }

    retryAttempt();
}
<|endoftext|>


<commit_before>var themeServer = process.env.THEME_SERVER || 'http://themes.jsonresume.org/theme/';

var fs = require('fs');
var http = require('http');
var request = require('superagent');
var open = require('open');
var chalk = require('chalk');

module.exports = function(port, theme, silent) {
    http.createServer(function(req, res) {
        if (req.url == '/favicon.ico') {
            res.writeHead(200, {
                'Content-Type': 'image/x-icon'
            });
            res.end();
            return;
        }
        var file = process.cwd() + '/resume.json';
        fs.readFile(file, function(err, resumeJson) {
            var resumeJson;
            if (err) {
                console.log(chalk.yellow('Could not find:'), file);
                console.log(chalk.cyan('Using example resume.json from resume-schema instead...'));
                resumeJson = require('resume-schema').resumeJson;
            } else {
                try {
                    // todo: test resume schema
                    resumeJson = JSON.parse(resumeJson);
                } catch (e) {
                    var msg = 'Parse error: ' + file;
                    res.writeHead(404);
                    res.end(msg);
                    process.stdout.clearLine();
                    process.stdout.cursorTo(0);
                    console.log(msg);
                    return;
                }
            }
            res.writeHead(200, {
                'Content-Type': 'text/html'
            });
            try {
                var render = require(process.cwd() + '/index').render;
                try {
                    res.end(render(resumeJson));
                    console.log(chalk.cyan('Using local theme.'));
                } catch (e) {
                    console.log(e);
                    throw e;
                }
            } catch (e) {
                console.log(chalk.yellow('Could not find the render function from local theme.'));
                console.log(chalk.red('Errors:'), e);
                sendExportHTML(resumeJson, theme, function(html) {
                    res.end(html);
                });
            }
        });
    }).listen(port);

    console.log('');
    var previewUrl = 'http://localhost:' + port;
    console.log('Preview: ' + previewUrl);
    console.log('Press ctrl-c to stop')
    console.log('');

    if (!silent) {
        open(previewUrl);
    }
};

function sendExportHTML(resumeJson, theme, callback) {
    console.log('Requesting theme from server...');
    request
        .post(themeServer + theme)
        .send({
            resume: resumeJson
        })
        .set('Accept', 'application/json')
        .end(function(response) {
            if (response.text) {
                callback(response.text);
            } else {
                console.log('There was an error downloading your generated html resume from our server.');
            }
        });
    return;
}

// console.log javascript errors. could not find render function.<commit_msg>update error wording<commit_after>var themeServer = process.env.THEME_SERVER || 'http://themes.jsonresume.org/theme/';

var fs = require('fs');
var http = require('http');
var request = require('superagent');
var open = require('open');
var chalk = require('chalk');

module.exports = function(port, theme, silent) {
    http.createServer(function(req, res) {
        if (req.url == '/favicon.ico') {
            res.writeHead(200, {
                'Content-Type': 'image/x-icon'
            });
            res.end();
            return;
        }
        var file = process.cwd() + '/resume.json';
        fs.readFile(file, function(err, resumeJson) {
            var resumeJson;
            if (err) {
                console.log(chalk.yellow('Could not find:'), file);
                console.log(chalk.cyan('Using example resume.json from resume-schema instead...'));
                resumeJson = require('resume-schema').resumeJson;
            } else {
                try {
                    // todo: test resume schema
                    resumeJson = JSON.parse(resumeJson);
                } catch (e) {
                    var msg = 'Parse error: ' + file;
                    res.writeHead(404);
                    res.end(msg);
                    process.stdout.clearLine();
                    process.stdout.cursorTo(0);
                    console.log(msg);
                    return;
                }
            }
            res.writeHead(200, {
                'Content-Type': 'text/html'
            });
            try {
                var render = require(process.cwd() + '/index').render;
                try {
                    res.end(render(resumeJson));
                    console.log(chalk.cyan('Using local theme.'));
                } catch (e) {
                    console.log(e);
                    throw e;
                }
            } catch (e) {
                console.log(chalk.yellow('Could not run the render function from local theme.'));
                console.log(chalk.red('Errors:'), e);
                sendExportHTML(resumeJson, theme, function(html) {
                    res.end(html);
                });
            }
        });
    }).listen(port);

    console.log('');
    var previewUrl = 'http://localhost:' + port;
    console.log('Preview: ' + previewUrl);
    console.log('Press ctrl-c to stop')
    console.log('');

    if (!silent) {
        open(previewUrl);
    }
};

function sendExportHTML(resumeJson, theme, callback) {
    console.log('Requesting theme from server...');
    request
        .post(themeServer + theme)
        .send({
            resume: resumeJson
        })
        .set('Accept', 'application/json')
        .end(function(response) {
            if (response.text) {
                callback(response.text);
            } else {
                console.log('There was an error downloading your generated html resume from our server.');
            }
        });
    return;
}

// console.log javascript errors. could not find render function.<|endoftext|>


<commit_before>// -------------------------------------------------
//
// Gets config vars from ./package.json
//
// -------------------------------------------------

var fs = require('fs'),
  c = require('./console_format'),
  _ = require('underscore'),
  nconf = require("nconf");

var config_path = './package.json';

function correct_object_syntax() {
  c.log('{');
  c.log('\t"frontend": {');
  c.log('\t\t"name": "Your Project Name",');
  c.log('\t\t"stylesheets": "PATH_TO_YOUR_JAVASCRIPTS_FOLDER",');
  c.log('\t\t"javascripts": "PATH_TO_YOUR_STYLESHEETS_FOLDER"');
  c.log('\t}');
  c.log('}');
}

var passed_setup = false;

var self = module.exports = {

  // ------------------------------------------------
  // Error

  init: function init(callback) {

    if (fs.existsSync(config_path)) {
      // Do something

      var n = nconf.argv()
        .env()
        .file({
          file: config_path
        });

      c.ok("Found package.json...");

      if (!_.isObject(n.get('frontend'))) {

        // ------------------------------------------------
        // Check for Frontend object
        //

        c.error("Frontend object not found in " + config_path);
        c.info("Fix by making sure a \"frontend\" object exists:");
        correct_object_syntax();

      } else if (!_.isString(n.get('frontend').stylesheets)) {

        // ------------------------------------------------
        // Check for SCSS string
        //

        c.error("Stylesheets key not found in frontend object");
        console.log("%j", n.get('frontend'));
        c.log("Fix by making sure the frontend object is correctly formatted:");
        correct_object_syntax();

      } else if (!_.isString(n.get('frontend').javascripts)) {

        // ------------------------------------------------
        // Check for JS string
        //

        c.error("Javascripts key not found in frontend object");
        console.log("%j", n.get('frontend'));
        c.log("Fix by making sure the frontend object is correctly formatted:");
        correct_object_syntax();

      } else if (!fs.existsSync(n.get('frontend').stylesheets)) {

        // ------------------------------------------------
        // Check for Stylesheets folder accesibility
        //

        c.error("Couldn't find stylesheets folder \"" + n.get('frontend').stylesheets + "\"");
        c.log("Please check the folder path and try again.");

      } else if (!fs.existsSync(n.get('frontend').javascripts)) {

        // ------------------------------------------------
        // Check for Javascripts folder accesibility
        //

        c.error("Couldn't find javascripts folder \"" + n.get('frontend').javascripts + "\"");
        c.log("Please check the folder path and try again.");

      } else {

        // ------------------------------------------------
        // All's well
        //

        c.ok("Found javascripts & stylesheets folders...");

        // Run the callback
        callback([{
          "type": "scss",
          "title": "Stylesheets",
          "path": n.get('frontend').stylesheets
        }, {
          "type": "js",
          "title": "Javascripts",
          "path": n.get('frontend').javascripts
        }], n.get('frontend').name);

      }

    } else {

      c.error("Couldn't find " + config_path + ". Please create it in the root of your project and include a \"frontend\" object:");
      correct_object_syntax();

    }

  }

}<commit_msg>+ sass callback<commit_after>// -------------------------------------------------
//
// Gets config vars from ./package.json
//
// -------------------------------------------------

var fs = require('fs'),
  c = require('./console_format'),
  _ = require('underscore'),
  nconf = require("nconf");

var config_path = './package.json';

function correct_object_syntax() {
  c.log('{');
  c.log('\t"frontend": {');
  c.log('\t\t"name": "Your Project Name",');
  c.log('\t\t"stylesheets": "PATH_TO_YOUR_JAVASCRIPTS_FOLDER",');
  c.log('\t\t"javascripts": "PATH_TO_YOUR_STYLESHEETS_FOLDER"');
  c.log('\t}');
  c.log('}');
}

var passed_setup = false;

var self = module.exports = {

  // ------------------------------------------------
  // Error

  init: function init(callback) {

    if (fs.existsSync(config_path)) {
      // Do something

      var n = nconf.argv()
        .env()
        .file({
          file: config_path
        });

      c.ok("Found package.json...");

      if (!_.isObject(n.get('frontend'))) {

        // ------------------------------------------------
        // Check for Frontend object
        //

        c.error("Frontend object not found in " + config_path);
        c.info("Fix by making sure a \"frontend\" object exists:");
        correct_object_syntax();

      } else if (!_.isString(n.get('frontend').stylesheets)) {

        // ------------------------------------------------
        // Check for SCSS string
        //

        c.error("Stylesheets key not found in frontend object");
        console.log("%j", n.get('frontend'));
        c.log("Fix by making sure the frontend object is correctly formatted:");
        correct_object_syntax();

      } else if (!_.isString(n.get('frontend').javascripts)) {

        // ------------------------------------------------
        // Check for JS string
        //

        c.error("Javascripts key not found in frontend object");
        console.log("%j", n.get('frontend'));
        c.log("Fix by making sure the frontend object is correctly formatted:");
        correct_object_syntax();

      } else if (!fs.existsSync(n.get('frontend').stylesheets)) {

        // ------------------------------------------------
        // Check for Stylesheets folder accesibility
        //

        c.error("Couldn't find stylesheets folder \"" + n.get('frontend').stylesheets + "\"");
        c.log("Please check the folder path and try again.");

      } else if (!fs.existsSync(n.get('frontend').javascripts)) {

        // ------------------------------------------------
        // Check for Javascripts folder accesibility
        //

        c.error("Couldn't find javascripts folder \"" + n.get('frontend').javascripts + "\"");
        c.log("Please check the folder path and try again.");

      } else {

        // ------------------------------------------------
        // All's well
        //

        c.ok("Found javascripts & stylesheets folders...");

        // Run the callback
        callback([{
          "type": "sass",
          "title": "Stylesheets",
          "path": n.get('frontend').stylesheets
        }, {
          "type": "scss",
          "title": "Stylesheets",
          "path": n.get('frontend').stylesheets
        }, {
          "type": "js",
          "title": "Javascripts",
          "path": n.get('frontend').javascripts
        }], n.get('frontend').name);

      }

    } else {

      c.error("Couldn't find " + config_path + ". Please create it in the root of your project and include a \"frontend\" object:");
      correct_object_syntax();

    }

  }

}
<|endoftext|>


<commit_before>'use strict';

var engine = require('./engine.js');
var _ = require('lodash');
var Sync = require('./share/sync/sync.js');
var core = require('./core.js');
var Promise = require('bluebird');
var container = require('./share/sync/syncContainer.js');
var async = require('async');

var CONTAINER_NAME = 'kalabox_syncthing';

var logDebug = core.log.debug;

var logInfo = core.log.info;

var isAppRunning = function(appName) {
  return new Promise(function(fulfill, reject) {
    engine.list(appName, function(err, containers) {
      if (err) {
        reject(err);
      } else {
        async.reduce(containers, false, function(found, container, next) {
          if (!found) {
            engine.inspect(container.name, function(err, data) {
              if (err) {
                next(err);
              } else if (data.State.Running) {
                next(null, true);
              } else {
                next(null, found);
              }
            });
          } else {
            next(null, found);
          }
        },
      function(err, found) {
        if (err) {
          reject(err);
        } else {
          fulfill(found);
        }
      });
      }
    });
  });
};

var getDataContainers = function() {
  return new Promise(function(fulfill, reject) {
    engine.list(function(err, containers) {
      if (err) {
        reject(err);
      } else {
        fulfill(containers);
      }
    });
  })
  .filter(function(container) {
    var parts = container.name.split('_');
    var isDataContainer =
      parts.length === 3 &&
      parts[0] === 'kb' &&
      parts[2] === 'data';
    if (!isDataContainer) {
      return false;
    } else {
      return isAppRunning(parts[1]);
    }
  })
  .then(function(dataContainers) {
    return Promise.all(dataContainers);
  })
  .then(function(dataContainers) {
    logDebug('SHARE => Data containers with an app running.', dataContainers);
    return dataContainers;
  });
};

var getDataContainerVolume = function(dataContainer) {
  return new Promise(function(fulfill, reject) {
    engine.inspect(dataContainer.name, function(err, data) {
      if (err) {
        reject(err);
      } else {
        if (data.Volumes['/data']) {
          fulfill(data.Volumes['/data']);
        } else {
          fulfill(null);
        }
      }
    });
  });
};

var getVolumes = function() {
  return getDataContainers()
  .then(function(dataContainers) {
    var binds = _.map(dataContainers, function(dataContainer) {
      return getDataContainerVolume(dataContainer)
      .then(function(volume) {
        if (volume) {
          return {app: dataContainer.app, volume: volume};
        } else {
          return null;
        }
      });
    });
    return Promise.all(binds)
    .then(function(values) {
      return values.filter(function(value) {
        return (value !== null);
      });
    });
  });
};

var getCurrentShares = function(cb) {
  engine.inspect(CONTAINER_NAME, function(err, data) {
    if (err) {
      cb(err);
    } else {
      cb(null, data.Volumes);
    }
  });
};

var sharesToBinds = function(shares) {
  var binds = [];
  for (var key in shares) {
    binds.push([shares[key], key].join(':'));
  }
  return binds;
};

var getLocalSync = exports.getLocalSync = function() {
  return new Promise(function(fulfill) {
    fulfill(new Sync('127.0.0.1'));
  });
};

var getRemoteSync = exports.getRemoteSync = function() {
  return new Promise(function(fulfill, reject) {
    engine.provider.engineConfig(function(err, engineConfig) {
      if (err) {
        reject(err);
      } else {
        fulfill(new Sync(engineConfig.host));
      }
    });
  });
};

var resetSync = function(sync) {
  return sync.isUp()
  .then(function(isUp) {
    if (isUp) {
      return sync.clear()
      .then(function() {
        return sync.restartWait();
      });
    }
  });
};

var setupSyncs = function(volumes) {
  logDebug('SHARE => Setting up syncs.');

  var startLocal = getLocalSync()
    .then(function(localSync) {
      return localSync.isUp()
      .then(function(isUp) {
        if (!isUp) {
          return localSync.start();
        }
      })
      .then(function() {
        return localSync;
      });
    });

  return Promise.join(startLocal, getRemoteSync(),
  function(localSync, remoteSync) {
    return remoteSync.wait()
    .then(function() {
      return localSync.linkDevices(remoteSync);
    })
    .then(function() {
      return Promise.resolve(volumes)
      .each(function(volume) {
        return localSync.shareFolder(volume.app, remoteSync);
      });
    })
    .all()
    .then(function() {
      return Promise.join(remoteSync.restartWait(), localSync.restartWait());
    });
  });
};

var stop = function() {
  logDebug('SHARE => Stopping.');

  var stopLocal = getLocalSync()
    .then(function(localSync) {
      return resetSync(localSync);
    });

  var stopRemote = container.isInstalled()
    .then(function(isInstalled) {
      if (isInstalled) {
        logDebug('SHARE => isInstalled => ' + isInstalled);
        return container.isRunning()
        .then(function(isRunning) {
          if (isRunning) {
            logDebug('SHARE => isRunning => ' + isRunning);
            return getRemoteSync()
            .then(function(remoteSync) {
              return resetSync(remoteSync);
            })
            .then(function() {
              logDebug('SHARE => Stopping container.');
              return container.stop();
            });
          }
        })
        .then(function() {
          logDebug('SHARE => Removing container.');
          return container.remove;
        });
      }
    });

  return Promise.all([stopLocal, stopRemote]);

};

var start = function() {
  var _volumes = null;
  return container.isInstalled()
  // Validate current state
  .then(function(isInstalled) {
    if (isInstalled) {
      return Promise.reject('Sync container is already installed.');
    }
  })
  // Create container
  .then(function() {
    return getVolumes()
    .then(function(volumes) {
      _volumes = volumes;
      var binds = _.map(volumes, function(x) {
        return [x.volume, '/' + x.app].join(':');
      });
      logDebug('SHARE => Creating container.');
      return container.create(binds);
    });
  })
  // Start container
  .then(function() {
    logDebug('SHARE => Starting container.');
    return container.start();
  })
  // Setup syncs
  .then(function() {
    if (_volumes && _volumes.length > 0) {
      return setupSyncs(_volumes);
    } else {
      return Promise.resolve();
    }
  });

};

var restart = exports.restart = function(cb) {
  logDebug('SHARE => Restarting...');
  // Stop
  stop()
  .delay(10000)
  // Start
  .then(function() {
    return start();
  })
  .then(function() {
    logDebug('SHARE => Finished restarting.');
    cb();
  })
  .catch(function(err) {
    logInfo('SHARE => Error while restarting.', err);
    cb(err);
  });
};
<commit_msg>Code styling errors.<commit_after>'use strict';

var engine = require('./engine.js');
var _ = require('lodash');
var Sync = require('./share/sync/sync.js');
var core = require('./core.js');
var Promise = require('bluebird');
var container = require('./share/sync/syncContainer.js');
var async = require('async');

var CONTAINER_NAME = 'kalabox_syncthing';

var logDebug = core.log.debug;

var logInfo = core.log.info;

var isAppRunning = function(appName) {
  return new Promise(function(fulfill, reject) {
    engine.list(appName, function(err, containers) {
      if (err) {
        reject(err);
      } else {
        async.reduce(containers, false, function(found, container, next) {
          if (!found) {
            engine.inspect(container.name, function(err, data) {
              if (err) {
                next(err);
              } else if (data.State.Running) {
                next(null, true);
              } else {
                next(null, found);
              }
            });
          } else {
            next(null, found);
          }
        },
      function(err, found) {
        if (err) {
          reject(err);
        } else {
          fulfill(found);
        }
      });
      }
    });
  });
};

var getDataContainers = function() {
  return new Promise(function(fulfill, reject) {
    engine.list(function(err, containers) {
      if (err) {
        reject(err);
      } else {
        fulfill(containers);
      }
    });
  })
  .filter(function(container) {
    var parts = container.name.split('_');
    var isDataContainer =
      parts.length === 3 &&
      parts[0] === 'kb' &&
      parts[2] === 'data';
    if (!isDataContainer) {
      return false;
    } else {
      return isAppRunning(parts[1]);
    }
  })
  .then(function(dataContainers) {
    return Promise.all(dataContainers);
  })
  .then(function(dataContainers) {
    logDebug('SHARE => Data containers with an app running.', dataContainers);
    return dataContainers;
  });
};

var getDataContainerVolume = function(dataContainer) {
  return new Promise(function(fulfill, reject) {
    engine.inspect(dataContainer.name, function(err, data) {
      if (err) {
        reject(err);
      } else {
        if (data.Volumes['/data']) {
          fulfill(data.Volumes['/data']);
        } else {
          fulfill(null);
        }
      }
    });
  });
};

var getVolumes = function() {
  return getDataContainers()
  .then(function(dataContainers) {
    var binds = _.map(dataContainers, function(dataContainer) {
      return getDataContainerVolume(dataContainer)
      .then(function(volume) {
        if (volume) {
          return {app: dataContainer.app, volume: volume};
        } else {
          return null;
        }
      });
    });
    return Promise.all(binds)
    .then(function(values) {
      return values.filter(function(value) {
        return (value !== null);
      });
    });
  });
};

var getCurrentShares = function(cb) {
  engine.inspect(CONTAINER_NAME, function(err, data) {
    if (err) {
      cb(err);
    } else {
      cb(null, data.Volumes);
    }
  });
};

var sharesToBinds = function(shares) {
  var binds = [];
  for (var key in shares) {
    binds.push([shares[key], key].join(':'));
  }
  return binds;
};

var getLocalSync = exports.getLocalSync = function() {
  return new Promise(function(fulfill) {
    fulfill(new Sync('127.0.0.1'));
  });
};

var getRemoteSync = exports.getRemoteSync = function() {
  return new Promise(function(fulfill, reject) {
    engine.provider.engineConfig(function(err, engineConfig) {
      if (err) {
        reject(err);
      } else {
        fulfill(new Sync(engineConfig.host));
      }
    });
  });
};

var resetSync = function(sync) {
  return sync.isUp()
  .then(function(isUp) {
    if (isUp) {
      return sync.clear()
      .then(function() {
        return sync.restartWait();
      });
    }
  });
};

var setupSyncs = function(volumes) {
  logDebug('SHARE => Setting up syncs.');

  var startLocal = getLocalSync()
    .then(function(localSync) {
      return localSync.isUp()
      .then(function(isUp) {
        if (!isUp) {
          return localSync.start();
        }
      })
      .then(function() {
        return localSync;
      });
    });

  return Promise.join(startLocal, getRemoteSync(),
  function(localSync, remoteSync) {
    return remoteSync.wait()
    .then(function() {
      return localSync.linkDevices(remoteSync);
    })
    .then(function() {
      return Promise.resolve(volumes)
      .each(function(volume) {
        return localSync.shareFolder(volume.app, remoteSync);
      });
    })
    .all()
    .then(function() {
      return Promise.join(remoteSync.restartWait(), localSync.restartWait());
    });
  });
};

var stop = function() {
  logDebug('SHARE => Stopping.');

  var stopLocal = getLocalSync()
    .then(function(localSync) {
      return resetSync(localSync);
    });

  var stopRemote = container.isInstalled()
    .then(function(isInstalled) {
      if (isInstalled) {
        logDebug('SHARE => isInstalled => ' + isInstalled);
        return container.isRunning()
        .then(function(isRunning) {
          if (isRunning) {
            logDebug('SHARE => isRunning => ' + isRunning);
            return getRemoteSync()
            .then(function(remoteSync) {
              return resetSync(remoteSync);
            })
            .then(function() {
              logDebug('SHARE => Stopping container.');
              return container.stop();
            });
          }
        })
        .then(function() {
          logDebug('SHARE => Removing container.');
          return container.remove;
        });
      }
    });

  return Promise.all([stopLocal, stopRemote]);

};

var start = function() {
  var _volumes = null;
  return container.isInstalled()
  // Validate current state
  .then(function(isInstalled) {
    if (isInstalled) {
      return Promise.reject('Sync container is already installed.');
    }
  })
  // Create container
  .then(function() {
    return getVolumes()
    .then(function(volumes) {
      _volumes = volumes;
      var binds = _.map(volumes, function(x) {
        return [x.volume, '/' + x.app].join(':');
      });
      logDebug('SHARE => Creating container.');
      return container.create(binds);
    });
  })
  // Start container
  .then(function() {
    logDebug('SHARE => Starting container.');
    return container.start();
  })
  // Setup syncs
  .then(function() {
    if (_volumes && _volumes.length > 0) {
      return setupSyncs(_volumes);
    } else {
      return Promise.resolve();
    }
  });

};

var restart = exports.restart = function(cb) {
  logDebug('SHARE => Restarting...');
  // Stop
  stop()
  .delay(10000)
  // Start
  .then(function() {
    return start();
  })
  .then(function() {
    logDebug('SHARE => Finished restarting.');
    cb();
  })
  .catch(function(err) {
    logInfo('SHARE => Error while restarting.', err);
    cb(err);
  });
};
<|endoftext|>


<commit_before>'use strict';

const fetch = require('node-fetch'),
    winston = require('winston'),
    moment = require('moment');

module.exports = (slackHook, slackChannel) => {
    return res => {
        return res.json()
            .then(json => {
                let reqBody = JSON.stringify({
                    attachments: [
                        {
                            fallback: `Uploaded ${json.name} to TestBuild.rocks`,
                            pretext: `Uploaded ${json.name} to TestBuild.rocks`,
                            title: json.name,
                            title_link: json.install,
                            color: 'good',
                            fields: [
                                {
                                    title: 'Version',
                                    value: ''+json.version,
                                    short: true
                                },
                                {
                                    title: 'Build#',
                                    value: ''+json.build,
                                    short: true
                                },
                                {
                                    title: 'Platform',
                                    value: json.type,
                                    short: true
                                },
                                {
                                    title: 'Date',
                                    value: moment.unix(json.date).format('llll'),
                                    short: true
                                },
                                {
                                    title: 'Comment',
                                    value: json.comment
                                }
                            ],
                            image_url: json.qrcode,
                            thumb_url: json.iconurl
                        }
                    ],
                    channel: slackChannel
                });
                return fetch(slackHook, {
                    method: 'POST',
                    body: req
                })
                    .then(res => {
                        return {res, reqBody}
                    });
            })
            .then(({res, reqBody}) => {
                if (res.status == 200) {
                    winston.info('Sent to Slack');
                    return;
                }
                return res.text().then((body) => {
                    throw new Error(`Failed to send to slack (${slackHook}, ${slackChannel}) [${body}] [${reqBody}]`);
                });
            });
    };
};
<commit_msg>fix incorrect var name<commit_after>'use strict';

const fetch = require('node-fetch'),
    winston = require('winston'),
    moment = require('moment');

module.exports = (slackHook, slackChannel) => {
    return res => {
        return res.json()
            .then(json => {
                let reqBody = JSON.stringify({
                    attachments: [
                        {
                            fallback: `Uploaded ${json.name} to TestBuild.rocks`,
                            pretext: `Uploaded ${json.name} to TestBuild.rocks`,
                            title: json.name,
                            title_link: json.install,
                            color: 'good',
                            fields: [
                                {
                                    title: 'Version',
                                    value: ''+json.version,
                                    short: true
                                },
                                {
                                    title: 'Build#',
                                    value: ''+json.build,
                                    short: true
                                },
                                {
                                    title: 'Platform',
                                    value: json.type,
                                    short: true
                                },
                                {
                                    title: 'Date',
                                    value: moment.unix(json.date).format('llll'),
                                    short: true
                                },
                                {
                                    title: 'Comment',
                                    value: json.comment
                                }
                            ],
                            image_url: json.qrcode,
                            thumb_url: json.iconurl
                        }
                    ],
                    channel: slackChannel
                });
                return fetch(slackHook, {
                    method: 'POST',
                    body: reqBody
                })
                    .then(res => {
                        return {res, reqBody}
                    });
            })
            .then(({res, reqBody}) => {
                if (res.status == 200) {
                    winston.info('Sent to Slack');
                    return;
                }
                return res.text().then((body) => {
                    throw new Error(`Failed to send to slack (${slackHook}, ${slackChannel}) [${body}] [${reqBody}]`);
                });
            });
    };
};
<|endoftext|>


<commit_before>'use strict';

// stack-only words; using only .dpop .dpush
// TODO add manipulations, double, float, return stack words

var def = require('./def'),
    Long = require('long');

function stack (cxt) {
    cxt.DS = [];
    cxt.RS = [];
    cxt.dtop = function () { return this.DS[this.DS.length - 1]; },
    cxt.dnext = function () { return this.DS[this.DS.length - 2]; },
    cxt.dpop = function () { return this.DS.pop(); },
    cxt.dpush = function (e) { this.DS.push(e); };
    cxt.rtop = function () { return this.RS[this.RS.length - 1]; },
    cxt.rnext = function () { return this.RS[this.RS.length - 2]; },
    cxt.rpick2 = function () { return this.RS[this.RS.length - 3]; },
    cxt.rpop = function () { return this.RS.pop(); },
    cxt.rpush = function (e) { this.RS.push(e); };

    // stack primitives
    var core = {
        drop: function () {
            this.dpop();
        },
        dup: function () {
            var t = this.dtop();
            this.dpush(t);
        },
        over: function () {
            var n = this.dnext();
            this.dpush(n);
        },
        swap: function () {
            var t = this.dpop();
            var n = this.dpop();
            this.dpush(t);
            this.dpush(n);
        },
        '>r': function () {
            this.rpush(this.dpop());
        },
        'r>': function () {
            this.dpush(this.rpop());
        },
        'r@': function () {
            var rtop = this.rtop();
            this.dpush(rtop);
        },
        // 6.1.0100 */ ( n1 n2 n3 -- n4 ) “star-slash” (CORE)
        // Multiply n1 by n2 producing the intermediate double-cell result d.
        // Divide d by n3 giving the single-cell quotient n4. An ambiguous
        // condition exists if n3 is zero or if the quotient n4 lies outside
        // the range of a signed number. If d and n3 differ in sign, the
        // implementation-defined result returned will be the same as that
        // returned by either the phrase >R M* R> FM/MOD SWAP DROP or
        // the phrase >R M* R> SM/REM SWAP DROP.
        '*/': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var m = this.dpop() | 0;
            var ddd = Long.fromInt(m);
            ddd = ddd.mul(Long.fromInt(n));
            ddd = ddd.div(Long.fromInt(t));
            ddd = ddd.toInt();
            this.dpush(ddd | 0);
        },

        // 6.1.0110 */MOD “star-slash-mod” (CORE)
        // ( n1 n2 n3 -- n4 n5 )
        // Multiply n1 by n2 producing the intermediate double-cell result d.
        // Divide d by n3 producing the single-cell remainder n4 and the
        // single-cell quotient n5. An ambiguous condition exists if n3 is zero,
        // or if the quotient n5 lies outside the range of a single-cell signed
        // integer. If d and n3 differ in sign, the implementation-defined
        // result returned will be the same as that returned by either
        // the phrase >R M* R> FM/MOD or the phrase >R M* R> SM/REM.
        '*/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var m = this.dpop() | 0;
            var ddd = Long.fromInt(m);
            ddd = ddd.mul(Long.fromInt(n));

            var r0 = ddd.div(Long.fromInt(t));
            r0 = r0.toInt();

            var r1 = ddd.mod(Long.fromInt(t));
            r1 = r1.toInt();

            this.dpush(r1 | 0);
            this.dpush(r0 | 0);
        },
        '/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            this.dpush((n % t) | 0);
            this.dpush((n / t) | 0);
        },
        nip: function () {
            'swap'();
            'drop'();
        },
        // rot ( x1 x2 x3 -- x2 x3 x1 )
        rot: function () {
            var x3 = this.dpop();
            var x2 = this.dpop();
            var x1 = this.dpop();
            this.dpush(x2);
            this.dpush(x3);
            this.dpush(x1);
        },
        // 2drop ( w1 w2 -- )
        '2drop': function () {
            'drop'();
            'drop'();
        },
        // 2dup ( w1 w2 -- w1 w2 w1 w2 )
        '2dup': function () {
            'over'();
            'over'();
        },
        // 2over ( w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2 )
        '2over': function () {
            '>r'(); '>r'();
            'over'(); 'over'();
            'r>'();
            'rot'(); 'rot'();
            'r>'();
            'rot'(); 'rot'();
        },
        // 2swap ( w1 w2 w3 w4 -- w3 w4 w1 w2 )
        '2swap': function () {
            'rot'(); '>r'(); 'rot'(); 'r>'();
        },

        'depth': function () {
            this.dpush(this.DS.length);
        },

        // 6.1.1810 M* “m-star” (CORE)
        // ( n1 n2 -- d )
        // d is the signed product of n1 times n2 .
        'm*': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var ddd = Long.fromInt(n);
            ddd = ddd.mul(Long.fromInt(t));
            this.dpush(ddd.low);
            this.dpush(ddd.high);
        },

        // 6.1.2360 UM* “u-m-star” (CORE)
        // ( u1 u2 -- ud )
        // Multiply u 1 by u 2, giving the unsigned double-cell product ud.
        // All values and arithmetic are unsigned.
        'um*': function () {
            var t = this.dpop();
            var n = this.dpop();
            var ddd = Long.fromInt(n, true);
            ddd = ddd.mul(t, true);
            this.dpush(ddd.low);
            this.dpush(ddd.high);
        },

        // 6.1.2214 SM/REM “s-m-slash-rem” (CORE)
        // ( d1 n1 -- n2 n3 )
        // Divide d1 by n1, giving the symmetric quotient n3 and the remainder n2.
        // Input and output stack arguments are signed. An ambiguous condition
        // exists if n1 is zero or if the quotient lies outside the range of a
        // single-cell signed integer.
        'sm/rem': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var s = this.dpop() | 0;
            var ddd = new Long(s, n);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1);
            this.dpush(r0);
        },

        // 6.1.2370 UM/MOD “u-m-slash-mod” (CORE)
        // ( ud u1 -- u2 u3 )
        // Divide ud by u1, giving the quotient u3 and the remainder u2.
        // All values and arithmetic are unsigned. An ambiguous condition exists
        // if u1 is zero or if the qukrusaotient lies outside the range of
        // a single-cell unsigned integer.
        'um/mod': function () {
            var t = this.dpop() >>> 0;
            var n = this.dpop() >>> 0;
            var s = this.dpop() >>> 0;
            var ddd = new Long(s, n, true);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1);
            this.dpush(r0);
        },

        // fm/mod
        // 6.1.1561 FM/MOD “f-m-slash-mod” (CORE)
        // ( d1 n1 -- n2 n3 )
        // Divide d1 by n1, giving the floored quotient n3 and the remainder n2.
        // Input and output stack arguments are signed. An ambiguous condition
        //  exists if n is zero or if the quotient lies outside 1the range of a
        // single-cell signed integer.
        'fm/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var s = this.dpop() | 0;
            var ddd = new Long(s, n);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1 | 0);
            this.dpush(r0 | 0);
        },

        // '?dup': null,

        // 6.1.2170 S>D “s-to-d” (CORE)
        // ( n -- d )
        // Convert the number n to the double-cell number d with the same numerical value.
        's>d': function () {
            var t = this.dpop() | 0;
            var ttt = Long.fromInt(t);
            this.dpush(ttt.low);
            this.dpush(ttt.high);
        }
        // sign
    };

    Object.keys(core).forEach(function (key) {
        def(key, core[key], cxt);
    });

    // x1 -- x2
    ' 0< # ((t < 0) ? -1 : 0) ; 0<> # ((t !== 0) ? -1 : 0) ; 0> # ((t > 0) ? -1 : 0) ; 0= # ((t === 0) ? -1 : 0) ; 1+ # (t + 1) | 0 ; 1- # (t - 1) | 0 ; 2* # (t << 1) ; 2/ # (t >> 1) ; abs # Math.abs(t) | 0 ; cell+ # (t + 4) | 0 ; cells # (t * 4) | 0 ; char+ # (t + 1) | 0 ; chars # t ; invert # (t ^ -1) ; negate # ((t ^ -1) + 1) | 0 '
    .split(';')
    .map(function (e) { return e.split('#'); })
    .forEach(function (e) {
        var fn;
        eval('fn = function () { var t = this.dpop() | 0; this.dpush(' + e[1] + '); };');
        def(e[0].trim(), fn, cxt);
    });

    // x1 x2 -- x3
    ' + # (n + t) | 0 ; - # (n - t) | 0 ; * # (n * t) | 0 ; / # (n / t) | 0 ; <> # ((t !== n) ? -1 : 0) ; and # (n & t) ; = # ((n === t) ? -1 : 0) ; > # ((n > t) ? -1 : 0) ; < # ((n < t) ? -1 : 0) ; lshift # (n << t) ; max # (Math.max(t, n)) ; min # (Math.min(t, n)) ; mod # (n % t) | 0; or # (n | t) ; rshift # (n >>> t) ; u< # (((n >>> 0) < (t >>> 0)) ? -1 : 0) ; xor # (n ^ t) ; u> # (((n >>> 0) > (t >>> 0)) ? -1 : 0) '
    .split(';')
    .map(function (e) { return e.split('#'); })
    .forEach(function (e) {
        var fn;
        eval('fn = function () { var t = this.dpop() | 0; var n = this.dpop() | 0; this.dpush(' + e[1] + '); };');
        def(e[0].trim(), fn, cxt);
    });

}

module.exports = stack;
<commit_msg>fixes #4 ; UM*<commit_after>'use strict';

// stack-only words; using only .dpop .dpush
// TODO add manipulations, double, float, return stack words

var def = require('./def'),
    Long = require('long');

function stack (cxt) {
    cxt.DS = [];
    cxt.RS = [];
    cxt.dtop = function () { return this.DS[this.DS.length - 1]; },
    cxt.dnext = function () { return this.DS[this.DS.length - 2]; },
    cxt.dpop = function () { return this.DS.pop(); },
    cxt.dpush = function (e) { this.DS.push(e); };
    cxt.rtop = function () { return this.RS[this.RS.length - 1]; },
    cxt.rnext = function () { return this.RS[this.RS.length - 2]; },
    cxt.rpick2 = function () { return this.RS[this.RS.length - 3]; },
    cxt.rpop = function () { return this.RS.pop(); },
    cxt.rpush = function (e) { this.RS.push(e); };

    // stack primitives
    var core = {
        drop: function () {
            this.dpop();
        },
        dup: function () {
            var t = this.dtop();
            this.dpush(t);
        },
        over: function () {
            var n = this.dnext();
            this.dpush(n);
        },
        swap: function () {
            var t = this.dpop();
            var n = this.dpop();
            this.dpush(t);
            this.dpush(n);
        },
        '>r': function () {
            this.rpush(this.dpop());
        },
        'r>': function () {
            this.dpush(this.rpop());
        },
        'r@': function () {
            var rtop = this.rtop();
            this.dpush(rtop);
        },
        // 6.1.0100 */ ( n1 n2 n3 -- n4 ) “star-slash” (CORE)
        // Multiply n1 by n2 producing the intermediate double-cell result d.
        // Divide d by n3 giving the single-cell quotient n4. An ambiguous
        // condition exists if n3 is zero or if the quotient n4 lies outside
        // the range of a signed number. If d and n3 differ in sign, the
        // implementation-defined result returned will be the same as that
        // returned by either the phrase >R M* R> FM/MOD SWAP DROP or
        // the phrase >R M* R> SM/REM SWAP DROP.
        '*/': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var m = this.dpop() | 0;
            var ddd = Long.fromInt(m);
            ddd = ddd.mul(Long.fromInt(n));
            ddd = ddd.div(Long.fromInt(t));
            ddd = ddd.toInt();
            this.dpush(ddd | 0);
        },

        // 6.1.0110 */MOD “star-slash-mod” (CORE)
        // ( n1 n2 n3 -- n4 n5 )
        // Multiply n1 by n2 producing the intermediate double-cell result d.
        // Divide d by n3 producing the single-cell remainder n4 and the
        // single-cell quotient n5. An ambiguous condition exists if n3 is zero,
        // or if the quotient n5 lies outside the range of a single-cell signed
        // integer. If d and n3 differ in sign, the implementation-defined
        // result returned will be the same as that returned by either
        // the phrase >R M* R> FM/MOD or the phrase >R M* R> SM/REM.
        '*/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var m = this.dpop() | 0;
            var ddd = Long.fromInt(m);
            ddd = ddd.mul(Long.fromInt(n));

            var r0 = ddd.div(Long.fromInt(t));
            r0 = r0.toInt();

            var r1 = ddd.mod(Long.fromInt(t));
            r1 = r1.toInt();

            this.dpush(r1 | 0);
            this.dpush(r0 | 0);
        },
        '/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            this.dpush((n % t) | 0);
            this.dpush((n / t) | 0);
        },
        nip: function () {
            'swap'();
            'drop'();
        },
        // rot ( x1 x2 x3 -- x2 x3 x1 )
        rot: function () {
            var x3 = this.dpop();
            var x2 = this.dpop();
            var x1 = this.dpop();
            this.dpush(x2);
            this.dpush(x3);
            this.dpush(x1);
        },
        // 2drop ( w1 w2 -- )
        '2drop': function () {
            'drop'();
            'drop'();
        },
        // 2dup ( w1 w2 -- w1 w2 w1 w2 )
        '2dup': function () {
            'over'();
            'over'();
        },
        // 2over ( w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2 )
        '2over': function () {
            '>r'(); '>r'();
            'over'(); 'over'();
            'r>'();
            'rot'(); 'rot'();
            'r>'();
            'rot'(); 'rot'();
        },
        // 2swap ( w1 w2 w3 w4 -- w3 w4 w1 w2 )
        '2swap': function () {
            'rot'(); '>r'(); 'rot'(); 'r>'();
        },

        'depth': function () {
            this.dpush(this.DS.length);
        },

        // 6.1.1810 M* “m-star” (CORE)
        // ( n1 n2 -- d )
        // d is the signed product of n1 times n2 .
        'm*': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var ddd = Long.fromInt(n);
            ddd = ddd.mul(Long.fromInt(t));
            this.dpush(ddd.low);
            this.dpush(ddd.high);
        },

        // 6.1.2360 UM* “u-m-star” (CORE)
        // ( u1 u2 -- ud )
        // Multiply u 1 by u 2, giving the unsigned double-cell product ud.
        // All values and arithmetic are unsigned.
        'um*': function () {
            var t = this.dpop() >>> 0;
            var n = this.dpop() >>> 0;
            var nn = Long.fromValue(n, true);
            var tt = Long.fromValue(t, true);
            var ddd = nn.mul(tt);
            this.dpush(ddd.low);
            this.dpush(ddd.high);
        },

        // 6.1.2214 SM/REM “s-m-slash-rem” (CORE)
        // ( d1 n1 -- n2 n3 )
        // Divide d1 by n1, giving the symmetric quotient n3 and the remainder n2.
        // Input and output stack arguments are signed. An ambiguous condition
        // exists if n1 is zero or if the quotient lies outside the range of a
        // single-cell signed integer.
        'sm/rem': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var s = this.dpop() | 0;
            var ddd = new Long(s, n);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1);
            this.dpush(r0);
        },

        // 6.1.2370 UM/MOD “u-m-slash-mod” (CORE)
        // ( ud u1 -- u2 u3 )
        // Divide ud by u1, giving the quotient u3 and the remainder u2.
        // All values and arithmetic are unsigned. An ambiguous condition exists
        // if u1 is zero or if the qukrusaotient lies outside the range of
        // a single-cell unsigned integer.
        'um/mod': function () {
            var t = this.dpop() >>> 0;
            var n = this.dpop() >>> 0;
            var s = this.dpop() >>> 0;
            var ddd = new Long(s, n, true);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1);
            this.dpush(r0);
        },

        // fm/mod
        // 6.1.1561 FM/MOD “f-m-slash-mod” (CORE)
        // ( d1 n1 -- n2 n3 )
        // Divide d1 by n1, giving the floored quotient n3 and the remainder n2.
        // Input and output stack arguments are signed. An ambiguous condition
        //  exists if n is zero or if the quotient lies outside 1the range of a
        // single-cell signed integer.
        'fm/mod': function () {
            var t = this.dpop() | 0;
            var n = this.dpop() | 0;
            var s = this.dpop() | 0;
            var ddd = new Long(s, n);

            var ttt = Long.fromInt(t);

            var r0 = ddd.div(ttt);
            r0 = r0.toInt();

            var r1 = ddd.mod(ttt);
            r1 = r1.toInt();

            this.dpush(r1 | 0);
            this.dpush(r0 | 0);
        },

        // '?dup': null,

        // 6.1.2170 S>D “s-to-d” (CORE)
        // ( n -- d )
        // Convert the number n to the double-cell number d with the same numerical value.
        's>d': function () {
            var t = this.dpop() | 0;
            var ttt = Long.fromInt(t);
            this.dpush(ttt.low);
            this.dpush(ttt.high);
        }
        // sign
    };

    Object.keys(core).forEach(function (key) {
        def(key, core[key], cxt);
    });

    // x1 -- x2
    ' 0< # ((t < 0) ? -1 : 0) ; 0<> # ((t !== 0) ? -1 : 0) ; 0> # ((t > 0) ? -1 : 0) ; 0= # ((t === 0) ? -1 : 0) ; 1+ # (t + 1) | 0 ; 1- # (t - 1) | 0 ; 2* # (t << 1) ; 2/ # (t >> 1) ; abs # Math.abs(t) | 0 ; cell+ # (t + 4) | 0 ; cells # (t * 4) | 0 ; char+ # (t + 1) | 0 ; chars # t ; invert # (t ^ -1) ; negate # ((t ^ -1) + 1) | 0 '
    .split(';')
    .map(function (e) { return e.split('#'); })
    .forEach(function (e) {
        var fn;
        eval('fn = function () { var t = this.dpop() | 0; this.dpush(' + e[1] + '); };');
        def(e[0].trim(), fn, cxt);
    });

    // x1 x2 -- x3
    ' + # (n + t) | 0 ; - # (n - t) | 0 ; * # (n * t) | 0 ; / # (n / t) | 0 ; <> # ((t !== n) ? -1 : 0) ; and # (n & t) ; = # ((n === t) ? -1 : 0) ; > # ((n > t) ? -1 : 0) ; < # ((n < t) ? -1 : 0) ; lshift # (n << t) ; max # (Math.max(t, n)) ; min # (Math.min(t, n)) ; mod # (n % t) | 0; or # (n | t) ; rshift # (n >>> t) ; u< # (((n >>> 0) < (t >>> 0)) ? -1 : 0) ; xor # (n ^ t) ; u> # (((n >>> 0) > (t >>> 0)) ? -1 : 0) '
    .split(';')
    .map(function (e) { return e.split('#'); })
    .forEach(function (e) {
        var fn;
        eval('fn = function () { var t = this.dpop() | 0; var n = this.dpop() | 0; this.dpush(' + e[1] + '); };');
        def(e[0].trim(), fn, cxt);
    });

}

module.exports = stack;
<|endoftext|>


<commit_before>var exec = require('child_process').exec
  , fs = require('fs')
  , promise = require('promised-io/lib/promise');

module.exports = {
	GIF: function (options) {
		exec('gifsicle -O -b "' + options.filename + '"', function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "gifsicle". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with gifsicle');
					err(stderror, options.log);
				}
			}
			options.promise.resolve(fs.statSync(options.filename));
		});

		return options.promise;
	},

	JPEG: function (options) {
		// jpegtran won't let us overwrite the file
		var jpegtranTmp = generateFilename();

		var jpegtran = 'jpegtran -copy none ';
		if (options.settings.aggressive) {
			jpegtran += '-progressive ';
		}
		jpegtran += '-optimize -outfile ' + jpegtranTmp + ' "' + options.filename + '"';

		exec(jpegtran, function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "jpegtran". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with jpegtran');
					err(stderror, options.log);
				}
			} else {
				fs.renameSync(jpegtranTmp, options.filename);
			}
			options.promise.resolve(fs.statSync(options.filename));
		});

		return options.promise;
	},

	PNG: function (options) {
		// pngcrush won't let us overwrite the file
		var pngcrushTmp = generateFilename(),
			optipngLevel = 'o1'; // Default compression level for optipng

		if (options.settings.aggressive) {
			optipngLevel = 'o7'; // Most agressive compression level for optipng
		}

		exec('optipng -' + optipngLevel + ' "' + options.filename + '"', function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "optipng". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with optipng');
					err(stderror, options.log);
				}
			}

			// Handle a case where a file has a .png extension but it not actually a proper .png
			try {
				var badPng = fs.statSync(options.filename + '.png');
				if (badPng) {
					fs.renameSync(options.filename + '.png', options.filename);
				}
			} catch (e) {
				// Everything is normal
			}

			var pngcrush = 'pngcrush -nofilecheck -q';

			if (options.settings.aggressive) {
				pngcrush += ' -brute';
			}

			pngcrush += ' "' + options.filename + '" ' + pngcrushTmp;

			exec(pngcrush, function (error, stdout, stderror) {
				if (error || stdout.match('pngcrush caught libpng error')) {
					if (error && error.code === 127 && options.settings.loud) {
						options.log.notice('Couldn\'t find "pngcrush". Skipping on: ' + options.original);
					} else {
						options.log.warning('Couldn\'t compress "' + options.original + '" with pngcrush');
						err(stderror, options.log);
					}
				} else {
					fs.renameSync(pngcrushTmp, options.filename);
				}
				options.promise.resolve(fs.statSync(options.filename));
			});
		});

		return options.promise;
	}
};

function generateFilename () {
	// Generate a random string
	var filename = process.cwd() + '/' + Math.floor(Math.random() * 1e16).toString(36);

	try {
		fs.statSync(filename);
	} catch (e) {
		// It's good if we get an error, it means the random filename we created doesn't already exist
		return filename;
	}

	// Otherwise we need to try again (what are the chances of that??)
	return arguments.callee.call();
}

function err (stderror, log) {
	if (stderror && log) {
		stderror = stderror.split('\n');
		stderror.forEach(function (line) {
			if (line) {
				log.error(line);
			}
		});
	}
}
<commit_msg>fixed promised-io in tasks.js<commit_after>var exec = require('child_process').exec
  , fs = require('fs')
  , promise = require('promised-io/promise');

module.exports = {
	GIF: function (options) {
		exec('gifsicle -O -b "' + options.filename + '"', function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "gifsicle". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with gifsicle');
					err(stderror, options.log);
				}
			}
			options.promise.resolve(fs.statSync(options.filename));
		});

		return options.promise;
	},

	JPEG: function (options) {
		// jpegtran won't let us overwrite the file
		var jpegtranTmp = generateFilename();

		var jpegtran = 'jpegtran -copy none ';
		if (options.settings.aggressive) {
			jpegtran += '-progressive ';
		}
		jpegtran += '-optimize -outfile ' + jpegtranTmp + ' "' + options.filename + '"';

		exec(jpegtran, function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "jpegtran". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with jpegtran');
					err(stderror, options.log);
				}
			} else {
				fs.renameSync(jpegtranTmp, options.filename);
			}
			options.promise.resolve(fs.statSync(options.filename));
		});

		return options.promise;
	},

	PNG: function (options) {
		// pngcrush won't let us overwrite the file
		var pngcrushTmp = generateFilename(),
			optipngLevel = 'o1'; // Default compression level for optipng

		if (options.settings.aggressive) {
			optipngLevel = 'o7'; // Most agressive compression level for optipng
		}

		exec('optipng -' + optipngLevel + ' "' + options.filename + '"', function (error, stdout, stderror) {
			if (error) {
				if (error.code === 127 && options.settings.loud) {
					options.log.notice('Couldn\'t find "optipng". Skipping on: ' + options.original);
				} else {
					options.log.warning('Couldn\'t compress "' + options.original + '" with optipng');
					err(stderror, options.log);
				}
			}

			// Handle a case where a file has a .png extension but it not actually a proper .png
			try {
				var badPng = fs.statSync(options.filename + '.png');
				if (badPng) {
					fs.renameSync(options.filename + '.png', options.filename);
				}
			} catch (e) {
				// Everything is normal
			}

			var pngcrush = 'pngcrush -nofilecheck -q';

			if (options.settings.aggressive) {
				pngcrush += ' -brute';
			}

			pngcrush += ' "' + options.filename + '" ' + pngcrushTmp;

			exec(pngcrush, function (error, stdout, stderror) {
				if (error || stdout.match('pngcrush caught libpng error')) {
					if (error && error.code === 127 && options.settings.loud) {
						options.log.notice('Couldn\'t find "pngcrush". Skipping on: ' + options.original);
					} else {
						options.log.warning('Couldn\'t compress "' + options.original + '" with pngcrush');
						err(stderror, options.log);
					}
				} else {
					fs.renameSync(pngcrushTmp, options.filename);
				}
				options.promise.resolve(fs.statSync(options.filename));
			});
		});

		return options.promise;
	}
};

function generateFilename () {
	// Generate a random string
	var filename = process.cwd() + '/' + Math.floor(Math.random() * 1e16).toString(36);

	try {
		fs.statSync(filename);
	} catch (e) {
		// It's good if we get an error, it means the random filename we created doesn't already exist
		return filename;
	}

	// Otherwise we need to try again (what are the chances of that??)
	return arguments.callee.call();
}

function err (stderror, log) {
	if (stderror && log) {
		stderror = stderror.split('\n');
		stderror.forEach(function (line) {
			if (line) {
				log.error(line);
			}
		});
	}
}
<|endoftext|>


<commit_before>/*jshint laxcomma: true, smarttabs: true, node:true, esnext:true*/
'use strict';
/**
 * Manage Timers on a node
 * @module skyring/lib/timer
 * @author Eric Satterwhite
 * @since 1.0.0
 * @requires debug
 * @requires skyring/lib/transports
 * @requires skyring/lib/nats
 * @requires skyring/lib/json
 */
const transports = require('./transports')
    , nats      = require('./nats')
    , json       = require('./json')
    , debug      = require('debug')('skyring:timer')
    , cache      = new Map()
    ;

let BAIL = false

/**
 * Node style callback
 * @typedef {Function} Nodeback
 * @property {?Error} [err] An error instance. If not null, the results should not be trusted
 * @property {Object} result The results of the function execution
 **/

/**
 * Sets a new time instance. If The timer has lapsed, it will be executed immediately
 * @method module:skyring/lib/timer#create
 * @param {String} id A unique Id of the time
 * @param {Object} body Configuration options for the timer instance
 * @param {Number} body.timeout Duration in milisecods to delay execution of the timer
 * @param {String} body.data The data to be assicated with the timer, when it is executed
 * @param {Object} callback Options for the outbound transport for the timer when it executes
 * @param {String} callback.transport The transport type ( http, etc )
 * @param {String} transport.method The method the transport should use when executing the timer
 * @param {String} transport.uri The target uri for the transport when the timer executes
 * @param {Nodeback} callback
 **/
exports.create = function create(id, body, cb) {
  const payload = body;
  const transport = transports[payload.callback.transport];
  if (cache.has(id)) {
    const err = new Error('Key exists');
    err.code = 'EKEYEXISTS';
    return setImmediate(cb, err)
  }
  const now = Date.now();
  const created = payload.created || now;

  if( now > created + payload.timeout ){
    debug('executing stale timer')
    setImmediate(
        transport
      , payload.callback.method
      , payload.callback.uri
      , payload.data
      , id
    );
    return cb(null)
  }

  debug('setting timer', id);
  cache.set( id, {
    payload: payload
  , created: Date.now()
  , id: id
  , timer: setTimeout(
            transport
          , payload.timeout
          , payload.callback.method
          , payload.callback.uri
          , payload.data
          , id
          ).unref()
  });
  setImmediate(cb, null);
}

/**
 * Cancels a specific timer
 * @method module:skyring/lib/timer#delete
 * @param {String} id The id of the timer to cancel
 * @param {Nodeback} callback Node style callback to execute
 **/
exports.delete = function(id, cb) {
  const t = cache.get(id);
  if( !t ) {
    const err = new Error('Not Found');
    err.code = 'ENOENT';
    return cb && setImmediate(cb, err);
  }
  clearTimeout(t.timer);
  cache.delete(id);
  debug('timer cleared', id)
  cb && setImmediate(cb, null);
}

/**
 * Updates a timer inplace
 * @method module:skyring/lib/timer#update
 * @param {String} id A unique Id of the time
 * @param {Object} body Configuration options for the timer instance
 * @param {Number} body.timeout Duration in milisecods to delay execution of the timer
 * @param {String} body.data The data to be assicated with the timer, when it is executed
 * @param {Object} callback Options for the outbound transport for the timer when it executes
 * @param {String} callback.transport The transport type ( http, etc )
 * @param {String} transport.method The method the transport should use when executing the timer
 * @param {String} transport.uri The target uri for the transport when the timer executes
 * @param {Nodeback} callback
 **/
exports.update = function update(id, body, cb){
  exports.delete(id, (err) => {
    if (err) return cb(err);
    debug('updating timer', id);
    exports.create(id, body, cb);
  })
}

/**
 * Triggers timers to be rebalanced with in the ring before sutdown, and cancels all locally pending timers
 * @method module:skyring/lib/timer#shutdown
 * @param {Nodeback} callback Node style callback to execute when the function is complete
 **/
exports.shutdown = function shutdown(cb) {
  BAIL = true;
  const exit = false;
  const size = cache.size;

  if( !size ) return cb();

  const client = nats.client;
  let count = 0;
  const run = (obj) => {
    clearTimeout(record.timer);
    debug('pushing', record.id)
    const data = Object.assign({}, record.payload, {
      id: record.id
    , created: record.created
    });

    nats.client.publish('skyring', data);
    if (++count === size) return setImmediate(nats.quit, cb)
}

for(var record of cache.values()) {
  run(record);
}
cache.clear();
}

/**
 * Starts an internal queue on a redis key to listen for incoming timers from a node rebalance
 * @method module:skyring/lib/timer#watch
 * @param {String} key The key name in redis to use as a timer queue
 * @param {Nodeback} callback Node style callback to execute when the function has finished execution
 **/
exports.watch = function( key, cb ){
  if(BAIL) return
  debug('nats subscribe: skyring')
  nats.client.subscribe('skyring', {queue: 'skyring'}, (data) => {
    if(BAIL) return
    const value = json.parse(data)
    cb(value.error, value.value);
  });
}

<commit_msg>fix up the rebalance logic for nats<commit_after>/*jshint laxcomma: true, smarttabs: true, node:true, esnext:true*/
'use strict';
/**
 * Manage Timers on a node
 * @module skyring/lib/timer
 * @author Eric Satterwhite
 * @since 1.0.0
 * @requires debug
 * @requires skyring/lib/transports
 * @requires skyring/lib/nats
 * @requires skyring/lib/json
 */
const transports = require('./transports')
    , nats      = require('./nats')
    , json       = require('./json')
    , debug      = require('debug')('skyring:timer')
    , rebalance  = require('debug')('skyring:rebalance')
    , cache      = new Map()
    ;

let BAIL = false
let NATS_SID = null
/**
 * Node style callback
 * @typedef {Function} Nodeback
 * @property {?Error} [err] An error instance. If not null, the results should not be trusted
 * @property {Object} result The results of the function execution
 **/

/**
 * Sets a new time instance. If The timer has lapsed, it will be executed immediately
 * @method module:skyring/lib/timer#create
 * @param {String} id A unique Id of the time
 * @param {Object} body Configuration options for the timer instance
 * @param {Number} body.timeout Duration in milisecods to delay execution of the timer
 * @param {String} body.data The data to be assicated with the timer, when it is executed
 * @param {Object} callback Options for the outbound transport for the timer when it executes
 * @param {String} callback.transport The transport type ( http, etc )
 * @param {String} transport.method The method the transport should use when executing the timer
 * @param {String} transport.uri The target uri for the transport when the timer executes
 * @param {Nodeback} callback
 **/
exports.create = function create(id, body, cb) {
  const payload = body;
  const transport = transports[payload.callback.transport];
  if (cache.has(id)) {
    const err = new Error('Key exists');
    err.code = 'EKEYEXISTS';
    return setImmediate(cb, err)
  }
  const now = Date.now();
  const created = payload.created || now;

  if( now > created + payload.timeout ){
    debug('executing stale timer')
    setImmediate(
        transport
      , payload.callback.method
      , payload.callback.uri
      , payload.data
      , id
    );
    return cb(null)
  }

  debug('setting timer', id);
  cache.set( id, {
    payload: payload
  , created: Date.now()
  , id: id
  , timer: setTimeout(
            transport
          , payload.timeout
          , payload.callback.method
          , payload.callback.uri
          , payload.data
          , id
          ).unref()
  });
  setImmediate(cb, null);
}

/**
 * Cancels a specific timer
 * @method module:skyring/lib/timer#delete
 * @param {String} id The id of the timer to cancel
 * @param {Nodeback} callback Node style callback to execute
 **/
exports.delete = function(id, cb) {
  const t = cache.get(id);
  if( !t ) {
    const err = new Error('Not Found');
    err.code = 'ENOENT';
    return cb && setImmediate(cb, err);
  }
  clearTimeout(t.timer);
  cache.delete(id);
  debug('timer cleared', id)
  cb && setImmediate(cb, null);
}

/**
 * Updates a timer inplace
 * @method module:skyring/lib/timer#update
 * @param {String} id A unique Id of the time
 * @param {Object} body Configuration options for the timer instance
 * @param {Number} body.timeout Duration in milisecods to delay execution of the timer
 * @param {String} body.data The data to be assicated with the timer, when it is executed
 * @param {Object} callback Options for the outbound transport for the timer when it executes
 * @param {String} callback.transport The transport type ( http, etc )
 * @param {String} transport.method The method the transport should use when executing the timer
 * @param {String} transport.uri The target uri for the transport when the timer executes
 * @param {Nodeback} callback
 **/
exports.update = function update(id, body, cb){
  exports.delete(id, (err) => {
    if (err) return cb(err);
    debug('updating timer', id);
    exports.create(id, body, cb);
  })
}

/**
 * Triggers timers to be rebalanced with in the ring before sutdown, and cancels all locally pending timers
 * @method module:skyring/lib/timer#shutdown
 * @param {Nodeback} callback Node style callback to execute when the function is complete
 **/
exports.shutdown = function shutdown(cb) {
  BAIL = true;
  const exit = false;
  const size = cache.size;
  const client = nats.client;
  let count = 0;

  if( !size ) return cb();

  client.unsubscribe(NATS_SID);
  NATS_SID = null;

  const run = (obj) => {
    clearTimeout(record.timer);
    debug('pushing', record.id);
    const data = Object.assign({}, record.payload, {
      id: record.id
    , created: record.created
    , count: ++count
    });

    nats.client.publish('skyring', JSON.stringify(data), () =>{
      rebalance('%s of %s processed', data.count, size);
      if (count === size) return setImmediate(nats.quit, cb)
    });
  }

  for(var record of cache.values()) {
    run(record);
  }
  cache.clear();
}

/**
 * Starts an internal queue on a redis key to listen for incoming timers from a node rebalance
 * @method module:skyring/lib/timer#watch
 * @param {String} key The key name in redis to use as a timer queue
 * @param {Nodeback} callback Node style callback to execute when the function has finished execution
 **/
exports.watch = function( key, cb ){
  if(BAIL) return
  debug('nats subscribe: skyring')
  NATS_SID = nats.client.subscribe('skyring', {queue: 'skyring'}, (data) => {
    if(BAIL) return
    const value = json.parse(data)
    rebalance('rebalance %s', value.value.count )
    cb(value.error, value.value);
  });
}

<|endoftext|>


<commit_before>'use strict';

var _isFunction = require('lodash.isfunction'),
    _noop     = require('lodash.noop'),
    crypto    = require('crypto'),
    _path     = require('path'),
    markdown  = require('markdown-it')().use(require('markdown-it-checkbox')),
    YAML      = require('js-yaml'),
    fastSort = require('fast-sort/dist/sort.js'),
    max_bytes = 512;
const chrono = require('chrono-node')

function mkdirp(fs, path, mode, cb, position) {
  if (_isFunction(mode)) {
    cb = mode;
    mode = "0777";
  }
  if (!cb) cb = _noop;

  var parts = _path.normalize(path).split(_path.sep);
  mode = mode || process.umask();
  position = position || 0;

  if (position >= parts.length) {
    return cb();
  }

  var directory = parts.slice(0, position + 1).join(_path.sep) || _path.sep;
  fs.stat(directory, function(err) {
    if (err === null) {
      mkdirp(fs, path, mode, cb, position + 1);
    } else {
      fs.mkdir(directory, mode, function (err) {
        if (err && err.code != 'EEXIST') {
          return cb(err);
        } else {
          mkdirp(fs, path, mode, cb, position + 1);
        }
      });
    }
  });
}

function isBinaryCheck(bytes, size) {
  if (size === 0)
    return false;

  var suspicious_bytes = 0;
  var total_bytes = Math.min(size, max_bytes);

  if (size >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
    // UTF-8 BOM. This isn't binary.
    return false;
  }

  for (var i = 0; i < total_bytes; i++) {
    if (bytes[i] === 0) { // NULL byte--it's binary!
      return true;
    }
    else if ((bytes[i] < 7 || bytes[i] > 14) && (bytes[i] < 32 || bytes[i] > 127)) {
      // UTF-8 detection
      if (bytes[i] > 191 && bytes[i] < 224 && i + 1 < total_bytes) {
          i++;
          if (bytes[i] < 192) {
              continue;
          }
      }
      else if (bytes[i] > 223 && bytes[i] < 239 && i + 2 < total_bytes) {
          i++;
          if (bytes[i] < 192 && bytes[i + 1] < 192) {
              i++;
              continue;
          }
      }
      suspicious_bytes++;
      // Read at least 32 bytes before making a decision
      if (i > 32 && (suspicious_bytes * 100) / total_bytes > 10) {
          return true;
      }
    }
  }

  if ((suspicious_bytes * 100) / total_bytes > 10) {
    return true;
  }

  return false;
}

module.exports = {
  escapeRegExp: require('escape-string-regexp'),
  marked: function(content) {
    return markdown.render(content);
  },

  /**
   * Description
   * @method userHome
   * @return LogicalExpression
   */
  userHome: function() {
    return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
  },

  /**
   * Description
   * @method user
   * @return LogicalExpression
   */
  user: function() {
    return process.env.USER || process.env.USERNAME;
  },

  /**
   * Description
   * @method cb
   * @param {} cb
   * @return ConditionalExpression
   */
  cb: function(cb) {
    return _isFunction(cb) ? cb : _noop;
  },

  inMixinsNoop: function(cb) {
    cb = this.cb(cb);
    cb(new Error("Implemented in mixins"));
  },

  /**
   * Description
   * @method sha
   * @param {} data
   * @return CallExpression
   */
  sha: function(data) {
    var shasum = crypto.createHash('sha1');
    shasum.update(data);
    return shasum.digest('hex');
  },

  /**
   * Description
   * @method format
   * @param {} template
   * @param {} col
   * @return CallExpression
   */
  format: function(template, col) {
    col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 2);

    return template.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {
        if (m == "{{") { return "{"; }
        if (m == "}}") { return "}"; }
        return col[n];
    });
  },

  isBinaryFile: function(fs, file, callback) {

    fs.exists(file, function (exists) {
      if (!exists) return callback(null, false);

      fs.open(file, 'r', function(err, descriptor){
          if (err) return callback(err);
          var bytes = new Buffer(max_bytes);
          // Read the file with no encoding for raw buffer access.
          fs.read(descriptor, bytes, 0, bytes.length, 0, function(err, size, bytes){
            fs.close(descriptor, function(err2){
                if (err || err2)
                    return callback(err || err2);
                return callback(null, isBinaryCheck(bytes, size));
            });
          });
      });
    });
  },

  isBinaryCheck: isBinaryCheck,

  readdirSyncRecursive: function(fs, baseDir) {
    baseDir = baseDir.replace(/\/$/, '');

    var readdirSyncRecursive = function(baseDir) {
        var files = [],
            curFiles,
            nextDirs,
            isDir = function(fname){
                return fs.existsSync(_path.join(baseDir, fname)) ? fs.statSync( _path.join(baseDir, fname) ).isDirectory() : false;
            },
            prependBaseDir = function(fname){
                return _path.join(baseDir, fname);
            };

        curFiles = fs.readdirSync(baseDir);
        nextDirs = curFiles.filter(isDir);
        curFiles = curFiles.map(prependBaseDir);

        files = files.concat( curFiles );

        while (nextDirs.length) {
            files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
        }

        return files;
    };

    // convert absolute paths to relative
    var fileList = readdirSyncRecursive(baseDir).map(function(val){
        return _path.relative(baseDir, val);
    });

    return fileList;
  },

  mkdirSyncRecursive: function(fs, path, mode) {
    var self = this;
    path = _path.normalize(path);

    try {
        fs.mkdirSync(path, mode);
    } catch(err) {
        if(err.code == "ENOENT") {
            var slashIdx = path.lastIndexOf(_path.sep);

            if(slashIdx > 0) {
                var parentPath = path.substring(0, slashIdx);
                this.mkdirSyncRecursive(parentPath, mode);
                this.mkdirSyncRecursive(path, mode);
            } else {
                throw err;
            }
        } else if(err.code == "EEXIST") {
            return;
        } else {
            throw err;
        }
    }
  },
  replaceDateLanguage (text, asDate) {
    return text.replace(/\(?\${(.*?)}\)?/g,(match, p1) => {
      const date = chrono.parseDate(p1)
      return date ? date.toISOString() : p1
    })
  },
  mkdirp: mkdirp,
  dumpYAML: YAML.dump,
  loadYAML: YAML.load,
  sortTasks (tasks) {
    return fastSort(tasks).by([{asc: 'order'}, {asc: 'text'}])
  },
  hasBlankLines (content) {
    return /^\s*\n/gm.test(content)
  }
};
<commit_msg>fix hasBlankLines<commit_after>'use strict';

var _isFunction = require('lodash.isfunction'),
    _noop     = require('lodash.noop'),
    crypto    = require('crypto'),
    _path     = require('path'),
    markdown  = require('markdown-it')().use(require('markdown-it-checkbox')),
    YAML      = require('js-yaml'),
    fastSort = require('fast-sort/dist/sort.js'),
    eol = require('eol'),
    max_bytes = 512;
const chrono = require('chrono-node')

function mkdirp(fs, path, mode, cb, position) {
  if (_isFunction(mode)) {
    cb = mode;
    mode = "0777";
  }
  if (!cb) cb = _noop;

  var parts = _path.normalize(path).split(_path.sep);
  mode = mode || process.umask();
  position = position || 0;

  if (position >= parts.length) {
    return cb();
  }

  var directory = parts.slice(0, position + 1).join(_path.sep) || _path.sep;
  fs.stat(directory, function(err) {
    if (err === null) {
      mkdirp(fs, path, mode, cb, position + 1);
    } else {
      fs.mkdir(directory, mode, function (err) {
        if (err && err.code != 'EEXIST') {
          return cb(err);
        } else {
          mkdirp(fs, path, mode, cb, position + 1);
        }
      });
    }
  });
}

function isBinaryCheck(bytes, size) {
  if (size === 0)
    return false;

  var suspicious_bytes = 0;
  var total_bytes = Math.min(size, max_bytes);

  if (size >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
    // UTF-8 BOM. This isn't binary.
    return false;
  }

  for (var i = 0; i < total_bytes; i++) {
    if (bytes[i] === 0) { // NULL byte--it's binary!
      return true;
    }
    else if ((bytes[i] < 7 || bytes[i] > 14) && (bytes[i] < 32 || bytes[i] > 127)) {
      // UTF-8 detection
      if (bytes[i] > 191 && bytes[i] < 224 && i + 1 < total_bytes) {
          i++;
          if (bytes[i] < 192) {
              continue;
          }
      }
      else if (bytes[i] > 223 && bytes[i] < 239 && i + 2 < total_bytes) {
          i++;
          if (bytes[i] < 192 && bytes[i + 1] < 192) {
              i++;
              continue;
          }
      }
      suspicious_bytes++;
      // Read at least 32 bytes before making a decision
      if (i > 32 && (suspicious_bytes * 100) / total_bytes > 10) {
          return true;
      }
    }
  }

  if ((suspicious_bytes * 100) / total_bytes > 10) {
    return true;
  }

  return false;
}

module.exports = {
  escapeRegExp: require('escape-string-regexp'),
  marked: function(content) {
    return markdown.render(content);
  },

  /**
   * Description
   * @method userHome
   * @return LogicalExpression
   */
  userHome: function() {
    return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
  },

  /**
   * Description
   * @method user
   * @return LogicalExpression
   */
  user: function() {
    return process.env.USER || process.env.USERNAME;
  },

  /**
   * Description
   * @method cb
   * @param {} cb
   * @return ConditionalExpression
   */
  cb: function(cb) {
    return _isFunction(cb) ? cb : _noop;
  },

  inMixinsNoop: function(cb) {
    cb = this.cb(cb);
    cb(new Error("Implemented in mixins"));
  },

  /**
   * Description
   * @method sha
   * @param {} data
   * @return CallExpression
   */
  sha: function(data) {
    var shasum = crypto.createHash('sha1');
    shasum.update(data);
    return shasum.digest('hex');
  },

  /**
   * Description
   * @method format
   * @param {} template
   * @param {} col
   * @return CallExpression
   */
  format: function(template, col) {
    col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 2);

    return template.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {
        if (m == "{{") { return "{"; }
        if (m == "}}") { return "}"; }
        return col[n];
    });
  },

  isBinaryFile: function(fs, file, callback) {

    fs.exists(file, function (exists) {
      if (!exists) return callback(null, false);

      fs.open(file, 'r', function(err, descriptor){
          if (err) return callback(err);
          var bytes = new Buffer(max_bytes);
          // Read the file with no encoding for raw buffer access.
          fs.read(descriptor, bytes, 0, bytes.length, 0, function(err, size, bytes){
            fs.close(descriptor, function(err2){
                if (err || err2)
                    return callback(err || err2);
                return callback(null, isBinaryCheck(bytes, size));
            });
          });
      });
    });
  },

  isBinaryCheck: isBinaryCheck,

  readdirSyncRecursive: function(fs, baseDir) {
    baseDir = baseDir.replace(/\/$/, '');

    var readdirSyncRecursive = function(baseDir) {
        var files = [],
            curFiles,
            nextDirs,
            isDir = function(fname){
                return fs.existsSync(_path.join(baseDir, fname)) ? fs.statSync( _path.join(baseDir, fname) ).isDirectory() : false;
            },
            prependBaseDir = function(fname){
                return _path.join(baseDir, fname);
            };

        curFiles = fs.readdirSync(baseDir);
        nextDirs = curFiles.filter(isDir);
        curFiles = curFiles.map(prependBaseDir);

        files = files.concat( curFiles );

        while (nextDirs.length) {
            files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
        }

        return files;
    };

    // convert absolute paths to relative
    var fileList = readdirSyncRecursive(baseDir).map(function(val){
        return _path.relative(baseDir, val);
    });

    return fileList;
  },

  mkdirSyncRecursive: function(fs, path, mode) {
    var self = this;
    path = _path.normalize(path);

    try {
        fs.mkdirSync(path, mode);
    } catch(err) {
        if(err.code == "ENOENT") {
            var slashIdx = path.lastIndexOf(_path.sep);

            if(slashIdx > 0) {
                var parentPath = path.substring(0, slashIdx);
                this.mkdirSyncRecursive(parentPath, mode);
                this.mkdirSyncRecursive(path, mode);
            } else {
                throw err;
            }
        } else if(err.code == "EEXIST") {
            return;
        } else {
            throw err;
        }
    }
  },
  replaceDateLanguage (text, asDate) {
    return text.replace(/\(?\${(.*?)}\)?/g,(match, p1) => {
      const date = chrono.parseDate(p1)
      return date ? date.toISOString() : p1
    })
  },
  mkdirp: mkdirp,
  dumpYAML: YAML.dump,
  loadYAML: YAML.load,
  sortTasks (tasks) {
    return fastSort(tasks).by([{asc: 'order'}, {asc: 'text'}])
  },
  hasBlankLines (content) {
    return new RegExp(`^\\s*${String(eol.auto)}`, 'gm').test(content)
  }
};
<|endoftext|>