<commit_before>var path = require('path')
  , http = require('http')
  , https = require('https')
  , url  = require('url')
  , EventEmitter = require('events').EventEmitter;

var allInterceptors = {};

function addGlobalInterceptor(key, interceptor) {
  if (! allInterceptors.hasOwnProperty(key)) {
    allInterceptors[key] = [];
  }
  allInterceptors[key].push(interceptor);
}

function remove(interceptor) {
  var key = interceptor._key.split(' ');
  var u = url.parse(key[1]);
  var hostKey = u.protocol + '//' + u.host;
  var interceptors = allInterceptors[hostKey];
  var interceptor;
  var thisInterceptor;

  for(var i = 0; i < interceptors.length; i++) {
    thisInterceptor = interceptors[i];
    if (thisInterceptor._key === interceptor._key) {
      interceptors.splice(i, 1);
      break;
    }
  }
  //if (! interceptors) { delete allInterceptors[hostKey]; }
}

function stringifyRequest(options) {
  var method = options.method || 'GET';
  var path = options.path;
  var body = options.body;
  if (body && typeof(body) !== 'string') {
    body = body.toString();
  }
  return method + ' ' + path + ' ' + body;
}

function getHeader(request, name) {
  if (!request._headers) return;

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._headers[key] = value;
  request._headerNames[key] = name;
}

function processRequest(interceptors, options, callback) {
  var req = new EventEmitter()
    , response = new EventEmitter()
    , requestBodyBuffers = []
    , aborted
    , end
    , ended;

  if (options.headers) {
    var headers = options.headers;
    var keys = Object.keys(headers);

    for (var i = 0, l = keys.length; i < l; i++) {
      var key = keys[i];

      setHeader(req, key, headers[key]);
    };

    options.headers = req._headers;
  }

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  if (options.host && !getHeader(req, 'host')) {
    var hostHeader = options.host;

    if (options.host && +options.port !== 80) {
      hostHeader += ':' + options.port;
    }

    setHeader(req, 'Host', hostHeader);
  }

  req.write = function(buffer, encoding) {
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
  };

  req.end = function(buffer, encoding) {
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end();
      req.emit('end');
    }
  };

  req.abort = function() {
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted'
    response.emit('close', err);
  };

  end = function() {
    ended = true;
    var encoding
      , requestBody
      , responseBody
      , interceptor
      , paused
      , next = []
      , callnext;

    requestBody = requestBodyBuffers.map(function(buffer) {
      return buffer.toString(encoding);
    }).join('');

    interceptors = interceptors.filter(function(interceptor) {
      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) { throw new Error("Nock: No match for HTTP request " + stringifyRequest(options)); }
    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};
    response.readable = true;
    responseBody = interceptor.body;
    if (! Buffer.isBuffer(responseBody)) {
      responseBody = new Buffer(responseBody);
    }
    response.setEncoding = function(newEncoding) {
      encoding = newEncoding;
    };
    remove(interceptor);
    interceptor.discard();

    if (aborted) { return; }

    response.pause = function() {
      paused = true;
    };

    response.resume = function() {
      paused = false;
      callnext();
    };

    response.pipe = function(dest, options) {
      var source = this;

      function ondata(chunk) {
        if (dest.writable) {
          if (false === dest.write(chunk)) source.pause();
        }
      }

      function ondrain() {
        if (source.readable) source.resume();
      }

      source.on('data', ondata);
      dest.on('drain', ondrain);

      // If the 'end' option is not supplied, dest.end() will be called when
      // source gets the 'end' or 'close' events.  Only dest.end() once, and
      // only when all sources have ended.
      if (!options || options.end !== false) {
        dest._pipeCount = dest._pipeCount || 0;
        dest._pipeCount++;

        source.on('end', onend);
        source.on('close', onclose);
      }

      var didOnEnd = false;
      function onend() {
        if (didOnEnd) return;
        didOnEnd = true;

        dest._pipeCount--;

        // remove the listeners
        cleanup();

        if (dest._pipeCount > 0) {
          // waiting for other incoming streams to end.
          return;
        }

        dest.end();
      }

      function onclose() {
        if (didOnEnd) return;
        didOnEnd = true;

        dest._pipeCount--;

        // remove the listeners
        cleanup();

        if (dest._pipeCount > 0) {
          // waiting for other incoming streams to end.
          return;
        }

        dest.destroy();
      }

      // don't leave dangling pipes when there are errors.
      function onerror(er) {
        cleanup();
        if (this.listeners('error').length === 0) {
          throw er; // Unhandled stream error in pipe.
        }
      }

      source.on('error', onerror);
      dest.on('error', onerror);

      // guarantee that source streams can be paused and resumed, even
      // if the only effect is to proxy the event back up the pipe chain.
      if (!source.pause) {
        source.pause = function() {
          source.emit('pause');
        };
      }

      if (!source.resume) {
        source.resume = function() {
          source.emit('resume');
        };
      }

      function onpause() {
        source.pause();
      }

      dest.on('pause', onpause);

      function onresume() {
        if (source.readable) source.resume();
      }

      dest.on('resume', onresume);

      // remove all the event listeners that were added.
      function cleanup() {
        source.removeListener('data', ondata);
        dest.removeListener('drain', ondrain);

        source.removeListener('end', onend);
        source.removeListener('close', onclose);

        dest.removeListener('pause', onpause);
        dest.removeListener('resume', onresume);

        source.removeListener('error', onerror);
        dest.removeListener('error', onerror);

        source.removeListener('end', cleanup);
        source.removeListener('close', cleanup);

        dest.removeListener('end', cleanup);
        dest.removeListener('close', cleanup);
      }

      source.on('end', cleanup);
      source.on('close', cleanup);

      dest.on('end', cleanup);
      dest.on('close', cleanup);

      dest.emit('pipe', source);
    };

    next.push(function() {
      if (encoding) {
        responseBody = responseBody.toString(encoding);
      }
      response.emit('data', responseBody);
    });

    next.push(function() {
      response.emit('end');
    });

    callnext = function() {
      if (paused || next.length === 0 || aborted) { return; }
      process.nextTick(function() {
        next.shift()();
        callnext();
      });
    };

    process.nextTick(function() {
      if (typeof callback === 'function') {
        callback(response);
      }
      req.emit('response', response);
      callnext();
    });
  };

  return req;
}

var httpRequest = http.request;

http.request = function(options, callback) {
  if (!options.host) {
    options.host = options.hostname;
    if (options.port)
      options.host += ":" + options.port;
  }
  var basePath = 'http://' + options.host
    , interceptors = allInterceptors[basePath];

  if (interceptors) {
    return processRequest(interceptors, options, callback);
  } else {
    return httpRequest.apply(http, arguments);
  }
};

var httpsRequest = https.request;

https.request = function(options, callback) {
  var basePath = 'https://' + options.host
    , interceptors = allInterceptors[basePath];

  options.https = true;

  if (interceptors && interceptors.length > 0) {
    return processRequest(interceptors, options, callback);
  } else {
    return httpsRequest.apply(https, arguments);
  }
};

module.exports = addGlobalInterceptor;
<commit_msg>Removed uneeded line<commit_after>var path = require('path')
  , http = require('http')
  , https = require('https')
  , url  = require('url')
  , EventEmitter = require('events').EventEmitter;

var allInterceptors = {};

function addGlobalInterceptor(key, interceptor) {
  if (! allInterceptors.hasOwnProperty(key)) {
    allInterceptors[key] = [];
  }
  allInterceptors[key].push(interceptor);
}

function remove(interceptor) {
  var key = interceptor._key.split(' ');
  var u = url.parse(key[1]);
  var hostKey = u.protocol + '//' + u.host;
  var interceptors = allInterceptors[hostKey];
  var interceptor;
  var thisInterceptor;

  for(var i = 0; i < interceptors.length; i++) {
    thisInterceptor = interceptors[i];
    if (thisInterceptor._key === interceptor._key) {
      interceptors.splice(i, 1);
      break;
    }
  }
  //if (! interceptors) { delete allInterceptors[hostKey]; }
}

function stringifyRequest(options) {
  var method = options.method || 'GET';
  var path = options.path;
  var body = options.body;
  if (body && typeof(body) !== 'string') {
    body = body.toString();
  }
  return method + ' ' + path + ' ' + body;
}

function getHeader(request, name) {
  if (!request._headers) return;

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._headers[key] = value;
  request._headerNames[key] = name;
}

