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

var minimist = require('minimist')
var fs = require('fs')
var log = require('single-line-log').stdout
var bytes = require('pretty-bytes')

var pkg = require('./package.json')
var torrent = require('./')
var createTorrent = require('create-torrent')
var parseTorrent = require('parse-torrent')
var concat = require('concat-stream')
var humanSize = require('human-format')
var prettySeconds = require('pretty-seconds')

var argv = minimist(process.argv.slice(2), {
  alias: { outfile: 'o' }
})

if (argv.version) {
  console.log(pkg.version)
  return
}

if (argv.help || argv._.length === 0) {
  fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout)
  return
}

if (argv.quiet) log = function() {}

var source = argv._.shift()

if (source === 'create') {
  var dir = argv._.shift()
  var outfile = argv.outfile
  if (outfile === '-') outfile = null

  if (outfile && fs.existsSync(outfile)) {
    console.error('refusing to overwrite existing torrent file')
    process.exit(1)
  }

  var opts = {}
  if (argv.tracker) {
    if (typeof argv.tracker === 'string') opts.announceList = [[argv.tracker]]
    else opts.announceList = argv.tracker.map(function(t) { return [t] })
  }

  opts.urlList = argv.urlList

  createTorrent(dir, opts, function (err, torrent) {
    if (err) {
      console.error(err.stack)
      process.exit(1)
    }
    else if (outfile) {
      fs.writeFile(outfile, torrent, function (err) {
        if (err) {
          console.error(err.stack)
          process.exit(1)
        }
      })
    }
    else process.stdout.write(torrent)
  })

  return
} else if (source === 'info') {
  var infile = argv._.shift()
  getInfo(infile, function (parsed) {
    delete parsed.infoBuffer
    delete parsed.info.pieces
    console.log(JSON.stringify(toString(parsed), null, 2))

    function toString (obj) {
      if (Array.isArray(obj)) {
        return obj.map(toString)
      } else if (Buffer.isBuffer(obj)) {
        return obj.toString('utf8')
      } else if (typeof obj === 'object') {
        return Object.keys(obj).reduce(function (acc, key) {
          acc[key] = toString(obj[key])
          return acc
        }, {})
      }
      else return obj
    }
  })
  return
} else if (source === 'ls' || source === 'list') {
  var infile = argv._.shift()
  getInfo(infile, function (parsed) {
    parsed.files.forEach(function (file) {
      var prefix = '';
      if (argv.s && argv.h) {
        prefix = humanSize(file.length).replace(/(\d)B$/, '$1 B')
        prefix = Array(10-prefix.length).join(' ') + prefix + ' '
      } else if (argv.s) {
        prefix = String(file.length)
        prefix = Array(10-prefix.length).join(' ') + prefix + ' '
      }
      console.log(prefix + file.path)
    })
  })
  return
} else if (source === 'seed') {
  var infile = argv._.shift()
  var filename = infile
  if (!argv.path) argv.path = process.cwd()
  if (source.indexOf('.torrent') > -1 && !/^magnet/.test(source)) source = fs.readFileSync(source)
  var dl = torrent(infile, argv)
  dl.on('ready', function() {
    var seeding = dl.torrent.pieces.every(function(piece, i) {
      return dl.bitfield.get(i)
    })
    if (!seeding) {
      console.error('Missing files!')
      process.exit(1)
    } else {
      console.log('Verified files successfully!')
    }
    function status() {
      log(
        'Seeding ' + filename + '\n' +
        'Connected to '+dl.swarm.wires.reduce(notChoked, 0)+'/'+dl.swarm.wires.length+' peers\n'+
        'Uploaded ' + bytes(dl.swarm.uploaded) + ' ('+ bytes(dl.swarm.uploadSpeed()) +')\n'
      )
    }
    setInterval(status, 1000)
    status()
  })
  dl.listen(0)
} else {
  if (source.indexOf('.torrent') > -1) source = fs.readFileSync(source)

  if (!argv.path) argv.path = process.cwd()

  var dl = torrent(source, argv)

  dl.on('ready', function() {

    if (argv.peer) {
      console.log('connecting to peer', argv.peer)
      dl.connect(argv.peer)
    }

    var fileCount = dl.files.length
    var timeStart = (new Date()).getTime()
    console.log(fileCount.toString(), (fileCount === 1 ? 'file' : 'files'), 'in torrent')
    console.log(dl.files.map(function(f){ return f.name.trim() }).join('\n'))

    var status = function() {
      var down = bytes(dl.swarm.downloaded)
      var downSpeed = bytes(dl.swarm.downloadSpeed()) +'/s'
      var up = bytes(dl.swarm.uploaded)
      var upSpeed = bytes(dl.swarm.uploadSpeed()) +'/s'
      var torrentSize = dl.torrent.length
      var bytesRemaining = torrentSize - dl.swarm.downloaded
      var percentage = ((dl.swarm.downloaded / dl.torrent.length) * 100).toPrecision(4)
      var progressBar = ''
      var bars = ~~((percentage) / 5)

      // (TimeTaken / bytesDownloaded) * bytesLeft=timeLeft
      if (dl.swarm.downloaded > 0) {
        if (dl.swarm.downloadSpeed() > 0) {
          var seconds = 1000;
          var timeNow = (new Date()).getTime()
          var timeElapsed = timeNow - timeStart
          var timeRemaining = (((timeElapsed / dl.swarm.downloaded) * bytesRemaining) / seconds).toPrecision(6)
          timeRemaining = 'Estimated ' + prettySeconds(~~timeRemaining) + ' remaining'
        } else {
          timeRemaining = 'Unknown time remaining'
        }
      } else {
        timeRemaining = "Calculating"
      }

      if (percentage > 100) { percentage = 100 }

      for (i = 0; i < bars; i++) {
        progressBar = progressBar + '='
      }

      progressBar = progressBar + Array(20 + 1 - progressBar.length).join(' ')

      log(
        'Connected to '+dl.swarm.wires.reduce(notChoked, 0)+'/'+dl.swarm.wires.length+' peers\n'+
        'Downloaded '+down+' ('+downSpeed+')\n'+
        'Uploaded '+up+ ' ('+upSpeed+')\n'+
        'Torrent Size '+bytes(torrentSize)+'\n\n'+
        'Complete: '+ percentage+'%\n'+
        '['+progressBar+']\n'+
        '0%    25   50   75   100%\n\n'+timeRemaining + '\n'
      )
    }

    var interval = setInterval(status, 500)
    status()
  })
}

function notChoked(result, wire) {
  return result + (wire.peerChoking ? 0 : 1)
}

function getInfo (infile, cb) {
  var instream = !infile || infile === '-'
    ? process.stdin
    : fs.createReadStream(infile)
  instream.pipe(concat(function (body) {
    try {
      var parsed = parseTorrent(body)
    } catch (err) {
      console.error(err.stack)
      process.exit(1)
    }
    cb(parsed)
  }))
}<commit_msg>use infile for `torrent seed`<commit_after>#!/usr/bin/env node

var minimist = require('minimist')
var fs = require('fs')
var log = require('single-line-log').stdout
var bytes = require('pretty-bytes')

var pkg = require('./package.json')
var torrent = require('./')
var createTorrent = require('create-torrent')
var parseTorrent = require('parse-torrent')
var concat = require('concat-stream')
var humanSize = require('human-format')
var prettySeconds = require('pretty-seconds')

var argv = minimist(process.argv.slice(2), {
  alias: { outfile: 'o' }
})

if (argv.version) {
  console.log(pkg.version)
  return
}

if (argv.help || argv._.length === 0) {
  fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout)
  return
}

if (argv.quiet) log = function() {}

var source = argv._.shift()

if (source === 'create') {
  var dir = argv._.shift()
  var outfile = argv.outfile
  if (outfile === '-') outfile = null

  if (outfile && fs.existsSync(outfile)) {
    console.error('refusing to overwrite existing torrent file')
    process.exit(1)
  }

  var opts = {}
  if (argv.tracker) {
    if (typeof argv.tracker === 'string') opts.announceList = [[argv.tracker]]
    else opts.announceList = argv.tracker.map(function(t) { return [t] })
  }

  opts.urlList = argv.urlList

  createTorrent(dir, opts, function (err, torrent) {
    if (err) {
      console.error(err.stack)
      process.exit(1)
    }
    else if (outfile) {
      fs.writeFile(outfile, torrent, function (err) {
        if (err) {
          console.error(err.stack)
          process.exit(1)
        }
      })
    }
    else process.stdout.write(torrent)
  })

  return
} else if (source === 'info') {
  var infile = argv._.shift()
  getInfo(infile, function (parsed) {
    delete parsed.infoBuffer
    delete parsed.info.pieces
    console.log(JSON.stringify(toString(parsed), null, 2))

    function toString (obj) {
      if (Array.isArray(obj)) {
        return obj.map(toString)
      } else if (Buffer.isBuffer(obj)) {
        return obj.toString('utf8')
      } else if (typeof obj === 'object') {
        return Object.keys(obj).reduce(function (acc, key) {
          acc[key] = toString(obj[key])
          return acc
        }, {})
      }
      else return obj
    }
  })
  return
} else if (source === 'ls' || source === 'list') {
  var infile = argv._.shift()
  getInfo(infile, function (parsed) {
    parsed.files.forEach(function (file) {
      var prefix = '';
      if (argv.s && argv.h) {
        prefix = humanSize(file.length).replace(/(\d)B$/, '$1 B')
        prefix = Array(10-prefix.length).join(' ') + prefix + ' '
      } else if (argv.s) {
        prefix = String(file.length)
        prefix = Array(10-prefix.length).join(' ') + prefix + ' '
      }
      console.log(prefix + file.path)
    })
  })
  return
} else if (source === 'seed') {
  var infile = argv._.shift()
  var filename = infile
  if (!argv.path) argv.path = process.cwd()
  var body
  if (!/^magnet:/.test(infile)) {
    body = fs.readFileSync(infile)
  }
  else body = infile

  var dl = torrent(body, argv)
  dl.on('ready', function() {
    var seeding = dl.torrent.pieces.every(function(piece, i) {
      return dl.bitfield.get(i)
    })
    if (!seeding) {
      console.error('Missing files!')
      process.exit(1)
    } else {
      console.log('Verified files successfully!')
    }
    function status() {
      log(
        'Seeding ' + filename + '\n' +
        'Connected to '+dl.swarm.wires.reduce(notChoked, 0)+'/'+dl.swarm.wires.length+' peers\n'+
        'Uploaded ' + bytes(dl.swarm.uploaded) + ' ('+ bytes(dl.swarm.uploadSpeed()) +')\n'
      )
    }
    setInterval(status, 1000)
    status()
  })
  dl.listen(0)
} else {
  if (source.indexOf('.torrent') > -1) source = fs.readFileSync(source)

  if (!argv.path) argv.path = process.cwd()

  var dl = torrent(source, argv)

  dl.on('ready', function() {

    if (argv.peer) {
      console.log('connecting to peer', argv.peer)
      dl.connect(argv.peer)
    }

    var fileCount = dl.files.length
    var timeStart = (new Date()).getTime()
    console.log(fileCount.toString(), (fileCount === 1 ? 'file' : 'files'), 'in torrent')
    console.log(dl.files.map(function(f){ return f.name.trim() }).join('\n'))

    var status = function() {
      var down = bytes(dl.swarm.downloaded)
      var downSpeed = bytes(dl.swarm.downloadSpeed()) +'/s'
      var up = bytes(dl.swarm.uploaded)
      var upSpeed = bytes(dl.swarm.uploadSpeed()) +'/s'
      var torrentSize = dl.torrent.length
      var bytesRemaining = torrentSize - dl.swarm.downloaded
      var percentage = ((dl.swarm.downloaded / dl.torrent.length) * 100).toPrecision(4)
      var progressBar = ''
      var bars = ~~((percentage) / 5)

      // (TimeTaken / bytesDownloaded) * bytesLeft=timeLeft
      if (dl.swarm.downloaded > 0) {
        if (dl.swarm.downloadSpeed() > 0) {
          var seconds = 1000;
          var timeNow = (new Date()).getTime()
          var timeElapsed = timeNow - timeStart
          var timeRemaining = (((timeElapsed / dl.swarm.downloaded) * bytesRemaining) / seconds).toPrecision(6)
          timeRemaining = 'Estimated ' + prettySeconds(~~timeRemaining) + ' remaining'
        } else {
          timeRemaining = 'Unknown time remaining'
        }
      } else {
        timeRemaining = "Calculating"
      }

      if (percentage > 100) { percentage = 100 }

      for (i = 0; i < bars; i++) {
        progressBar = progressBar + '='
      }

      progressBar = progressBar + Array(20 + 1 - progressBar.length).join(' ')

      log(
        'Connected to '+dl.swarm.wires.reduce(notChoked, 0)+'/'+dl.swarm.wires.length+' peers\n'+
        'Downloaded '+down+' ('+downSpeed+')\n'+
        'Uploaded '+up+ ' ('+upSpeed+')\n'+
        'Torrent Size '+bytes(torrentSize)+'\n\n'+
        'Complete: '+ percentage+'%\n'+
        '['+progressBar+']\n'+
        '0%    25   50   75   100%\n\n'+timeRemaining + '\n'
      )
    }

    var interval = setInterval(status, 500)
    status()
  })
}

