summaryrefslogtreecommitdiff
path: root/node_modules/nugget/index.js
diff options
context:
space:
mode:
authorLinuxWizard42 <computerwizard@linuxmail.org>2022-10-12 22:54:37 +0300
committerLinuxWizard42 <computerwizard@linuxmail.org>2022-10-12 22:54:37 +0300
commit703e03aba33f234712206769f57717ba7d92d23d (patch)
tree0041f04ccb75bd5379c764e9fe42249fffe75fc3 /node_modules/nugget/index.js
parentab6e257e6e9d9a483d7e86f220d8b209a2cd7753 (diff)
downloadFlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.gz
FlashRunner-703e03aba33f234712206769f57717ba7d92d23d.tar.zst
Added export_allowed file to make repository visible in cgit
Diffstat (limited to 'node_modules/nugget/index.js')
-rw-r--r--node_modules/nugget/index.js203
1 files changed, 203 insertions, 0 deletions
diff --git a/node_modules/nugget/index.js b/node_modules/nugget/index.js
new file mode 100644
index 0000000..b36918b
--- /dev/null
+++ b/node_modules/nugget/index.js
@@ -0,0 +1,203 @@
+var request = require('request')
+var fs = require('fs')
+var path = require('path')
+var log = require('single-line-log').stdout
+var progress = require('progress-stream')
+var prettyBytes = require('pretty-bytes')
+var throttle = require('throttleit')
+var EventEmitter = require('events').EventEmitter
+var debug = require('debug')('nugget')
+
+function noop () {}
+
+module.exports = function (urls, opts, cb) {
+ if (!Array.isArray(urls)) urls = [urls]
+ if (urls.length === 1) opts.singleTarget = true
+
+ var defaultProps = {}
+
+ if (opts.sockets) {
+ var sockets = +opts.sockets
+ defaultProps.pool = {maxSockets: sockets}
+ }
+
+ if (opts.proxy) {
+ defaultProps.proxy = opts.proxy
+ }
+
+ if (opts.strictSSL !== null) {
+ defaultProps.strictSSL = opts.strictSSL
+ }
+
+ if (Object.keys(defaultProps).length > 0) {
+ request = request.defaults(defaultProps)
+ }
+
+ var downloads = []
+ var errors = []
+ var pending = 0
+ var truncated = urls.length * 2 >= (process.stdout.rows - 15)
+
+ urls.forEach(function (url) {
+ debug('start dl', url)
+ pending++
+ var dl = startDownload(url, opts, function done (err) {
+ debug('done dl', url, pending)
+ if (err) {
+ debug('error dl', url, err)
+ errors.push(err)
+ dl.error = err.message
+ }
+ if (truncated) {
+ var i = downloads.indexOf(dl)
+ downloads.splice(i, 1)
+ downloads.push(dl)
+ }
+ if (--pending === 0) {
+ render()
+ cb(errors.length ? errors : undefined)
+ }
+ })
+
+ downloads.push(dl)
+
+ dl.on('start', function (progressStream) {
+ throttledRender()
+ })
+
+ dl.on('progress', function (data) {
+ debug('progress', url, data.percentage)
+
+ dl.speed = data.speed
+ if (dl.percentage === 100) render()
+ else throttledRender()
+ })
+ })
+
+ var _log = opts.quiet ? noop : log
+ render()
+ var throttledRender = throttle(render, opts.frequency || 250)
+
+ if (opts.singleTarget) return downloads[0]
+ else return downloads
+
+ function render () {
+ var height = process.stdout.rows
+ var rendered = 0
+ var output = ''
+ var totalSpeed = 0
+ downloads.forEach(function (dl) {
+ if (2 * rendered >= height - 15) return
+ rendered++
+ if (dl.error) {
+ output += 'Downloading ' + path.basename(dl.target) + '\n'
+ output += 'Error: ' + dl.error + '\n'
+ return
+ }
+ var pct = dl.percentage
+ var speed = dl.speed
+ var total = dl.fileSize
+ totalSpeed += speed
+ var bar = Array(Math.floor(45 * pct / 100)).join('=') + '>'
+ while (bar.length < 45) bar += ' '
+ output += 'Downloading ' + path.basename(dl.target) + '\n' +
+ '[' + bar + '] ' + pct.toFixed(1) + '%'
+ if (total) output += ' of ' + prettyBytes(total)
+ output += ' (' + prettyBytes(speed) + '/s)\n'
+ })
+ if (rendered < downloads.length) output += '\n... and ' + (downloads.length - rendered) + ' more\n'
+ if (downloads.length > 1) output += '\nCombined Speed: ' + prettyBytes(totalSpeed) + '/s\n'
+ _log(output)
+ }
+
+ function startDownload (url, opts, cb) {
+ var targetName = path.basename(url).split('?')[0]
+ if (opts.singleTarget && opts.target) targetName = opts.target
+ var target = path.resolve(opts.dir || process.cwd(), targetName)
+ if (opts.resume) {
+ resume(url, opts, cb)
+ } else {
+ download(url, opts, cb)
+ }
+
+ var progressEmitter = new EventEmitter()
+ progressEmitter.target = target
+ progressEmitter.speed = 0
+ progressEmitter.percentage = 0
+
+ return progressEmitter
+
+ function resume (url, opts, cb) {
+ fs.stat(target, function (err, stats) {
+ if (err && err.code === 'ENOENT') {
+ return download(url, opts, cb)
+ }
+ if (err) {
+ return cb(err)
+ }
+ var offset = stats.size
+ var req = request.get(url)
+
+ req.on('error', cb)
+ req.on('response', function (resp) {
+ resp.destroy()
+
+ var length = parseInt(resp.headers['content-length'], 10)
+
+ // file is already downloaded.
+ if (length === offset) return cb()
+
+ if (!isNaN(length) && length > offset && /bytes/.test(resp.headers['accept-ranges'])) {
+ opts.range = [offset, length]
+ }
+
+ download(url, opts, cb)
+ })
+ })
+ }
+
+ function download (url, opts, cb) {
+ var headers = opts.headers || {}
+ if (opts.range) {
+ headers.Range = 'bytes=' + opts.range[0] + '-' + opts.range[1]
+ }
+ var read = request(url, { headers: headers })
+
+ read.on('error', cb)
+ read.on('response', function (resp) {
+ debug('response', url, resp.statusCode)
+ if (resp.statusCode > 299 && !opts.force) return cb(new Error('GET ' + url + ' returned ' + resp.statusCode))
+ var write = fs.createWriteStream(target, {flags: opts.resume ? 'a' : 'w'})
+ write.on('error', cb)
+ write.on('finish', cb)
+
+ var fullLen
+ var contentLen = Number(resp.headers['content-length'])
+ var range = resp.headers['content-range']
+ if (range) {
+ fullLen = Number(range.split('/')[1])
+ } else {
+ fullLen = contentLen
+ }
+
+ progressEmitter.fileSize = fullLen
+ if (range) {
+ var downloaded = fullLen - contentLen
+ }
+ var progressStream = progress({ length: fullLen, transferred: downloaded }, onprogress)
+ progressEmitter.emit('start', progressStream)
+
+ resp
+ .pipe(progressStream)
+ .pipe(write)
+ })
+
+ function onprogress (p) {
+ var pct = p.percentage
+ progressEmitter.progress = p
+ progressEmitter.percentage = pct
+ progressEmitter.emit('progress', p)
+ }
+ }
+ }
+}