-
Notifications
You must be signed in to change notification settings - Fork 146
/
Copy pathdownloader.js
92 lines (86 loc) · 2.35 KB
/
downloader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'use strict'
const crypto = require('crypto')
const axios = require('axios')
const MemoryStream = require('memory-stream')
const zlib = require('zlib')
const tar = require('tar')
const fs = require('fs')
const CMLog = require('./cmLog')
class Downloader {
constructor(options) {
this.options = options || {}
this.log = new CMLog(this.options)
}
downloadToStream(url, stream, hash) {
const self = this
const shasum = hash ? crypto.createHash(hash) : null
return new Promise(function (resolve, reject) {
let length = 0
let done = 0
let lastPercent = 0
axios
.get(url, { responseType: 'stream' })
.then(function (response) {
length = parseInt(response.headers['content-length'])
if (typeof length !== 'number') {
length = 0
}
response.data.on('data', function (chunk) {
if (shasum) {
shasum.update(chunk)
}
if (length) {
done += chunk.length
let percent = (done / length) * 100
percent = Math.round(percent / 10) * 10 + 10
if (percent > lastPercent) {
self.log.verbose('DWNL', '\t' + lastPercent + '%')
lastPercent = percent
}
}
})
response.data.pipe(stream)
})
.catch(function (err) {
reject(err)
})
stream.once('error', function (err) {
reject(err)
})
stream.once('finish', function () {
resolve(shasum ? shasum.digest('hex') : undefined)
})
})
}
async downloadString(url) {
const result = new MemoryStream()
await this.downloadToStream(url, result)
return result.toString()
}
async downloadFile(url, options) {
if (typeof options === 'string') {
options.path = options
}
const result = fs.createWriteStream(options.path)
const sum = await this.downloadToStream(url, result, options.hash)
this.testSum(url, sum, options)
return sum
}
async downloadTgz(url, options) {
if (typeof options === 'string') {
options.cwd = options
}
const gunzip = zlib.createGunzip()
const extractor = tar.extract(options)
gunzip.pipe(extractor)
const sum = await this.downloadToStream(url, gunzip, options.hash)
this.testSum(url, sum, options)
return sum
}
testSum(url, sum, options) {
if (options.hash && sum && options.sum && options.sum !== sum) {
throw new Error(options.hash.toUpperCase() + " sum of download '" + url + "' mismatch!")
}
}
}
module.exports = Downloader