function notChoked(result, wire) {
  return result + (wire.peerChoking ? 0 : 1)
}

function getInfo (infile, cb) {
  var instream = !infile || infile === '-'
    ? process.stdin
    : fs.createReadStream(infile)
  instream.pipe(concat(function (body) {
    try {
      var parsed = parseTorrent(body)
    } catch (err) {
      console.error(err.stack)
      process.exit(1)
    }
    cb(parsed)
  }))
}
<|endoftext|>


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

var fs = require('fs'),
    path = require('path'),
    commander = require('commander'),
    async = require('async'),
    glob = require('glob'),
    mkdirp = require('mkdirp'),
    typogr = require('./typogr');

function isDirectory(pathString) {
  try {
    // Query the entry
    return fs.statSync(pathString).isDirectory();
  }
  catch (error) {
    // if file doesn't exist, statSync throws an error instead of just returning false
    return false;
  }
}

// path.dirname and path.basename don't always work right, so we have to create our own functions
function dirname(pathString) {
  return pathString.substring(0, pathString.lastIndexOf('/') + 1);
}

function basename(pathString) {
  return pathString.substring(pathString.lastIndexOf('/') + 1);
}

function readRenderWrite(input, output, force) {
  input = path.normalize(input);
  output = path.normalize(output);

  if(isDirectory(input))
    input = input + '/**';  // add glob to get all files under directory

  var inputDirectory = dirname(input),
      inputGlob = basename(input),
      after,
      outputString;

  // process input
  glob(inputGlob, { cwd: inputDirectory }, function (error, files) {
    async.eachSeries(files, function (file, eachCallback) {
      // only process files; other types such as directories or links are ignored
      fs.stat(inputDirectory + '/' + file, function (error, stats) {
        if(stats.isFile()) {
          // read file
          fs.readFile(inputDirectory + '/' + file, 'utf8', function (error, before) {
            // process the html
            after = typogr.typogrify(before);
            // write file
            if(output === '/dev/stdout') // writeFile doesn't like /dev/stdout even though readFile works with /dev/stdin
              console.log(after);
            else {
              if(files.length > 1) {
                // multiple input files means we are dealing with a directory or a glob,
                // so make sure directory exists
                mkdirp.sync(output + '/' + dirname(file));
                outputString = path.normalize(output + '/' + file);
              }
              else // one input file means we are only writing one file
                outputString = output;
              if(force) {
                fs.writeFile(outputString, after, function (error) {
                  eachCallback(error);
                });
              }
              else {
                confirmOverwrite(outputString, function (ok) {
                  if(ok)
                    fs.writeFile(outputString, after, function (error) {
                      eachCallback(error);
                    });
                });
              }
            }
          });
        }
        else
          eachCallback(null);
      });
    }, function (error) {
      if(error) throw error;
    });
  });
}

function confirmOverwrite(fileName, callback) {
  fs.stat(fileName, function(error, stats) {
    if(stats) {
      if(stats.isFile()) {
        commander.confirm('Confirm: overwrite file (' + fileName + ')? ', function(ok) {
          // work around bug in commander.js
          // see (https://github.com/visionmedia/commander.js/issues/109)
          // also see (https://github.com/visionmedia/commander.js/pull/133)
          process.stdin.pause();

          if(ok)
            callback(true);
          else {
            console.log("  Cancelling action, file wasn't modified.");
            callback(false);
          }
        });
      }
      else {
        // fileName is not of type 'file' (close our eyes and assume it's a directory)
        callback(true);
      }
    }
    else {
      // fileName doesn't exist
      callback(true);
    }
  });
}

function main() {
  // specify cli options
  commander
    .version('0.6.5')
    .usage('[options] [input] [output]')
    .option('-i, --inplace', 'Use single path as both input and output')
    .option('-f, --force', 'Do not prompt to verify file overwrites');

  // specify example help text
  commander.on('--help', function() {
    console.log('  reads input from stdin, individual files, directories, or globs');
    console.log('  writes ouput to stdout, individual files, or directories');
    console.log('');
    console.log('  Examples:');
    console.log('');
    console.log('    $ typogr inputFile.html outputFile.html');
    console.log('    $ typogr < inputFile.html > outputFile.html');
    console.log('    $ typogr -i singleFile.html');
    console.log('    $ typogr inputDirectory outputDirectory');
    console.log('    $ typogr inputDirectory/*.html outputDirectory');
    console.log('');
  });

  // parse arguments and generate object mappings in the *commander* object
  commander.parse(process.argv);

  switch (commander.args.length) {
    case 0:
      // get input from stdin and send output to stdout
      readRenderWrite('/dev/stdin', '/dev/stdout');
      break;
    case 1:
      if (commander.inplace) {
        // modify the file in place
        readRenderWrite(commander.args[0], commander.args[0], commander.force);
      }
      else {
        // get input from file specified and send output to stdout
        readRenderWrite(commander.args[0], '/dev/stdout');
      }
      break;
    case 2:
      // get input from first parameter and send output to second parameter
      readRenderWrite(commander.args[0], commander.args[1], commander.force);
      break;
  }

}

module.exports.main = main;
<commit_msg>0.6.6<commit_after>#!/usr/bin/env node

var fs = require('fs'),
    path = require('path'),
    commander = require('commander'),
    async = require('async'),
    glob = require('glob'),
    mkdirp = require('mkdirp'),
    typogr = require('./typogr');

function isDirectory(pathString) {
  try {
    // Query the entry
    return fs.statSync(pathString).isDirectory();
  }
  catch (error) {
    // if file doesn't exist, statSync throws an error instead of just returning false
    return false;
  }
}

// path.dirname and path.basename don't always work right, so we have to create our own functions
function dirname(pathString) {
  return pathString.substring(0, pathString.lastIndexOf('/') + 1);
}

function basename(pathString) {
  return pathString.substring(pathString.lastIndexOf('/') + 1);
}

function readRenderWrite(input, output, force) {
  input = path.normalize(input);
  output = path.normalize(output);

  if(isDirectory(input))
    input = input + '/**';  // add glob to get all files under directory

  var inputDirectory = dirname(input),
      inputGlob = basename(input),
      after,
      outputString;

  // process input
  glob(inputGlob, { cwd: inputDirectory }, function (error, files) {
    async.eachSeries(files, function (file, eachCallback) {
      // only process files; other types such as directories or links are ignored
      fs.stat(inputDirectory + '/' + file, function (error, stats) {
        if(stats.isFile()) {
          // read file
          fs.readFile(inputDirectory + '/' + file, 'utf8', function (error, before) {
            // process the html
            after = typogr.typogrify(before);
            // write file
            if(output === '/dev/stdout') // writeFile doesn't like /dev/stdout even though readFile works with /dev/stdin
              console.log(after);
            else {
              if(files.length > 1) {
                // multiple input files means we are dealing with a directory or a glob,
                // so make sure directory exists
                mkdirp.sync(output + '/' + dirname(file));
                outputString = path.normalize(output + '/' + file);
              }
              else // one input file means we are only writing one file
                outputString = output;
              if(force) {
                fs.writeFile(outputString, after, function (error) {
                  eachCallback(error);
                });
              }
              else {
                confirmOverwrite(outputString, function (ok) {
                  if(ok)
                    fs.writeFile(outputString, after, function (error) {
                      eachCallback(error);
                    });
                });
              }
            }
          });
        }
        else
          eachCallback(null);
      });
    }, function (error) {
      if(error) throw error;
    });
  });
}

function confirmOverwrite(fileName, callback) {
  fs.stat(fileName, function(error, stats) {
    if(stats) {
      if(stats.isFile()) {
        commander.confirm('Confirm: overwrite file (' + fileName + ')? ', function(ok) {
          // work around bug in commander.js
          // see (https://github.com/visionmedia/commander.js/issues/109)
          // also see (https://github.com/visionmedia/commander.js/pull/133)
          process.stdin.pause();

          if(ok)
            callback(true);
          else {
            console.log("  Cancelling action, file wasn't modified.");
            callback(false);
          }
        });
      }
      else {
        // fileName is not of type 'file' (close our eyes and assume it's a directory)
        callback(true);
      }
    }
    else {
      // fileName doesn't exist
      callback(true);
    }
  });
}

function main() {
  // specify cli options
  commander
    .version('0.6.6')
    .usage('[options] [input] [output]')
    .option('-i, --inplace', 'Use single path as both input and output')
    .option('-f, --force', 'Do not prompt to verify file overwrites');

  // specify example help text
  commander.on('--help', function() {
    console.log('  reads input from stdin, individual files, directories, or globs');
    console.log('  writes ouput to stdout, individual files, or directories');
    console.log('');
    console.log('  Examples:');
    console.log('');
    console.log('    $ typogr inputFile.html outputFile.html');
    console.log('    $ typogr < inputFile.html > outputFile.html');
    console.log('    $ typogr -i singleFile.html');
    console.log('    $ typogr inputDirectory outputDirectory');
    console.log('    $ typogr inputDirectory/*.html outputDirectory');
    console.log('');
  });

  // parse arguments and generate object mappings in the *commander* object
  commander.parse(process.argv);

  switch (commander.args.length) {
    case 0:
      // get input from stdin and send output to stdout
      readRenderWrite('/dev/stdin', '/dev/stdout');
      break;
    case 1:
      if (commander.inplace) {
        // modify the file in place
        readRenderWrite(commander.args[0], commander.args[0], commander.force);
      }
      else {
        // get input from file specified and send output to stdout
        readRenderWrite(commander.args[0], '/dev/stdout');
      }
      break;
    case 2:
      // get input from first parameter and send output to second parameter
      readRenderWrite(commander.args[0], commander.args[1], commander.force);
      break;
  }

}

module.exports.main = main;
<|endoftext|>


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

"use strict";

var path = require("path");
var vm = require("vm");
var fs = require("fs");
var chalk = require('chalk');
var spider = require("./lib/spider");

var opts = require("nomnom")
  .option("files", {
    position: 0,
    help: "files to compile",
    list: true
  })
  .option("compile", {
    abbr: "c",
    flag: true,
    help: "compile to JavaScript and save as .js files"
  })
  .option("verbose", {
    abbr: "v",
    flag: true,
    help: "verbose mode"
  })
  .option("disable-source-map", {
    flag: true,
    help: "disable source map files (.map) generation"
  })
  .option("version", {
    flag: true,
    help: "display the version number",
    callback: function () {
      return "version " + require("./package.json").version;
    }
  })
  .parse();

function generateSpace(len) {
  var chars = [];
  for (var i = 0; i < len; i++) {
    chars.push(' ');
  }

  return chars.join('');
}

function generateErrorColumnString(errorStartIndex, errorEndIndex) {
  var chars = [];
  var i = 0;

  if (!errorEndIndex) {
    errorEndIndex = errorStartIndex;
  }

  for (; i < errorStartIndex; i++) {
    chars.push(' ');
  }

  for (i = errorStartIndex; i <= errorEndIndex; i++) {
    chars.push('^');
  }

  return chars.join('');
}

