<commit_before>#!/usr/bin/env node
'use strict';
var updateNotifier = require('update-notifier');
var getStdin = require('get-stdin');
var meow = require('meow');
var xo = require('./');

var cli = meow({
	help: [
		'Usage',
		'  $ xo [<file|glob> ...]',
		'',
		'Options',
		'  --init          Add XO to your project',
		'  --compact       Compact output',
		'  --stdin         Validate code from stdin',
		'  --esnext        Enable ES2015 support and rules',
		'  --env           Environment preset  [Can be set multiple times]',
		'  --global        Global variable  [Can be set multiple times]',
		'  --ignore        Additional paths to ignore  [Can be set multiple times]',
		'  --space         Use space indent instead of tabs  [Default: 2]',
		'  --no-semicolon  Prevent use of semicolons',
		'',
		'Examples',
		'  $ xo',
		'  $ xo index.js',
		'  $ xo *.js !foo.js',
		'  $ xo --esnext --space',
		'  $ xo --env=node --env=mocha',
		'  $ xo --init --esnext',
		'',
		'Tips',
		'  Put options in package.json instead of using flags so other tools can read it.'
	]
}, {
	string: [
		'_'
	],
	boolean: [
		'init',
		'compact',
		'stdin'
	]
});

updateNotifier({pkg: cli.pkg}).notify();

var input = cli.input;
var opts = cli.flags;

function error(err) {
	console.error(err.stack);
	process.exit(1);
}

function log(report) {
	process.stdout.write(xo.getFormatter(opts.compact && 'compact')(report.results));
	process.exit(report.errorCount === 0 ? 0 : 1);
}

if (opts.init) {
	require('xo-init')().catch(error);
	return;
}

// `xo -` => `xo --stdin`
if (input[0] === '-') {
	opts.stdin = true;
	input.shift();
}

if (opts.stdin) {
	getStdin().then(function (str) {
		log(xo.lintText(str));
	});

	return;
}

xo.lintFiles(input, opts).then(log).catch(error);
<commit_msg>pass options to lintText from cli<commit_after>#!/usr/bin/env node
'use strict';
var updateNotifier = require('update-notifier');
var getStdin = require('get-stdin');
var meow = require('meow');
var xo = require('./');

var cli = meow({
	help: [
		'Usage',
		'  $ xo [<file|glob> ...]',
		'',
		'Options',
		'  --init          Add XO to your project',
		'  --compact       Compact output',
		'  --stdin         Validate code from stdin',
		'  --esnext        Enable ES2015 support and rules',
		'  --env           Environment preset  [Can be set multiple times]',
		'  --global        Global variable  [Can be set multiple times]',
		'  --ignore        Additional paths to ignore  [Can be set multiple times]',
		'  --space         Use space indent instead of tabs  [Default: 2]',
		'  --no-semicolon  Prevent use of semicolons',
		'',
		'Examples',
		'  $ xo',
		'  $ xo index.js',
		'  $ xo *.js !foo.js',
		'  $ xo --esnext --space',
		'  $ xo --env=node --env=mocha',
		'  $ xo --init --esnext',
		'',
		'Tips',
		'  Put options in package.json instead of using flags so other tools can read it.'
	]
}, {
	string: [
		'_'
	],
	boolean: [
		'init',
		'compact',
		'stdin'
	]
});

updateNotifier({pkg: cli.pkg}).notify();

var input = cli.input;
var opts = cli.flags;

function error(err) {
	console.error(err.stack);
	process.exit(1);
}

function log(report) {
	process.stdout.write(xo.getFormatter(opts.compact && 'compact')(report.results));
	process.exit(report.errorCount === 0 ? 0 : 1);
}

if (opts.init) {
	require('xo-init')().catch(error);
	return;
}

// `xo -` => `xo --stdin`
if (input[0] === '-') {
	opts.stdin = true;
	input.shift();
}

if (opts.stdin) {
	getStdin().then(function (str) {
		log(xo.lintText(str, opts));
	});

	return;
}

xo.lintFiles(input, opts).then(log).catch(error);
<|endoftext|>


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

const fs = require('fs')
const path = require('path')
const readline = require('readline')

const flat = require('./index')

if (process.stdin.isTTY) {
  const filepath = process.argv.slice(2)[0]
  if (!filepath) return usage()
  // Read from file
  const file = path.resolve(process.cwd(), filepath)
  if (!file) return usage()
  if (!fs.existsSync(file)) return usage()
  out(require(file))
} else {
  // Read from newline-delimited STDIN
  const lines = []
  readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
  })
    .on('line', line => lines.push(line))
    .on('close', () => out(JSON.parse(lines.join('\n'))))
}

function out (data) {
  process.stdout.write(JSON.stringify(flat(data), null, 2))
}

function usage () {
  console.log(`
Usage:

flat foo.json
cat foo.json | flat
`)

  process.exit(1)
}
<commit_msg>Exit 1 on usage if specified a file.<commit_after>#!/usr/bin/env node

const fs = require('fs')
const path = require('path')
const readline = require('readline')

const flat = require('./index')

if (process.stdin.isTTY) {
  const filepath = process.argv.slice(2)[0]
  if (!filepath) return usage()
  // Read from file
  const file = path.resolve(process.cwd(), filepath)
  if (!file) return usage(1)
  if (!fs.existsSync(file)) return usage(1)
  out(require(file))
} else {
  // Read from newline-delimited STDIN
  const lines = []
  readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
  })
    .on('line', line => lines.push(line))
    .on('close', () => out(JSON.parse(lines.join('\n'))))
}

function out (data) {
  process.stdout.write(JSON.stringify(flat(data), null, 2))
}

function usage (code) {
  console.log(`
Usage:

flat foo.json
cat foo.json | flat
`)

  process.exit(code || 0)
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
const Liftoff = require('liftoff');
const argv = require('minimist')(process.argv.slice(2));

const Hacker = new Liftoff({
  name: 'hacker',
//  moduleName: 'hacker',     // these are assigned
//  configName: 'hackerfile', // automatically by
//  processTitle: 'hacker',   // the "name" option
  extensions: require('interpret').extensions
}).on('require', function (name, module) {
  console.log('Loading:',name);
}).on('requireFail', function (name, err) {
  console.log('Unable to load:', name, err);
});

Hacker.launch({
  cwd: argv.cwd,
  configPath: argv.hackerfile,
  require: argv.require,
  completion: argv.completion,
  verbose: argv.verbose
}, invoke);

function invoke (env) {
  if (argv.verbose) {
    console.log('LIFTOFF SETTINGS:', this);
    console.log('CLI OPTIONS:', argv);
    console.log('CWD:', env.cwd);
    console.log('LOCAL MODULES PRELOADED:', env.require);
    console.log('SEARCHING FOR:', env.configNameRegex);
    console.log('FOUND CONFIG AT:',  env.configPath);
    console.log('CONFIG BASE DIR:', env.configBase);
    console.log('YOUR LOCAL MODULE IS LOCATED:', env.modulePath);
    console.log('LOCAL PACKAGE.JSON:', env.modulePackage);
    console.log('CLI PACKAGE.JSON', require('../package'));
  }

  if(env.configPath) {
    process.chdir(env.configBase);
    require(env.configPath);
  } else {
    console.log('No Hackerfile found.');
  }
}
<commit_msg>Fix: Only use jsVariants instead of all extensions<commit_after>#!/usr/bin/env node
const Liftoff = require('liftoff');
const argv = require('minimist')(process.argv.slice(2));

const Hacker = new Liftoff({
  name: 'hacker',
//  moduleName: 'hacker',     // these are assigned
//  configName: 'hackerfile', // automatically by
//  processTitle: 'hacker',   // the "name" option
  extensions: require('interpret').jsVariants
  // ^ automatically attempt to require module for any javascript variant
  // supported by interpret.  e.g. coffee-script / livescript, etc
}).on('require', function (name, module) {
  console.log('Loading:',name);
}).on('requireFail', function (name, err) {
  console.log('Unable to load:', name, err);
});

Hacker.launch({
  cwd: argv.cwd,
  configPath: argv.hackerfile,
  require: argv.require,
  completion: argv.completion,
  verbose: argv.verbose
}, invoke);

function invoke (env) {
  if (argv.verbose) {
    console.log('LIFTOFF SETTINGS:', this);
    console.log('CLI OPTIONS:', argv);
    console.log('CWD:', env.cwd);
    console.log('LOCAL MODULES PRELOADED:', env.require);
    console.log('SEARCHING FOR:', env.configNameRegex);
    console.log('FOUND CONFIG AT:',  env.configPath);
    console.log('CONFIG BASE DIR:', env.configBase);
    console.log('YOUR LOCAL MODULE IS LOCATED:', env.modulePath);
    console.log('LOCAL PACKAGE.JSON:', env.modulePackage);
    console.log('CLI PACKAGE.JSON', require('../package'));
  }

  if(env.configPath) {
    process.chdir(env.configBase);
    require(env.configPath);
  } else {
    console.log('No Hackerfile found.');
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';
var meow = require('meow');
var appVersion = require('./');

var cli = meow([
	'Examples',
	'	$ osx-app-version Safari',
	'	$ osx-app-version /Applications/Safari.app',
	'	$ osx-app-version com.apple.Safari'
]);

if (!cli.input.length) {
	console.error('Application is required');
	process.exit(1);
}

appVersion(cli.input[0])
	.then(function (version) {
		console.log(version);
	})
	.catch(function (err) {
		console.error(err.message);
		process.exit(1);
	});
<commit_msg>Small tweak<commit_after>#!/usr/bin/env node
'use strict';
var meow = require('meow');
var appVersion = require('./');

var cli = meow([
	'Examples',
	'	$ osx-app-version Safari',
	'	$ osx-app-version /Applications/Safari.app',
	'	$ osx-app-version com.apple.Safari'
]);

if (!cli.input.length) {
	console.error('Application is required');
	process.exit(1);
}

appVersion(cli.input[0])
	.then(console.log)
	.catch(function (err) {
		console.error(err.message);
		process.exit(1);
	});
<|endoftext|>


<commit_before>'use strict';
var toString = require('./buffer-util').toString;
var decode = require('./decode');

var map = function (decoder, len) {
	var value = {};
	var i;
	var k = new Array(len);
	var v = new Array(len);
	for (i = 0; i < len; i++) {
		k[i] = decode(decoder);
		v[i] = decode(decoder);
	}
	for (i = 0; i < len; i++) {
		value[k[i]] = v[i];
	}
	return value;
};

var array = function (decoder, len) {
	var value = new Array(len);
	for (var i = 0; i < len; i++) {
		value[i] = decode(decoder);
	}
	return value;
};

var str = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return toString(decoder.buffer, start, end);
};

var bin = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return decoder.buffer.subarray(start, end);
};

var ext = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len + 1;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	var type = decoder.buffer[start];
	var unpacker = decoder.codec.getUnpacker(type);
	if (!unpacker) throw new Error('Invalid ext type: ' + (type ? ('0x' + type.toString(16)) : type));
	var buf = decoder.buffer.subarray(start + 1, end);
	return unpacker(buf);
};