function processRequest(interceptors, options, callback) {
  var req = new EventEmitter()
    , response = new EventEmitter()
    , requestBodyBuffers = []
    , aborted
    , end
    , ended;

  if (options.headers) {
    var headers = options.headers;
    var keys = Object.keys(headers);

    for (var i = 0, l = keys.length; i < l; i++) {
      var key = keys[i];

      setHeader(req, key, headers[key]);
    };
  }

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  if (options.host && !getHeader(req, 'host')) {
    var hostHeader = options.host;

    if (options.host && +options.port !== 80) {
      hostHeader += ':' + options.port;
    }

    setHeader(req, 'Host', hostHeader);
  }

  req.write = function(buffer, encoding) {
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
  };

  req.end = function(buffer, encoding) {
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end();
      req.emit('end');
    }
  };

  req.abort = function() {
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted'
    response.emit('close', err);
  };

  end = function() {
    ended = true;
    var encoding
      , requestBody
      , responseBody
      , interceptor
      , paused
      , next = []
      , callnext;

    requestBody = requestBodyBuffers.map(function(buffer) {
      return buffer.toString(encoding);
    }).join('');

    interceptors = interceptors.filter(function(interceptor) {
      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) { throw new Error("Nock: No match for HTTP request " + stringifyRequest(options)); }
    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};
    response.readable = true;
    responseBody = interceptor.body;
    if (! Buffer.isBuffer(responseBody)) {
      responseBody = new Buffer(responseBody);
    }
    response.setEncoding = function(newEncoding) {
      encoding = newEncoding;
    };
    remove(interceptor);
    interceptor.discard();

    if (aborted) { return; }

    response.pause = function() {
      paused = true;
    };

    response.resume = function() {
      paused = false;
      callnext();
    };

    response.pipe = function(dest, options) {
      var source = this;

      function ondata(chunk) {
        if (dest.writable) {
          if (false === dest.write(chunk)) source.pause();
        }
      }

      function ondrain() {
        if (source.readable) source.resume();
      }

      source.on('data', ondata);
      dest.on('drain', ondrain);

      // If the 'end' option is not supplied, dest.end() will be called when
      // source gets the 'end' or 'close' events.  Only dest.end() once, and
      // only when all sources have ended.
      if (!options || options.end !== false) {
        dest._pipeCount = dest._pipeCount || 0;
        dest._pipeCount++;

        source.on('end', onend);
        source.on('close', onclose);
      }

      var didOnEnd = false;
      function onend() {
        if (didOnEnd) return;
        didOnEnd = true;

        dest._pipeCount--;

        // remove the listeners
        cleanup();

        if (dest._pipeCount > 0) {
          // waiting for other incoming streams to end.
          return;
        }

        dest.end();
      }

      function onclose() {
        if (didOnEnd) return;
        didOnEnd = true;

        dest._pipeCount--;

        // remove the listeners
        cleanup();

        if (dest._pipeCount > 0) {
          // waiting for other incoming streams to end.
          return;
        }

        dest.destroy();
      }

      // don't leave dangling pipes when there are errors.
      function onerror(er) {
        cleanup();
        if (this.listeners('error').length === 0) {
          throw er; // Unhandled stream error in pipe.
        }
      }

      source.on('error', onerror);
      dest.on('error', onerror);

      // guarantee that source streams can be paused and resumed, even
      // if the only effect is to proxy the event back up the pipe chain.
      if (!source.pause) {
        source.pause = function() {
          source.emit('pause');
        };
      }

      if (!source.resume) {
        source.resume = function() {
          source.emit('resume');
        };
      }

      function onpause() {
        source.pause();
      }

      dest.on('pause', onpause);

      function onresume() {
        if (source.readable) source.resume();
      }

      dest.on('resume', onresume);

      // remove all the event listeners that were added.
      function cleanup() {
        source.removeListener('data', ondata);
        dest.removeListener('drain', ondrain);

        source.removeListener('end', onend);
        source.removeListener('close', onclose);

        dest.removeListener('pause', onpause);
        dest.removeListener('resume', onresume);

        source.removeListener('error', onerror);
        dest.removeListener('error', onerror);

        source.removeListener('end', cleanup);
        source.removeListener('close', cleanup);

        dest.removeListener('end', cleanup);
        dest.removeListener('close', cleanup);
      }

      source.on('end', cleanup);
      source.on('close', cleanup);

      dest.on('end', cleanup);
      dest.on('close', cleanup);

      dest.emit('pipe', source);
    };

    next.push(function() {
      if (encoding) {
        responseBody = responseBody.toString(encoding);
      }
      response.emit('data', responseBody);
    });

    next.push(function() {
      response.emit('end');
    });

    callnext = function() {
      if (paused || next.length === 0 || aborted) { return; }
      process.nextTick(function() {
        next.shift()();
        callnext();
      });
    };

    process.nextTick(function() {
      if (typeof callback === 'function') {
        callback(response);
      }
      req.emit('response', response);
      callnext();
    });
  };

  return req;
}

var httpRequest = http.request;

http.request = function(options, callback) {
  if (!options.host) {
    options.host = options.hostname;
    if (options.port)
      options.host += ":" + options.port;
  }
  var basePath = 'http://' + options.host
    , interceptors = allInterceptors[basePath];

  if (interceptors) {
    return processRequest(interceptors, options, callback);
  } else {
    return httpRequest.apply(http, arguments);
  }
};

var httpsRequest = https.request;

https.request = function(options, callback) {
  var basePath = 'https://' + options.host
    , interceptors = allInterceptors[basePath];

  options.https = true;

  if (interceptors && interceptors.length > 0) {
    return processRequest(interceptors, options, callback);
  } else {
    return httpsRequest.apply(https, arguments);
  }
};

module.exports = addGlobalInterceptor;
<|endoftext|>


<commit_before>/**
 * Contains binary handling suff
 * @module machine.bin
 */

'use strict';

module.exports = function(kbox) {

  // Node modules
  var path = require('path');

  // NPM modules
  var _ = require('lodash');

  // Kalabox modules
  var Promise = kbox.Promise;
  var shell = kbox.util.shell;

  // Provider config
  var providerConfig = kbox.core.deps.get('providerConfig');

  // Get VB config
  var VIRTUALBOX_CONFIG = providerConfig.virtualbox;

  // Set of logging functions.
  var log = kbox.core.log.make('DOCKER');

  /*
   * Get directory for docker executables.
   */
  var getBinPath = function() {

    // Get sysconf
    var sysConfRoot = kbox.core.deps.get('config').sysConfRoot;
    return path.join(sysConfRoot, 'bin');

  };

  /*
   * Return the machine executable location
   */
  var getMachineExecutable = function() {

    // Get machine bin path
    var machinePath = getBinPath();
    var machineBin = path.join(machinePath, 'docker-machine');

    // Return exec based on path
    switch (process.platform) {
      case 'win32': return machineBin + '.exe';
      case 'darwin': return machineBin;
      case 'linux': return machineBin;
    }

  };

  /*
   * Return the machine executable location
   */
  var getComposeExecutable = function() {

    // Get compose bin path
    var composePath = getBinPath();
    var composeBin = path.join(composePath, 'docker-compose');

    // Return exec based on path
    switch (process.platform) {
      case 'win32': return composeBin + '.exe';
      case 'darwin': return composeBin;
      case 'linux': return composeBin;
    }

  };

  /*
   * Exec or spawn a shell command.
   */
  var sh = function(cmd, opts) {

    // If we have a mode then we need to spawn
    if (opts && opts.mode) {

      /*
       * Compose run's require stdin to be a tty to get the correct output back
       * so we have to set stdin on collect to pty so it get's replaced with a
       * pseudo terminal's stdin.
       */

      // Stdio per mode
      var mode = kbox.core.deps.get('mode');
      var stdinMode = (mode === 'gui') ? 'ignore' : process.stdin;
      var collect = {stdio: [stdinMode, 'pipe', process.stderr]};
      var attach = {stdio: 'inherit'};
      var stdio = (opts.mode === 'attach') ? attach : collect;

      // Merge in our options
      var options = (opts) ? _.extend(opts, stdio) : stdio;

      return shell.spawn(cmd, options);
    }

    // Otherwise we can do a basic exec
    else {

      // Do the exec
      return shell.exec(cmd, opts)

      // Log results.
      .tap(function(data) {
        log.debug('Command results.', data);
      });

    }
  };

  /*
   * Check to see if VirtualBox's modules are loaded
   */
  var checkVBModules = function() {

    // Do the checks on linux
    if (process.platform === 'linux') {

      // This is how /etc/init.d/vboxdrv checks if the modules are loaded
      return sh('lsmod | grep -q "vboxdrv[^_-]"')

      // Exit status != 0, modules are not loaded
      .catch(function(/*err*/) {
        // Modules are not loaded
        return Promise.resolve(false);
      })

      .then(function(err) {
        if (_.isEmpty(err)) {
          return Promise.resolve(true);
        } else {
          return Promise.resolve(false);
        }
      });
    }

    // Otherwise assume we are good
    else {
      return Promise.resolve(true);
    }

  };

  /*
   * Recompile VirtualBox's kernel modules
   *
   * @todo: @jeffesquivels - Try to load VirtualBox's kernel modules and only
   * recompile if that fails
   */
  var bringVBModulesUp = function() {
    var flavor = kbox.util.linux.getFlavor();
    var packager = (flavor === 'debian') ? 'apt' : 'dnf';
    var cmd = VIRTUALBOX_CONFIG[packager].recompile;

    log.info('VBox\'s kernel modules seem to be down. Attempting recompile...');

    // Run the recompile command
    return shell.execAdmin(cmd)

    // Return good or bad
    .then(function(output) {
      if (_.includes(output, 'wrong')) {
        log.info('The modules couldn\'t be compiled. Dying now.', output);
        return Promise.resolve(false);
      } else {
        log.info('VirtualBox\'s modules seem to be up. Retrying.');
        return Promise.resolve(true);
      }
    });
  };

  // Build module function.
  return {
    checkVBModules: checkVBModules,
    bringVBModulesUp: bringVBModulesUp,
    sh: sh,
    getBinPath: getBinPath,
    getMachineExecutable: getMachineExecutable,
    getComposeExecutable: getComposeExecutable
  };

};
<commit_msg>#928: Stderr also needs to be ignored for collect on GUI<commit_after>/**
 * Contains binary handling suff
 * @module machine.bin
 */

'use strict';