var problems = 0;

opts.files.forEach(function (fileName, fileIndex) {
  fs.readFile(fileName, "utf-8", function (error, content) {
    if (error) {
      return console.log(error);
    }

    var enableSourceMap = !opts['disable-source-map'];

    var errors = [];
    var outFileName = fileName.substring(0,
          fileName.lastIndexOf('.')) + ".js";
    var compilerOutput = spider.compile(content, opts.verbose, errors,
      opts.compile && enableSourceMap ? path.basename(fileName) : false, outFileName + ".map", true, true);

    if (errors.length > 0) {
      var output = [];

      var maxCol = 0;
      var maxLine = 0;

      output.push(chalk.white(fileName), "\n");

      var lines = content.split("\n");
      var tabCharacter = "__SPIDER_TAB";

      errors.forEach(function (error, errorIndex) {
        var line = error.loc.start.line;
        var column = error.loc.start.column + 1;

        var lineCharCount = line.toString().length;
        var columnCharCount = column.toString().length;

        maxCol = Math.max(maxCol, columnCharCount);
        maxLine = Math.max(maxCol, lineCharCount);

        output.push(tabCharacter);
        output.push(chalk.gray("line", line));
        output.push(tabCharacter, lineCharCount);
        output.push(chalk.gray("col", column));
        output.push(tabCharacter, columnCharCount);

        output.push(chalk.red(error.message), "\n");

        if (error.loc && error.loc.start) {
          var start = error.loc.start;
          var end = error.loc.end;

          if (start.line > 0 && start.line <= lines.length) {
            output.push(tabCharacter, tabCharacter, tabCharacter);

            output.push(chalk.green(lines[start.line - 1].replace(/(\r\n|\n|\r)/gm, ""),
              "\n", tabCharacter, tabCharacter));
            output.push(chalk.red(generateErrorColumnString(start.column, end ? end.column - 1 : 0)));
          }
        }

        output.push("\n");

        problems++;

        if (problems > 0 &&
            fileIndex === opts.files.length - 1
            && errorIndex === errors.length - 1)  {
          output.push(chalk.red(problems + (problems === 1 ? " problem" : " problems")));
        }
      });

      var str = output.join("");
      var tabLength = Math.max(maxLine, maxCol);

      for (var i = 1; i <= tabLength; i++) {
        var regex = new RegExp(tabCharacter + i, "g");
        str = str.replace(regex, generateSpace(Math.max(2 + tabLength - i, 2)));
      }

      console.log(str.replace(new RegExp(tabCharacter, "g"), generateSpace(2)));
    } else {
      if (opts.compile) {
        var code = compilerOutput.code;

        fs.writeFile(outFileName, code, function (error) {
          if (error) {
            return console.log(error);
          }
        });

        if (enableSourceMap) {
          fs.writeFile(outFileName + ".map",
            compilerOutput.map.toString(),
            function (error) {
              if (error) {
                return console.log(error);
              }
            });
        }
      } else {
        vm.runInThisContext(compilerOutput);
      }
    }
  });
});<commit_msg>fix cli execute script<commit_after>#! /usr/bin/env node

"use strict";

var path = require("path");
var vm = require("vm");
var fs = require("fs");
var chalk = require('chalk');
var spider = require("./lib/spider");

var opts = require("nomnom")
  .option("files", {
    position: 0,
    help: "files to compile",
    list: true
  })
  .option("compile", {
    abbr: "c",
    flag: true,
    help: "compile to JavaScript and save as .js files"
  })
  .option("verbose", {
    abbr: "v",
    flag: true,
    help: "verbose mode"
  })
  .option("disable-source-map", {
    flag: true,
    help: "disable source map files (.map) generation"
  })
  .option("version", {
    flag: true,
    help: "display the version number",
    callback: function () {
      return "version " + require("./package.json").version;
    }
  })
  .parse();

function generateSpace(len) {
  var chars = [];
  for (var i = 0; i < len; i++) {
    chars.push(' ');
  }

  return chars.join('');
}

function generateErrorColumnString(errorStartIndex, errorEndIndex) {
  var chars = [];
  var i = 0;

  if (!errorEndIndex) {
    errorEndIndex = errorStartIndex;
  }

  for (; i < errorStartIndex; i++) {
    chars.push(' ');
  }

  for (i = errorStartIndex; i <= errorEndIndex; i++) {
    chars.push('^');
  }

  return chars.join('');
}

var problems = 0;

opts.files.forEach(function (fileName, fileIndex) {
  fs.readFile(fileName, "utf-8", function (error, content) {
    if (error) {
      return console.log(error);
    }

    var enableSourceMap = !opts['disable-source-map'];

    var errors = [];
    var outFileName = fileName.substring(0,
          fileName.lastIndexOf('.')) + ".js";
    var compilerOutput = spider.compile(content, opts.verbose, errors,
      opts.compile && enableSourceMap ? path.basename(fileName) : false, outFileName + ".map", true, true);

    if (errors.length > 0) {
      var output = [];

      var maxCol = 0;
      var maxLine = 0;

      output.push(chalk.white(fileName), "\n");

      var lines = content.split("\n");
      var tabCharacter = "__SPIDER_TAB";

      errors.forEach(function (error, errorIndex) {
        var line = error.loc.start.line;
        var column = error.loc.start.column + 1;

        var lineCharCount = line.toString().length;
        var columnCharCount = column.toString().length;

        maxCol = Math.max(maxCol, columnCharCount);
        maxLine = Math.max(maxCol, lineCharCount);

        output.push(tabCharacter);
        output.push(chalk.gray("line", line));
        output.push(tabCharacter, lineCharCount);
        output.push(chalk.gray("col", column));
        output.push(tabCharacter, columnCharCount);

        output.push(chalk.red(error.message), "\n");

        if (error.loc && error.loc.start) {
          var start = error.loc.start;
          var end = error.loc.end;

          if (start.line > 0 && start.line <= lines.length) {
            output.push(tabCharacter, tabCharacter, tabCharacter);

            output.push(chalk.green(lines[start.line - 1].replace(/(\r\n|\n|\r)/gm, ""),
              "\n", tabCharacter, tabCharacter));
            output.push(chalk.red(generateErrorColumnString(start.column, end ? end.column - 1 : 0)));
          }
        }

        output.push("\n");

        problems++;

        if (problems > 0 &&
            fileIndex === opts.files.length - 1
            && errorIndex === errors.length - 1)  {
          output.push(chalk.red(problems + (problems === 1 ? " problem" : " problems")));
        }
      });

      var str = output.join("");
      var tabLength = Math.max(maxLine, maxCol);

      for (var i = 1; i <= tabLength; i++) {
        var regex = new RegExp(tabCharacter + i, "g");
        str = str.replace(regex, generateSpace(Math.max(2 + tabLength - i, 2)));
      }

      console.log(str.replace(new RegExp(tabCharacter, "g"), generateSpace(2)));
    } else {
      if (opts.compile) {
        var code = compilerOutput.code;

        fs.writeFile(outFileName, code, function (error) {
          if (error) {
            return console.log(error);
          }
        });

        if (enableSourceMap) {
          fs.writeFile(outFileName + ".map",
            compilerOutput.map.toString(),
            function (error) {
              if (error) {
                return console.log(error);
              }
            });
        }
      } else {
        vm.runInThisContext(compilerOutput.code);
      }
    }
  });
});<|endoftext|>


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

var pagespeed = require('./index');
var pkg = require('./package.json');
var query = process.argv[2];
var argv = require('minimist')((process.argv.slice(2)));
var opts = {};

function printHelp() {
  console.log(pkg.description);
  console.log('');
  console.log('Usage:');
  console.log('  $ gpagespeed <url> --key=<key>');
  console.log('');
  console.log('Optional, supply other arguments.');
  console.log('See https://developers.google.com/speed/docs/insights/v2/getting-started');
  console.log('  $ gpagespeed <url> --key=<key> filter_third_party_resources=<boolean> --locale=<locale> --rule=<rule> --screenshot=<boolean> --strategy=<desktop|mobile>');
  console.log('You can also use https instead of googleapis and pick another version of the api');
  console.log('  $ gpagespeed <url> --key=<key> --useweb=true --apiversion=<versionstring>');
}

if (!query || process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
  printHelp();
  return;
}

if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
  console.log(pkg.version);
  return;
}

if (query.indexOf('http') !== -1) {
  opts.url = argv._[0];
}

if (!opts.url || (!argv.key && !argv.nokey)) {
  printHelp();
  return;
}

if (argv.url) {
  opts.url = argv.url;
}

if (argv.key) {
  opts.key = argv.key;
}

if (argv.filter_third_party_resources) {
  opts.filter_third_party_resources = true;
}

if (argv.rule) {
  opts.rule = argv.rule;
}

if (argv.screenshot) {
  opts.screenshot = true;
}

if (argv.locale) {
  opts.locale = argv.locale;
}

if (argv.strategy) {
  opts.strategy = argv.strategy;
}

if (argv.nokey) {
  opts.nokey = argv.nokey;
}

if (argv.userequest) {
  opts.userequest = argv.userequest;
}

if (argv.apiversion) {
  opts.apiversion = argv.apiversion;
}

pagespeed(opts, function(err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});<commit_msg>Puts back options from api v1<commit_after>#!/usr/bin/env node
'use strict';

var pagespeed = require('./index');
var pkg = require('./package.json');
var query = process.argv[2];
var argv = require('minimist')((process.argv.slice(2)));
var opts = {};

function printHelp() {
  console.log(pkg.description);
  console.log('');
  console.log('Usage:');
  console.log('  $ gpagespeed <url> --key=<key>');
  console.log('');
  console.log('Optional, supply other arguments.');
  console.log('See https://developers.google.com/speed/docs/insights/v2/getting-started');
  console.log('  $ gpagespeed <url> --key=<key> filter_third_party_resources=<boolean> --locale=<locale> --rule=<rule> --screenshot=<boolean> --strategy=<desktop|mobile>');
  console.log('You can also use https instead of googleapis and pick another version of the api');
  console.log('  $ gpagespeed <url> --key=<key> --useweb=true --apiversion=<versionstring>');
}

if (!query || process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
  printHelp();
  return;
}

if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
  console.log(pkg.version);
  return;
}

if (query.indexOf('http') !== -1) {
  opts.url = argv._[0];
}

if (!opts.url || (!argv.key && !argv.nokey)) {
  printHelp();
  return;
}

if (argv.url) {
  opts.url = argv.url;
}

if (argv.key) {
  opts.key = argv.key;
}

if (argv.callback) {
  opts.callback = argv.callback;
}

if (argv.prettyprint) {
  opts.prettyprint = argv.prettyprint;
}

if (argv.userIp) {
  opts.userIp = argv.userIp;
}

if (argv.filter_third_party_resources) {
  opts.filter_third_party_resources = true;
}

if (argv.rule) {
  opts.rule = argv.rule;
}

if (argv.screenshot) {
  opts.screenshot = true;
}

if (argv.locale) {
  opts.locale = argv.locale;
}

if (argv.strategy) {
  opts.strategy = argv.strategy;
}

if (argv.nokey) {
  opts.nokey = argv.nokey;
}

if (argv.userequest) {
  opts.userequest = argv.userequest;
}

if (argv.apiversion) {
  opts.apiversion = argv.apiversion;
}

pagespeed(opts, function(err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});<|endoftext|>


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

var concat = require('concat-stream'),
    argv = require('minimist')(process.argv.slice(2), {
        string: 'overpass-url',
        boolean: 'flat-properties',
        boolean: 'version',
        default: {
            'flat-properties': false
        }
    }),
    fs = require('fs'),
    overpass = require('./');

if (argv['version'])
  return process.stdout.write(require('./package.json').version+'\n');

function openData(s) {
    var query = s.toString();
    overpass(query, function(err, geojson) {
        if (!err) {
            console.log(JSON.stringify(geojson));
        } else {
            console.error(err);
            process.exit(1);
        }
    }, {
        overpassUrl: argv['overpass-url'],
        flatProperties: argv['flat-properties']
    });
}