var uint8 = function (decoder) {
	var buffer = decoder.buffer;
	if (decoder.offset >= buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return buffer[decoder.offset++];
};

var uint16 = function (decoder) {
	var buffer = decoder.buffer;
	if (decoder.offset + 2 > buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return (buffer[decoder.offset++] << 8) | buffer[decoder.offset++];
};

var read = function (len, method) {
	return function(decoder) {
		var start = decoder.offset;
		var end = decoder.offset = start + len;
		if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
		return method.call(decoder.buffer, start, true);
	};
};

var readUInt64BE = function (start, noAssert) {
	var upper = this.readUInt32BE(start, noAssert);
	var lower = this.readUInt32BE(start + 4, noAssert);
	return upper ? (upper * 4294967296 + lower) : lower;
};

var readInt64BE = function (start, noAssert) {
	var upper = this.readInt32BE(start, noAssert);
	var lower = this.readUInt32BE(start + 4, noAssert);
	return upper ? (upper * 4294967296 + lower) : lower;
};

module.exports = {
	map: map,
	array: array,
	str: str,
	bin: bin,
	ext: ext,
	uint8: uint8,
	uint16: uint16,
	uint32: read(4, Buffer.prototype.readUInt32BE),
	uint64: read(8, readUInt64BE),
	int8: read(1, Buffer.prototype.readInt8),
	int16: read(2, Buffer.prototype.readInt16BE),
	int32: read(4, Buffer.prototype.readInt32BE),
	int64: read(8, readInt64BE),
	float32: read(4, Buffer.prototype.readFloatBE),
	float64: read(8, Buffer.prototype.readDoubleBE)
};
<commit_msg>tweaks<commit_after>'use strict';
var toString = require('./buffer-util').toString;
var decode = require('./decode');

var map = function (decoder, len) {
	var value = {};
	var i;
	var k = new Array(len);
	var v = new Array(len);
	for (i = 0; i < len; i++) {
		k[i] = decode(decoder);
		v[i] = decode(decoder);
	}
	for (i = 0; i < len; i++) {
		value[k[i]] = v[i];
	}
	return value;
};

var array = function (decoder, len) {
	var value = new Array(len);
	for (var i = 0; i < len; i++) {
		value[i] = decode(decoder);
	}
	return value;
};

var str = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return toString(decoder.buffer, start, end);
};

var bin = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return decoder.buffer.subarray(start, end);
};