module.exports = function(kbox) {

  // Node modules
  var path = require('path');

  // NPM modules
  var _ = require('lodash');

  // Kalabox modules
  var Promise = kbox.Promise;
  var shell = kbox.util.shell;

  // Provider config
  var providerConfig = kbox.core.deps.get('providerConfig');

  // Get VB config
  var VIRTUALBOX_CONFIG = providerConfig.virtualbox;

  // Set of logging functions.
  var log = kbox.core.log.make('DOCKER');

  /*
   * Get directory for docker executables.
   */
  var getBinPath = function() {

    // Get sysconf
    var sysConfRoot = kbox.core.deps.get('config').sysConfRoot;
    return path.join(sysConfRoot, 'bin');

  };

  /*
   * Return the machine executable location
   */
  var getMachineExecutable = function() {

    // Get machine bin path
    var machinePath = getBinPath();
    var machineBin = path.join(machinePath, 'docker-machine');

    // Return exec based on path
    switch (process.platform) {
      case 'win32': return machineBin + '.exe';
      case 'darwin': return machineBin;
      case 'linux': return machineBin;
    }

  };

  /*
   * Return the machine executable location
   */
  var getComposeExecutable = function() {

    // Get compose bin path
    var composePath = getBinPath();
    var composeBin = path.join(composePath, 'docker-compose');

    // Return exec based on path
    switch (process.platform) {
      case 'win32': return composeBin + '.exe';
      case 'darwin': return composeBin;
      case 'linux': return composeBin;
    }

  };

  /*
   * Exec or spawn a shell command.
   */
  var sh = function(cmd, opts) {

    // If we have a mode then we need to spawn
    if (opts && opts.mode) {

      /*
       * Compose run's require stdin to be a tty to get the correct output back
       * so we have to set stdin on collect to pty so it get's replaced with a
       * pseudo terminal's stdin.
       */

      // Stdio per mode
      var mode = kbox.core.deps.get('mode');
      var stdinMode = (mode === 'gui') ? 'ignore' : process.stdin;
      var stdErrMode = (mode === 'gui') ? 'ignore' : process.stderr;

      // Attach and collect modes
      var collect = {stdio: [stdinMode, 'pipe', stdErrMode]};
      var attach = {stdio: 'inherit'};
      var stdio = (opts.mode === 'attach') ? attach : collect;

      // Merge in our options
      var options = (opts) ? _.extend(opts, stdio) : stdio;

      return shell.spawn(cmd, options);
    }

    // Otherwise we can do a basic exec
    else {

      // Do the exec
      return shell.exec(cmd, opts)

      // Log results.
      .tap(function(data) {
        log.debug('Command results.', data);
      });

    }
  };

  /*
   * Check to see if VirtualBox's modules are loaded
   */
  var checkVBModules = function() {

    // Do the checks on linux
    if (process.platform === 'linux') {

      // This is how /etc/init.d/vboxdrv checks if the modules are loaded
      return sh('lsmod | grep -q "vboxdrv[^_-]"')

      // Exit status != 0, modules are not loaded
      .catch(function(/*err*/) {
        // Modules are not loaded
        return Promise.resolve(false);
      })

      .then(function(err) {
        if (_.isEmpty(err)) {
          return Promise.resolve(true);
        } else {
          return Promise.resolve(false);
        }
      });
    }

    // Otherwise assume we are good
    else {
      return Promise.resolve(true);
    }

  };

  /*
   * Recompile VirtualBox's kernel modules
   *
   * @todo: @jeffesquivels - Try to load VirtualBox's kernel modules and only
   * recompile if that fails
   */
  var bringVBModulesUp = function() {
    var flavor = kbox.util.linux.getFlavor();
    var packager = (flavor === 'debian') ? 'apt' : 'dnf';
    var cmd = VIRTUALBOX_CONFIG[packager].recompile;

    log.info('VBox\'s kernel modules seem to be down. Attempting recompile...');

    // Run the recompile command
    return shell.execAdmin(cmd)

    // Return good or bad
    .then(function(output) {
      if (_.includes(output, 'wrong')) {
        log.info('The modules couldn\'t be compiled. Dying now.', output);
        return Promise.resolve(false);
      } else {
        log.info('VirtualBox\'s modules seem to be up. Retrying.');
        return Promise.resolve(true);
      }
    });
  };

  // Build module function.
  return {
    checkVBModules: checkVBModules,
    bringVBModulesUp: bringVBModulesUp,
    sh: sh,
    getBinPath: getBinPath,
    getMachineExecutable: getMachineExecutable,
    getComposeExecutable: getComposeExecutable
  };

};
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs'),
    libString = '';

fs.readFile(process.argv[2], 'utf8', function (err, data) {
    if (err) throw err;

    fs.writeFile('stringified.js', 'window.stringified = ' + JSON.stringify(data), function (err) {
        if (err) throw err;
        console.log('It\'s saved!');
    });
});<commit_msg>Remove unused variable.<commit_after>'use strict';

var fs = require('fs');

fs.readFile(process.argv[2], 'utf8', function (err, data) {
    if (err) throw err;

    fs.writeFile('stringified.js', 'window.stringified = ' + JSON.stringify(data), function (err) {
        if (err) throw err;
        console.log('It\'s saved!');
    });
});
<|endoftext|>


<commit_before>var http = require("http");
var fs = require("fs");
var os = require("os");
var exec = require("child_process").exec;

var targetDir = __dirname + "/tools/";
try {
    fs.statSync(targetDir);
} catch (e) {
    fs.mkdirSync(targetDir);
}

var platform = null;
if (os.type() === "Darwin") {
    platform = "macosx";
} else if (os.type() === "Linux") {
    platform = "linux";
} else {
    throw new Error("Unknown OS!");
}

function attemptDownload(attemptsLeft) {
    var url = "https://dl-ssl.google.com/android/repository/platform-tools_r16-" + platform + ".zip";
    var tempFile = "/tmp/platform-tools-" + (new Date().getTime()) + ".zip";

    var file = fs.createWriteStream(tempFile);
    var request = http.get(url, function (response) {
        response.pipe(file);
        response.on("end", function () {
            exec("unzip -j -o " + tempFile + " platform-tools/aapt -d tools/", function (err) {
                if (err) {
                    if (attemptsLeft === 0) {
                        throw err;
                    } else {
                        attemptDownload(attemptsLeft - 1);
                        return;
                    }
                }
                fs.chmodSync("tools/aapt", "755");
                fs.unlinkSync(tempFile);
                process.exit();
            });
        });
    });
}

attemptDownload(3);
<commit_msg>Ugh, node requires a different module for https.<commit_after>var https = require("https");
var fs = require("fs");
var os = require("os");
var exec = require("child_process").exec;

var targetDir = __dirname + "/tools/";
try {
    fs.statSync(targetDir);
} catch (e) {
    fs.mkdirSync(targetDir);
}

var platform = null;
if (os.type() === "Darwin") {
    platform = "macosx";
} else if (os.type() === "Linux") {
    platform = "linux";
} else {
    throw new Error("Unknown OS!");
}

function attemptDownload(attemptsLeft) {
    var url = "https://dl-ssl.google.com/android/repository/platform-tools_r16-" + platform + ".zip";
    var tempFile = "/tmp/platform-tools-" + (new Date().getTime()) + ".zip";

    var file = fs.createWriteStream(tempFile);
    var request = https.get(url, function (response) {
        response.pipe(file);
        response.on("end", function () {
            exec("unzip -j -o " + tempFile + " platform-tools/aapt -d tools/", function (err) {
                if (err) {
                    if (attemptsLeft === 0) {
                        throw err;
                    } else {
                        attemptDownload(attemptsLeft - 1);
                        return;
                    }
                }
                fs.chmodSync("tools/aapt", "755");
                fs.unlinkSync(tempFile);
                process.exit();
            });
        });
    });
}