((argv._[0] && fs.createReadStream(argv._[0])) || process.stdin).pipe(concat(openData));
<commit_msg>Fix return outside function<commit_after>#!/usr/bin/env node

var concat = require('concat-stream'),
    argv = require('minimist')(process.argv.slice(2), {
        string: 'overpass-url',
        boolean: 'flat-properties',
        boolean: 'version',
        default: {
            'flat-properties': false
        }
    }),
    fs = require('fs'),
    overpass = require('./');

if (argv['version']) {
    process.stdout.write(require('./package.json').version+'\n');
    process.exit(0);
}

function openData(s) {
    var query = s.toString();
    overpass(query, function(err, geojson) {
        if (!err) {
            console.log(JSON.stringify(geojson));
        } else {
            console.error(err);
            process.exit(1);
        }
    }, {
        overpassUrl: argv['overpass-url'],
        flatProperties: argv['flat-properties']
    });
}

((argv._[0] && fs.createReadStream(argv._[0])) || process.stdin).pipe(concat(openData));
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';
var addStream = require('add-stream');
var conventionalChangelog = require('conventional-changelog');
var fs = require('fs');
var meow = require('meow');
var tempfile = require('tempfile');
var _ = require('lodash');
var resolve = require('path').resolve;

var cli = meow({
  help: [
    'Usage',
    '  conventional-changelog',
    '',
    'Example',
    '  conventional-changelog -i CHANGELOG.md --same-file',
    '',
    'Options',
    '  -i, --infile              Read the CHANGELOG from this file',
    '',
    '  -o, --outfile             Write the CHANGELOG to this file.',
    '                            If unspecified, it prints to stdout',
    '',
    '  -s, --same-file           Ouputting to the infile so you don\'t need to specify the same file as outfile',
    '',
    '  -p, --preset              Name of the preset you want to use. Must be one of the following:',
    '                            angular, atom, codemirror, ember, eslint, express, jquery, jscs or jshint',
    '',
    '  -k, --pkg                 A filepath of where your package.json is located',
    '                            Default is the closest package.json from cwd',
    '',
    '  -a, --append              Should the newer release be appended to the older release',
    '                            Default: false',
    '',
    '  -r, --release-count       How many releases to be generated from the latest',
    '                            If 0, the whole changelog will be regenerated and the outfile will be overwritten',
    '                            Default: 1',
    '',
    '  -v, --verbose             Verbose output',
    '                            Default: false',
    '',
    '  -n, --config              A filepath of your config script',
    '                            This value is ignored if preset is specified.',
    '',
    '  -c, --context             A filepath of a json that is used to define template variables'
  ]
}, {
  alias: {
    i: 'infile',
    o: 'outfile',
    s: 'sameFile',
    p: 'preset',
    k: 'pkg',
    a: 'append',
    r: 'releaseCount',
    v: 'verbose',
    n: 'config',
    c: 'context'
  }
});

var flags = cli.flags;
var infile = flags.infile;
var outfile = flags.outfile;
var sameFile = flags.sameFile;
var append = flags.append;
var releaseCount = flags.releaseCount;

if (infile && infile === outfile) {
  sameFile = true;
} else if (sameFile) {
  if (infile) {
    outfile = infile;
  } else {
    console.error('infile must be provided if same-file flag presents.');
    process.exit(1);
  }
}

var options = _.omit({
  preset: flags.preset,
  pkg: {
    path: flags.pkg
  },
  append: append,
  releaseCount: releaseCount
}, _.isUndefined);

if (flags.verbose) {
  options.warn = console.warn.bind(console);
}

var templateContext;

var outStream;

try {
  if (flags.context) {
    templateContext = require(resolve(process.cwd(), flags.context));
  }

  if (flags.config) {
    options.config = require(resolve(process.cwd(), flags.config));
  }
} catch (err) {
  console.error('Failed to get file. ' + err);
  process.exit(1);
}

var changelogStream = conventionalChangelog (options, templateContext)
  .on('error', function (err) {
    if (flags.verbose) {
      console.error(err.stack);
    } else {
      console.error(err.toString());
    }
    process.exit(1);
  });

function noInputFile() {
  if (outfile) {
    outStream = fs.createWriteStream(outfile);
  } else {
    outStream = process.stdout;
  }

  changelogStream
    .pipe(outStream);
}

if (infile && releaseCount !== 0) {
  var readStream = fs.createReadStream(infile)
    .on('error', function () {
      if (flags.verbose) {
        console.warn('infile does not exist.');
      }

      if (sameFile) {
        noInputFile();
      }
    });

  if (sameFile) {
    if (options.append) {
      changelogStream
        .pipe(fs.createWriteStream(outfile, {
          flags: 'a'
        }));
    } else {
      var tmp = tempfile();

      changelogStream
        .pipe(addStream(readStream))
        .pipe(fs.createWriteStream(tmp))
        .on('finish', function () {
          fs.createReadStream(tmp)
            .pipe(fs.createWriteStream(outfile));
        });
    }
  } else {
    if (outfile) {
      outStream = fs.createWriteStream(outfile);
    } else {
      outStream = process.stdout;
    }

    var stream;

    if (options.append) {
      stream = readStream
        .pipe(addStream(changelogStream));
    } else {
      stream = changelogStream
        .pipe(addStream(readStream));
    }

    stream
      .pipe(outStream);
  }
} else {
  noInputFile();
}
<commit_msg>docs(help): remove unneeded dots<commit_after>#!/usr/bin/env node
'use strict';
var addStream = require('add-stream');
var conventionalChangelog = require('conventional-changelog');
var fs = require('fs');
var meow = require('meow');
var tempfile = require('tempfile');
var _ = require('lodash');
var resolve = require('path').resolve;

var cli = meow({
  help: [
    'Usage',
    '  conventional-changelog',
    '',
    'Example',
    '  conventional-changelog -i CHANGELOG.md --same-file',
    '',
    'Options',
    '  -i, --infile              Read the CHANGELOG from this file',
    '',
    '  -o, --outfile             Write the CHANGELOG to this file',
    '                            If unspecified, it prints to stdout',
    '',
    '  -s, --same-file           Ouputting to the infile so you don\'t need to specify the same file as outfile',
    '',
    '  -p, --preset              Name of the preset you want to use. Must be one of the following:',
    '                            angular, atom, codemirror, ember, eslint, express, jquery, jscs or jshint',
    '',
    '  -k, --pkg                 A filepath of where your package.json is located',
    '                            Default is the closest package.json from cwd',
    '',
    '  -a, --append              Should the newer release be appended to the older release',
    '                            Default: false',
    '',
    '  -r, --release-count       How many releases to be generated from the latest',
    '                            If 0, the whole changelog will be regenerated and the outfile will be overwritten',
    '                            Default: 1',
    '',
    '  -v, --verbose             Verbose output',
    '                            Default: false',
    '',
    '  -n, --config              A filepath of your config script',
    '                            This value is ignored if preset is specified',
    '',
    '  -c, --context             A filepath of a json that is used to define template variables'
  ]
}, {
  alias: {
    i: 'infile',
    o: 'outfile',
    s: 'sameFile',
    p: 'preset',
    k: 'pkg',
    a: 'append',
    r: 'releaseCount',
    v: 'verbose',
    n: 'config',
    c: 'context'
  }
});

var flags = cli.flags;
var infile = flags.infile;
var outfile = flags.outfile;
var sameFile = flags.sameFile;
var append = flags.append;
var releaseCount = flags.releaseCount;

if (infile && infile === outfile) {
  sameFile = true;
} else if (sameFile) {
  if (infile) {
    outfile = infile;
  } else {
    console.error('infile must be provided if same-file flag presents.');
    process.exit(1);
  }
}

var options = _.omit({
  preset: flags.preset,
  pkg: {
    path: flags.pkg
  },
  append: append,
  releaseCount: releaseCount
}, _.isUndefined);

if (flags.verbose) {
  options.warn = console.warn.bind(console);
}

var templateContext;

var outStream;

try {
  if (flags.context) {
    templateContext = require(resolve(process.cwd(), flags.context));
  }

  if (flags.config) {
    options.config = require(resolve(process.cwd(), flags.config));
  }
} catch (err) {
  console.error('Failed to get file. ' + err);
  process.exit(1);
}

var changelogStream = conventionalChangelog (options, templateContext)
  .on('error', function (err) {
    if (flags.verbose) {
      console.error(err.stack);
    } else {
      console.error(err.toString());
    }
    process.exit(1);
  });

function noInputFile() {
  if (outfile) {
    outStream = fs.createWriteStream(outfile);
  } else {
    outStream = process.stdout;
  }

  changelogStream
    .pipe(outStream);
}