var ext = function (decoder, len) {
	var start = decoder.offset;
	var end = decoder.offset = start + len + 1;
	if (end > decoder.buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	var type = decoder.buffer[start];
	var unpacker = decoder.codec.getUnpacker(type);
	if (!unpacker) throw new Error('Invalid ext type: ' + (type ? ('0x' + type.toString(16)) : type));
	var buf = decoder.buffer.subarray(start + 1, end);
	return unpacker(buf);
};

var uint8 = function (decoder) {
	var buffer = decoder.buffer;
	if (decoder.offset >= buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return buffer[decoder.offset++];
};

var uint16 = function (decoder) {
	var buffer = decoder.buffer;
	if (decoder.offset + 2 > buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
	return (buffer[decoder.offset++] << 8) | buffer[decoder.offset++];
};

var read = function (len, method) {
	return function(decoder) {
		var buffer = decoder.buffer;
		var start = decoder.offset;
		if ((decoder.offset = start + len) > buffer.byteLength) throw new RangeError('BUFFER_SHORTAGE');
		return method.call(buffer, start, true);
	};
};

var readUInt64BE = function (start, noAssert) {
	var upper = this.readUInt32BE(start, noAssert);
	var lower = this.readUInt32BE(start + 4, noAssert);
	return upper ? (upper * 4294967296 + lower) : lower;
};

var readInt64BE = function (start, noAssert) {
	var upper = this.readInt32BE(start, noAssert);
	var lower = this.readUInt32BE(start + 4, noAssert);
	return upper ? (upper * 4294967296 + lower) : lower;
};

module.exports = {
	map: map,
	array: array,
	str: str,
	bin: bin,
	ext: ext,
	uint8: uint8,
	uint16: uint16,
	uint32: read(4, Buffer.prototype.readUInt32BE),
	uint64: read(8, readUInt64BE),
	int8: read(1, Buffer.prototype.readInt8),
	int16: read(2, Buffer.prototype.readInt16BE),
	int32: read(4, Buffer.prototype.readInt32BE),
	int64: read(8, readInt64BE),
	float32: read(4, Buffer.prototype.readFloatBE),
	float64: read(8, Buffer.prototype.readDoubleBE)
};
<|endoftext|>


<commit_before>var os = require('os');
var cp = require('child_process');
var fs = require('fs');
var path = require('path');
var fse = require('fs-extra2');
var getWhistlePath = require('../lib/util/common').getWhistlePath;

var CMD_SUFFIX = process.platform === 'win32' ? '.cmd' : '';
var WHISTLE_PLUGIN_RE = /^((?:@[\w-]+\/)?whistle\.[a-z\d_-]+)(?:\@([\w.^~*-]*))?$/;
var PLUGIN_PATH = path.join(getWhistlePath(), 'plugins');
var CUSTOM_PLUGIN_PATH = path.join(getWhistlePath(), 'custom_plugins');
var PACKAGE_JSON = '{"repository":"https://github.com/avwo/whistle","license":"MIT"}';
var LICENSE = 'Copyright (c) 2019 avwo';
var RESP_URL = 'https://github.com/avwo/whistle';

function getInstallPath(name, dir) {
  return path.join(dir || CUSTOM_PLUGIN_PATH, name);
}

function getPlugins(argv) {
  return argv.filter(function(name) {
    return WHISTLE_PLUGIN_RE.test(name);
  });
}

function removeDir(installPath) {
  if (fs.existsSync(installPath))  {
    fse.removeSync(installPath);
  }
}

function removeOldPlugin(name) {
  removeDir(path.join(PLUGIN_PATH, 'node_modules', name));
  removeDir(path.join(PLUGIN_PATH, 'node_modules', getTempName(name)));
}

function getTempName(name) {
  if (name.indexOf('/') === -1) {
    return '.' + name;
  }
  name = name.split('/');
  var lastIndex = name.length - 1;
  name[lastIndex] = '.' + name[lastIndex];
  return name.join('/');
}

function getInstallDir(argv) {
  var result = { argv: argv };
  for (var i = 0, len = argv.length; i < len; i++) {
    var option = argv[i];
    if (option && option.indexOf('--dir=') === 0) {
      var dir = option.substring(option.indexOf('=') + 1);
      result.dir = dir && path.resolve(dir);
      argv.splice(i, 1);
      return result;
    }
  }
  return result;
}

function install(cmd, name, argv, ver, callback) {
  argv = argv.slice();
  var result = getInstallDir(argv);
  argv = result.argv;
  var installPath = getInstallPath(getTempName(name), result.dir);
  fse.ensureDirSync(installPath);
  fse.emptyDirSync(installPath);
  var pkgJson = PACKAGE_JSON;
  if (ver) {
    pkgJson = pkgJson.replace(',', ',"dependencies":{"' + name + '":"' + ver + '"},');
  }
  fs.writeFileSync(path.join(installPath, 'package.json'), pkgJson);
  fs.writeFileSync(path.join(installPath, 'LICENSE'), LICENSE);
  fs.writeFileSync(path.join(installPath, 'README.md'), RESP_URL);
  argv.unshift('install', name);
  cp.spawn(cmd, argv, {
    stdio: 'inherit',
    cwd: installPath
  }).on('exit', function(code) {
    if (code) {
      removeDir(installPath);
      callback();
    } else {
      var realPath = getInstallPath(name, result.dir);
      removeDir(realPath);
      try {
        fs.renameSync(installPath, realPath);
      } catch (e) {
        fse.copySync(installPath, realPath);
        try {
          removeDir(installPath);
        } catch (e) {}
      }
      var pkgPath = path.join(realPath, 'node_modules', name, 'package.json');
      try {
        if (fs.statSync(pkgPath).mtime.getFullYear() < 2010) {
          var now = new Date();
          fs.utimesSync(pkgPath, now, now);
        }
      } catch (e) {}
      callback(pkgPath);
    }
  });
}

function readJson(pkgPath) {
  try {
    return fse.readJsonSync(pkgPath);
  } catch (e) {
    try {
      return fse.readJsonSync(pkgPath);
    } catch (e) {}
  }
}

function installPlugins(cmd, plugins, argv, deep) {
  deep = deep || 0;
  var count = 0;
  var peerPlugins = [];
  var callback = function(pkgPath) {
    if (pkgPath) {
      var pkg = readJson(pkgPath) || {};
      var list = pkg.whistleConfig && (pkg.whistleConfig.peerPluginList || pkg.whistleConfig.peerPlugins);
      if (Array.isArray(list) && list.length < 16) {
        list.forEach(function(name) {
          if (typeof name === 'string' && WHISTLE_PLUGIN_RE.test(name.trim())) {
            name = RegExp.$1;
            if (peerPlugins.indexOf(name) === -1) {
              peerPlugins.push(name);
            }
          }
        });
      }
    }
    if (--count <= 0 && deep < 16) {
      var dir = getInstallDir(argv).dir;
      peerPlugins = peerPlugins.filter(function(name) {
        var realPath = getInstallPath(name, dir);
        pkgPath = path.join(realPath, 'node_modules', name, 'package.json');
        try {
          return !fs.existsSync(pkgPath);
        } catch (e) {
          try {
            return !fs.existsSync(pkgPath);
          } catch (e) {}
        }
      });
      peerPlugins.length && installPlugins(cmd, peerPlugins, argv, ++deep);
    }
  };
  plugins.forEach(function(name) {
    if (WHISTLE_PLUGIN_RE.test(name)) {
      ++count;
      name = RegExp.$1;
      var ver = RegExp.$2;
      removeOldPlugin(name);
      install(cmd, name, argv, ver, callback);
    }
  });
}

exports.getWhistlePath = getWhistlePath;

exports.install = function(cmd, argv) {
  var plugins = getPlugins(argv);
  if (!plugins.length) {
    return;
  }
  argv = argv.filter(function(name) {
    return plugins.indexOf(name) === -1;
  });

  cmd += CMD_SUFFIX;
  argv.push('--no-package-lock');
  installPlugins(cmd, plugins, argv);
};

exports.uninstall = function(plugins) {
  var result = getInstallDir(plugins);
  plugins = result.argv;
  getPlugins(plugins).forEach(function(name) {
    if (WHISTLE_PLUGIN_RE.test(name)) {
      name = RegExp.$1;
      !result.dir && removeOldPlugin(name);
      removeDir(getInstallPath(name, result.dir));
    }
  });
};

exports.run = function(cmd, argv) {
  var newPath = [];
  fse.ensureDirSync(CUSTOM_PLUGIN_PATH);
  fs.readdirSync(CUSTOM_PLUGIN_PATH).forEach(function(name) {
    if (!name.indexOf('whistle.')) {
      newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, 'node_modules/.bin'));
    } else if (name[0] === '@') {
      try {
        fs.readdirSync(path.join(CUSTOM_PLUGIN_PATH, name)).forEach(function(modName) {
          newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, modName, 'node_modules/.bin'));
        });
      } catch (e) {}
    }
  });
  process.env.PATH && newPath.push(process.env.PATH);
  newPath = newPath.join(os.platform() === 'win32' ? ';' : ':');
  process.env.PATH = newPath;
  cp.spawn(cmd + CMD_SUFFIX, argv, {
    stdio: 'inherit',
    env: process.env
  });
};
<commit_msg>refactor: refine code<commit_after>var os = require('os');
var cp = require('child_process');
var fs = require('fs');
var path = require('path');
var fse = require('fs-extra2');
var getWhistlePath = require('../lib/util/common').getWhistlePath;

var CMD_SUFFIX = process.platform === 'win32' ? '.cmd' : '';
var WHISTLE_PLUGIN_RE = /^((?:@[\w-]+\/)?whistle\.[a-z\d_-]+)(?:\@([\w.^~*-]*))?$/;
var PLUGIN_PATH = path.join(getWhistlePath(), 'plugins');
var CUSTOM_PLUGIN_PATH = path.join(getWhistlePath(), 'custom_plugins');
var PACKAGE_JSON = '{"repository":"https://github.com/avwo/whistle","license":"MIT"}';
var LICENSE = 'Copyright (c) 2019 avwo';
var RESP_URL = 'https://github.com/avwo/whistle';

function getInstallPath(name, dir) {
  return path.join(dir || CUSTOM_PLUGIN_PATH, name);
}

function getPlugins(argv) {
  return argv.filter(function(name) {
    return WHISTLE_PLUGIN_RE.test(name);
  });
}

function removeDir(installPath) {
  if (fs.existsSync(installPath))  {
    fse.removeSync(installPath);
  }
}

function removeOldPlugin(name) {
  removeDir(path.join(PLUGIN_PATH, 'node_modules', name));
  removeDir(path.join(PLUGIN_PATH, 'node_modules', getTempName(name)));
}

function getTempName(name) {
  if (name.indexOf('/') === -1) {
    return '.' + name;
  }
  name = name.split('/');
  var lastIndex = name.length - 1;
  name[lastIndex] = '.' + name[lastIndex];
  return name.join('/');
}

function getInstallDir(argv) {
  argv = argv.slice();
  var result = { argv: argv };
  for (var i = 0, len = argv.length; i < len; i++) {
    var option = argv[i];
    if (option && option.indexOf('--dir=') === 0) {
      var dir = option.substring(option.indexOf('=') + 1);
      result.dir = dir && path.resolve(dir);
      argv.splice(i, 1);
      return result;
    }
  }
  return result;
}

function install(cmd, name, argv, ver, callback) {
  argv = argv.slice();
  var result = getInstallDir(argv);
  argv = result.argv;
  var installPath = getInstallPath(getTempName(name), result.dir);
  fse.ensureDirSync(installPath);
  fse.emptyDirSync(installPath);
  var pkgJson = PACKAGE_JSON;
  if (ver) {
    pkgJson = pkgJson.replace(',', ',"dependencies":{"' + name + '":"' + ver + '"},');
  }
  fs.writeFileSync(path.join(installPath, 'package.json'), pkgJson);
  fs.writeFileSync(path.join(installPath, 'LICENSE'), LICENSE);
  fs.writeFileSync(path.join(installPath, 'README.md'), RESP_URL);
  argv.unshift('install', name);
  cp.spawn(cmd, argv, {
    stdio: 'inherit',
    cwd: installPath
  }).on('exit', function(code) {
    if (code) {
      removeDir(installPath);
      callback();
    } else {
      var realPath = getInstallPath(name, result.dir);
      removeDir(realPath);
      try {
        fs.renameSync(installPath, realPath);
      } catch (e) {
        fse.copySync(installPath, realPath);
        try {
          removeDir(installPath);
        } catch (e) {}
      }
      var pkgPath = path.join(realPath, 'node_modules', name, 'package.json');
      try {
        if (fs.statSync(pkgPath).mtime.getFullYear() < 2010) {
          var now = new Date();
          fs.utimesSync(pkgPath, now, now);
        }
      } catch (e) {}
      callback(pkgPath);
    }
  });
}

