Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorFeross Aboukhadijeh <feross@feross.org>2015-01-10 09:03:19 +0300
committerFeross Aboukhadijeh <feross@feross.org>2015-01-10 09:03:19 +0300
commit6a666528fdaa23230d45676f24bbb5f3b899ada1 (patch)
tree4c9822a59b52c28ef5027d2ceac5bc800870f009 /bin
parentb76408ac5d6f56d2fbb8ae1603286417393e3850 (diff)
command line: add `info` command
Fix #233
Diffstat (limited to 'bin')
-rwxr-xr-xbin/cmd.js624
1 files changed, 333 insertions, 291 deletions
diff --git a/bin/cmd.js b/bin/cmd.js
index d3df10a..cf202bb 100755
--- a/bin/cmd.js
+++ b/bin/cmd.js
@@ -6,6 +6,7 @@ var fs = require('fs')
var minimist = require('minimist')
var moment = require('moment')
var networkAddress = require('network-address')
+var parseTorrent = require('parse-torrent')
var path = require('path')
var prettyBytes = require('pretty-bytes')
var WebTorrent = require('../')
@@ -51,14 +52,42 @@ var argv = minimist(process.argv.slice(2), {
}
})
-if (argv.version) {
- console.log(require('../package.json').version)
- done()
+if (process.env.DEBUG || argv.stdout) {
+ argv.quiet = argv.q = true
+}
+
+var torrentId
+var command = argv._[0]
+
+if (command === 'help' || argv.help) {
+ help()
+} else if (command === 'version' || argv.version) {
+ version()
+} else if (command === 'info') {
+ torrentId = argv._[1]
+ info(torrentId)
+} else if (command === 'download') {
+ torrentId = argv._[1]
+ download(torrentId)
+} else if (command) {
+ // assume download when no command specified
+ torrentId = command
+ download(torrentId)
+} else {
+ help()
+}
+
+function errorAndExit (err) {
+ clivas.line('{red:ERROR:} ' + (err.message || err))
+ process.exit(1)
}
-var torrentId = argv._[0]
+function version () {
+ console.log(require('../package.json').version)
+ process.exit(0)
+}
-if (argv.help || !torrentId) {
+function help () {
fs.readFileSync(path.join(__dirname, 'ascii-logo.txt'), 'utf8')
.split('\n')
.forEach(function (line) {
@@ -67,15 +96,22 @@ if (argv.help || !torrentId) {
console.log(function () {/*
Usage:
- webtorrent <options> <torrent-uri>
+ webtorrent [command] <torrent-id> <options>
+
+ Example:
+ webtorrent download "magnet:?xt=urn:btih:..." --vlc
+
+ Available commands:
+ download download a torrent
+ info show info for a .torrent file or magnet uri
- Download the torrent from:
- * magnet uri
- * http url to .torrent file
- * filesystem path to .torrent file
- * info hash (hex string)
+ Specify torrents as one of the following:
+ * magnet uri
+ * http url to .torrent file
+ * filesystem path to .torrent file
+ * info hash (hex string)
- Streaming options:
+ Options (streaming):
--airplay Apple TV
--chromecast Chromecast
--mplayer MPlayer
@@ -85,7 +121,7 @@ if (argv.help || !torrentId) {
--xbmc XBMC
--stdout standard out (implies --quiet)
- Options:
+ Options (all):
-o, --out [path] set download destination [default: /tmp/webtorrent]
-l, --list list files in torrent (with indexes)
-i, --index [index] stream a particular file from torrent (by index)
@@ -98,334 +134,340 @@ if (argv.help || !torrentId) {
Please report bugs! https://github.com/feross/webtorrent/issues
*/}.toString().split(/\n/).slice(1, -1).join('\n'))
- done()
+ process.exit(0)
}
-if (process.env.DEBUG || argv.stdout) {
- argv.quiet = argv.q = true
-}
-
-var VLC_ARGS = process.env.DEBUG
- ? '-q --play-and-exit'
- : '--play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'
-var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0'
-var MPV_EXEC = 'mpv --ontop --really-quiet --loop=no'
-var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
- ? argv.omx
- : 'hdmi'
-
-if (argv.subtitles) {
- VLC_ARGS += ' --sub-file=' + argv.subtitles
- MPLAYER_EXEC += ' -sub ' + argv.subtitles
- MPV_EXEC += ' --sub-file=' + argv.subtitles
- OMX_EXEC += ' --subtitles ' + argv.subtitles
-}
-
-function error (err) {
- clivas.line('{red:ERROR:} ' + (err.message || err))
-}
+function info (torrentId) {
+ var parsedTorrent = parseTorrent(torrentId)
+ if (!parsedTorrent || !parsedTorrent.infoHash) {
+ try {
+ parsedTorrent = parseTorrent(fs.readFileSync(torrentId))
+ } catch (err) {
+ errorAndExit(err)
+ }
+ }
+ if (!parsedTorrent) errorAndExit('Invalid torrent identifier')
-function errorAndExit (err) {
- error(err)
- process.exit(1)
-}
+ delete parsedTorrent.info
+ delete parsedTorrent.infoBuffer
-var started = Date.now()
-function getRuntime () {
- return Math.floor((Date.now() - started) / 1000)
+ console.log(JSON.stringify(parsedTorrent, undefined, 2))
}
-var client = new WebTorrent({
- blocklist: argv.blocklist
-})
-.on('error', errorAndExit)
+function download (torrentId) {
+ var VLC_ARGS = process.env.DEBUG
+ ? '-q --play-and-exit'
+ : '--play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'
+ var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0'
+ var MPV_EXEC = 'mpv --ontop --really-quiet --loop=no'
+ var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
+ ? argv.omx
+ : 'hdmi'
+
+ if (argv.subtitles) {
+ VLC_ARGS += ' --sub-file=' + argv.subtitles
+ MPLAYER_EXEC += ' -sub ' + argv.subtitles
+ MPV_EXEC += ' --sub-file=' + argv.subtitles
+ OMX_EXEC += ' --subtitles ' + argv.subtitles
+ }
-if (!argv.out) { // If no output file has been specified
- process.on('SIGINT', remove)
- process.on('SIGTERM', remove)
-}
+ var started = Date.now()
+ function getRuntime () {
+ return Math.floor((Date.now() - started) / 1000)
+ }
-function remove () {
- process.removeListener('SIGINT', remove)
- process.removeListener('SIGTERM', remove)
+ var client = new WebTorrent({
+ blocklist: argv.blocklist
+ })
+ .on('error', errorAndExit)
- // destroying can take a while, so print a message to the user
- clivas.line('')
- clivas.line('{green:webtorrent is exiting...}')
+ if (!argv.out) { // If no output file has been specified
+ process.on('SIGINT', remove)
+ process.on('SIGTERM', remove)
+ }
- client.destroy(process.exit)
-}
+ function remove () {
+ process.removeListener('SIGINT', remove)
+ process.removeListener('SIGTERM', remove)
-var torrent = client.add(torrentId, (argv.out ? { tmp: argv.out } : {}))
+ // destroying can take a while, so print a message to the user
+ clivas.line('')
+ clivas.line('{green:webtorrent is exiting...}')
-torrent.on('infoHash', function () {
- function updateMetadata () {
- var numPeers = torrent.swarm.numPeers
- clivas.clear()
- clivas.line('{green:fetching torrent metadata from} {bold:'+numPeers+'} {green:peers}')
+ client.destroy(process.exit)
}
- if (!argv.quiet && !argv.list) {
- torrent.swarm.on('wire', updateMetadata)
- torrent.on('metadata', function () {
- torrent.swarm.removeListener('wire', updateMetadata)
- })
- updateMetadata()
- }
-})
+ var torrent = client.add(torrentId, (argv.out ? { tmp: argv.out } : {}))
-var filename, swarm, wires, server, serving
+ torrent.on('infoHash', function () {
+ function updateMetadata () {
+ var numPeers = torrent.swarm.numPeers
+ clivas.clear()
+ clivas.line('{green:fetching torrent metadata from} {bold:'+numPeers+'} {green:peers}')
+ }
-if (argv.list) torrent.once('ready', onReady)
-else {
- server = torrent.createServer()
- server.listen(argv.port, function () {
- if (torrent.ready) onReady()
- else torrent.once('ready', onReady)
- }).once('connection', function () {
- serving = true
+ if (!argv.quiet && !argv.list) {
+ torrent.swarm.on('wire', updateMetadata)
+ torrent.on('metadata', function () {
+ torrent.swarm.removeListener('wire', updateMetadata)
+ })
+ updateMetadata()
+ }
})
-}
-
-function done () {
- if (!serving) {
- process.exit(0)
- }
-}
-function onReady () {
- filename = torrent.name
- swarm = torrent.swarm
- wires = torrent.swarm.wires
+ var filename, swarm, wires, server, serving
- if (argv.list) {
- torrent.files.forEach(function (file, i) {
- clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'} {blue:('+prettyBytes(file.length)+')}')
+ if (argv.list) torrent.once('ready', onReady)
+ else {
+ server = torrent.createServer()
+ server.listen(argv.port, function () {
+ if (torrent.ready) onReady()
+ else torrent.once('ready', onReady)
+ }).once('connection', function () {
+ serving = true
})
- return done()
}
- torrent.on('verifying', function (data) {
- if (argv.quiet) return
- clivas.clear()
- clivas.line(
- '{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ' +
- '({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})'
- )
- })
-
- torrent.on('done', function () {
- if (!argv.quiet) {
- // TODO: expose this data from bittorrent-swarm
- var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
- return num + (wire.downloaded > 0)
- }, 0)
- clivas.line(
- 'torrent downloaded {green:successfully} from ' +
- '{bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} ' +
- 'in {bold:'+getRuntime()+'s}!'
- )
+ function done () {
+ if (!serving) {
+ process.exit(0)
}
- done()
- })
+ }
- var cmd, player
- var playerName = argv.airplay ? 'Airplay'
- : argv.chromecast ? 'Chromecast'
- : argv.xbmc ? 'XBMC'
- : argv.vlc ? 'VLC'
- : argv.mplayer ? 'MPlayer'
- : argv.mpv ? 'mpv'
- : argv.omx ? 'OMXPlayer'
- : null
-
- // if no index specified, use largest file
- var index = (typeof argv.index === 'number')
- ? argv.index
- : torrent.files.indexOf(torrent.files.reduce(function (a, b) {
- return a.length > b.length ? a : b
- }))
- var href = 'http://' + networkAddress() + ':' + argv.port + '/' + index
- var localHref = 'http://localhost:' + argv.port + '/' + index
-
- if (playerName) torrent.files[index].select()
- if (argv.stdout) torrent.files[index].createReadStream().pipe(process.stdout)
-
- if (argv.vlc && process.platform === 'win32') {
- var registry = require('windows-no-runnable').registry
- var key
- if (process.arch === 'x64') {
- try {
- key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
- } catch (e) {}
- } else {
- try {
- key = registry('HKLM/Software/VideoLAN/VLC')
- } catch (err) {}
- }
+ function onReady () {
+ filename = torrent.name
+ swarm = torrent.swarm
+ wires = torrent.swarm.wires
- if (key) {
- var vlcPath = key.InstallDir.value + path.sep + 'vlc'
- VLC_ARGS = VLC_ARGS.split(' ')
- VLC_ARGS.unshift(localHref)
- cp.execFile(vlcPath, VLC_ARGS, function (err) {
- if (err) return errorAndExit(err)
- done()
+ if (argv.list) {
+ torrent.files.forEach(function (file, i) {
+ clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'} {blue:('+prettyBytes(file.length)+')}')
})
+ return done()
}
- } else if (argv.vlc) {
- var root = '/Applications/VLC.app/Contents/MacOS/VLC'
- var home = (process.env.HOME || '') + root
- cmd = 'vlc ' + localHref + ' ' + VLC_ARGS + ' || ' +
- root + ' ' + localHref + ' ' + VLC_ARGS + ' || ' +
- home + ' ' + localHref + ' ' + VLC_ARGS
- } else if (argv.mplayer) {
- cmd = MPLAYER_EXEC + ' ' + localHref
- } else if (argv.mpv) {
- cmd = MPV_EXEC + ' ' + localHref
- } else if (argv.omx) {
- cmd = OMX_EXEC + ' ' + localHref
- }
- if (cmd) {
- player = cp.exec(cmd, function (err) {
- if (err) return errorAndExit(err)
+ torrent.on('verifying', function (data) {
+ if (argv.quiet) return
+ clivas.clear()
+ clivas.line(
+ '{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ' +
+ '({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})'
+ )
+ })
+
+ torrent.on('done', function () {
+ if (!argv.quiet) {
+ // TODO: expose this data from bittorrent-swarm
+ var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
+ return num + (wire.downloaded > 0)
+ }, 0)
+ clivas.line(
+ 'torrent downloaded {green:successfully} from ' +
+ '{bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} ' +
+ 'in {bold:'+getRuntime()+'s}!'
+ )
+ }
done()
})
- }
- if (argv.airplay) {
- var airplay = require('airplay-js')
- airplay.createBrowser()
- .on('deviceOn', function (device) {
- device.play(href, 0, function () {})
- })
- .start()
- // TODO: handle case where user closes airplay. do same thing as when VLC is closed
- }
+ var cmd, player
+ var playerName = argv.airplay ? 'Airplay'
+ : argv.chromecast ? 'Chromecast'
+ : argv.xbmc ? 'XBMC'
+ : argv.vlc ? 'VLC'
+ : argv.mplayer ? 'MPlayer'
+ : argv.mpv ? 'mpv'
+ : argv.omx ? 'OMXPlayer'
+ : null
+
+ // if no index specified, use largest file
+ var index = (typeof argv.index === 'number')
+ ? argv.index
+ : torrent.files.indexOf(torrent.files.reduce(function (a, b) {
+ return a.length > b.length ? a : b
+ }))
+ var href = 'http://' + networkAddress() + ':' + argv.port + '/' + index
+ var localHref = 'http://localhost:' + argv.port + '/' + index
+
+ if (playerName) torrent.files[index].select()
+ if (argv.stdout) torrent.files[index].createReadStream().pipe(process.stdout)
+
+ if (argv.vlc && process.platform === 'win32') {
+ var registry = require('windows-no-runnable').registry
+ var key
+ if (process.arch === 'x64') {
+ try {
+ key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
+ } catch (e) {}
+ } else {
+ try {
+ key = registry('HKLM/Software/VideoLAN/VLC')
+ } catch (err) {}
+ }
- if (argv.chromecast) {
- var chromecast = require('chromecast-js')
- new chromecast.Browser()
- .on('deviceOn', function (device) {
- device.connect()
- device.on('connected', function () {
- device.play(href)
+ if (key) {
+ var vlcPath = key.InstallDir.value + path.sep + 'vlc'
+ VLC_ARGS = VLC_ARGS.split(' ')
+ VLC_ARGS.unshift(localHref)
+ cp.execFile(vlcPath, VLC_ARGS, function (err) {
+ if (err) return errorAndExit(err)
+ done()
})
- })
- }
+ }
+ } else if (argv.vlc) {
+ var root = '/Applications/VLC.app/Contents/MacOS/VLC'
+ var home = (process.env.HOME || '') + root
+ cmd = 'vlc ' + localHref + ' ' + VLC_ARGS + ' || ' +
+ root + ' ' + localHref + ' ' + VLC_ARGS + ' || ' +
+ home + ' ' + localHref + ' ' + VLC_ARGS
+ } else if (argv.mplayer) {
+ cmd = MPLAYER_EXEC + ' ' + localHref
+ } else if (argv.mpv) {
+ cmd = MPV_EXEC + ' ' + localHref
+ } else if (argv.omx) {
+ cmd = OMX_EXEC + ' ' + localHref
+ }
- if (argv.xbmc) {
- var xbmc = require('nodebmc')
- new xbmc.Browser()
- .on('deviceOn', function (device) {
- device.play(href, function () {})
+ if (cmd) {
+ player = cp.exec(cmd, function (err) {
+ if (err) return errorAndExit(err)
+ done()
})
- }
+ }
- var hotswaps = 0
- torrent.on('hotswap', function () {
- hotswaps += 1
- })
+ if (argv.airplay) {
+ var airplay = require('airplay-js')
+ airplay.createBrowser()
+ .on('deviceOn', function (device) {
+ device.play(href, 0, function () {})
+ })
+ .start()
+ // TODO: handle case where user closes airplay. do same thing as when VLC is closed
+ }
- if (!argv.quiet) {
- process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing
+ if (argv.chromecast) {
+ var chromecast = require('chromecast-js')
+ new chromecast.Browser()
+ .on('deviceOn', function (device) {
+ device.connect()
+ device.on('connected', function () {
+ device.play(href)
+ })
+ })
+ }
- setInterval(draw, 500)
- }
+ if (argv.xbmc) {
+ var xbmc = require('nodebmc')
+ new xbmc.Browser()
+ .on('deviceOn', function (device) {
+ device.play(href, function () {})
+ })
+ }
- function active (wire) {
- return !wire.peerChoking
- }
+ var hotswaps = 0
+ torrent.on('hotswap', function () {
+ hotswaps += 1
+ })
- function draw () {
- var unchoked = wires.filter(active)
- var linesremaining = clivas.height
- var peerslisted = 0
- var speed = swarm.downloadSpeed()
- var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
- var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()
+ if (!argv.quiet) {
+ process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing
- clivas.clear()
+ setInterval(draw, 500)
+ }
- if (playerName)
- clivas.line('{green:Streaming to} {bold:' + playerName + '}')
- if (server)
- clivas.line('{green:server running at} {bold:' + href + '}')
- if (argv.out)
- clivas.line('{green:downloading to} {bold:' + argv.out + '}')
+ function active (wire) {
+ return !wire.peerChoking
+ }
- clivas.line('')
- clivas.line('{green:downloading:} {bold:' + filename + '}')
- clivas.line(
- '{green:speed: }{bold:' + prettyBytes(speed) + '/s} ' +
- '{green:downloaded:} {bold:' + prettyBytes(swarm.downloaded) + '}' +
- '/{bold:' + prettyBytes(torrent.length) + '} ' +
- '{green:uploaded:} {bold:' + prettyBytes(swarm.uploaded) + '} ' +
- '{green:peers:} {bold:' + unchoked.length + '/' + wires.length + '} ' +
- '{green:hotswaps:} {bold:' + hotswaps + '}'
- )
- clivas.line(
- '{green:time remaining:} {bold:' + estimate + ' remaining} ' +
- '{green:total time:} {bold:' + getRuntime() + 's} ' +
- '{green:queued peers:} {bold:' + swarm.numQueued + '} ' +
- '{green:blocked:} {bold:' + torrent.numBlockedPeers + '}'
- )
- clivas.line('{80:}')
- linesremaining -= 8
-
- var pieces = torrent.storage.pieces
- for (var i = 0; i < pieces.length; i++) {
- var piece = pieces[i]
- if (piece.verified || piece.blocksWritten === 0) {
- continue;
- }
- var bar = ''
- for (var j = 0; j < piece.blocks.length; j++) {
- bar += piece.blocks[j] ? '{green:█}' : '{red:█}';
+ function draw () {
+ var unchoked = wires.filter(active)
+ var linesremaining = clivas.height
+ var peerslisted = 0
+ var speed = swarm.downloadSpeed()
+ var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
+ var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()
+
+ clivas.clear()
+
+ if (playerName)
+ clivas.line('{green:Streaming to} {bold:' + playerName + '}')
+ if (server)
+ clivas.line('{green:server running at} {bold:' + href + '}')
+ if (argv.out)
+ clivas.line('{green:downloading to} {bold:' + argv.out + '}')
+
+ clivas.line('')
+ clivas.line('{green:downloading:} {bold:' + filename + '}')
+ clivas.line(
+ '{green:speed: }{bold:' + prettyBytes(speed) + '/s} ' +
+ '{green:downloaded:} {bold:' + prettyBytes(swarm.downloaded) + '}' +
+ '/{bold:' + prettyBytes(torrent.length) + '} ' +
+ '{green:uploaded:} {bold:' + prettyBytes(swarm.uploaded) + '} ' +
+ '{green:peers:} {bold:' + unchoked.length + '/' + wires.length + '} ' +
+ '{green:hotswaps:} {bold:' + hotswaps + '}'
+ )
+ clivas.line(
+ '{green:time remaining:} {bold:' + estimate + ' remaining} ' +
+ '{green:total time:} {bold:' + getRuntime() + 's} ' +
+ '{green:queued peers:} {bold:' + swarm.numQueued + '} ' +
+ '{green:blocked:} {bold:' + torrent.numBlockedPeers + '}'
+ )
+ clivas.line('{80:}')
+ linesremaining -= 8
+
+ var pieces = torrent.storage.pieces
+ for (var i = 0; i < pieces.length; i++) {
+ var piece = pieces[i]
+ if (piece.verified || piece.blocksWritten === 0) {
+ continue;
+ }
+ var bar = ''
+ for (var j = 0; j < piece.blocks.length; j++) {
+ bar += piece.blocks[j] ? '{green:█}' : '{red:█}';
+ }
+ clivas.line('{4+cyan:' + i + '} ' + bar);
+ linesremaining -= 1
}
- clivas.line('{4+cyan:' + i + '} ' + bar);
+ clivas.line('{80:}')
linesremaining -= 1
- }
- clivas.line('{80:}')
- linesremaining -= 1
-
- wires.every(function (wire) {
- var progress = '?'
- if (torrent.parsedTorrent) {
- var bits = 0
- var piececount = Math.ceil(torrent.parsedTorrent.length / torrent.parsedTorrent.pieceLength)
- for (var i = 0; i < piececount; i++) {
- if (wire.peerPieces.get(i)) {
- bits++
+
+ wires.every(function (wire) {
+ var progress = '?'
+ if (torrent.parsedTorrent) {
+ var bits = 0
+ var piececount = Math.ceil(torrent.parsedTorrent.length / torrent.parsedTorrent.pieceLength)
+ for (var i = 0; i < piececount; i++) {
+ if (wire.peerPieces.get(i)) {
+ bits++
+ }
}
+ progress = bits === piececount ? 'S' : Math.floor(100 * bits / piececount) + '%'
}
- progress = bits === piececount ? 'S' : Math.floor(100 * bits / piececount) + '%'
- }
- var tags = []
- if (wire.peerChoking) tags.push('choked')
- var reqStats = wire.requests.map(function (req) {
- return req.piece;
+ var tags = []
+ if (wire.peerChoking) tags.push('choked')
+ var reqStats = wire.requests.map(function (req) {
+ return req.piece;
+ })
+ clivas.line(
+ '{3:' + progress + '} ' +
+ '{25+magenta:' + wire.remoteAddress + '} {10:'+prettyBytes(wire.downloaded)+'} ' +
+ '{10+cyan:' + prettyBytes(wire.downloadSpeed()) + '/s} ' +
+ '{10+red:' + prettyBytes(wire.uploadSpeed()) + '/s} ' +
+ '{15+grey:' + tags.join(', ') + '}' +
+ '{15+cyan:' + reqStats.join(' ') + '}'
+ )
+ peerslisted++
+ return linesremaining - peerslisted > 4
})
- clivas.line(
- '{3:' + progress + '} ' +
- '{25+magenta:' + wire.remoteAddress + '} {10:'+prettyBytes(wire.downloaded)+'} ' +
- '{10+cyan:' + prettyBytes(wire.downloadSpeed()) + '/s} ' +
- '{10+red:' + prettyBytes(wire.uploadSpeed()) + '/s} ' +
- '{15+grey:' + tags.join(', ') + '}' +
- '{15+cyan:' + reqStats.join(' ') + '}'
- )
- peerslisted++
- return linesremaining - peerslisted > 4
- })
- linesremaining -= peerslisted
+ linesremaining -= peerslisted
+
+ if (wires.length > peerslisted) {
+ clivas.line('{80:}')
+ clivas.line('... and '+(wires.length - peerslisted)+' more')
+ }
- if (wires.length > peerslisted) {
clivas.line('{80:}')
- clivas.line('... and '+(wires.length - peerslisted)+' more')
+ clivas.flush(true)
}
-
- clivas.line('{80:}')
- clivas.flush(true)
}
}