if (infile && releaseCount !== 0) {
  var readStream = fs.createReadStream(infile)
    .on('error', function () {
      if (flags.verbose) {
        console.warn('infile does not exist.');
      }

      if (sameFile) {
        noInputFile();
      }
    });

  if (sameFile) {
    if (options.append) {
      changelogStream
        .pipe(fs.createWriteStream(outfile, {
          flags: 'a'
        }));
    } else {
      var tmp = tempfile();

      changelogStream
        .pipe(addStream(readStream))
        .pipe(fs.createWriteStream(tmp))
        .on('finish', function () {
          fs.createReadStream(tmp)
            .pipe(fs.createWriteStream(outfile));
        });
    }
  } else {
    if (outfile) {
      outStream = fs.createWriteStream(outfile);
    } else {
      outStream = process.stdout;
    }

    var stream;

    if (options.append) {
      stream = readStream
        .pipe(addStream(changelogStream));
    } else {
      stream = changelogStream
        .pipe(addStream(readStream));
    }

    stream
      .pipe(outStream);
  }
} else {
  noInputFile();
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';
var _ = require('lodash');
var multiline = require('multiline');
var updateNotifier = require('update-notifier');
var stdin = require('get-stdin');
var subarg = require('subarg');
var sudoBlock = require('sudo-block');
var logSymbols = require('log-symbols');
var pkg = require('./package.json');
var Pageres = require('./');

var options = subarg(process.argv.slice(2), {
	boolean: [
		'verbose',
		'crop',
		'help',
		'version'
	],
	default: {
		delay: 0,
		scale: 1
	},
	alias: {
		v: 'verbose',
		c: 'crop',
		d: 'delay'
	}
});

var args = options._;
delete options._;

function showHelp() {
  console.log(multiline(function () {/*

  Capture screenshots of websites in various resolutions.

  Specify urls and screen resolutions as arguments. Order doesn't matter.
  Group arguments with [ ]. Options defined inside a group will override the outer ones.
  Screenshots are saved in the current directory.

  Usage
    pageres <url> <resolution>
    pageres [ <url> <resolution> ] [ <url> <resolution> ]
    pageres [ <url> <resolution> ... ] < <file>
    cat <file> | pageres [ <url> <resolution> ... ]

  Example
    pageres todomvc.com yeoman.io 1366x768 1600x900
    pageres [ yeoman.io 1366x768 1600x900 --no-crop ] [ todomvc.com 1024x768 480x320 ] --crop
    pageres todomvc.com 1024x768 --filename '<%= date %> - <%= url %>'
    pageres yeoman.io 1366x768 --selector '.page-header'
    pageres --delay 3 1366x768 < urls.txt
    pageres unicorn.html 1366x768
    cat screen-resolutions.txt | pageres todomvc.com yeoman.io

  Options
    -v, --verbose            Verbose output
    -c, --crop               Crop to the set height
    -d, --delay <seconds>    Delay screenshot capture
    --filename <template>    Custom filename
    --selector <element>     Capture DOM element
    --hide <element>         Hide DOM element, can be set multiple times
    --cookie <cookie>        Browser cookie, can be set multiple times
    --username <username>    Username for HTTP auth
    --password <password>    Password for HTTP auth
    --scale <number>         Scale webpage

  <url> can also be a local file path.

  You can also pipe in a newline separated list of urls and screen resolutions which will get merged with the arguments.
  */}));
}

function generate(args, options) {
	var pageres = new Pageres()
		.dest(process.cwd());

	args.forEach(function (arg) {
		pageres.src(arg.url, arg.sizes, arg.options);
	});

	if (options.verbose) {
		pageres.on('warn', console.error.bind(console));
	}

	pageres.run(function (err) {
		if (err) {
			if (err.noStack) {
				console.error(err.message);
				process.exit(1);
			} else {
				throw err;
			}
		}

		pageres.successMessage();
	});
}

function get(args) {
	var ret = [];

	args.forEach(function (arg, i) {
		if (!arg.url.length) {
			console.error(logSymbols.warning, 'Specify a url');
			process.exit(1);
		}

		if (!arg.sizes.length && !arg.keywords.length) {
			console.error(logSymbols.warning, 'Specify a size');
			process.exit(1);
		}

		if (arg.keywords.length) {
			arg.sizes = arg.sizes.concat(arg.keywords);
		}

		arg.url.forEach(function (el) {
			ret.push({
				url: el,
				sizes: arg.sizes,
				options: arg.options
			});
		});
	});

	return ret;
}

function parse(args, globalOptions) {
	return args.map(function (arg) {
		var options = _.defaults(arg, globalOptions);
		arg = arg._;
		delete options._;

		if (options.cookie) {
			options.cookie = Array.isArray(options.cookie) ? options.cookie : [options.cookie];
		}

		// plural makes more sense for a programmatic option
		options.cookies = options.cookie;
		delete options.cookie;

		if (options.hide) {
			options.hide = Array.isArray(options.hide) ? options.hide : [options.hide];
		}

		var url = _.uniq(arg.filter(/./.test, /\.|localhost/));
		var sizes = _.uniq(arg.filter(/./.test, /^\d{3,4}x\d{3,4}$/i));
		var keywords = _.difference(arg, url.concat(sizes));

		return {
			url: url,
			sizes: sizes,
			keywords: keywords,
			options: options
		};
	});
}

function init(args, options) {
	if (options.version) {
		console.log(pkg.version);
		return;
	}

	if (options.help || !args.length) {
		showHelp();
		return;
	}

	var nonGroupedArgs = args.filter(function (arg) {
		return !arg._;
	});

	// filter grouped args
	args = args.filter(function (arg) {
		return arg._;
	});

	if (nonGroupedArgs.length) {
		args.push({_: nonGroupedArgs});
	}

	var parsedArgs = parse(args, options);
	var items = get(parsedArgs);

	generate(items, options);
}

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

if (process.stdin.isTTY) {
	init(args, options);
} else {
	stdin(function (data) {
		[].push.apply(args, data.trim().split('\n'));
		init(args, options);
	});
}
<commit_msg>minor tweaks<commit_after>#!/usr/bin/env node
'use strict';
var multiline = require('multiline');
var updateNotifier = require('update-notifier');
var stdin = require('get-stdin');
var subarg = require('subarg');
var sudoBlock = require('sudo-block');
var logSymbols = require('log-symbols');
var arrayUniq = require('array-uniq');
var arrayDiffer = require('array-differ');
var objectAssign = require('object-assign');
var pkg = require('./package.json');
var Pageres = require('./');

var options = subarg(process.argv.slice(2), {
	boolean: [
		'verbose',
		'crop',
		'help',
		'version'
	],
	default: {
		delay: 0,
		scale: 1
	},
	alias: {
		v: 'verbose',
		c: 'crop',
		d: 'delay'
	}
});

var args = options._;
delete options._;

function showHelp() {
  console.log(multiline(function () {/*

  Capture screenshots of websites in various resolutions.

  Specify urls and screen resolutions as arguments. Order doesn't matter.
  Group arguments with [ ]. Options defined inside a group will override the outer ones.
  Screenshots are saved in the current directory.

  Usage
    pageres <url> <resolution>
    pageres [ <url> <resolution> ] [ <url> <resolution> ]
    pageres [ <url> <resolution> ... ] < <file>
    cat <file> | pageres [ <url> <resolution> ... ]

  Example
    pageres todomvc.com yeoman.io 1366x768 1600x900
    pageres [ yeoman.io 1366x768 1600x900 --no-crop ] [ todomvc.com 1024x768 480x320 ] --crop
    pageres todomvc.com 1024x768 --filename '<%= date %> - <%= url %>'
    pageres yeoman.io 1366x768 --selector '.page-header'
    pageres --delay 3 1366x768 < urls.txt
    pageres unicorn.html 1366x768
    cat screen-resolutions.txt | pageres todomvc.com yeoman.io

  Options
    -v, --verbose            Verbose output
    -c, --crop               Crop to the set height
    -d, --delay <seconds>    Delay screenshot capture
    --filename <template>    Custom filename
    --selector <element>     Capture DOM element
    --hide <element>         Hide DOM element, can be set multiple times
    --cookie <cookie>        Browser cookie, can be set multiple times
    --username <username>    Username for HTTP auth
    --password <password>    Password for HTTP auth
    --scale <number>         Scale webpage

  <url> can also be a local file path.

  You can also pipe in a newline separated list of urls and screen resolutions which will get merged with the arguments.
  */}));
}

function generate(args, options) {
	var pageres = new Pageres()
		.dest(process.cwd());

	args.forEach(function (arg) {
		pageres.src(arg.url, arg.sizes, arg.options);
	});

	if (options.verbose) {
		pageres.on('warn', console.error.bind(console));
	}

	pageres.run(function (err) {
		if (err) {
			if (err.noStack) {
				console.error(err.message);
				process.exit(1);
			} else {
				throw err;
			}
		}

		pageres.successMessage();
	});
}

function get(args) {
	var ret = [];

	args.forEach(function (arg, i) {
		if (!arg.url.length) {
			console.error(logSymbols.warning, 'Specify a url');
			process.exit(1);
		}

		if (!arg.sizes.length && !arg.keywords.length) {
			console.error(logSymbols.warning, 'Specify a size');
			process.exit(1);
		}

		if (arg.keywords.length) {
			arg.sizes = arg.sizes.concat(arg.keywords);
		}

		arg.url.forEach(function (el) {
			ret.push({
				url: el,
				sizes: arg.sizes,
				options: arg.options
			});
		});
	});

	return ret;
}

function parse(args, globalOptions) {
	return args.map(function (arg) {
		var options = objectAssign({}, globalOptions, arg);
		arg = arg._;
		delete options._;

		if (options.cookie) {
			options.cookie = Array.isArray(options.cookie) ? options.cookie : [options.cookie];
		}

		// plural makes more sense for a programmatic option
		options.cookies = options.cookie;
		delete options.cookie;

		if (options.hide) {
			options.hide = Array.isArray(options.hide) ? options.hide : [options.hide];
		}

		var url = arrayUniq(arg.filter(/./.test, /\.|localhost/));
		var sizes = arrayUniq(arg.filter(/./.test, /^\d{3,4}x\d{3,4}$/i));
		var keywords = arrayDiffer(arg, url.concat(sizes));

		return {
			url: url,
			sizes: sizes,
			keywords: keywords,
			options: options
		};
	});
}

function init(args, options) {
	if (options.version) {
		console.log(pkg.version);
		return;
	}

	if (options.help || !args.length) {
		showHelp();
		return;
	}

	var nonGroupedArgs = args.filter(function (arg) {
		return !arg._;
	});

	// filter grouped args
	args = args.filter(function (arg) {
		return arg._;
	});

	if (nonGroupedArgs.length) {
		args.push({_: nonGroupedArgs});
	}

	var parsedArgs = parse(args, options);
	var items = get(parsedArgs);

	generate(items, options);
}

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

if (process.stdin.isTTY) {
	init(args, options);
} else {
	stdin(function (data) {
		[].push.apply(args, data.trim().split('\n'));
		init(args, options);
	});
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
var args = require('minimist')(process.argv.splice(2), {
  alias: {p: 'port', q: 'quiet', v: 'version'},
  boolean: ['color'],
  default: {color: true}
})

process.title = 'dat'

// set debug before requiring other modules
if (args.debug) {
  var debug = args.debug
  if (typeof args.debug === 'boolean') debug = '*' // default
  process.env.DEBUG = debug
}

if (args.version) {
  var pkg = require(__dirname + '/package.json')
  console.log(pkg.version)
  process.exit(0)
}

var fs = require('fs')
var singleLineLog = require('single-line-log')
var prettyBytes = require('pretty-bytes')
var chalk = require('chalk')
var dat = require('./index.js')
var usage = require('./usage')

function noop () {}

var cmd = args._[0]
var logger = getLogger()

var LOG_INTERVAL = (args.logspeed ? +args.logspeed : 200)
if (isNaN(LOG_INTERVAL)) LOG_INTERVAL = 200
if (!args.color) chalk = new chalk.constructor({enabled: false})

checkLocation()

function checkLocation () {
  var loc = process.cwd()
  if (!args.path) return runCommand(loc)
  loc = args.path
  fs.exists(loc, function (exists) {
    if (!exists) {
      logger.error('Does not exist:', loc)
      return usage('root.txt')
    }
    runCommand(loc)
  })
}

function runCommand (loc) {
  if (!cmd) return usage('root.txt')

  var db = dat({home: args.home})

  if (cmd === 'link') link(loc, db)
  else if (cmd === 'list') list(loc, db)
  else if (cmd) download(loc, db)
}

function link (loc, db) {
  var dirs = args._.slice(1)
  if (dirs.length === 0) dirs = loc

  var stats = {}

  stats.total = db.fileStats(dirs, function (err) {
    if (err) throw err
    printScanProgress(stats, {done: true})
    clearInterval(scanInterval)
    var statsProgress = db.addFiles(dirs, function (err, link) {
      printAddProgress(stats, {done: true})
      clearInterval(addInterval)
      if (err) throw err
      db.joinTcpSwarm({link: link, port: args.port}, function (_err, swarm) {
        // ignore _err
        startProgressLogging({swarm: swarm})
      })
    })
    stats.progress = statsProgress.progress
    stats.fileQueue = statsProgress.fileQueue

    var addInterval = setInterval(function () {
      printAddProgress(stats)
    }, LOG_INTERVAL)
  })

  var scanInterval = setInterval(function () {
    printScanProgress(stats)
  }, LOG_INTERVAL)
}

function list (loc, db) {
  var hash = args._[1]
  db.joinTcpSwarm({link: hash, port: args.port}, function (err, swarm) {
    if (err) throw err
    var archive = db.drive.get(swarm.link, loc)
    archive.ready(function (err) {
      if (err) throw err
      archive.createEntryStream().on('data', function (o) {
        logger.log(o)
      })
    })
  })
}

function download (loc, db) {
  // download/share
  var hash = args._[0]
  if (!hash) return usage('root.txt')
  hash = hash.trim().replace('dat://', '').replace('dat:', '')
  if (hash.length !== 64) {
    logger.error('Error: Invalid dat link\n')
    return usage('root.txt')
  }
  var downloadStats = db.download(hash, loc, function (err, swarm) {
    if (err) throw err
    swarm.downloading = false
    swarm.downloadComplete = true
  })
  startProgressLogging(downloadStats)
}

function startProgressLogging (stats) {
  setInterval(function () {
    printSwarmStatus(stats)
  }, LOG_INTERVAL)
  printSwarmStatus(stats)
}

function printScanProgress (stats, opts) {
  if (!opts) opts = {}
  var statusText = chalk.bold.blue('Calculating Size')
  if (opts.done) statusText = chalk.bold.green('Creating Dat Link')
  var msg = getScanOutput(stats, statusText)
  logger.stdout(msg)
  if (opts.done) logger.log('')
}

function printAddProgress (stats, opts) {
  if (!opts) opts = {}
  if (opts.done) {
    var msg = printFileProgress(stats, {
      returnMsg: true, message: 'Files Read to Dat'
    })
    logger.stdout(msg)
    logger.log('')
  } else {
    printFileProgress(stats, {message: 'Adding Files to Dat'})
  }
}

function printSwarmStatus (stats) {
  var swarm = stats.swarm
  if (!swarm) return logger.stdout('Finding data sources...\n')

  if (swarm.hasMetadata && swarm.gettingMetadata) {
    // Print final metadata output
    var scanMsg = ''
    swarm.gettingMetadata = false
    scanMsg = getScanOutput(stats, chalk.bold.green('Downloading Data'))
    logger.stdout(scanMsg)
    logger.log('')
  }

  var msg = swarm.downloading ? downloadMsg() : ''
  if (swarm.downloadComplete) msg = downloadCompleteMsg()

  var count = '0'
  var activePeers = swarm.connections.length
  var totalPeers = swarm.connecting + swarm.connections.length
  if (activePeers > 0) count = activePeers + '/' + totalPeers
  msg += chalk.bold('[Status] ') + 'Connected to ' + chalk.bold(count) + ' sources\n'

  if (!swarm.downloading) msg += chalk.bold('[Sharing] ')
  else if (swarm.downloading) msg += chalk.bold('[Downloading] ')
  msg += chalk.underline.blue('dat://' + swarm.link)

  logger.stdout(msg)

  function downloadMsg () {
    if (!stats.total.bytesTotal) return chalk.bold('Connecting...\n')
    if (swarm.gettingMetadata && !swarm.hasMetadata) {
      return getScanOutput(stats, chalk.bold.blue('Getting Metadata')) + '\n'
    }
    return printFileProgress(stats, {
      returnMsg: true, message: 'Downloading Data'
    })
  }

  function downloadCompleteMsg () {
    var outMsg = printFileProgress(stats, {
      returnMsg: true, showFilesOnly: true
    })
    outMsg += chalk.green.bold('[Done] ')
    outMsg += chalk.magenta(
      'Downloaded ' + prettyBytes(stats.progress.bytesRead) + ' '
    )
    if (stats.parentFolder) outMsg += chalk.magenta('to ') + chalk.magenta.bold(stats.parentFolder)
    outMsg += '\n'
    return outMsg
  }
}

function getScanOutput (stats, statusMsg) {
  if (!statusMsg) statusMsg = chalk.bold.green('Scan Progress')
  var dirCount = stats.total.directories + 1 // parent folder
  return statusMsg + ' ' + chalk.bold(
    '(' + stats.total.filesTotal + ' files, ' + dirCount + ' folders, ' +
    (stats.total.bytesTotal ? prettyBytes(stats.total.bytesTotal) + ' total' : '') + ')'
  )
}

function printFileProgress (stats, opts) {
  if (!opts) opts = {}
  var totalMsg = opts.message || 'File Progress'
  var indent = '  ' // indent for single file info
  var msg = ''

  while (true) {
    if (stats.fileQueue.length === 0) break
    var file = stats.fileQueue[0]
    msg = getSingleFileOutput(file)
    var complete = (file.stats.bytesTotal === file.stats.bytesRead)
    if (!complete && stats.fileQueue.length === 1) break
    if (stats.fileQueue.length === 1 && !queueDone) msg = getSingleFileOutput(file)
    logger.stdout(chalk.green.dim(indent + '[Done] ') + chalk.dim(file.name))
    logger.log('')
    stats.fileQueue.shift()
  }

  var queueDone = (stats.total.bytesTotal <= stats.progress.bytesRead)
  if (queueDone) msg = ''
  else msg += '\n'

  if (opts.showFilesOnly && opts.returnMsg) return msg

  msg += getTotalProgressOutput(stats, totalMsg)
  if (opts.returnMsg) return msg
  else logger.stdout(msg)
}

function getSingleFileOutput (file) {
  var fileMsg = ''
  var indent = '  ' // indent for single file info
  var filePercent = 0
  if (file.stats.bytesTotal > 0) {
    filePercent = Math.floor(
      100 * (file.stats.bytesRead / file.stats.bytesTotal)
    )
  }
  if (filePercent > 0 && filePercent < 100) {
    fileMsg = chalk.bold.gray(indent + '[' + ('   ' + filePercent).slice(-3) + '%] ')
  } else {
    fileMsg = chalk.bold.gray(indent + '       ') // # spaces = '[100%] '
  }
  fileMsg += chalk.blue(file.name)
  return fileMsg
}

function getTotalProgressOutput (stats, statusText, msg) {
  if (!stats) return ''
  if (!msg) msg = ''

  var bytesProgress = stats.progress.bytesRead
  var fileProgress = stats.progress.filesRead
  var totalPer = Math.floor(100 * (bytesProgress / stats.total.bytesTotal))

  if (totalPer === 100) msg += chalk.bold.green('[Done] ')
  else if (totalPer >= 0) msg += chalk.bold.red('[' + ('  ' + totalPer).slice(-3) + '%] ')
  else msg += '        '
  msg += chalk.magenta(
    statusText + ': ' + fileProgress + ' of ' + stats.total.filesTotal +
    chalk.dim(
      ' (' + prettyBytes(bytesProgress) +
      ' of ' + prettyBytes(stats.total.bytesTotal) + ') '
    )
  )
  if (stats.downloadRate) msg += chalk.red(prettyBytes(stats.downloadRate()) + '/s ')
  msg += '\n'
  return msg
}

function getLogger () {
  if (args.quiet) {
    return {
      stderr: noop,
      stdout: noop,
      log: noop,
      error: noop
    }
  }

  if (args.debug) {
    return {
      stderr: console.error.bind(console),
      stdout: console.log.bind(console),
      log: console.error.bind(console),
      error: console.log.bind(console)
    }
  }

  return {
    stderr: singleLineLog.stderr,
    stdout: singleLineLog.stdout,
    log: console.log.bind(console),
    error: console.error.bind(console)
  }
}
<commit_msg>make the progress look a little bit more like airtar<commit_after>#!/usr/bin/env node
var args = require('minimist')(process.argv.splice(2), {
  alias: {p: 'port', q: 'quiet', v: 'version'},
  boolean: ['color'],
  default: {color: true}
})

process.title = 'dat'

// set debug before requiring other modules
if (args.debug) {
  var debug = args.debug
  if (typeof args.debug === 'boolean') debug = '*' // default
  process.env.DEBUG = debug
}

if (args.version) {
  var pkg = require(__dirname + '/package.json')
  console.log(pkg.version)
  process.exit(0)
}

var fs = require('fs')
var singleLineLog = require('single-line-log')
var prettyBytes = require('pretty-bytes')
var chalk = require('chalk')
var dat = require('./index.js')
var usage = require('./usage')

function noop () {}

var cmd = args._[0]
var logger = getLogger()

var LOG_INTERVAL = (args.logspeed ? +args.logspeed : 200)
if (isNaN(LOG_INTERVAL)) LOG_INTERVAL = 200
if (!args.color) chalk = new chalk.constructor({enabled: false})

checkLocation()

function checkLocation () {
  var loc = process.cwd()
  if (!args.path) return runCommand(loc)
  loc = args.path
  fs.exists(loc, function (exists) {
    if (!exists) {
      logger.error('Does not exist:', loc)
      return usage('root.txt')
    }
    runCommand(loc)
  })
}

function runCommand (loc) {
  if (!cmd) return usage('root.txt')

  var db = dat({home: args.home})

  if (cmd === 'link') link(loc, db)
  else if (cmd === 'list') list(loc, db)
  else if (cmd) download(loc, db)
}

function link (loc, db) {
  var dirs = args._.slice(1)
  if (dirs.length === 0) dirs = loc

  var stats = {}

  stats.total = db.fileStats(dirs, function (err) {
    if (err) throw err
    printScanProgress(stats, {done: true})
    clearInterval(scanInterval)
    var statsProgress = db.addFiles(dirs, function (err, link) {
      printAddProgress(stats, {done: true})
      clearInterval(addInterval)
      if (err) throw err
      db.joinTcpSwarm({link: link, port: args.port}, function (_err, swarm) {
        // ignore _err
        startProgressLogging({swarm: swarm})
      })
    })
    stats.progress = statsProgress.progress
    stats.fileQueue = statsProgress.fileQueue

    var addInterval = setInterval(function () {
      printAddProgress(stats)
    }, LOG_INTERVAL)
  })

  var scanInterval = setInterval(function () {
    printScanProgress(stats)
  }, LOG_INTERVAL)
}

function list (loc, db) {
  var hash = args._[1]
  db.joinTcpSwarm({link: hash, port: args.port}, function (err, swarm) {
    if (err) throw err
    var archive = db.drive.get(swarm.link, loc)
    archive.ready(function (err) {
      if (err) throw err
      archive.createEntryStream().on('data', function (o) {
        logger.log(o)
      })
    })
  })
}

function download (loc, db) {
  // download/share
  var hash = args._[0]
  if (!hash) return usage('root.txt')
  hash = hash.trim().replace('dat://', '').replace('dat:', '')
  if (hash.length !== 64) {
    logger.error('Error: Invalid dat link\n')
    return usage('root.txt')
  }
  var downloadStats = db.download(hash, loc, function (err, swarm) {
    if (err) throw err
    swarm.downloading = false
    swarm.downloadComplete = true
  })
  startProgressLogging(downloadStats)
}

function startProgressLogging (stats) {
  setInterval(function () {
    printSwarmStatus(stats)
  }, LOG_INTERVAL)
  printSwarmStatus(stats)
}

function printScanProgress (stats, opts) {
  if (!opts) opts = {}
  var statusText = chalk.bold.blue('Calculating Size')
  if (opts.done) statusText = chalk.bold.dim('Creating Dat Link')
  var msg = getScanOutput(stats, statusText)
  logger.stdout(msg)
  if (opts.done) logger.log('')
}

function printAddProgress (stats, opts) {
  if (!opts) opts = {}
  if (opts.done) {
    var msg = printFileProgress(stats, {
      returnMsg: true, message: 'Files Read to Dat'
    })
    logger.stdout(msg)
    logger.log('')
  } else {
    printFileProgress(stats, {message: 'Adding Files to Dat'})
  }
}

function printSwarmStatus (stats) {
  var swarm = stats.swarm
  if (!swarm) return logger.stdout('Finding data sources...\n')

  if (swarm.hasMetadata && swarm.gettingMetadata) {
    // Print final metadata output
    var scanMsg = ''
    swarm.gettingMetadata = false
    scanMsg = getScanOutput(stats, chalk.bold.green('Downloading Data'))
    logger.stdout(scanMsg)
    logger.log('')
  }

  var msg = swarm.downloading ? downloadMsg() : ''
  if (swarm.downloadComplete) msg = downloadCompleteMsg()

  var count = '0'
  var activePeers = swarm.connections.length
  var totalPeers = swarm.connecting + swarm.connections.length
  if (activePeers > 0) count = activePeers + '/' + totalPeers
  msg += chalk.bold('[Status] ') + 'Connected to ' + chalk.bold(count) + ' sources\n'

  if (!swarm.downloading) msg += chalk.bold('[Sharing] ')
  else if (swarm.downloading) msg += chalk.bold('[Downloading] ')
  msg += chalk.underline.blue('dat://' + swarm.link)

  logger.stdout(msg)

  function downloadMsg () {
    if (!stats.total.bytesTotal) return chalk.bold('Connecting...\n')
    if (swarm.gettingMetadata && !swarm.hasMetadata) {
      return getScanOutput(stats, chalk.bold.blue('Getting Metadata')) + '\n'
    }
    return printFileProgress(stats, {
      returnMsg: true, message: 'Downloading Data'
    })
  }

  function downloadCompleteMsg () {
    var outMsg = printFileProgress(stats, {
      returnMsg: true, showFilesOnly: true
    })
    outMsg += chalk.green.bold('[Done] ')
    outMsg += chalk.magenta(
      'Downloaded ' + prettyBytes(stats.progress.bytesRead) + ' '
    )
    if (stats.parentFolder) outMsg += chalk.magenta('to ') + chalk.magenta.bold(stats.parentFolder)
    outMsg += '\n'
    return outMsg
  }
}

function getScanOutput (stats, statusMsg) {
  if (!statusMsg) statusMsg = chalk.bold.green('Scan Progress')
  var dirCount = stats.total.directories + 1 // parent folder
  return statusMsg + ' ' + chalk.bold(
    '(' + stats.total.filesTotal + ' files, ' + dirCount + ' folders, ' +
    (stats.total.bytesTotal ? prettyBytes(stats.total.bytesTotal) + ' total' : '') + ')'
  )
}

function printFileProgress (stats, opts) {
  if (!opts) opts = {}
  var totalMsg = opts.message || 'File Progress'
  var msg = ''

  while (true) {
    if (stats.fileQueue.length === 0) break
    var file = stats.fileQueue[0]
    msg = getSingleFileOutput(file)
    var complete = (file.stats.bytesTotal === file.stats.bytesRead)
    if (!complete && stats.fileQueue.length === 1) break
    if (stats.fileQueue.length === 1 && !queueDone) msg = getSingleFileOutput(file)
    logger.stdout(chalk.green.dim('[Done] ') + chalk.dim(file.name))
    logger.log('')
    stats.fileQueue.shift()
  }

  var queueDone = (stats.total.bytesTotal <= stats.progress.bytesRead)
  if (queueDone) msg = ''
  else msg += '\n'

  if (opts.showFilesOnly && opts.returnMsg) return msg

  msg += getTotalProgressOutput(stats, totalMsg)
  if (opts.returnMsg) return msg
  else logger.stdout(msg)
}

function getSingleFileOutput (file) {
  var fileMsg = ''
  var indent = '  ' // indent for single file info
  var filePercent = 0
  if (file.stats.bytesTotal > 0) {
    filePercent = Math.floor(
      100 * (file.stats.bytesRead / file.stats.bytesTotal)
    )
  }
  if (filePercent > 0 && filePercent < 100) {
    fileMsg = chalk.bold.gray(indent + '[' + ('   ' + filePercent).slice(-3) + '%] ')
  } else {
    fileMsg = chalk.bold.gray(indent + '       ') // # spaces = '[100%] '
  }
  fileMsg += chalk.blue(file.name)
  return fileMsg
}

function getTotalProgressOutput (stats, statusText, msg) {
  if (!stats) return ''
  if (!msg) msg = ''

  var bytesProgress = stats.progress.bytesRead
  var fileProgress = stats.progress.filesRead
  var totalPer = Math.floor(100 * (bytesProgress / stats.total.bytesTotal))

  if (totalPer === 100) msg += chalk.bold.green('[Done] ')
  else if (totalPer >= 0) msg += chalk.bold.red('[' + ('  ' + totalPer).slice(-3) + '%] ')
  else msg += '        '
  msg += chalk.dim(
    statusText + ': ' + fileProgress + ' of ' + stats.total.filesTotal +
    chalk.dim(
      ' (' + prettyBytes(bytesProgress) +
      ' of ' + prettyBytes(stats.total.bytesTotal) + ') '
    )
  )
  if (stats.downloadRate) msg += chalk.red(prettyBytes(stats.downloadRate()) + '/s ')
  msg += '\n'
  return msg
}

function getLogger () {
  if (args.quiet) {
    return {
      stderr: noop,
      stdout: noop,
      log: noop,
      error: noop
    }
  }

  if (args.debug) {
    return {
      stderr: console.error.bind(console),
      stdout: console.log.bind(console),
      log: console.error.bind(console),
      error: console.log.bind(console)
    }
  }

  return {
    stderr: singleLineLog.stderr,
    stdout: singleLineLog.stdout,
    log: console.log.bind(console),
    error: console.error.bind(console)
  }
}
<|endoftext|>


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

const yargs = require('yargs');
const inquirer = require('inquirer');
const fs = require('fs');
const ora = require('ora');
const chalk = require('chalk');
const config = require('./config');
const path = require('path');
const Table = require('cli-table');
const template = require('./template');
const languages = require('./languages');

const { LANG_ERR, QUES_ERR, TASK_COMPL } = require('./constants');

/**
 * Returns full path of file
 */
const getPath = (folderPath, name) => path.resolve(folderPath, name);

/**
 * Generates boiler plate
 */
const generate = (folderPath, ques, lang) => {
  const files = [`${ques}.${languages[lang]}`, 'input.txt', 'output.txt'];
  const data = [template[lang] === undefined ? '' : template[lang], '', ''];
  fs.mkdirSync(folderPath);
  for (let i = 0; i < files.length; i += 1) {
    fs.writeFileSync(getPath(folderPath, files[i]), data[i], 'utf8');
  }
};

const argv = yargs
  .usage('sudo hbg <command>')
  .command('gen', 'Generate boilerplate', (yargs) => {
    const argv = yargs
      .usage('Usage: hbg gen <options>')
      .alias('l', 'lang')
        .describe('l', 'Language. Change `config` for default')
      .alias('q', 'ques')
        .describe('q', 'Number of questions. Change `config` for default')
      .example('$ sudo hbg gen -l cpp -q 4')
      .argv;
    const spinner = ora('Generating Boilerplate').start();

    let lang = (argv.l === undefined ? config.default_lang : argv.l);
    if (lang !== undefined) {
      lang = lang.toLowerCase();
    }

    const ques = (argv.ques ? argv.ques : config.default_ques);
    if (languages[lang] && ques !== undefined) {
      for (let i = 1; i <= ques; i += 1) {
        const folderPath = getPath(process.cwd(), i.toString());
        generate(folderPath, i, lang);
      }
      spinner.stop();
      console.log(chalk.green(TASK_COMPL));
    } else {
      spinner.stop();
      if (!languages[lang]) {
        console.log(chalk.red(LANG_ERR));
      } else {
        console.log(chalk.red(QUES_ERR));
      }
    }
  })
  .command('add', 'Add default template', (yargs) => {
    const argv = yargs
      .usage('Usage: hbg add <options>')
      .demand(['t', 'l'])
      .alias('t', 'template')
        .describe('t', 'Path to the template file')
      .alias('l', 'lang')
        .describe('l', 'Language chosen')
      .example('$ sudo hbg add -t test/template.cpp -l cpp')
      .argv;
    const spinner = ora('Adding template').start();
    const lang = (argv.l ? argv.l : config.lang).toLowerCase();
    if (languages[lang]) {
      const obj = template;
      const data = fs.readFileSync(getPath(process.cwd(), argv.t), 'utf8');
      obj[lang] = data;
      fs.writeFileSync(getPath(__dirname, 'template.json'), JSON.stringify(obj, null, 2), 'utf8');
      spinner.stop();
      console.log(chalk.green(TASK_COMPL));
    } else {
      spinner.stop();
      console.log(chalk.red(LANG_ERR));
    }
  })
  .command('config', 'Change config file', (yargs) => {
    const argv = yargs
      .usage('Usage: sudo hbg config')
      .alias('l', 'list').describe('l', 'List language and their extension').boolean('l')
      .example('$ sudo hbg config -l')
      .argv;

    if (argv.list) {
      const spinner = ora('Getting languages').start();
      let table = new Table({
        head: ['Language', 'File Extension'],
        colWidths: [20, 20],
      });
      for (let name in languages) {
        table.push([chalk.cyan(name), chalk.green(languages[name])]);
      }
      spinner.stop();
      console.log(table.toString());
    } else {
      const questions = [{
        type: 'input',
        name: 'default_lang',
        message: 'Enter default language code <Leave blank in case unchanged>',
      }, {
        type: 'input',
        name: 'default_ques',
        message: 'Enter default number of questions <Leave blank in case unchanged>',
      }];
      inquirer.prompt(questions).then((answers) => {
        const spinner = ora('Saving').start();
        let obj = config;
        if (answers.default_lang !== '') {
          obj.default_lang = answers.default_lang;
        }
        if (answers.default_ques !== '') {
          obj.default_ques = answers.default_ques;
        }
        fs.writeFileSync(getPath(__dirname, 'config.json'), JSON.stringify(obj, null, 2), 'utf8');
        spinner.stop();
        console.log(chalk.green(TASK_COMPL));
      });
    }
  })
  .help('h')
  .alias('h', 'help')
  .argv;
<commit_msg>CLI: Fix listing issues<commit_after>#!/usr/bin/env node

const yargs = require('yargs');
const inquirer = require('inquirer');
const fs = require('fs');
const ora = require('ora');
const chalk = require('chalk');
const config = require('./config');
const path = require('path');
const Table = require('cli-table');
const template = require('./template');
const languages = require('./languages');

const { LANG_ERR, QUES_ERR, TASK_COMPL } = require('./constants');

/**
 * Returns full path of file
 */
const getPath = (folderPath, name) => path.resolve(folderPath, name);

/**
 * Generates boiler plate
 */
const generate = (folderPath, ques, lang) => {
  const files = [`${ques}.${languages[lang]}`, 'input.txt', 'output.txt'];
  const data = [template[lang] === undefined ? '' : template[lang], '', ''];
  fs.mkdirSync(folderPath);
  for (let i = 0; i < files.length; i += 1) {
    fs.writeFileSync(getPath(folderPath, files[i]), data[i], 'utf8');
  }
};

/* eslint-disable no-unused-vars, no-console, no-shadow */

const argv = yargs
  .usage('sudo hbg <command>')
  .command('gen', 'Generate boilerplate', (yargs) => {
    const argv = yargs
      .usage('Usage: hbg gen <options>')
      .alias('l', 'lang')
        .describe('l', 'Language. Change `config` for default')
      .alias('q', 'ques')
        .describe('q', 'Number of questions. Change `config` for default')
      .example('$ sudo hbg gen -l cpp -q 4')
      .argv;
    const spinner = ora('Generating Boilerplate').start();

    let lang = (argv.l === undefined ? config.default_lang : argv.l);
    if (lang !== undefined) {
      lang = lang.toLowerCase();
    }

    const ques = (argv.ques ? argv.ques : config.default_ques);
    if (languages[lang] && ques !== undefined) {
      for (let i = 1; i <= ques; i += 1) {
        const folderPath = getPath(process.cwd(), i.toString());
        generate(folderPath, i, lang);
      }
      spinner.stop();
      console.log(chalk.green(TASK_COMPL));
    } else {
      spinner.stop();
      if (!languages[lang]) {
        console.log(chalk.red(LANG_ERR));
      } else {
        console.log(chalk.red(QUES_ERR));
      }
    }
  })
  .command('add', 'Add default template', (yargs) => {
    const argv = yargs
      .usage('Usage: hbg add <options>')
      .demand(['t', 'l'])
      .alias('t', 'template')
        .describe('t', 'Path to the template file')
      .alias('l', 'lang')
        .describe('l', 'Language chosen')
      .example('$ sudo hbg add -t test/template.cpp -l cpp')
      .argv;
    const spinner = ora('Adding template').start();
    const lang = (argv.l ? argv.l : config.lang).toLowerCase();
    if (languages[lang]) {
      const obj = template;
      const data = fs.readFileSync(getPath(process.cwd(), argv.t), 'utf8');
      obj[lang] = data;
      fs.writeFileSync(getPath(__dirname, 'template.json'), JSON.stringify(obj, null, 2), 'utf8');
      spinner.stop();
      console.log(chalk.green(TASK_COMPL));
    } else {
      spinner.stop();
      console.log(chalk.red(LANG_ERR));
    }
  })
  .command('config', 'Change config file', (yargs) => {
    const argv = yargs
      .usage('Usage: sudo hbg config')
      .alias('l', 'list').describe('l', 'List language and their extension').boolean('l')
      .example('$ sudo hbg config -l')
      .argv;

    if (argv.list) {
      const spinner = ora('Getting languages').start();
      const table = new Table({
        head: ['Language', 'File Extension'],
        colWidths: [20, 20],
      });

      for (const name in languages) {
        table.push([chalk.cyan(name), chalk.green(languages[name])]);
      }

      spinner.stop();
      console.log(table.toString());
    } else {
      const questions = [{
        type: 'input',
        name: 'default_lang',
        message: 'Enter default language code <Leave blank in case unchanged>',
      }, {
        type: 'input',
        name: 'default_ques',
        message: 'Enter default number of questions <Leave blank in case unchanged>',
      }];
      inquirer.prompt(questions).then((answers) => {
        const spinner = ora('Saving').start();
        const obj = config;

        if (answers.default_lang !== '') {
          obj.default_lang = answers.default_lang;
        }
        if (answers.default_ques !== '') {
          obj.default_ques = answers.default_ques;
        }
        fs.writeFileSync(getPath(__dirname, 'config.json'), JSON.stringify(obj, null, 2), 'utf8');
        spinner.stop();
        console.log(chalk.green(TASK_COMPL));
      });
    }
  })
  .help('h')
  .alias('h', 'help')
  .argv;

/* eslint-enable no-unused-vars, no-console */
<|endoftext|>


<commit_before>function Id(a) {
    this.value = a;
}

// Semigroup (value must also be a Semigroup)
Id.prototype.concat = function(b) {
    return new Id(this.value.concat(b.value));
};

// Monoid (value must also be a Monoid)
Id.prototype.zero = function() {
    return new Id(this.value.zero ? this.value.zero() : this.value.constructor.zero());
};

// Functor
Id.prototype.map = function(f) {
    return new Id(f(this.value));
};

// Applicative
Id.prototype.ap = function(b) {
    return new Id(this.value(b.value));
};

// Chain
Id.prototype.chain = function(f) {
    return f(this.value);
};

// Monad
Id.of = function(a) {
    return new Id(a);
};
<commit_msg>Change Id zero to empty<commit_after>function Id(a) {
    this.value = a;
}

// Semigroup (value must also be a Semigroup)
Id.prototype.concat = function(b) {
    return new Id(this.value.concat(b.value));
};

// Monoid (value must also be a Monoid)
Id.prototype.empty = function() {
    return new Id(this.value.empty ? this.value.empty() : this.value.constructor.empty());
};

// Functor
Id.prototype.map = function(f) {
    return new Id(f(this.value));
};

// Applicative
Id.prototype.ap = function(b) {
    return new Id(this.value(b.value));
};

// Chain
Id.prototype.chain = function(f) {
    return f(this.value);
};

// Monad
Id.of = function(a) {
    return new Id(a);
};
<|endoftext|>


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

const fs = require('fs')
const path = require('path')
const yargs = require('yargs')
const retyped = require('./retyped_node')

yargs
  .usage('retyped')
  .version(require('./package.json').version)
  .command('compile [files...]', 'Generate BuckleScript interfaces from a file', {}, compileFiles)
  .option('flow-typed', {
    describe: 'Generate interfaces from the flow-typed directory'
  })
  .demandCommand(1, '')
  .help()
  .argv

function compileFiles ({ files }) {
  files.forEach(compileFile)
}

function compileFile (filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) return reject(err)

      const fileName = path.basename(filePath)
      const [moduleName, _, bsCode] = retyped.compile(fileName, data.toString())

      const writeDirName = path.dirname(filePath)
      const writeFileName = path.join(writeDirName, moduleName + '.re')

      console.log(`Writing ${filePath} -> ${writeFileName}`)
      fs.writeFile(writeFileName, bsCode, err => {
        if (err) return reject(err)

        resolve()
      })
    })
  })
}
<commit_msg>Fix cmd<commit_after>#!/usr/bin/env node