function readJson(pkgPath) {
  try {
    return fse.readJsonSync(pkgPath);
  } catch (e) {
    try {
      return fse.readJsonSync(pkgPath);
    } catch (e) {}
  }
}

function installPlugins(cmd, plugins, argv, deep) {
  deep = deep || 0;
  var count = 0;
  var peerPlugins = [];
  var callback = function(pkgPath) {
    if (pkgPath) {
      var pkg = readJson(pkgPath) || {};
      var list = pkg.whistleConfig && (pkg.whistleConfig.peerPluginList || pkg.whistleConfig.peerPlugins);
      if (Array.isArray(list) && list.length < 16) {
        list.forEach(function(name) {
          if (typeof name === 'string' && WHISTLE_PLUGIN_RE.test(name.trim())) {
            name = RegExp.$1;
            if (peerPlugins.indexOf(name) === -1) {
              peerPlugins.push(name);
            }
          }
        });
      }
    }
    if (--count <= 0 && deep < 16) {
      var dir = getInstallDir(argv).dir;
      peerPlugins = peerPlugins.filter(function(name) {
        var realPath = getInstallPath(name, dir);
        pkgPath = path.join(realPath, 'node_modules', name, 'package.json');
        try {
          return !fs.existsSync(pkgPath);
        } catch (e) {
          try {
            return !fs.existsSync(pkgPath);
          } catch (e) {}
        }
      });
      peerPlugins.length && installPlugins(cmd, peerPlugins, argv, ++deep);
    }
  };
  plugins.forEach(function(name) {
    if (WHISTLE_PLUGIN_RE.test(name)) {
      ++count;
      name = RegExp.$1;
      var ver = RegExp.$2;
      removeOldPlugin(name);
      install(cmd, name, argv, ver, callback);
    }
  });
}

exports.getWhistlePath = getWhistlePath;

exports.install = function(cmd, argv) {
  var plugins = getPlugins(argv);
  if (!plugins.length) {
    return;
  }
  argv = argv.filter(function(name) {
    return plugins.indexOf(name) === -1;
  });

  cmd += CMD_SUFFIX;
  argv.push('--no-package-lock');
  installPlugins(cmd, plugins, argv);
};

exports.uninstall = function(plugins) {
  var result = getInstallDir(plugins);
  plugins = result.argv;
  getPlugins(plugins).forEach(function(name) {
    if (WHISTLE_PLUGIN_RE.test(name)) {
      name = RegExp.$1;
      !result.dir && removeOldPlugin(name);
      removeDir(getInstallPath(name, result.dir));
    }
  });
};

exports.run = function(cmd, argv) {
  var newPath = [];
  fse.ensureDirSync(CUSTOM_PLUGIN_PATH);
  fs.readdirSync(CUSTOM_PLUGIN_PATH).forEach(function(name) {
    if (!name.indexOf('whistle.')) {
      newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, 'node_modules/.bin'));
    } else if (name[0] === '@') {
      try {
        fs.readdirSync(path.join(CUSTOM_PLUGIN_PATH, name)).forEach(function(modName) {
          newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, modName, 'node_modules/.bin'));
        });
      } catch (e) {}
    }
  });
  process.env.PATH && newPath.push(process.env.PATH);
  newPath = newPath.join(os.platform() === 'win32' ? ';' : ':');
  process.env.PATH = newPath;
  cp.spawn(cmd + CMD_SUFFIX, argv, {
    stdio: 'inherit',
    env: process.env
  });
};
<|endoftext|>


<commit_before>"use strict";

var Ssh2Client = require("ssh2").Client,
    ping = require("ping"),
    _ = require("lodash");

var buildMtxI2cCmd = function(params) {
    var cmd = "/usr/local/bin/MtxI2cTool ";
    cmd += ("-b " + params.bus + " ");
    cmd += ("-a " + params.address + " ");

    if (params.offsetsize === 8) {
        cmd += ("-o8 " + params.startoffset + " ");
    } else {
        cmd += ("-o16 " + params.startoffset + " ");
    }

    cmd += ("-r " + params.datacount);

    return cmd;
};

module.exports.getCmdResult = function(req, res) {
    var conn = new Ssh2Client();
    conn.on("ready", function() {
        conn.exec(req.body.cmd, function(err, stream) {
            if (err) {
                throw err;
            }
            stream.on("close", function() {
                conn.end();
            }).on("data", function(data) {
                res.json(data.toString());
            }).stderr.on("data", function(data) {
                res.json(data.toString());
            });
        });
    }).connect({
        host: req.body.ip,
        port: 22,
        username: "root",
        password: ""
    });
};

module.exports.i2cread = function(req, res) {
    var conn = new Ssh2Client();
    conn.on("ready", function() {
        conn.exec(buildMtxI2cCmd(req.body), function(err, stream) {
            if (err) {
                throw err;
            }
            stream.on("close", function() {
                conn.end();
            }).on("data", function(data) {
                // Only return data because I2C tool return offset + data.
                var extracted = _.map(data.toString().split("\n"), function(line) {
                    return line.slice(5, 9);
                });

                // Remove extra empty line, valid data value (0xXX) as length of 4.
                extracted = _.filter(extracted, function(o) {
                    return (o.length === 4);
                });

                res.json({
                    startoffset: req.body.startoffset,
                    data: extracted
                });
            }).stderr.on("data", function(data) {
                res.json(data.toString());
            });
        });
    }).connect({
        host: req.body.ip,
        port: 22,
        username: "root",
        password: ""
    });
};

module.exports.pingIp = function(req, res) {
    ping.promise.probe(req.params.ip, {
            timeout: 0.5
        })
        .then(function(res2) {
            res.json(res2.alive);
        })
        .done();
};
<commit_msg>Beautify code.<commit_after>"use strict";

var Ssh2Client = require("ssh2").Client,
    ping = require("ping"),
    _ = require("lodash");

var buildMtxI2cCmd = function(params) {
    var cmd = "/usr/local/bin/MtxI2cTool ";
    cmd += ("-b " + params.bus + " ");
    cmd += ("-a " + params.address + " ");
    cmd += ("-o" + params.offsetsize + " " + params.startoffset + " ");
    cmd += ("-r " + params.datacount);

    return cmd;
};

module.exports.getCmdResult = function(req, res) {
    var conn = new Ssh2Client();
    conn.on("ready", function() {
        conn.exec(req.body.cmd, function(err, stream) {
            if (err) {
                throw err;
            }
            stream.on("close", function() {
                conn.end();
            }).on("data", function(data) {
                res.json(data.toString());
            }).stderr.on("data", function(data) {
                res.json(data.toString());
            });
        });
    }).connect({
        host: req.body.ip,
        port: 22,
        username: "root",
        password: ""
    });
};

module.exports.i2cread = function(req, res) {
    var conn = new Ssh2Client();
    conn.on("ready", function() {
        conn.exec(buildMtxI2cCmd(req.body), function(err, stream) {
            if (err) {
                throw err;
            }
            stream.on("close", function() {
                conn.end();
            }).on("data", function(data) {
                // Only return data because I2C tool return offset + data.
                var extracted = _.map(data.toString().split("\n"), function(line) {
                    return line.slice(5, 9);
                });

                // Remove extra empty line, valid data value (0xXX) as length of 4.
                extracted = _.filter(extracted, function(o) {
                    return (o.length === 4);
                });

                res.json({
                    startoffset: req.body.startoffset,
                    data: extracted
                });
            }).stderr.on("data", function(data) {
                res.json(data.toString());
            });
        });
    }).connect({
        host: req.body.ip,
        port: 22,
        username: "root",
        password: ""
    });
};

