-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdownload.js
130 lines (112 loc) · 3.4 KB
/
download.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const WebTorrent = require("webtorrent");
const path = require("path");
const log = require("single-line-log").stdout;
const { orderBy } = require("lodash");
const _formatBytes = bytes => {
if (bytes < 1024) return bytes + " Bytes";
else if (bytes < 1048576) return (bytes / 1024).toFixed(2) + " KB";
else return (bytes / 1048576).toFixed(2) + " MB";
};
const _formatTime = millis => {
let sec = Math.floor(millis / 1000);
let hrs = Math.floor(sec / 3600);
sec -= hrs * 3600;
let min = Math.floor(sec / 60);
sec -= min * 60;
sec = "" + sec;
sec = ("00" + sec).substring(sec.length);
if (hrs > 0) {
min = "" + min;
min = ("00" + min).substring(min.length);
return `${hrs}h ${min}m ${sec}s`;
} else {
return `${min}m ${sec}s`;
}
};
const torrentLog = torrent => {
let progress = Number(torrent.progress * 100).toFixed(2);
let progressBar = "";
let bars = ~~(progress / 4);
for (let i = 0; i < bars; i++) {
progressBar += "=";
}
progressBar = progressBar + Array(26 - progressBar.length).join("-");
// prettier-ignore
log(
'\n Connected : ' + torrent.numPeers + ' peers\n' +
' Downloaded : ' + _formatBytes(torrent.downloaded) + ' (' + _formatBytes(torrent.downloadSpeed) + '/s)\n' +
' Uploaded : ' + _formatBytes(torrent.uploaded) + ' (' + _formatBytes(torrent.uploadSpeed) + '/s)\n' +
' Ratio : ' + torrent.ratio.toFixed(2) + '\n' +
' Size : ' + _formatBytes(torrent.length) + '\n' +
' ETA : ' + _formatTime(torrent.timeRemaining) + '\n' +
' [' + progressBar + '] ' + progress + '%\n'
);
};
const download = (torrentId, downloadPath) => {
return new Promise((resolve, reject) => {
// check if torrentId exist
if (!torrentId) {
return reject("No torrent id provided");
}
// client
const client = new WebTorrent({ maxConns: 200 });
client.on("error", err => {
client.destroy(() => {
return reject(err);
});
});
// torrent
const torrent = client.add(torrentId, { path: path.join(downloadPath) });
let st = setTimeout(() => {
if (torrent.numPeers < 1) {
client.destroy(() => {
return reject("Cannot find any peers!");
});
}
}, 1000 * 10);
torrent.on("error", err => {
if (st) clearTimeout(st);
client.destroy(() => {
return reject(err);
});
});
torrent.on("metadata", () => {
console.log("\n " + torrent.name);
torrent.files.forEach(file => {
console.log(` ├── ${file.name} (${_formatBytes(file.length)})`);
});
});
let time = Date.now() + 1000;
torrent.on("download", bytes => {
let t = Date.now();
if (t - time >= 1000) {
time = t;
torrentLog(torrent);
}
});
torrent.on("done", () => {
if (st) clearTimeout(st);
torrentLog(torrent);
let info = {
title: torrent.name,
infohash: torrent.infoHash,
path: torrent.path
};
let files = torrent.files.map(item => {
let { name, length, downloaded, progress } = item;
return {
name,
path: path.join(downloadPath, item.path),
length,
downloaded,
progress
};
});
client.destroy(() => {
console.log("");
resolve({ ...info, files: orderBy(files, ["length"], ["desc"]) });
});
});
});
};
module.exports = download;