const fs = require('fs')
const path = require('path')
const yargs = require('yargs')
const retyped = require('./retyped_node')

yargs
  .usage('retyped')
  .version(require('./package.json').version)
  .command('compile [files...]', 'Generate BuckleScript interfaces from a file', {}, compileFiles)
  .option('flow-typed', {
    describe: 'Generate interfaces from the flow-typed directory'
  })
  .demandCommand(1, '')
  .help()
  .argv

function compileFiles ({ files }) {
  files.forEach(compileFile)
}

function compileFile (filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) return reject(err)

      const fileName = path.basename(filePath)
      const [moduleName, _, bsCode] = retyped.compile(fileName, data.toString())

      const writeDirName = path.dirname(filePath)
      const writeFileName = path.join(writeDirName, moduleName + '.re')

      console.log(`Writing ${filePath} -> ${writeFileName}`)
      fs.writeFile(writeFileName, bsCode, err => {
        if (err) return reject(err)

        resolve()
      })
    })
  })
}
<|endoftext|>


<commit_before>function sendJointResult (result, sort, callback) {

    var items = [];

    for (var i = 0, l = result.length; i < l; ++i) {
        if (result[i]) {
            items.push(result[i]);
        }
    }

    // sort result
    if (sort && (sort = sort[0])) {

        sort[0] = sort[0].split('.');

        items.sort(function compare(a,b) {

            for (var i = 0, l = sort[0].length; i < l; ++i) {
                if (a[sort[0][i]]) {
                    a = a[sort[0][i]];
                }

                if (b[sort[0][i]]) {
                    b = b[sort[0][i]];
                }
            }

            if (a < b) {
                return (sort[1] * -1);
            }

            if (a > b) {
                return sort[1];
            }

            return 0;
        });
    }

    callback(null, result);
}