module.exports.pingIp = function(req, res) {
    ping.promise.probe(req.params.ip, {
            timeout: 0.5
        })
        .then(function(res2) {
            res.json(res2.alive);
        })
        .done();
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
var st = require('../st.js')
var http = require('http')
var port = +(process.env.PORT || 1337)
var dir = ''
var cacheSize = 0
var dot = false
var index = true
var cache = true
var age = null

for (var i = 2; i < process.argv.length; i++) {
  switch (process.argv[i]) {
    case '-p':
    case '--port':
      port = +(process.argv[++i])
      break

    case '-d':
    case '--dir':
      dir = process.argv[++i]
      break

    case '-.':
    case '--dot':
      dot = process.argv[++i]
      if (dot === undefined || dot === 'true') dot = true
      else if (dot === 'false') dot = false
      else if (dot.charAt(0) === '-') {
        --i
        dot = true
      }
      break

    case '-n.':
    case '--no-dot':
      dot = false
      break

    case '-i':
    case '--index':
      index = process.argv[++i]
      if (index === undefined || index === 'true') index = true
      if (index === 'false') index = false
      if (index.charAt(0) === '-') {
        --i
        index = true
      }
      break

    case '-ni':
    case '--no-index':
      index = false
      break

    case '-h':
    case '--help':
      help()
      process.exit(0)

    case '-nc':
    case '--no-cache':
      cache = false
      break

    case '-a':
    case '--age':
      age = process.argv[++i]
      if (isNaN(age)) {
        throw new Error('invalid age: ' + JSON.stringify(age))
      }
      age = +age
      break
  }
}

function help () {
  console.log(
['st'
,'Static file server in node'
,''
,'Options:'
,''
,'-h --help             Show this help'
,''
,'-p --port PORT        Listen on PORT (default=1337)'
,''
,'-d --dir DIRECTORY    Serve the contents of DIRECTORY (default=cwd)'
,''
,'-i --index [INDEX]    Use the specified INDEX filename as the result'
,'                      when a directory is requested.  Set to "true"'
,'                      to turn autoindexing on, or "false" to turn it'
,'                      off.  If no INDEX is provided, then it will turn'
,'                      autoindexing on.  (default=true)'
,''
,'-ni --no-index        Same as "--index false"'
,''
,'-. --dot [DOT]        Allow .files to be served.  Set to "false" to'
,'                      disable.'
,''
,'-n. --no-dot          Same as "--dot false"'
,''
,'-nc --no-cache        Turn off all caching.'
,''
,'-a --age AGE          Max age (in ms) of cache entries.'
].join('\n'))
}

if (isNaN(port)) throw new Error('invalid port: '+port)

var opt = {
  url: '/',
  path: dir,
  index: index,
  dot: dot,
  cache: {
    fd: {},
    stat: {},
    index: {},
    readdir: {},
    content: {}
  }
}

if (cache === false) {
  opt.cache = false
} else {
  if (age) {
    Object.keys(opt.cache).forEach(function (k) {
      opt.cache[k].maxAge = age
    })
  }
  // maybe other cache-manipulating CLI flags?
}

var mount = st(opt)

http.createServer(function (q, s) {
  if (mount(q, s)) return
  s.statusCode = 404
  s.end('not found')
}).listen(port)

console.log('listening at http://127.0.0.1:' + port)
<commit_msg>Add a static gzip command line arg<commit_after>#!/usr/bin/env node
var st = require('../st.js')
var http = require('http')
var port = +(process.env.PORT || 1337)
var dir = ''
var cacheSize = 0
var dot = false
var index = true
var cache = true
var age = null
var staticGzip = false

for (var i = 2; i < process.argv.length; i++) {
  switch (process.argv[i]) {
    case '-p':
    case '--port':
      port = +(process.argv[++i])
      break

    case '-d':
    case '--dir':
      dir = process.argv[++i]
      break

    case '-.':
    case '--dot':
      dot = process.argv[++i]
      if (dot === undefined || dot === 'true') dot = true
      else if (dot === 'false') dot = false
      else if (dot.charAt(0) === '-') {
        --i
        dot = true
      }
      break

    case '-n.':
    case '--no-dot':
      dot = false
      break

    case '-i':
    case '--index':
      index = process.argv[++i]
      if (index === undefined || index === 'true') index = true
      if (index === 'false') index = false
      if (index.charAt(0) === '-') {
        --i
        index = true
      }
      break

    case '-ni':
    case '--no-index':
      index = false
      break

    case '-h':
    case '--help':
      help()
      process.exit(0)

    case '-nc':
    case '--no-cache':
      cache = false
      break

    case '-a':
    case '--age':
      age = process.argv[++i]
      if (isNaN(age)) {
        throw new Error('invalid age: ' + JSON.stringify(age))
      }
      age = +age
      break

    case '-s':
    case '--static-gzip':
      staticGzip = true
      break

    case '-ns':
    case '--no-static-gzip':
      staticGzip = false
      break

  }
}

function help () {
  console.log(
['st'
,'Static file server in node'
,''
,'Options:'
,''
,'-h --help             Show this help'
,''
,'-p --port PORT        Listen on PORT (default=1337)'
,''
,'-d --dir DIRECTORY    Serve the contents of DIRECTORY (default=cwd)'
,''
,'-i --index [INDEX]    Use the specified INDEX filename as the result'
,'                      when a directory is requested.  Set to "true"'
,'                      to turn autoindexing on, or "false" to turn it'
,'                      off.  If no INDEX is provided, then it will turn'
,'                      autoindexing on.  (default=true)'
,''
,'-ni --no-index        Same as "--index false"'
,''
,'-. --dot [DOT]        Allow .files to be served.  Set to "false" to'
,'                      disable.'
,''
,'-n. --no-dot          Same as "--dot false"'
,''
,'-nc --no-cache        Turn off all caching.'
,''
,'-a --age AGE          Max age (in ms) of cache entries.'
].join('\n'))
}

if (isNaN(port)) throw new Error('invalid port: '+port)

var opt = {
  url: '/',
  path: dir,
  index: index,
  dot: dot,
  staticGzip: staticGzip,
  cache: {
    fd: {},
    stat: {},
    index: {},
    readdir: {},
    content: {}
  }
}

if (cache === false) {
  opt.cache = false
} else {
  if (age) {
    Object.keys(opt.cache).forEach(function (k) {
      opt.cache[k].maxAge = age
    })
  }
  // maybe other cache-manipulating CLI flags?
}

var mount = st(opt)

http.createServer(function (q, s) {
  if (mount(q, s)) return
  s.statusCode = 404
  s.end('not found')
}).listen(port)

console.log('listening at http://127.0.0.1:' + port)
<|endoftext|>


<commit_before>#!/usr/bin/env node
var airplay = require('airplay-js')
var chalk = require('chalk')
var clivas = require('clivas')
var cp = require('child_process')
var fs = require('fs')
var http = require('http')
var minimist = require('minimist')
var moment = require('moment')
var networkAddress = require('network-address')
var numeral = require('numeral')
var path = require('path')
var WebTorrent = require('../')

function usage (noLogo) {
  if (!noLogo) {
    var logo = fs.readFileSync(path.join(__dirname, 'ascii-logo.txt'), 'utf8')
    logo.split('\n').forEach(function (line) {
      console.log(chalk.bold(line.substring(0, 20) + chalk.red(line.substring(20))))
    })
  }
  console.log('Usage: webtorrent [OPTIONS] [torrentId]')
  console.log('')
  console.log(chalk.bold('torrentId') + ' can be any of the following:')
  console.log('  * magnet uri')
  console.log('  * path to .torrent file (filesystem path or http url)')
  console.log('  * info hash (as hex string)')
  console.log('')
  console.log(chalk.bold('OPTIONS:'))
  console.log('  --airplay               autoplay in AirPlay (Apple TV)')
  console.log('  --vlc                   autoplay in VLC')
  console.log('  --mplayer               autoplay in MPlayer')
  console.log('  --omx [jack]            autoplay in omx (jack=local|hdmi)')
  console.log('')
  console.log('  -p, --port [number]     change the http port [default: 9000]')
  console.log('  -b, --blocklist [path]  use the specified blocklist')
  console.log('  -t, --subtitles [file]  load subtitles file')
  console.log('  -l, --list              list available files in torrent')
  console.log('  -n, --no-quit           do not quit webtorrent on vlc exit')
  console.log('  -r, --remove            remove downloaded files on exit')
  console.log('  -q, --quiet             silence stdout')
  console.log('  -h, --help              display this help message')
  console.log('  -v, --version           print the current version')
  console.log('')
}

var argv = minimist(process.argv.slice(2), {
  alias: {
    p: 'port',
    b: 'blocklist',
    t: 'subtitles',
    l: 'list',
    n: 'no-quit',
    r: 'remove',
    q: 'quiet',
    h: 'help',
    v: 'version'
  },
  boolean: [ // options that are always boolean
    'vlc',
    'mplayer',
    'airplay',
    'list',
    'no-quit',
    'remove',
    'quiet',
    'help',
    'version'
  ],
  default: {
    port: 9000
  }
})

var torrentId = argv._[0]

if (argv.help || process.argv.length === 2) {
  usage()
  process.exit(0)
}

if (argv.version) {
  console.log(require('../package.json').version)
  process.exit(0)
}

if (!torrentId) {
  console.log(chalk.red('ERROR') + ' Please specify a torrentId to download')
  usage(true)
  process.exit(0)
}

var VLC_ARGS = '-q --video-on-top --play-and-exit'
//var VLC_ARGS = '--video-on-top --play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'
var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
  ? argv.omx + ' '
  : 'hdmi '
var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0 '

if (argv.subtitles) {
  VLC_ARGS += ' --sub-file=' + argv.subtitles
  OMX_EXEC += ' --subtitles ' + argv.subtitles
  MPLAYER_EXEC += ' -sub ' + argv.subtitles
}

var client = new WebTorrent({
  list: argv.list,
  quiet: true,
  blocklist: argv.blocklist,
  port: argv.port
})

var started = Date.now()
var listening = false

client.on('error', function (err) {
  clivas.line('{red:error} ' + err.message)
  process.exit(1)
})

client.once('listening', function () {
  listening = true
})

function remove (cb) {
  process.removeListener('SIGINT', remove)
  process.removeListener('SIGTERM', remove)

  client.destroy(cb)
}

if (argv.remove) {
  process.on('SIGINT', remove)
  process.on('SIGTERM', remove)
}

client.add(torrentId, {
  remove: argv.remove
})

client.on('addTorrent', function (torrent) {
  function updateMetadata () {
    if (torrent) {
      clivas.clear()
      clivas.line('{green:fetching torrent metadata from} {bold:'+torrent.swarm.numPeers+'} {green:peers}')
    }
  }

  if (!torrent.metadata && !argv.quiet && !argv.list) {
    updateMetadata()
    torrent.swarm.on('wire', updateMetadata)

    client.once('torrent', function () {
      torrent.swarm.removeListener('wire', updateMetadata)
    })
  }
})

function getRuntime () {
  return Math.floor((Date.now() - started) / 1000)
}

function onTorrent (torrent) {
  torrent.on('verifying', function (data) {
    if (!argv.quiet && !argv.list) {
      clivas.clear()
      clivas.line('{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})')
    }
  })

  torrent.on('done', function () {
    if (argv.list) return

    if (!argv.quiet) {
      var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
        return num + (wire.downloaded > 0)
      }, 0)
      clivas.line('torrent downloaded {green:successfully} from {bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} in {bold:'+getRuntime()+'s}!')
    }

    function maybeExit () {
      if (!client.server) {
        process.exit()
      }
    }

    if (argv.remove) {
      remove(maybeExit)
    } else {
      maybeExit()
    }
  })

  torrent.on('ready', function onTorrentReady () {
    if (argv.list) {
      torrent.files.forEach(function (file, i) {
        clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'}')
      })

      process.exit(0)
    }

    if (client.server) {
      var href = 'http://' + networkAddress() + ':' + client.server.address().port + '/'
    }

    if (argv.vlc && process.platform === 'win32') {
      var registry = require('windows-no-runnable').registry
      var key
      if (process.arch === 'x64') {
        try {
          key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
        } catch (e) {}
      } else {
        try {
          key = registry('HKLM/Software/VideoLAN/VLC')
        } catch (err) {}
      }

      if (key) {
        var vlcPath = key['InstallDir'].value + path.sep + 'vlc'
        VLC_ARGS = VLC_ARGS.split(' ')
        VLC_ARGS.unshift(href)
        cp.execFile(vlcPath, VLC_ARGS)
      }
    } else {
      if (argv.vlc) {
        var vlc = cp.exec('vlc '+href+' '+VLC_ARGS+' || /Applications/VLC.app/Contents/MacOS/VLC '+href+' '+VLC_ARGS, function (error) {
          if (error) {
            process.exit(1)
          }
        })

        vlc.on('exit', function () {
          if (!argv['no-quit']) process.exit(0)
        })
      }
    }

    if (argv.omx) cp.exec(OMX_EXEC + ' ' + href)
    if (argv.mplayer) cp.exec(MPLAYER_EXEC + ' ' + href)
    if (argv.airplay) {
      var browser = airplay.createBrowser()
      browser.on('deviceOn', function (device) {
        device.play(href, 0, function () {})
      })
      browser.start()
    }
    //if (quiet) console.log('server is listening on', href)

    var filename = torrent.name
    //var filename = index.name.split('/').pop().replace(/\{|\}/g, '')
    var swarm = torrent.swarm
    var wires = swarm.wires
    var hotswaps = 0

    torrent.on('hotswap', function () {
      hotswaps++
    })

    function active (wire) {
      return !wire.peerChoking
    }

    function bytes (num) {
      return numeral(num).format('0.0b')
    }

    function draw () {
      var unchoked = swarm.wires.filter(active)
      var runtime = getRuntime()
      var linesremaining = clivas.height
      var peerslisted = 0
      var speed = swarm.downloadSpeed()
      var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
      var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()

      clivas.clear()
      clivas.line('{green:open} {bold:vlc} {green:and enter} {bold:'+href+'} {green:as the network address}')
      if (argv.airplay) clivas.line('{green:Streaming via} {bold:AirPlay} {green:to Apple TV}')
      clivas.line('')
      clivas.line('{yellow:info} {green:streaming} {bold:'+filename+'} {green:-} {bold:'+bytes(speed)+'/s} {green:from} {bold:'+unchoked.length +'/'+wires.length+'} {green:peers}    ')
      clivas.line('{yellow:info} {green:downloaded} {bold:'+bytes(swarm.downloaded)+'} {green:out of} {bold:'+bytes(torrent.length)+'} {green:and uploaded }{bold:'+bytes(swarm.uploaded)+'} {green:in }{bold:'+runtime+'s} {green:with} {bold:'+hotswaps+'} {green:hotswaps}     ')
      clivas.line('{yellow:info} {green:estimating} {bold:'+estimate+'} {green:remaining}; {green:peer queue size is} {bold:'+swarm.numQueued+'}     ')
      clivas.line('{80:}')
      linesremaining -= 8

      wires.every(function (wire) {
        var tags = []
        if (wire.peerChoking) tags.push('choked')
        clivas.line('{25+magenta:'+wire.remoteAddress+'} {10:'+bytes(wire.downloaded)+'} {10+cyan:'+bytes(wire.downloadSpeed())+'/s} {15+grey:'+tags.join(', ')+'}   ')
        peerslisted++
        return linesremaining - peerslisted > 4
      })
      linesremaining -= peerslisted

      if (wires.length > peerslisted) {
        clivas.line('{80:}')
        clivas.line('... and '+(wires.length - peerslisted)+' more     ')
      }

      clivas.line('{80:}')
      clivas.flush()
    }

    if (!argv.quiet) {
      process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing

      process.nextTick(function () {
        setInterval(draw, 500)
      })
    }
  })
}