attemptDownload(3);
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Petka Antonov

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

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

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

    function escapeForQuote( str ) {
        return (str + "").replace( /(\\|")/g, "\\$1" );
    }

    var returnNull = function() {
        return null;
    };

    if( !global.localStorage ) {
        global.localStorage = {
            getItem: returnNull,
            setItem: returnNull,
            removeItem: returnNull,
            clear: returnNull
        };
    }

    function FieldState( form ) {

        if( !form ) {
            this.element = document.createElement("form");
        }
        else if( "jquery" in form ) {
            this.element = form.filter("form")[0];
        }
        else if( "appendChild" in form ) {
            this.element = form;
        }

        form = this.element;
        this.identifier = (form.id + "");
    }

    FieldState.prototype = {

        restore: function() {
            var items = global.localStorage.getItem( this.identifier ),
                storedValue, storedValueType, $elems;

            if( !items ) {
                return;
            }
            try {
                items = $.parseJSON( items );
            }
            catch( error ) {
                return;
            }

            for( var key in items ) {
                storedValue = items[key];
                storedValueType = $.type( storedValue );

                $elems = $( '[name="' + escapeForQuote(key)  + '"]', this.element );

                if( storedValueType === "array" ) { //Multiple elements with same name or single element with multiple values

                    if( $elems.length === 1 ) { // A single element with multiple values
                        $elems.val( storedValue );
                    }
                    else {
                        $elems.each( $.proxy( function(index, elem){
                            var value = this[index];

                            if( typeof value === "boolean" ) {  //Radio/Checkbox
                                elem.checked = value;
                            }
                            else {
                                $( elem ).val( value )
                            }
                        }, storedValue ) );
                    }
                }
                else if( storedValueType === "boolean" ) { //Radio/Checkbox
                    $elems.prop("checked", storedValue);
                }
                else {
                    $elems.val( items[key] );
                }

                $elems.trigger("fieldstate:restored");
            }

        },

        clear: function() {
            global.localStorage.removeItem( this.identifier );
        },

        save: function() {
            if( !global.JSON || !global.JSON.stringify ) {
                return;
            }

            var obj = {};
            $( '[name][type!="hidden"][type!="file"][data-fieldstate!="false"]', this.element ).each( function(){
                var name = this.name, value, type = this.type && this.type.toLowerCase() || "";

                if( name && $(this).is("input,select,textarea") ) {

                    value = type === "radio" || type === "checkbox" ? !!this.checked : $(this).val();

                    if( name in obj ) { //Multiple elements with same name
                        if( $.type( obj[name] ) !== "array" ) {
                            obj[name] = [obj[name]];
                        }
                        obj[name].push( value );
                    }
                    else {
                        obj[name] = value;
                    }
                }
            });

            global.localStorage.setItem( this.identifier, global.JSON.stringify( obj ) );
        },

        constructor: FieldState
    };

    $.fn.fieldstate = function( option ) {

        return this.filter( "form" ).each( function() {

            var $this = $(this),
                instance = $this.data( "FieldState-instance" );

            if( !instance ) {
                $this.data( "FieldState-instance", ( instance = new FieldState( this ) ) );
                if( !option ) {
                    option = $this.data( "fieldstate" );
                }
            }

            if( typeof option === "string" && option in instance ) {
                instance[option]();
            }

        });

    };

    $.fn.fieldstate.Constructor = FieldState;

    $( function() {
        $( "form[data-fieldstate]" ).fieldstate().on( {
            submit: function() {
                $(this).fieldstate("save");
            },

            reset: function() {
                $(this).fieldstate("clear");
            },

            change: function() {
                $(this).fieldstate("save");
            }
        });

        $( window ).on( "beforeunload", function(){
            $( "form[data-fieldstate]" ).fieldstate("save");
        });
    });

})( this, this.jQuery );<commit_msg>clean constructor<commit_after>/*
Copyright (c) 2012 Petka Antonov

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

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

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

    function escapeForQuote( str ) {
        return (str + "").replace( /(\\|")/g, "\\$1" );
    }

    var returnNull = function() {
        return null;
    };

    if( !global.localStorage ) {
        global.localStorage = {
            getItem: returnNull,
            setItem: returnNull,
            removeItem: returnNull,
            clear: returnNull
        };
    }

    function FieldState( form ) {
        this.element = $(form);
        this.identifier = (this.element.prop("id") + "");
    }

    FieldState.prototype = {

        restore: function() {
            var items = global.localStorage.getItem( this.identifier ),
                storedValue, storedValueType, $elems;

            if( !items ) {
                return;
            }

            try {
                items = $.parseJSON( items );
            }
            catch( error ) {
                return;
            }

            for( var key in items ) {
                storedValue = items[key];
                storedValueType = $.type( storedValue );

                $elems = $( '[name="' + escapeForQuote(key)  + '"]', this.element );

                if( storedValueType === "array" ) { //Multiple elements with same name or single element with multiple values

                    if( $elems.length === 1 ) { // A single element with multiple values
                        $elems.val( storedValue );
                    }
                    else {
                        $elems.each( $.proxy( function(index, elem){
                            var value = this[index];

                            if( typeof value === "boolean" ) {  //Radio/Checkbox
                                elem.checked = value;
                            }
                            else {
                                $( elem ).val( value )
                            }
                        }, storedValue ) );
                    }
                }
                else if( storedValueType === "boolean" ) { //Radio/Checkbox
                    $elems.prop("checked", storedValue);
                }
                else {
                    $elems.val( items[key] );
                }

                $elems.trigger("fieldstate:restored");
            }

        },

        clear: function() {
            global.localStorage.removeItem( this.identifier );
        },

        save: function() {
            if( !global.JSON || !global.JSON.stringify ) {
                return;
            }

            var obj = {};
            $( '[name][type!="hidden"][type!="file"][data-fieldstate!="false"]', this.element ).each( function(){
                var name = this.name, value, type = this.type && this.type.toLowerCase() || "";

                if( name && $(this).is("input,select,textarea") ) {

                    value = type === "radio" || type === "checkbox" ? !!this.checked : $(this).val();

                    if( name in obj ) { //Multiple elements with same name
                        if( $.type( obj[name] ) !== "array" ) {
                            obj[name] = [obj[name]];
                        }
                        obj[name].push( value );
                    }
                    else {
                        obj[name] = value;
                    }
                }
            });

            global.localStorage.setItem( this.identifier, global.JSON.stringify( obj ) );
        },

        constructor: FieldState
    };

    $.fn.fieldstate = function( option ) {

        return this.filter( "form" ).each( function() {

            var $this = $(this),
                instance = $this.data( "FieldState-instance" );

            if( !instance ) {
                $this.data( "FieldState-instance", ( instance = new FieldState( this ) ) );
                if( !option ) {
                    option = $this.data( "fieldstate" );
                }
            }

            if( typeof option === "string" && option in instance ) {
                instance[option]();
            }

        });

    };

    $.fn.fieldstate.Constructor = FieldState;

    $( function() {
        $( "form[data-fieldstate]" ).fieldstate().on( {
            submit: function() {
                $(this).fieldstate("save");
            },

            reset: function() {
                $(this).fieldstate("clear");
            },

            change: function() {
                $(this).fieldstate("save");
            }
        });

        $( window ).on( "beforeunload", function(){
            $( "form[data-fieldstate]" ).fieldstate("save");
        });
    });

})( this, this.jQuery );<|endoftext|>


<commit_before>const escape = (str) =>
  String(str)
    .replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/'/g, ''')

const selfClosing = [
  'area',
  'base',
  'br',
  'col',
  'embed',
  'hr',
  'img',
  'input',
  'link',
  'meta',
  'param',
  'source',
  'track',
  'wbr'
]

const noop = () => {}

const resolve = (obj) => {
  if (typeof obj === 'function') {
    obj = obj(noop)
  }

  return obj
}

export const stringify = (obj) => {
  const {tag, attributes, children, variables} = resolve(obj)

  let result = `<${tag}`
  const isSelfClosing = selfClosing.includes(tag)

  const reducedAttributes = attributes.reduce((acc, curr) => {
    if (curr.key) {
      if (curr.key.startsWith('on')) return acc

      acc.push(curr)
    } else {
      for (const [key, value] of Object.entries(variables[curr.value])) {
        if (key.startsWith('on')) continue

        acc.push({key, value})
      }
    }

    return acc
  }, [])

  for (const attr of reducedAttributes) {
    let value = attr.value

    if (attr.variable) {
      value = variables[value]
    }

    if (value === true) {
      result += ` ${attr.key}`
    } else if (value !== false) {
      result += ` ${attr.key}="${escape(value)}"`
    }
  }

  result += '>'

  if (!isSelfClosing) {
    let i = 0

    const descendants = []

    for (let i = 0; i < children.length; i++) {
      let child = children[i]

      if (child?.type === 'variable') {
        child = resolve(variables[child.value])
      }

      if (child?.[Symbol.iterator] != null && typeof child !== 'string') {
        for (const c of child) {
          descendants.push(c.key != null ? c.value : c)
        }
      } else {
        descendants.push(child)
      }
    }

    while (i < descendants.length) {
      const child = descendants[i]

      if (child != null) {
        if (child.type != null) {
          switch (child.type) {
            case 'text':
              result += tag !== 'style' ? escape(child.value) : child.value
              break

            case 'node':
              result += stringify(
                Object.assign({}, child, {
                  variables: child.view != null ? child.variables : variables
                })
              )
              break
          }
        } else {
          result += tag !== 'style' ? escape(child) : child
        }
      }

      i++
    }

    result += `</${tag}>`
  }

  return result
}
<commit_msg>Fix incorrect code with stringify<commit_after>const escape = (str) =>
  String(str)
    .replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/'/g, ''')

const selfClosing = [
  'area',
  'base',
  'br',
  'col',
  'embed',
  'hr',
  'img',
  'input',
  'link',
  'meta',
  'param',
  'source',
  'track',
  'wbr'
]

const noop = () => {}

const resolve = (obj) => {
  if (typeof obj === 'function') {
    obj = obj(noop)
  }

  return obj
}

export const stringify = (obj) => {
  const {tag, attributes, children, variables} = resolve(obj)

  let result = `<${tag}`
  const isSelfClosing = selfClosing.includes(tag)

  const reducedAttributes = attributes.reduce((acc, curr) => {
    if (curr.key) {
      if (curr.key.startsWith('on')) return acc

      acc.push(curr)
    } else {
      for (const [key, value] of Object.entries(variables[curr.value])) {
        if (key.startsWith('on')) continue

        acc.push({key, value})
      }
    }

    return acc
  }, [])

  for (const attr of reducedAttributes) {
    let value = attr.value

    if (attr.variable) {
      value = variables[value]
    }

    if (value === true) {
      result += ` ${attr.key}`
    } else if (value !== false) {
      result += ` ${attr.key}="${escape(value)}"`
    }
  }

  result += '>'

  if (!isSelfClosing) {
    let i = 0

    const descendants = []

    for (let i = 0; i < children.length; i++) {
      let child = children[i]

      if (child?.type === 'variable') {
        child = variables[child.value]
      }

      if (child?.[Symbol.iterator] == null || typeof child === 'string') {
        child = [child]
      }

      for (let c of child) {
        c = resolve(c) ?? ''

        descendants.push(c.key != null ? c.value : c)
      }
    }

    while (i < descendants.length) {
      const child = descendants[i]

      if (child != null) {
        if (child.type != null) {
          switch (child.type) {
            case 'text':
              result += tag !== 'style' ? escape(child.value) : child.value
              break

            case 'node':
              result += stringify(
                Object.assign({}, child, {
                  variables: child.view != null ? child.variables : variables
                })
              )
              break
          }
        } else {
          result += tag !== 'style' ? escape(child) : child
        }
      }

      i++
    }

    result += `</${tag}>`
  }

  return result
}
<|endoftext|>


<commit_before>var
    // An array of objects representing files to copy
    copyFiles = [{
      from: 'bower_components/viking-base/example-.gitignore',
      to: '.gitignore'
    }, {
      from: 'bower_components/viking-base/example-404.html',
      to: '404.html'
    }, {
      from: 'bower_components/viking-base/example-index.html',
      to: 'index.html'
    }, {
      from: 'bower_components/viking-base/example-pom.xml',
      to: 'pom.xml'
    }, {
      from: 'bower_components/viking-base/example-humans.txt',
      to: 'humans.txt'
    }, {
      from: 'bower_components/viking-base/example-robots.txt',
      to: 'robots.txt'
    }, {
      from: 'bower_components/viking-base/css/example-style.scss',
      to: 'css/style.scss'
    }, {
      from: 'bower_components/viking-base/img/example-apple-touch-icon-precomposed.png',
      to: 'apple-touch-icon-precomposed.png'
    }, {
      from: 'bower_components/viking-base/img/example-favicon.ico',
      to: 'favicon.ico'
    }, {
      from: 'bower_components/viking-base/js/example-main.js',
      to: 'js/main.js',
    }, {
      from: 'bower_components/viking-base/js/example-plugins.js',
      to: 'js/plugins.js'
    }, {
      from: 'bower_components/viking-base/js/example-pre-app.js',
      to: 'js/pre-app.js'
    }, {
      from: 'bower_components/viking-base/js/example-templates/example-application.hbs',
      to: 'js/templates/application.hbs'
    }, {
      from: 'bower_components/viking-base/js/example-app.js',
      to: 'js/app/app.js'
    }],
    // Require the file system module
    fs = require('fs'),
    i = 0,
    // An array of directories to make
    makeDirs = [
      'css',
      'js',
      'js/app',
      'js/templates'
    ],
    sourceFile = '',
    targetFile = '';

// Copy a file
function copyFile(source, target) {

  var readFile = fs.createReadStream(source),
      writeFile = null;

  // Try to read the source file
  readFile.on('error', function(err) {

    console.error(err);
  });

  // Check if target file exists
  if (!fs.existsSync(target)) {

    writeFile = fs.createWriteStream(target);

    // Try to create the target file
    writeFile.on('error', function(err) {

      console.error(err);
    });

    writeFile.on('close', function(ex) {

      console.info('  Copied: ' + source + ' to ' + target);
    });

    // Read the contents of the source file into the target file
    readFile.pipe(writeFile);

  } else {

    console.warn('  File exists: ' + target + '. Did not copy.');
  }
}

console.info('Creating base project directories...');

// Create some needed folders
for (i = 0; i < makeDirs.length; i++) {

  if (!fs.existsSync(makeDirs[i])) {

    fs.mkdir(makeDirs[i]);

    console.info('  ' + makeDirs[i]);

  } else {

    console.warn('  Directory exists: ' + makeDirs[i] + '. Did not create.');
  }
}

console.info('Copying example files...');

// Copy each file in the array
for (i = 0; i < copyFiles.length; i++) {

  sourceFile = copyFiles[i].from;
  targetFile = copyFiles[i].to;

  copyFile(sourceFile, targetFile);
}<commit_msg>Updated scaffolding script<commit_after>var
    // An array of objects representing files to copy
    copyFiles = [
      {
        canOverride: false,
        from: 'bower_components/viking-base/.bowerrc',
        to: '.bowerrc'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/.gitignore',
        to: '.gitignore'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/404.html',
        to: '404.html'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/apple-touch-icon-precomposed.png',
        to: 'apple-touch-icon-precomposed.png'
      }, {
        canOverride: true,
        from: 'bower_components/viking-base/bower.json',
        to: 'bower.json'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/img/favicon.ico',
        to: 'favicon.ico'
      }, {
        canOverride: true,
        from: 'bower_components/viking-base/gulpfile.js',
        to: 'gulpfile.js'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/humans.txt',
        to: 'humans.txt'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/index.html',
        to: 'index.html'
      }, {
        canOverride: true,
        from: 'bower_components/viking-base/package.json',
        to: 'package.json'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/robots.txt',
        to: 'robots.txt'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/hbs/application.hbs',
        to: 'hbs/application.hbs'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/js/main.js',
        to: 'js/main.js',
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/js/plugins.js',
        to: 'js/plugins.js'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/js/pre-app.js',
        to: 'js/pre-app.js'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/js/app/app.js',
        to: 'js/app/app.js'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/js/vendor/jquery-1.11.1.js',
        to: 'js/vendor/jquery-1.11.1.js'
      }, {
        canOverride: false,
        from: 'bower_components/viking-base/scss/style.scss',
        to: 'scss/style.scss'
      }
    ],
    // Require the file system module
    fs = require('fs'),
    i = 0,
    // An array of directories to make
    makeDirs = [
      'hbs',
      'js',
      'js/app',
      'js/vendor',
      'scss'
    ];

// Copy a file
function copyFile( copyFile ) {

  var readFile = fs.createReadStream( copyFile.from ),
      writeFile = null;

  // Try to read the source file
  readFile.on('error', function( err ) {

    console.error( err );
  });

  // Check if target file exists
  if ( copyFile.canOverride || !fs.existsSync( copyFile.to ) ) {

    writeFile = fs.createWriteStream( copyFile.to );

    // Try to create the target file
    writeFile.on('error', function( err ) {

      console.error( err );
    });

    writeFile.on('close', function( ex ) {

      console.info('  Copied: ' + copyFile.from + ' to ' + copyFile.to);
    });

    // Read the contents of the source file into the target file
    readFile.pipe( writeFile );

  } else {

    console.warn('  File exists: ' + copyFile.to + '. Did not copy.');
  }
}

console.info('Creating base project directories...');

// Create some needed folders
for ( i = 0; i < makeDirs.length; i++ ) {

  if ( !fs.existsSync( makeDirs[i] ) ) {

    fs.mkdir( makeDirs[i] );

    console.info('  ' + makeDirs[i]);

  } else {

    console.warn('  Directory exists: ' + makeDirs[i] + '. Did not create.');
  }
}

console.info('Copying scaffolding files...');

// Copy each file in the array
for ( i = 0; i < copyFiles.length; i++ ) {

  copyFile( copyFiles[i] );
}<|endoftext|>


<commit_before>class MealService {
    constructor(DayModel, MealModel, FirebaseStorageService) {
        Object.assign(this, {DayModel, MealModel, FirebaseStorageService});
        this.meals = this.MealModel.emptyMealsList(); //useless
    }

    findDateRangeMealList(start, q, userId) {
        const dayNames = [];
        //let results = [];

        for (let i = 0; i < q; i++) {
            dayNames.push(moment(start).add(i, 'days').format("YYYY-M-D"));
        }

        return this.FirebaseStorageService.getAllMealsForUser(userId).then((response) =>
            this._resolveExistingMealData(response, dayNames)
        );
    };

    updateMealInfo(mealContent, date, userId, mealType, mealNo) {
        const fullDateName = moment(date).format("YYYY-M-D"); //in case nonformatted date were passed
        this.FirebaseStorageService.getSingleDateMealsList(fullDateName, userId).then((response) => {
            const newDayContent = this._resolveNewDayData(response, date, mealContent, mealType, mealNo);
            this.cleanAndSetMealsList(fullDateName, newDayContent, userId);
        });
    }

    cleanAndSetMealsList(date, rawData, id) {
        const cleanData = MealService._cleanEmptyRecipes(angular.copy(rawData));
        this.FirebaseStorageService.setSingleDateMealsList(date, cleanData, id);
    }

    _resolveNewDayData(oldDayContent, date, mealContent, mealType, mealNo)  {
        //check if there is smth. for this DAY
        if (oldDayContent === null) {
            return this._createNewDayWithNewContent(date, mealContent, mealType, mealNo);
        } else {
            //check if we already have smth. for this MEAL
            const oldMealContent = oldDayContent.mealsList.find(meal => meal.mealNo === mealNo);

            if (!!oldMealContent) {
                MealService._editMeal(oldMealContent, mealContent, mealType);
                return oldDayContent;
            } else {
                const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
                oldDayContent.mealsList.push(meal);
                return oldDayContent;
            }
        }
    }

    _createNewMealWithNewContent(mealContent, mealNo, mealType) {
        const newMeal = this.MealModel.createNewMeal(mealNo);
        return MealService._editMeal(newMeal, mealContent, mealType);
    }

    _createNewDayWithNewContent(date, mealContent, mealType, mealNo) {
        const day = this.DayModel.createNewDay(moment(date));
        const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
        day.mealsList.push(meal);
        return day;
    }

    static _editMeal(meal, newContent, mealType) {
        if (mealType === 'list') {
            meal.dishesList = meal.dishesList.concat(newContent.productsList);
        } else if (mealType === 'recipe') {
            meal.dishesList.push(newContent);
        } else if (mealType === 'stored') {
            meal.dishesList = meal.dishesList.concat(newContent.dishesList);
        }

        return meal;
    }

    static _cleanEmptyRecipes(data) {
        data.mealsList.forEach(a => a.dishesList.map((b, i) => {
            if (b.type === 'recipe' && b.productsList.length === 0) {
                a.dishesList.splice(i, 1);
            }
        }));
        return data;
    }

    deleteMeal(mealName, date) {
        const storedDayName = date.format("YYYY-M-D");
        let availableItem = this.getMealsList(storedDayName);
        let i = availableItem.mealsList.findIndex(b => b.mealName === mealName);
        availableItem.mealsList.splice(i, 1);
        this.updateCleanMealsList(storedDayName,availableItem);
    };

    _resolveExistingMealData(data, datesList) {
        const resolved = [];
        if (data === null) {
            datesList.forEach((singleDate) => {
                resolved.push(getEmptyDay.call(this, singleDate));
            })
        } else {
            datesList.forEach((singleDate) => {
                let existingDay = null;
                for (const storedDay in data) {
                    if (storedDay === singleDate) {
                        existingDay = data[storedDay];
                    }
                }
                if (existingDay === null) {
                    resolved.push(getEmptyDay.call(this, singleDate));
                } else {
                    if (existingDay.mealsList === undefined) {
                        existingDay.mealsList = this.MealModel.emptyMealsList();
                    } else {
                        for (let i = 0; i < this.meals.length; i++) {
                            let k = existingDay.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                            if (k.length === 0) {
                                existingDay.mealsList.push(this.meals[i]);
                            } else {
                                //just leave as it is if all meals are there
                            }
                        }
                    }
                    resolved.push(existingDay);
                }
            })
        }

        return resolved;

        function getEmptyDay(date) {
            const newDay = this.DayModel.createNewDay(moment(date));
            newDay.mealsList = this.MealModel.emptyMealsList();
            return newDay;
        }
    }

    findMealList(data) {
        //let data = this.getMealsList(forDate);
        if (data === null) return this.meals;
        if (data != null) {
            if (data.mealsList === undefined) {
                return this.meals; //empty meals
            } else {
                for (let i = 0; i < this.meals.length; i++) {
                    let k = data.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                    if (k.length === 0) {
                        data.mealsList.push(this.meals[i]);
                    } else {
                        //just leave as it is
                    }
                }
                return data.mealsList;
            }
        }
    };

    getMealsList(forDate) {
        let all = [];
        try {
            all = JSON.parse(localStorage.getItem(forDate));
        } catch (error) {
            console.log(error);
        }
        return all;
    }

}

Mealpler.service('MealService', MealService);<commit_msg>MP-42: added condition if meal doesn't have dishesList for some reason<commit_after>class MealService {
    constructor(DayModel, MealModel, FirebaseStorageService) {
        Object.assign(this, {DayModel, MealModel, FirebaseStorageService});
        this.meals = this.MealModel.emptyMealsList(); //useless
    }

    findDateRangeMealList(start, q, userId) {
        const dayNames = [];
        //let results = [];

        for (let i = 0; i < q; i++) {
            dayNames.push(moment(start).add(i, 'days').format("YYYY-M-D"));
        }

        return this.FirebaseStorageService.getAllMealsForUser(userId).then((response) =>
            this._resolveExistingMealData(response, dayNames)
        );
    };

    updateMealInfo(mealContent, date, userId, mealType, mealNo) {
        const fullDateName = moment(date).format("YYYY-M-D"); //in case nonformatted date were passed
        this.FirebaseStorageService.getSingleDateMealsList(fullDateName, userId).then((response) => {
            const newDayContent = this._resolveNewDayData(response, date, mealContent, mealType, mealNo);
            this.cleanAndSetMealsList(fullDateName, newDayContent, userId);
        });
    }

    cleanAndSetMealsList(date, rawData, id) {
        const cleanData = MealService._cleanEmptyRecipes(angular.copy(rawData));
        this.FirebaseStorageService.setSingleDateMealsList(date, cleanData, id);
    }

    _resolveNewDayData(oldDayContent, date, mealContent, mealType, mealNo)  {
        //check if there is smth. for this DAY
        if (oldDayContent === null) {
            return this._createNewDayWithNewContent(date, mealContent, mealType, mealNo);
        } else {
            //check if we already have smth. for this MEAL
            const oldMealContent = oldDayContent.mealsList.find(meal => meal.mealNo === mealNo);

            if (!!oldMealContent) {
                MealService._editMeal(oldMealContent, mealContent, mealType);
                return oldDayContent;
            } else {
                const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
                oldDayContent.mealsList.push(meal);
                return oldDayContent;
            }
        }
    }

    _createNewMealWithNewContent(mealContent, mealNo, mealType) {
        const newMeal = this.MealModel.createNewMeal(mealNo);
        return MealService._editMeal(newMeal, mealContent, mealType);
    }

    _createNewDayWithNewContent(date, mealContent, mealType, mealNo) {
        const day = this.DayModel.createNewDay(moment(date));
        const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
        day.mealsList.push(meal);
        return day;
    }

    static _editMeal(meal, newContent, mealType) {
        if (!meal.dishesList) meal.dishesList = [];

        if (mealType === 'list') {
            meal.dishesList = meal.dishesList.concat(newContent.productsList);
        } else if (mealType === 'recipe') {
            meal.dishesList.push(newContent);
        } else if (mealType === 'stored') {
            meal.dishesList = meal.dishesList.concat(newContent.dishesList);
        }

        return meal;
    }

    static _cleanEmptyRecipes(data) {
        data.mealsList.forEach(a => a.dishesList.map((b, i) => {
            if (b.type === 'recipe' && b.productsList.length === 0) {
                a.dishesList.splice(i, 1);
            }
        }));
        return data;
    }

    deleteMeal(mealName, date) {
        const storedDayName = date.format("YYYY-M-D");
        let availableItem = this.getMealsList(storedDayName);
        let i = availableItem.mealsList.findIndex(b => b.mealName === mealName);
        availableItem.mealsList.splice(i, 1);
        this.updateCleanMealsList(storedDayName,availableItem);
    };

    _resolveExistingMealData(data, datesList) {
        const resolved = [];
        if (data === null) {
            datesList.forEach((singleDate) => {
                resolved.push(getEmptyDay.call(this, singleDate));
            })
        } else {
            datesList.forEach((singleDate) => {
                let existingDay = null;
                for (const storedDay in data) {
                    if (storedDay === singleDate) {
                        existingDay = data[storedDay];
                    }
                }
                if (existingDay === null) {
                    resolved.push(getEmptyDay.call(this, singleDate));
                } else {
                    if (existingDay.mealsList === undefined || existingDay.mealsList.length === 0) {
                        existingDay.mealsList = this.MealModel.emptyMealsList();
                    } else {
                        for (let i = 0; i < this.meals.length; i++) {
                            let k = existingDay.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                            if (k.length === 0) {
                                existingDay.mealsList.push(this.meals[i]);
                            } else if (k[0].dishesList === undefined ) {
                                //findIndex because in Object *i could be differ from *j
                                const j = existingDay.mealsList.findIndex(b => b.mealNo === this.meals[i].mealNo);
                                existingDay.mealsList.splice(j, 1, this.meals[i]);
                            } else {
                                //just leave as it is if all meals are there
                            }
                        }
                    }
                    resolved.push(existingDay);
                }
            })
        }

        resolved.map(day => {
            day.mealsList.forEach(a => a.hasMeals = a.dishesList.length > 0);
        });

        return resolved;

        function getEmptyDay(date) {
            const newDay = this.DayModel.createNewDay(moment(date));
            newDay.mealsList = this.MealModel.emptyMealsList();
            return newDay;
        }
    }

    findMealList(data) {
        //let data = this.getMealsList(forDate);
        if (data === null) return this.meals;
        if (data != null) {
            if (data.mealsList === undefined) {
                return this.meals; //empty meals
            } else {
                for (let i = 0; i < this.meals.length; i++) {
                    let k = data.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                    if (k.length === 0) {
                        data.mealsList.push(this.meals[i]);
                    } else {
                        //just leave as it is
                    }
                }
                return data.mealsList;
            }
        }
    };

    getMealsList(forDate) {
        let all = [];
        try {
            all = JSON.parse(localStorage.getItem(forDate));
        } catch (error) {
            console.log(error);
        }
        return all;
    }

}

Mealpler.service('MealService', MealService);<|endoftext|>


<commit_before>'use strict';

// Module dependencies
var readline = require('readline');
var path = require('path');
var fs = require('fs');
var os = require('os');
var async = require('async');
var openVeoAPI = require('@openveo/api');
var confDir = path.join(openVeoAPI.fileSystem.getConfDir(), 'publish');

var exit = process.exit;

// Set module root directory
process.rootPublish = __dirname;
process.requirePublish = function(filePath) {
  return require(path.join(process.rootPublish, filePath));
};

// Create a readline interface to interact with the user
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

/**
 * Creates conf directory if it does not exist.
 */
