relic/packages/core/src/helpers/downloadTorrent.js

93 lines
2.6 KiB
JavaScript

import fs from "node:fs"
import path from "node:path"
import cliProgress from "cli-progress"
import humanFormat from "human-format"
function convertSize(size) {
return `${humanFormat(size, {
decimals: 2,
})}B`
}
export default async function downloadTorrent(
magnet,
destination,
{
onStart,
onProgress,
onDone,
onError,
} = {}
) {
let progressInterval = null
let tickProgress = {
total: 0,
transferred: 0,
speed: 0,
totalString: "0B",
transferredString: "0B",
speedString: "0B/s",
}
const client = new WebTorrent()
await new Promise((resolve, reject) => {
client.add(magnet, (torrentInstance) => {
const progressBar = new cliProgress.SingleBar({
format: "[{bar}] {percentage}% | {total_formatted} | {speed}/s | {eta_formatted}",
barCompleteChar: "\u2588",
barIncompleteChar: "\u2591",
hideCursor: true
}, cliProgress.Presets.shades_classic)
if (typeof onStart === "function") {
onStart(torrentInstance)
}
progressBar.start(tickProgress.total, 0, {
speed: "0B/s",
total_formatted: tickProgress.totalString,
})
torrentInstance.on("done", () => {
progressBar.stop()
clearInterval(progressInterval)
if (typeof onDone === "function") {
onDone(torrentInstance)
}
resolve(torrentInstance)
})
torrentInstance.on("error", (error) => {
progressBar.stop()
clearInterval(progressInterval)
if (typeof onError === "function") {
onError(error)
} else {
reject(error)
}
})
progressInterval = setInterval(() => {
tickProgress.speed = torrentInstance.downloadSpeed
tickProgress.transferred = torrentInstance.downloaded
tickProgress.transferredString = convertSize(tickProgress.transferred)
tickProgress.totalString = convertSize(tickProgress.total)
tickProgress.speedString = convertSize(tickProgress.speed)
if (typeof onProgress === "function") {
onProgress(tickProgress)
}
progressBar.update(tickProgress.transferred, {
speed: tickProgress.speedString,
})
}, 1000)
})
})
}