client.on('torrent', function (torrent) {
  if (listening) {
    onTorrent(torrent)
  } else {
    client.on('listening', function (torrent) {
      onTorrent(torrent)
    })
  }
})
<commit_msg>code cleanup<commit_after>#!/usr/bin/env node

var airplay = require('airplay-js')
var chalk = require('chalk')
var clivas = require('clivas')
var cp = require('child_process')
var fs = require('fs')
var minimist = require('minimist')
var moment = require('moment')
var networkAddress = require('network-address')
var numeral = require('numeral')
var path = require('path')
var WebTorrent = require('../')

function usage (noLogo) {
  if (!noLogo) {
    var logo = fs.readFileSync(path.join(__dirname, 'ascii-logo.txt'), 'utf8')
    logo.split('\n').forEach(function (line) {
      console.log(chalk.bold(line.substring(0, 20) + chalk.red(line.substring(20))))
    })
  }
  console.log('Usage: webtorrent [OPTIONS] <torrent_id>')
  console.log('')
  clivas.line('{bold:torrent_id} can be any of the following:')
  console.log('  * magnet uri (string)')
  console.log('  * http/https url to .torrent file')
  console.log('  * filesystem path to .torrent file')
  console.log('  * info hash (as hex string)')
  console.log('')
  clivas.line('{bold:OPTIONS:}')
  console.log('  --airplay               autoplay in AirPlay (Apple TV)')
  console.log('  --vlc                   autoplay in VLC')
  console.log('  --mplayer               autoplay in MPlayer')
  console.log('  --omx [jack]            autoplay in omx (jack=local|hdmi)')
  console.log('')
  console.log('  -p, --port [number]     change the http port [default: 9000]')
  console.log('  -b, --blocklist [path]  use the specified blocklist')
  console.log('  -t, --subtitles [file]  load subtitles file')
  console.log('  -l, --list              list available files in torrent')
  console.log('  -n, --no-quit           do not quit webtorrent on vlc exit')
  console.log('  -r, --remove            remove downloaded files on exit')
  console.log('  -q, --quiet             silence stdout')
  console.log('  -h, --help              display this help message')
  console.log('  -v, --version           print the current version')
}

var argv = minimist(process.argv.slice(2), {
  alias: {
    p: 'port',
    b: 'blocklist',
    t: 'subtitles',
    l: 'list',
    n: 'no-quit',
    r: 'remove',
    q: 'quiet',
    h: 'help',
    v: 'version'
  },
  boolean: [ // options that are always boolean
    'vlc',
    'mplayer',
    'airplay',
    'list',
    'no-quit',
    'remove',
    'quiet',
    'help',
    'version'
  ],
  default: {
    port: 9000
  }
})