function createConfDir(callback) {
  openVeoAPI.fileSystem.mkdir(confDir, callback);
}

/**
 * Creates logger directory if it does not exist.
 */
function createVideoTmpDir(callback) {
  var conf = require(path.join(confDir, 'publishConf.json'));
  openVeoAPI.fileSystem.mkdir(conf.videoTmpDir, callback);
}

/**
 * Creates hot folders if they do not exist.
 */
function createHotFolder(callback) {
  var conf = require(path.join(confDir, 'watcherConf.json'));

  for (var i = 0; i < conf.hotFolders.length; i++)
    openVeoAPI.fileSystem.mkdir(conf.hotFolders[i].path, callback);
}

/**
 * Creates general configuration file if it does not exist.
 */
function createConf(callback) {
  var confFile = path.join(confDir, 'publishConf.json');

  fs.exists(confFile, function(exists) {
    if (exists) {
      process.stdout.write(confFile + ' already exists\n');
      callback();
    } else {
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'videos');
      rl.question('Enter video temporary directory path (default: ' + defaultPath + ') :\n', function(answer) {
        var conf = {
          videoTmpDir: (answer || defaultPath).replace(/\\/g, '/'),
          maxConcurrentPublish: 3,
          timecodeFileName: 'synchro.xml',
          metadataFileName: '.session'
        };

        fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
      });
    }
  });
}