function jointRequest (dbReq, jointDbReq, result, callback) {
    jointDbReq.template._modm.collection.find(jointDbReq.query, jointDbReq.options, function (err, cursor) {

        // ignore query when no items in result
        if (err) {
            return callback(err);
        }

        cursor.toArray(function (err, jointResult) {

            if (err || jointResult.length === 0) {
                return callback(err);
            }

            // create joint object
            var jointData = {};
            for (var i = 0, l = jointResult.length; i < l; ++i) {
                jointData[jointResult[i]._id] = jointResult[i];
            }

            // merge linked data
            for (var i = 0, l = result.length; i < l; ++i) {

                if (
                    result[i] &&
                    result[i][jointDbReq.merge] &&
                    jointData[result[i][jointDbReq.merge]] &&
                    jointData[result[i][jointDbReq.merge]]._id.toString() === result[i][jointDbReq.merge].toString()
                ) {
                    // merge linked data in result field
                    result[i][jointDbReq.merge] = jointData[result[i][jointDbReq.merge]];
                } else {
                    result[i] = null;
                }
            }

            callback();
        });
    });
}

function jointResponse (dbReq, cursor, callback) {

    cursor.toArray(function (err, result) {

        if (err) {
            return callback(err);
        }

        // don't merge if no documents are found
        if (result.length === 0) {
            return callback(null, []);
        }

        var current = 0;
        for (var joint in dbReq.joints) {

            // set limit to length of result
            dbReq.joints[joint].options.limit = result.length;

            // get ids from linked fields
            var uniqueId = {};
            dbReq.joints[joint].query._id = {$in: []};
            for (var i = 0, l = result.length; i < l; ++i) {
                if (!uniqueId[result[i][dbReq.joints[joint].merge]] && result[i][dbReq.joints[joint].merge]) {
                    uniqueId[result[i][dbReq.joints[joint].merge]] = 1;
                    dbReq.joints[joint].query._id.$in.push(result[i][dbReq.joints[joint].merge]);
                }
            }

            // get linked data
            jointRequest(dbReq, dbReq.joints[joint], result, function (err, emtpy) {

                if (err) {
                    return callback(err);
                }

                if (++current === dbReq.jointsLength) {
                    sendJointResult(result, dbReq.options.sort, callback);
                }
            });
        }
    });
}