var torrentId = argv._[0]

function error (err) {
  clivas.line('{red:ERROR:} ' + (err.message || err))
}

if (argv.help) {
  usage()
  process.exit(0)
}

if (argv.version) {
  console.log(require('../package.json').version)
  process.exit(0)
}

if (!torrentId) {
  error('Please specify a torrent to download')
  usage(true)
  process.exit(1)
}

var VLC_ARGS = '-q --video-on-top --play-and-exit'
// var VLC_ARGS = '--video-on-top --play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'

var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
  ? argv.omx + ' '
  : 'hdmi '
var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0 '

if (argv.subtitles) {
  VLC_ARGS += ' --sub-file=' + argv.subtitles
  OMX_EXEC += ' --subtitles ' + argv.subtitles
  MPLAYER_EXEC += ' -sub ' + argv.subtitles
}

var client = new WebTorrent({
  list: argv.list,
  quiet: true,
  blocklist: argv.blocklist,
  port: argv.port
})

var started = Date.now()
var listening = false

client.on('error', function (err) {
  error(err)
  process.exit(1)
})

client.once('listening', function () {
  listening = true
})

function remove (cb) {
  process.removeListener('SIGINT', remove)
  process.removeListener('SIGTERM', remove)

  client.destroy(cb)
}

if (argv.remove) {
  process.on('SIGINT', remove)
  process.on('SIGTERM', remove)
}

client.add(torrentId, {
  remove: argv.remove
})

client.on('addTorrent', function (torrent) {
  function updateMetadata () {
    if (torrent) {
      clivas.clear()
      clivas.line('{green:fetching torrent metadata from} {bold:'+torrent.swarm.numPeers+'} {green:peers}')
    }
  }

  if (!torrent.metadata && !argv.quiet && !argv.list) {
    updateMetadata()
    torrent.swarm.on('wire', updateMetadata)

    client.once('torrent', function () {
      torrent.swarm.removeListener('wire', updateMetadata)
    })
  }
})

function getRuntime () {
  return Math.floor((Date.now() - started) / 1000)
}

function onTorrent (torrent) {
  torrent.on('verifying', function (data) {
    if (!argv.quiet && !argv.list) {
      clivas.clear()
      clivas.line('{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})')
    }
  })

  torrent.on('done', function () {
    if (argv.list) return

    if (!argv.quiet) {
      var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
        return num + (wire.downloaded > 0)
      }, 0)
      clivas.line('torrent downloaded {green:successfully} from {bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} in {bold:'+getRuntime()+'s}!')
    }

    function maybeExit () {
      if (!client.server) {
        process.exit()
      }
    }

    if (argv.remove) {
      remove(maybeExit)
    } else {
      maybeExit()
    }
  })

  torrent.on('ready', function onTorrentReady () {
    if (argv.list) {
      torrent.files.forEach(function (file, i) {
        clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'}')
      })

      process.exit(0)
    }

    var href
    if (client.server) {
      href = 'http://' + networkAddress() + ':' + client.server.address().port + '/'
    }

    if (argv.vlc) {
      if (process.platform === 'win32') {
        var registry = require('windows-no-runnable').registry
        var key
        if (process.arch === 'x64') {
          try {
            key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
          } catch (e) {}
        } else {
          try {
            key = registry('HKLM/Software/VideoLAN/VLC')
          } catch (err) {}
        }

        if (key) {
          var vlcPath = key.InstallDir.value + path.sep + 'vlc'
          VLC_ARGS = VLC_ARGS.split(' ')
          VLC_ARGS.unshift(href)
          cp.execFile(vlcPath, VLC_ARGS)
        }
      } else {
        var vlc = cp.exec('vlc '+href+' '+VLC_ARGS+' || /Applications/VLC.app/Contents/MacOS/VLC '+href+' '+VLC_ARGS, function (err) {
          if (err) {
            error(err)
            process.exit(1)
          }
        })

        vlc.on('exit', function () {
          if (!argv['no-quit']) process.exit(0)
        })
      }
    }

    if (argv.omx) cp.exec(OMX_EXEC + ' ' + href)
    if (argv.mplayer) cp.exec(MPLAYER_EXEC + ' ' + href)
    if (argv.airplay) {
      var browser = airplay.createBrowser()
      browser.on('deviceOn', function (device) {
        device.play(href, 0, function () {})
      })
      browser.start()
    }
    //if (quiet) console.log('server is listening on', href)

    var filename = torrent.name
    //var filename = index.name.split('/').pop().replace(/\{|\}/g, '')
    var swarm = torrent.swarm
    var wires = swarm.wires
    var hotswaps = 0

    torrent.on('hotswap', function () {
      hotswaps++
    })

    function active (wire) {
      return !wire.peerChoking
    }

    function bytes (num) {
      return numeral(num).format('0.0b')
    }

    function draw () {
      var unchoked = swarm.wires.filter(active)
      var runtime = getRuntime()
      var linesremaining = clivas.height
      var peerslisted = 0
      var speed = swarm.downloadSpeed()
      var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
      var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()

      clivas.clear()
      clivas.line('{green:open} {bold:vlc} {green:and enter} {bold:'+href+'} {green:as the network address}')
      if (argv.airplay) clivas.line('{green:Streaming via} {bold:AirPlay} {green:to Apple TV}')
      clivas.line('')
      clivas.line('{yellow:info} {green:streaming} {bold:'+filename+'} {green:-} {bold:'+bytes(speed)+'/s} {green:from} {bold:'+unchoked.length +'/'+wires.length+'} {green:peers}    ')
      clivas.line('{yellow:info} {green:downloaded} {bold:'+bytes(swarm.downloaded)+'} {green:out of} {bold:'+bytes(torrent.length)+'} {green:and uploaded }{bold:'+bytes(swarm.uploaded)+'} {green:in }{bold:'+runtime+'s} {green:with} {bold:'+hotswaps+'} {green:hotswaps}     ')
      clivas.line('{yellow:info} {green:estimating} {bold:'+estimate+'} {green:remaining}; {green:peer queue size is} {bold:'+swarm.numQueued+'}     ')
      clivas.line('{80:}')
      linesremaining -= 8

      wires.every(function (wire) {
        var tags = []
        if (wire.peerChoking) tags.push('choked')
        clivas.line('{25+magenta:'+wire.remoteAddress+'} {10:'+bytes(wire.downloaded)+'} {10+cyan:'+bytes(wire.downloadSpeed())+'/s} {15+grey:'+tags.join(', ')+'}   ')
        peerslisted++
        return linesremaining - peerslisted > 4
      })
      linesremaining -= peerslisted

      if (wires.length > peerslisted) {
        clivas.line('{80:}')
        clivas.line('... and '+(wires.length - peerslisted)+' more     ')
      }

      clivas.line('{80:}')
      clivas.flush()
    }

    if (!argv.quiet) {
      process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing

      process.nextTick(function () {
        setInterval(draw, 500)
      })
    }
  })
}

client.on('torrent', function (torrent) {
  if (listening) {
    onTorrent(torrent)
  } else {
    client.on('listening', function (torrent) {
      onTorrent(torrent)
    })
  }
})
<|endoftext|>


<commit_before>let logger = require('./lib/logger');

let COMMANDS = [{
  name: 'list',
  description: "List integrations in the current project, or all available integrations if -a is used",
  examples: ["datafire list", "datafire list -a"],
  runner: require('./commands/list'),
  options: [{
    name: 'all',
    alias: 'a',
    description: "Show all available integrations",
  }, {
    name: 'query',
    alias: 'q',
    description: "Filter integrations by text",
  }]
}, {
  name: 'integrate [integrations..]',
  description: "Add an integration to the current project",
  examples: ["datafire integrate hacker_news"],
  runner: require('./commands/integrate'),
  options: [{
    name: 'openapi',
    description: "The URL of an Open API JSON specification",
  }, {
    name: 'rss',
    description: "The URL of an RSS feed",
  }, {
    name: 'name',
    description: "An alias to use for the integration in this project",
  }]
}, {
  name: 'describe <integration>',
  description: "Show details for an integration or operation",
  examples: [
    "datafire describe hacker_news",
    "datafire describe hacker_news -o getUser",
  ],
  runner: require('./commands/describe'),
  options: [{
    name: 'operation',
    alias: 'o',
    description: "The operation to describe",
  }, {
    name: 'query',
    alias: 'q',
    description: "Filters for operations matching the query",
  }]
}, {
  name: 'authenticate <integration>',
  examples: ["datafire authenticate github"],
  description: "Store a set of credentials for a given integration",
  runner: require('./commands/authenticate'),
  options: [{
    name: 'as',
    description: 'The alias of the account to edit',
  }, {
    name: 'set_default',
    description: 'Set a default account for the given integration'
  }, {
    name: 'generate_token',
    description: "Generate a new OAuth 2.0 token",
  }, {
    name: 'client',
    description: "With generate_token, the account alias to use as the OAuth client",
  }]
}, {
  name: 'call <integration>',
  description: "Make a test call to an operation",
  examples: ["datafire call hacker_news -o getUser -p.username sama"],
  runner: require('./commands/call'),
  options: [{
    name: 'operation',
    alias: 'o',
    description: "The operation to call",
  }, {
    name: 'as',
    description: "The account alias to use",
  }, {
    name: 'params',
    alias: 'p',
    description: "Pass parameters to the operation",
  }]
}, {
  name: 'run <flow>',
  examples: ["datafire run ./flow.js"],
  description: "Run a flow locally",
  runner: require('./commands/run'),
  options: [{
    name: 'params',
    alias: 'p',
    description: "Pass parameters to the flow",
  }]
}]