/**
 * Creates loggers configuration file if it does not exist.
 */
function createLoggerConf(callback) {
  var confFile = path.join(confDir, 'loggerConf.json');
  var defaultPath = path.join(os.tmpdir(), 'openveo', 'logs');
  var conf = {
    watcher: {
      fileName: path.join(defaultPath, 'openveo-watcher.log').replace(/\\/g, '/'),
      level: 'info',
      maxFileSize: 1048576,
      maxFiles: 2
    }
  };

  fs.exists(confFile, function(exists) {
    if (exists) {
      process.stdout.write(confFile + ' already exists\n');
      callback();
    }
    else
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
  });
}

/**
 * Creates video platform configuration file if it does not exist.
 */
function createVideoPlatformConf(callback) {
  var confFile = path.join(confDir, 'videoPlatformConf.json');
  var conf = {
    vimeo: {},
    youtube: {
      uploadMethod: 'uploadResumable',
      googleOAuth: {
        clientId: '',
        clientSecret: '',
        redirectUrl: 'http://localhost:3000/be/publish/configuration/googleOAuthAssosiation'
      }
    }
  };

  async.series([
    function(callback) {
      fs.exists(confFile, function(exists) {
        if (exists)
          callback(new Error(confFile + ' already exists\n'));
        else
          callback();
      });
    },
    function(callback) {
      rl.question('Enter Vimeo Web Service client id (available in your Vimeo account) :\n', function(answer) {
        conf.vimeo.clientId = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Enter Vimeo Web Service client secret (available in your Vimeo account) :\n', function(answer) {
        conf.vimeo.clientSecret = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Enter Vimeo Web Service access token (available in your Vimeo account) :\n', function(answer) {
        conf.vimeo.accessToken = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Enter Youtube API client Id (available in your Google Developper Console ) :\n', function(answer) {
        conf.youtube.googleOAuth.clientId = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Enter Youtube API client secret (available in your Google Developper Console )  :\n',
      function(answer) {
        conf.youtube.googleOAuth.clientSecret = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Do you want to overwrite Youtube resumable upload by classic upload (y/N) :\n', function(answer) {
        if (answer === 'y') conf.youtube.uploadMethod = 'uploadClassic';
        callback();
      });
    }
  ], function(error, results) {
    if (error) {
      process.stdout.write(error.message);
      callback();
    }
    else
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
  });
}

/**
 * Creates watcher configuration file if it does not exist.
 */
function createWatcherConf(callback) {
  var confFile = path.join(confDir, 'watcherConf.json');
  var conf = {hotFolders: []};

  async.series([
    function(callback) {
      fs.exists(confFile, function(exists) {
        if (exists)
          callback(new Error(confFile + ' already exists\n'));
        else
          callback();
      });
    },
    function(callback) {
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'hotFolder', 'vimeo');
      rl.question('Enter Vimeo hot folder path to listen to (default: ' + defaultPath + ') :\n', function(answer) {
        conf.hotFolders.push({
          type: 'vimeo',
          path: (answer || defaultPath).replace(/\\/g, '/')
        });
        callback();
      });
    },
    function(callback) {
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'hotFolder', 'youtube');
      rl.question('Enter Youtube hot folder path to listen to (default: ' + defaultPath + ') :\n', function(answer) {
        conf.hotFolders.push({
          type: 'youtube',
          path: (answer || defaultPath).replace(/\\/g, '/')
        });
        callback();
      });
    }
  ], function(error, results) {
    if (error) {
      process.stdout.write(error.message);
      callback();
    }
    else
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
  });
}