// CRUD interface

exports.create = function (dbReq, callback) {
    dbReq.template._modm.collection.insert(dbReq.data, dbReq.options, callback);
};

exports.read = function (dbReq, callback) {
    // get data and count
    dbReq.template._modm.collection.find(dbReq.query, dbReq.options, function (err, cursor) {

        if (err) {
            return callback(err);
        }

        dbReq.template._modm.collection.count(dbReq.query, function (countErr, count) {

            if (countErr) {
                count = -1;
            }

            // merge linked data in result data
            if (dbReq.joints) {
                return jointResponse(dbReq, cursor, function (err, result) {
                    callback(err, result, count);
                });
            }

            callback(null, cursor, count);
        });
    });
};

exports.update = function (dbReq, callback) {
    dbReq.template._modm.collection.update(dbReq.query, dbReq.data, dbReq.options, callback);
};

exports['delete'] = function (dbReq, callback) {
    dbReq.template._modm.collection.remove(dbReq.query, dbReq.options, callback);
};

<commit_msg>overwrite only the merge field, not the hole item<commit_after>function sendJointResult (result, sort, callback) {

    var items = [];

    for (var i = 0, l = result.length; i < l; ++i) {
        if (result[i]) {
            items.push(result[i]);
        }
    }

    // sort result
    if (sort && (sort = sort[0])) {

        sort[0] = sort[0].split('.');

        items.sort(function compare(a,b) {

            for (var i = 0, l = sort[0].length; i < l; ++i) {
                if (a[sort[0][i]]) {
                    a = a[sort[0][i]];
                }

                if (b[sort[0][i]]) {
                    b = b[sort[0][i]];
                }
            }

            if (a < b) {
                return (sort[1] * -1);
            }

            if (a > b) {
                return sort[1];
            }

            return 0;
        });
    }

    callback(null, result);
}

function jointRequest (dbReq, jointDbReq, result, callback) {
    jointDbReq.template._modm.collection.find(jointDbReq.query, jointDbReq.options, function (err, cursor) {

        // ignore query when no items in result
        if (err) {
            return callback(err);
        }

        cursor.toArray(function (err, jointResult) {

            if (err || jointResult.length === 0) {
                return callback(err);
            }

            // create joint object
            var jointData = {};
            for (var i = 0, l = jointResult.length; i < l; ++i) {
                jointData[jointResult[i]._id] = jointResult[i];
            }

            // merge linked data
            for (var i = 0, l = result.length; i < l; ++i) {

                if (
                    result[i] &&
                    result[i][jointDbReq.merge] &&
                    jointData[result[i][jointDbReq.merge]] &&
                    jointData[result[i][jointDbReq.merge]]._id.toString() === result[i][jointDbReq.merge].toString()
                ) {
                    // merge linked data in result field
                    result[i][jointDbReq.merge] = jointData[result[i][jointDbReq.merge]];
                } else {
                    result[i][jointDbReq.merge] = '';
                }
            }

            callback();
        });
    });
}

function jointResponse (dbReq, cursor, callback) {

    cursor.toArray(function (err, result) {

        if (err) {
            return callback(err);
        }

        // don't merge if no documents are found
        if (result.length === 0) {
            return callback(null, []);
        }

        var current = 0;
        for (var joint in dbReq.joints) {

            // set limit to length of result
            dbReq.joints[joint].options.limit = result.length;

            // get ids from linked fields
            var uniqueId = {};
            dbReq.joints[joint].query._id = {$in: []};
            for (var i = 0, l = result.length; i < l; ++i) {
                if (!uniqueId[result[i][dbReq.joints[joint].merge]] && result[i][dbReq.joints[joint].merge]) {
                    uniqueId[result[i][dbReq.joints[joint].merge]] = 1;
                    dbReq.joints[joint].query._id.$in.push(result[i][dbReq.joints[joint].merge]);
                }
            }

            // get linked data
            jointRequest(dbReq, dbReq.joints[joint], result, function (err, emtpy) {

                if (err) {
                    return callback(err);
                }

                if (++current === dbReq.jointsLength) {
                    sendJointResult(result, dbReq.options.sort, callback);
                }
            });
        }
    });
}

// CRUD interface

exports.create = function (dbReq, callback) {
    dbReq.template._modm.collection.insert(dbReq.data, dbReq.options, callback);
};

exports.read = function (dbReq, callback) {
    // get data and count
    dbReq.template._modm.collection.find(dbReq.query, dbReq.options, function (err, cursor) {

        if (err) {
            return callback(err);
        }

        dbReq.template._modm.collection.count(dbReq.query, function (countErr, count) {

            if (countErr) {
                count = -1;
            }

            // merge linked data in result data
            if (dbReq.joints) {
                return jointResponse(dbReq, cursor, function (err, result) {
                    callback(err, result, count);
                });
            }

            callback(null, cursor, count);
        });
    });
};

exports.update = function (dbReq, callback) {
    dbReq.template._modm.collection.update(dbReq.query, dbReq.data, dbReq.options, callback);
};

exports['delete'] = function (dbReq, callback) {
    dbReq.template._modm.collection.remove(dbReq.query, dbReq.options, callback);
};

<|endoftext|>