let args = require('yargs')
           .option('v', {alias: 'verbose'})
           .global('v')
           .recommendCommands();

COMMANDS.forEach(cmd => {
  args = args.command(
        cmd.name,
        cmd.description,
        (yargs) => {
          (cmd.options || []).forEach(o => {
            yargs.option(o.name, {alias: o.alias, describe: o.description})
          })
        },
        (args) => {
          let handleError = e => {
            if (!e) return;
            logger.logError(e.toString());
            if (args.verbose) {
              logger.log(e.stack);
            } else {
              process.exit(1);
            }
          }
          try {
            cmd.runner(args, handleError);
          } catch (e) {
            handleError(e);
          }
        });
  (cmd.examples || []).forEach(ex => {
    args = args.example(cmd.name, ex);
  })
})

args = args.help('h').alias('h', 'help').strict().argv;

<commit_msg>require operation in describe<commit_after>let logger = require('./lib/logger');

let COMMANDS = [{
  name: 'list',
  description: "List integrations in the current project, or all available integrations if -a is used",
  examples: ["datafire list", "datafire list -a"],
  runner: require('./commands/list'),
  options: [{
    name: 'all',
    alias: 'a',
    description: "Show all available integrations",
  }, {
    name: 'query',
    alias: 'q',
    description: "Filter integrations by text",
  }]
}, {
  name: 'integrate [integrations..]',
  description: "Add an integration to the current project",
  examples: ["datafire integrate hacker_news"],
  runner: require('./commands/integrate'),
  options: [{
    name: 'openapi',
    description: "The URL of an Open API JSON specification",
  }, {
    name: 'rss',
    description: "The URL of an RSS feed",
  }, {
    name: 'name',
    description: "An alias to use for the integration in this project",
  }]
}, {
  name: 'describe <integration>',
  description: "Show details for an integration or operation",
  examples: [
    "datafire describe hacker_news",
    "datafire describe hacker_news -o getUser",
  ],
  runner: require('./commands/describe'),
  options: [{
    name: 'operation',
    alias: 'o',
    description: "The operation to describe",
  }, {
    name: 'query',
    alias: 'q',
    description: "Filters for operations matching the query",
  }]
}, {
  name: 'authenticate <integration>',
  examples: ["datafire authenticate github"],
  description: "Store a set of credentials for a given integration",
  runner: require('./commands/authenticate'),
  options: [{
    name: 'as',
    description: 'The alias of the account to edit',
  }, {
    name: 'set_default',
    description: 'Set a default account for the given integration'
  }, {
    name: 'generate_token',
    description: "Generate a new OAuth 2.0 token",
  }, {
    name: 'client',
    description: "With generate_token, the account alias to use as the OAuth client",
  }]
}, {
  name: 'call <integration>',
  description: "Make a test call to an operation",
  examples: ["datafire call hacker_news -o getUser -p.username sama"],
  runner: require('./commands/call'),
  options: [{
    name: 'operation',
    alias: 'o',
    required: true,
    description: "The operation to call",
  }, {
    name: 'as',
    description: "The account alias to use",
  }, {
    name: 'params',
    alias: 'p',
    description: "Pass parameters to the operation",
  }]
}, {
  name: 'run <flow>',
  examples: ["datafire run ./flow.js"],
  description: "Run a flow locally",
  runner: require('./commands/run'),
  options: [{
    name: 'params',
    alias: 'p',
    description: "Pass parameters to the flow",
  }]
}]

let args = require('yargs')
           .option('v', {alias: 'verbose'})
           .global('v')
           .recommendCommands();

COMMANDS.forEach(cmd => {
  cmd.examples = cmd.examples || [];
  cmd.options = cmd.options || [];
  args = args.command(
        cmd.name,
        cmd.description,
        (yargs) => {
          cmd.options.forEach(o => {
            yargs.option(o.name, {alias: o.alias, describe: o.description, demand: o.required})
          })
        },
        (args) => {
          let handleError = e => {
            if (!e) return;
            logger.logError(e.toString());
            if (args.verbose) {
              logger.log(e.stack);
            } else {
              process.exit(1);
            }
          }
          try {
            cmd.runner(args, handleError);
          } catch (e) {
            handleError(e);
          }
        });
  cmd.examples.forEach(ex => {
    args = args.example(cmd.name, ex);
  });
})

args = args.help('h').alias('h', 'help').strict().argv;

<|endoftext|>


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

var chokidar = require('chokidar')
  , child = require('child_process')
  , argv = require('yargs')
    .usage('Usage: $0 -c "command" -t file-or-dir')
    .command('chokidar-cmd', 'Watch directory or file for file for changes and run given command')
    .example('$0 -c "npm run less" -t src/styles', 'Run less build on changes to styles')
    .demand(['command', 'target'])
    .alias('command', 'c')
    .alias('target', 't')
    .boolean('verbose')
    .alias('verbose', 'v')
    .describe('verbose', 'Show verbose output')
    .help('help')
    .alias('help', 'h')
    .version(function() { return require('./package').version })
    .argv

var watcher = chokidar.watch(argv.target, {persistent: true})
var run = runner(argv.command)

watcher
  .on('error', logError)
  .on('change', run)

console.log('Watching', argv.target, 'and running command "' + argv.command + '" on changes')

function runner(command) {
  var running = false

  return function() {
    if (running) return
    running = true
    verboseLog('Executing command', command)
    execAsync(command, function(err, output) {
      if (err) logError(err)
      else verboseLog('Command completed successfully.')

      running = false
    })
  }
}

function logError() {
  console.error('chokidar-cmd error:', arguments)
}

function verboseLog() {
  if (argv.verbose) console.log.apply(console, arguments)
}

function execAsync(cmd, callback) {
  var output = ''

  var c = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) {
    callback(err ? err : null, output)
  })

  c.stdout.on('data', function(data) {
    output += data
  });

  c.stderr.on('data', function(data) {
    output += data
    process.stdout.write(data)
  });

  return c
}
<commit_msg>Modify logging and run command outputs<commit_after>#!/usr/bin/env node
"use strict";

var chokidar = require('chokidar')
  , child = require('child_process')
  , argv = require('yargs')
    .usage('Usage: $0 -c "command" -t file-or-dir')
    .command('chokidar-cmd', 'Watch directory or file for file for changes and run given command')
    .example('$0 -c "npm run less" -t src/styles', 'Run less build on changes to styles')
    .demand(['command', 'target'])
    .alias('command', 'c')
    .alias('target', 't')
    .boolean('verbose')
    .alias('verbose', 'v')
    .describe('verbose', 'Show verbose output')
    .help('help')
    .alias('help', 'h')
    .version(function() { return require('./package').version })
    .argv

var watcher = chokidar.watch(argv.target, {persistent: true})
var run = runner(argv.command)

watcher
  .on('error', logError)
  .on('change', run)

console.log('Watching', argv.target, 'and running command "' + argv.command + '" on changes')

function runner(command) {
  var running = false

  return function() {
    if (running) return
    running = true
    verboseLog('Executing command', command)
    execAsync(command, function(err, output) {
      if (err) logError(err)
      else verboseLog('Command completed successfully.')

      running = false
    })
  }
}

function logError() {
  console.error.apply(console, ['chokidar-cmd error:'].concat(arguments))
}

function verboseLog() {
  if (argv.verbose) console.log.apply(console, arguments)
}

function execAsync(cmd, callback) {
  var output = ''

  var c = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) {
    callback(err ? err : null, output)
  })

  c.stdout.on('data', function(data) {
    output += data
    process.stdout.write(data)
  });

  c.stderr.on('data', function(data) {
    output += data
    process.stderr.write(data)
  });

  return c
}
<|endoftext|>