// Launch installation
async.series([
  createConfDir,
  createConf,
  createVideoTmpDir,
  createLoggerConf,
  createVideoPlatformConf,
  createWatcherConf,
  createHotFolder
], function(error, results) {
  if (error)
    throw error;
  else {
    process.stdout.write('Installation complete');
    exit();
  }
});
<commit_msg>Add the possibilty to skip Vimeo and / or Youtube account creation in installation<commit_after>'use strict';

// Module dependencies
var readline = require('readline');
var path = require('path');
var fs = require('fs');
var os = require('os');
var async = require('async');
var openVeoAPI = require('@openveo/api');
var confDir = path.join(openVeoAPI.fileSystem.getConfDir(), 'publish');

var exit = process.exit;

// Set module root directory
process.rootPublish = __dirname;
process.requirePublish = function(filePath) {
  return require(path.join(process.rootPublish, filePath));
};

// Create a readline interface to interact with the user
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

/**
 * Creates conf directory if it does not exist.
 */
function createConfDir(callback) {
  openVeoAPI.fileSystem.mkdir(confDir, callback);
}

/**
 * Creates logger directory if it does not exist.
 */
function createVideoTmpDir(callback) {
  var conf = require(path.join(confDir, 'publishConf.json'));
  openVeoAPI.fileSystem.mkdir(conf.videoTmpDir, callback);
}

/**
 * Creates hot folders if they do not exist.
 */
function createHotFolder(callback) {
  var conf = require(path.join(confDir, 'watcherConf.json'));
  var parallelFunctions = [];

  // Add closure to create a hot folder
  function createFunction(hotFolderPath) {
    return function(callback) {
      openVeoAPI.fileSystem.mkdir(hotFolderPath, callback);
    };
  }

  // Create a function for each hot folder
  for (var i = 0; i < conf.hotFolders.length; i++)
    parallelFunctions.push(createFunction(conf.hotFolders[i].path));

  // Create hot folders
  async.parallel(parallelFunctions, function(error, results) {
    if (error)
      throw error;
    else
      callback();
  });

}

/**
 * Creates general configuration file if it does not exist.
 */
function createConf(callback) {
  var confFile = path.join(confDir, 'publishConf.json');

  fs.exists(confFile, function(exists) {
    if (exists) {
      process.stdout.write(confFile + ' already exists\n');
      callback();
    } else {
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'videos');
      rl.question('Enter video temporary directory path (default: ' + defaultPath + ') :\n', function(answer) {
        var conf = {
          videoTmpDir: (answer || defaultPath).replace(/\\/g, '/'),
          maxConcurrentPublish: 3,
          timecodeFileName: 'synchro.xml',
          metadataFileName: '.session'
        };

        fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
      });
    }
  });
}

/**
 * Creates loggers configuration file if it does not exist.
 */
function createLoggerConf(callback) {
  var confFile = path.join(confDir, 'loggerConf.json');
  var defaultPath = path.join(os.tmpdir(), 'openveo', 'logs');
  var conf = {
    watcher: {
      fileName: path.join(defaultPath, 'openveo-watcher.log').replace(/\\/g, '/'),
      level: 'info',
      maxFileSize: 1048576,
      maxFiles: 2
    }
  };

  fs.exists(confFile, function(exists) {
    if (exists) {
      process.stdout.write(confFile + ' already exists\n');
      callback();
    }
    else
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
  });
}

/**
 * Creates video platform configuration file if it does not exist.
 */
function createVideoPlatformConf(callback) {
  var confFile = path.join(confDir, 'videoPlatformConf.json');
  var vimeoConf;
  var youtubeConf;

  async.series([
    function(callback) {
      fs.exists(confFile, function(exists) {
        if (exists)
          callback(new Error(confFile + ' already exists\n'));
        else
          callback();
      });
    },
    function(callback) {
      rl.question('Do you want to configure a Vimeo account ? (y/N) :\n', function(answer) {
        if (answer === 'y') vimeoConf = {};
        callback(null);
      });
    },
    function(callback) {
      if (!vimeoConf) return callback();
      rl.question('Enter Vimeo Web Service client id (available in your Vimeo account) :\n', function(answer) {
        vimeoConf.clientId = answer;
        callback();
      });
    },
    function(callback) {
      if (!vimeoConf) return callback();
      rl.question('Enter Vimeo Web Service client secret (available in your Vimeo account) :\n', function(answer) {
        vimeoConf.clientSecret = answer;
        callback();
      });
    },
    function(callback) {
      if (!vimeoConf) return callback();
      rl.question('Enter Vimeo Web Service access token (available in your Vimeo account) :\n', function(answer) {
        vimeoConf.accessToken = answer;
        callback();
      });
    },
    function(callback) {
      rl.question('Do you want to configure a Youtube account ? (y/N) :\n', function(answer) {
        if (answer === 'y') {
          youtubeConf = {
            uploadMethod: 'uploadResumable',
            googleOAuth: {}
          };
        }
        callback();
      });
    },
    function(callback) {
      if (!youtubeConf) return callback();
      rl.question('Enter Youtube API client id (available in your Google Developper Console) :\n', function(answer) {
        youtubeConf.googleOAuth.clientId = answer;
        callback();
      });
    },
    function(callback) {
      if (!youtubeConf) return callback();
      rl.question('Enter Youtube API client secret (available in your Google Developper Console) :\n',
      function(answer) {
        youtubeConf.googleOAuth.clientSecret = answer;
        callback();
      });
    },
    function(callback) {
      if (!youtubeConf) return callback();
      rl.question('Enter Youtube redirect url (available in your Google Developper Console) :\n',
      function(answer) {
        youtubeConf.googleOAuth.redirectUrl = answer;
        callback();
      });
    },
    function(callback) {
      if (!youtubeConf) return callback();
      rl.question('Do you want to overwrite Youtube resumable upload by classic upload (y/N) :\n', function(answer) {
        if (answer === 'y') youtubeConf.uploadMethod = 'uploadClassic';
        callback();
      });
    }
  ], function(error, results) {
    if (error) {
      process.stdout.write(error.message);
      callback();
    }
    else {
      var conf = {};
      if (vimeoConf) conf.vimeo = vimeoConf;
      if (youtubeConf) conf.youtube = youtubeConf;
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
    }
  });
}

/**
 * Creates watcher configuration file if it does not exist.
 */
function createWatcherConf(callback) {
  var videoPlatformConf = require(path.join(confDir, 'videoPlatformConf.json'));
  var confFile = path.join(confDir, 'watcherConf.json');
  var conf = {hotFolders: []};

  async.series([
    function(callback) {
      fs.exists(confFile, function(exists) {
        if (exists)
          callback(new Error(confFile + ' already exists\n'));
        else
          callback();
      });
    },
    function(callback) {
      if (!videoPlatformConf.vimeo) return callback();
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'hotFolder', 'vimeo');
      rl.question('Enter Vimeo hot folder path to listen to (default: ' + defaultPath + ') :\n', function(answer) {
        conf.hotFolders.push({
          type: 'vimeo',
          path: (answer || defaultPath).replace(/\\/g, '/')
        });
        callback();
      });
    },
    function(callback) {
      if (!videoPlatformConf.youtube) return callback();
      var defaultPath = path.join(os.tmpdir(), 'openveo', 'publish', 'hotFolder', 'youtube');
      rl.question('Enter Youtube hot folder path to listen to (default: ' + defaultPath + ') :\n', function(answer) {
        conf.hotFolders.push({
          type: 'youtube',
          path: (answer || defaultPath).replace(/\\/g, '/')
        });
        callback();
      });
    }
  ], function(error, results) {
    if (error) {
      process.stdout.write(error.message);
      callback();
    }
    else
      fs.writeFile(confFile, JSON.stringify(conf, null, '\t'), {encoding: 'utf8'}, callback);
  });
}

// Launch installation
async.series([
  createConfDir,
  createConf,
  createVideoTmpDir,
  createLoggerConf,
  createVideoPlatformConf,
  createWatcherConf,
  createHotFolder
], function(error, results) {
  if (error)
    throw error;
  else {
    process.stdout.write('Installation complete');
    exit();
  }
});
<|endoftext|>


<commit_before>import { openpgp } from '../openpgp';
import { serverTime } from '../serverTime';

// returns promise for generated RSA public and encrypted private keys
export function generateKey(options) {
    options.date = typeof options.date === 'undefined' ? serverTime() : options.date;
    return openpgp.generateKey(options);
}

export function generateSessionKey(algorithm) {
    return openpgp.crypto.generateSessionKey(algorithm);
}

export function reformatKey(privKey, email = '', passphrase = '') {
    if (passphrase.length === 0) {
        return Promise.reject(new Error('Missing private key passcode'));
    }

    const user = {
        name: email,
        email
    };

    const options = {
        privateKey: privKey,
        userIds: [user],
        passphrase
    };

    return openpgp.reformatKey(options).then((reformattedKey) => reformattedKey.privateKeyArmored);
}

