-
Notifications
You must be signed in to change notification settings - Fork 0
/
autofile.js
95 lines (73 loc) · 2.53 KB
/
autofile.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
93
94
95
'use strict';
var request = require('request');
var progress = require('request-progress');
var async = require('async');
var fs = require('fs');
// -----------------------------------------------------------------------------
module.exports = function (task) {
task
.id('download')
.name('Download')
.author('Indigo United')
// TODO: add support for only specifying destination folder and name is auto
.option('files', 'An object with the links (keys) and destination location (values).')
.option('concurrency', 'The maximum concurrent downloads. 0 is unlimited.', 0)
.setup(function (opts, ctx, next) {
opts.totalFiles = Object.keys(opts.files).length;
opts.concurrency = parseInt(opts.concurrency);
next();
})
.do(function (opts, ctx, next) {
var stats = {
totalData: 0,
accountedForTotal: {},
receivedData: 0
};
var downloads = {};
for (var url in opts.files) {
downloads[url] = downloader(url, opts.files[url], stats, ctx);
}
parallel(downloads, opts.concurrency, function (err) {
ctx.log.debugln('Completed all downloads');
next(err);
});
}, {
description: 'Download {{totalFiles}} files'
});
};
// -----------------------------------------------------------------------------
function downloader(url, dest, stats, ctx) {
return function (cb) {
progress(request(url), {
throttle: 1000,
delay: 0
})
.on('progress', function (state) {
stats.receivedData += state.received;
if (!stats.accountedForTotal.hasOwnProperty(url)) {
stats.totalData += state.total;
stats.accountedForTotal[url] = true;
}
ctx.log.infoln(url, state.percent + '%');
})
.on('error', function (err) {
// TODO: maybe give option to fail silently individual files?
return cb(err);
})
.pipe(fs.createWriteStream(dest))
.on('error', function (err) {
// TODO: maybe give option to fail silently individual files?
return cb(err);
})
.on('close', function (err) {
ctx.log.successln('Completed download');
return cb(err);
});
};
}
function parallel(tasks, limit, callback) {
if (limit) {
return async.parallelLimit(tasks, limit, callback);
}
return async.parallel(tasks, callback);
}