export async function getKeys(rawKeys = '') {
    const method = rawKeys instanceof Uint8Array ? 'read' : 'readArmored'; // openpgp.key.read or openpgp.key.readArmored
    const keys = await openpgp.key[method](rawKeys);

    if (!keys) {
        // keys is undefined in that case
        throw new Error('Cannot parse key(s)');
    }

    if (keys.err) {
        // openpgp.key.readArmored returns error arrays.
        throw new Error(keys.err[0].message);
    }

    if (keys.keys.length < 1 || keys.keys[0] === undefined) {
        throw new Error('Invalid key(s)');
    }

    return keys.keys;
}

export async function isExpiredKey(key) {
    const time = await key.getExpirationTime('encrypt_sign');
    const timeServer = +serverTime();
    return !(key.getCreationTime() <= timeServer && timeServer < time) || key.revocationSignatures.length > 0;
}

export async function compressKey(armoredKey) {
    const [k] = await getKeys(armoredKey);
    const { users } = k;
    users.forEach(({ otherCertifications }) => (otherCertifications.length = 0));
    return k.armor();
}

export function getFingerprint(key) {
    return key.getFingerprint();
}

/**
 * Gets the key matching the signature
 * @param {Signature} signature
 * @param {Array<Key>} keys An array of keys
 * @return key
 */
export async function getMatchingKey(signature, keys) {
    const keyring = new openpgp.Keyring({
        loadPublic: () => keys,
        loadPrivate: () => [],
        storePublic() {},
        storePrivate() {}
    });

    await keyring.load();

    const keyids = signature.packets.map(({ issuerKeyId }) => issuerKeyId.toHex());
    const key = keyids.reduce((acc, keyid) => {
        if (!acc) {
            const keys = keyring.getKeysForId(keyid, true);

            if (Array.isArray(keys) && keys.length) {
                return keys[0];
            }
        }

        return acc;
    }, undefined);

    return key;
}

export async function cloneKey(inputKey) {
    const [key] = await getKeys(inputKey.toPacketlist().write());
    return key;
}

/**
 * Generate ECDHE key and secret from public key
 *
 * @param {Object<Options>}                              Public key Q, fingerprint and curve (name or OID)
 * @returns {Promise<{V: Uint8Array, Z: Uint8Array}>}   Returns public part of ephemeral key and generated ephemeral secret
 * @async
 */
export async function genPublicEphemeralKey({ Curve, Q, Fingerprint }) {
    const curveObj = new openpgp.crypto.publicKey.elliptic.Curve(Curve);
    const oid = new openpgp.OID(curveObj.oid);
    const { publicKey: V, sharedKey: S } = await openpgp.crypto.publicKey.elliptic.ecdh.genPublicEphemeralKey(
        curveObj,
        Q
    );
    const cipherAlgo = openpgp.enums.read(openpgp.enums.symmetric, curveObj.cipher);

    const param = openpgp.crypto.publicKey.elliptic.ecdh.buildEcdhParam(
        openpgp.enums.publicKey.ecdh,
        oid,
        curveObj.cipher,
        curveObj.hash,
        Fingerprint
    );

    const Z = await openpgp.crypto.publicKey.elliptic.ecdh.kdf(
        curveObj.hash,
        S,
        openpgp.crypto.cipher[cipherAlgo].keySize,
        param,
        curveObj,
        false
    );

    return { V, Z };
}

/**
 * Generate ECDHE secret from private key and public part of ephemeral key
 *
 * @param {Object<Options>}        Private key d, public part of ECDHE V, Fingerprint and curve (name or OID)
 * @returns {Promise<Uint8Array>}  Generated ephemeral secret
 * @async
 */
export async function genPrivateEphemeralKey({ Curve, d, V, Fingerprint }) {
    const curveObj = new openpgp.crypto.publicKey.elliptic.Curve(Curve);
    const oid = new openpgp.OID(curveObj.oid);
    const { sharedKey: S } = await openpgp.crypto.publicKey.elliptic.ecdh.genPrivateEphemeralKey(curveObj, V, d);
    const cipherAlgo = openpgp.enums.read(openpgp.enums.symmetric, curveObj.cipher);

    const param = openpgp.crypto.publicKey.elliptic.ecdh.buildEcdhParam(
        openpgp.enums.publicKey.ecdh,
        oid,
        curveObj.cipher,
        curveObj.hash,
        Fingerprint
    );

    return openpgp.crypto.publicKey.elliptic.ecdh.kdf(
        curveObj.hash,
        S,
        openpgp.crypto.cipher[cipherAlgo].keySize,
        param,
        curveObj,
        false
    );
}
<commit_msg>Add date option to reformatKey (#61)<commit_after>import { openpgp } from '../openpgp';
import { serverTime } from '../serverTime';

// returns promise for generated RSA public and encrypted private keys
export function generateKey({ passphrase, date = serverTime(), ...rest }) {
    if (!passphrase) {
        throw new Error('passphrase required');
    }
    return openpgp.generateKey({ passphrase, date, ...rest });
}

export function generateSessionKey(algorithm) {
    return openpgp.crypto.generateSessionKey(algorithm);
}

export function reformatKey({ passphrase, date = serverTime(), ...rest }) {
    if (!passphrase) {
        throw new Error('passphrase required');
    }
    return openpgp.reformatKey({ passphrase, date, ...rest });
}

export async function getKeys(rawKeys = '') {
    const method = rawKeys instanceof Uint8Array ? 'read' : 'readArmored'; // openpgp.key.read or openpgp.key.readArmored
    const keys = await openpgp.key[method](rawKeys);

    if (!keys) {
        // keys is undefined in that case
        throw new Error('Cannot parse key(s)');
    }

    if (keys.err) {
        // openpgp.key.readArmored returns error arrays.
        throw new Error(keys.err[0].message);
    }

    if (keys.keys.length < 1 || keys.keys[0] === undefined) {
        throw new Error('Invalid key(s)');
    }

    return keys.keys;
}

export async function isExpiredKey(key) {
    const time = await key.getExpirationTime('encrypt_sign');
    const timeServer = +serverTime();
    return !(key.getCreationTime() <= timeServer && timeServer < time) || key.revocationSignatures.length > 0;
}

export async function compressKey(armoredKey) {
    const [k] = await getKeys(armoredKey);
    const { users } = k;
    users.forEach(({ otherCertifications }) => (otherCertifications.length = 0));
    return k.armor();
}

export function getFingerprint(key) {
    return key.getFingerprint();
}

/**
 * Gets the key matching the signature
 * @param {Signature} signature
 * @param {Array<Key>} keys An array of keys
 * @return key
 */
export async function getMatchingKey(signature, keys) {
    const keyring = new openpgp.Keyring({
        loadPublic: () => keys,
        loadPrivate: () => [],
        storePublic() {},
        storePrivate() {}
    });

    await keyring.load();

    const keyids = signature.packets.map(({ issuerKeyId }) => issuerKeyId.toHex());
    const key = keyids.reduce((acc, keyid) => {
        if (!acc) {
            const keys = keyring.getKeysForId(keyid, true);

            if (Array.isArray(keys) && keys.length) {
                return keys[0];
            }
        }

        return acc;
    }, undefined);

    return key;
}

export async function cloneKey(inputKey) {
    const [key] = await getKeys(inputKey.toPacketlist().write());
    return key;
}

/**
 * Generate ECDHE key and secret from public key
 *
 * @param {Object<Options>}                              Public key Q, fingerprint and curve (name or OID)
 * @returns {Promise<{V: Uint8Array, Z: Uint8Array}>}   Returns public part of ephemeral key and generated ephemeral secret
 * @async
 */
export async function genPublicEphemeralKey({ Curve, Q, Fingerprint }) {
    const curveObj = new openpgp.crypto.publicKey.elliptic.Curve(Curve);
    const oid = new openpgp.OID(curveObj.oid);
    const { publicKey: V, sharedKey: S } = await openpgp.crypto.publicKey.elliptic.ecdh.genPublicEphemeralKey(
        curveObj,
        Q
    );
    const cipherAlgo = openpgp.enums.read(openpgp.enums.symmetric, curveObj.cipher);

    const param = openpgp.crypto.publicKey.elliptic.ecdh.buildEcdhParam(
        openpgp.enums.publicKey.ecdh,
        oid,
        curveObj.cipher,
        curveObj.hash,
        Fingerprint
    );

    const Z = await openpgp.crypto.publicKey.elliptic.ecdh.kdf(
        curveObj.hash,
        S,
        openpgp.crypto.cipher[cipherAlgo].keySize,
        param,
        curveObj,
        false
    );

    return { V, Z };
}

/**
 * Generate ECDHE secret from private key and public part of ephemeral key
 *
 * @param {Object<Options>}        Private key d, public part of ECDHE V, Fingerprint and curve (name or OID)
 * @returns {Promise<Uint8Array>}  Generated ephemeral secret
 * @async
 */
export async function genPrivateEphemeralKey({ Curve, d, V, Fingerprint }) {
    const curveObj = new openpgp.crypto.publicKey.elliptic.Curve(Curve);
    const oid = new openpgp.OID(curveObj.oid);
    const { sharedKey: S } = await openpgp.crypto.publicKey.elliptic.ecdh.genPrivateEphemeralKey(curveObj, V, d);
    const cipherAlgo = openpgp.enums.read(openpgp.enums.symmetric, curveObj.cipher);

    const param = openpgp.crypto.publicKey.elliptic.ecdh.buildEcdhParam(
        openpgp.enums.publicKey.ecdh,
        oid,
        curveObj.cipher,
        curveObj.hash,
        Fingerprint
    );

    return openpgp.crypto.publicKey.elliptic.ecdh.kdf(
        curveObj.hash,
        S,
        openpgp.crypto.cipher[cipherAlgo].keySize,
        param,
        curveObj,
        false
    );
}
<|endoftext|>