mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-15 08:23:02 -03:00
refactor: remove unused JsMultiLinkDownloader and ensure aria2 spawning on startup
This commit is contained in:
@@ -34,11 +34,7 @@ export const loadState = async () => {
|
|||||||
|
|
||||||
await import("./events");
|
await import("./events");
|
||||||
|
|
||||||
// Only spawn aria2 if user explicitly disabled native HTTP downloader
|
Aria2.spawn();
|
||||||
// Default is to use native HTTP downloader (aria2 is opt-in)
|
|
||||||
if (userPreferences?.useNativeHttpDownloader === false) {
|
|
||||||
Aria2.spawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userPreferences?.realDebridApiToken) {
|
if (userPreferences?.realDebridApiToken) {
|
||||||
RealDebridClient.authorize(userPreferences.realDebridApiToken);
|
RealDebridClient.authorize(userPreferences.realDebridApiToken);
|
||||||
|
|||||||
@@ -2,4 +2,3 @@ export * from "./download-manager";
|
|||||||
export * from "./real-debrid";
|
export * from "./real-debrid";
|
||||||
export * from "./torbox";
|
export * from "./torbox";
|
||||||
export * from "./js-http-downloader";
|
export * from "./js-http-downloader";
|
||||||
export * from "./js-multi-link-downloader";
|
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
import { JsHttpDownloader, JsHttpDownloaderStatus } from "./js-http-downloader";
|
|
||||||
import { logger } from "../logger";
|
|
||||||
|
|
||||||
export interface JsMultiLinkDownloaderOptions {
|
|
||||||
urls: string[];
|
|
||||||
savePath: string;
|
|
||||||
headers?: Record<string, string>;
|
|
||||||
totalSize?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CompletedDownload {
|
|
||||||
name: string;
|
|
||||||
size: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class JsMultiLinkDownloader {
|
|
||||||
private downloader: JsHttpDownloader | null = null;
|
|
||||||
private currentOptions: JsMultiLinkDownloaderOptions | null = null;
|
|
||||||
private currentUrlIndex = 0;
|
|
||||||
private completedDownloads: CompletedDownload[] = [];
|
|
||||||
private totalSize: number | null = null;
|
|
||||||
private isDownloading = false;
|
|
||||||
private isPaused = false;
|
|
||||||
|
|
||||||
async startDownload(options: JsMultiLinkDownloaderOptions): Promise<void> {
|
|
||||||
this.currentOptions = options;
|
|
||||||
this.currentUrlIndex = 0;
|
|
||||||
this.completedDownloads = [];
|
|
||||||
this.totalSize = options.totalSize ?? null;
|
|
||||||
this.isDownloading = true;
|
|
||||||
this.isPaused = false;
|
|
||||||
|
|
||||||
await this.downloadNextUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async downloadNextUrl(): Promise<void> {
|
|
||||||
if (!this.currentOptions || this.isPaused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { urls, savePath, headers } = this.currentOptions;
|
|
||||||
|
|
||||||
if (this.currentUrlIndex >= urls.length) {
|
|
||||||
logger.log("[JsMultiLinkDownloader] All downloads complete");
|
|
||||||
this.isDownloading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = urls[this.currentUrlIndex];
|
|
||||||
logger.log(
|
|
||||||
`[JsMultiLinkDownloader] Starting download ${this.currentUrlIndex + 1}/${urls.length}`
|
|
||||||
);
|
|
||||||
|
|
||||||
this.downloader = new JsHttpDownloader();
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.downloader.startDownload({
|
|
||||||
url,
|
|
||||||
savePath,
|
|
||||||
headers,
|
|
||||||
});
|
|
||||||
|
|
||||||
const status = this.downloader.getDownloadStatus();
|
|
||||||
if (status?.status === "complete") {
|
|
||||||
this.completedDownloads.push({
|
|
||||||
name: status.folderName,
|
|
||||||
size: status.fileSize,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentUrlIndex++;
|
|
||||||
this.downloader = null;
|
|
||||||
|
|
||||||
if (!this.isPaused) {
|
|
||||||
await this.downloadNextUrl();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("[JsMultiLinkDownloader] Download error:", err);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pauseDownload(): void {
|
|
||||||
logger.log("[JsMultiLinkDownloader] Pausing download");
|
|
||||||
this.isPaused = true;
|
|
||||||
if (this.downloader) {
|
|
||||||
this.downloader.pauseDownload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async resumeDownload(): Promise<void> {
|
|
||||||
if (!this.currentOptions) {
|
|
||||||
throw new Error("No download options available for resume");
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.log("[JsMultiLinkDownloader] Resuming download");
|
|
||||||
this.isPaused = false;
|
|
||||||
this.isDownloading = true;
|
|
||||||
|
|
||||||
if (this.downloader) {
|
|
||||||
await this.downloader.startDownload({
|
|
||||||
url: this.currentOptions.urls[this.currentUrlIndex],
|
|
||||||
savePath: this.currentOptions.savePath,
|
|
||||||
headers: this.currentOptions.headers,
|
|
||||||
});
|
|
||||||
|
|
||||||
const status = this.downloader.getDownloadStatus();
|
|
||||||
if (status?.status === "complete") {
|
|
||||||
this.completedDownloads.push({
|
|
||||||
name: status.folderName,
|
|
||||||
size: status.fileSize,
|
|
||||||
});
|
|
||||||
this.currentUrlIndex++;
|
|
||||||
this.downloader = null;
|
|
||||||
await this.downloadNextUrl();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.downloadNextUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelDownload(): void {
|
|
||||||
logger.log("[JsMultiLinkDownloader] Cancelling download");
|
|
||||||
this.isPaused = true;
|
|
||||||
this.isDownloading = false;
|
|
||||||
|
|
||||||
if (this.downloader) {
|
|
||||||
this.downloader.cancelDownload();
|
|
||||||
this.downloader = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
getDownloadStatus(): JsHttpDownloaderStatus | null {
|
|
||||||
if (!this.currentOptions && this.completedDownloads.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalBytesDownloaded = 0;
|
|
||||||
let currentDownloadSpeed = 0;
|
|
||||||
let currentFolderName = "";
|
|
||||||
let currentStatus: "active" | "paused" | "complete" | "error" = "active";
|
|
||||||
|
|
||||||
for (const completed of this.completedDownloads) {
|
|
||||||
totalBytesDownloaded += completed.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.downloader) {
|
|
||||||
const status = this.downloader.getDownloadStatus();
|
|
||||||
if (status) {
|
|
||||||
totalBytesDownloaded += status.bytesDownloaded;
|
|
||||||
currentDownloadSpeed = status.downloadSpeed;
|
|
||||||
currentFolderName = status.folderName;
|
|
||||||
currentStatus = status.status;
|
|
||||||
}
|
|
||||||
} else if (this.completedDownloads.length > 0) {
|
|
||||||
currentFolderName = this.completedDownloads[0].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFolderName?.includes("/")) {
|
|
||||||
currentFolderName = currentFolderName.split("/")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalFileSize =
|
|
||||||
this.totalSize ||
|
|
||||||
this.completedDownloads.reduce((sum, d) => sum + d.size, 0) +
|
|
||||||
(this.downloader?.getDownloadStatus()?.fileSize || 0);
|
|
||||||
|
|
||||||
const allComplete =
|
|
||||||
!this.isDownloading &&
|
|
||||||
this.currentOptions &&
|
|
||||||
this.currentUrlIndex >= this.currentOptions.urls.length;
|
|
||||||
|
|
||||||
if (allComplete) {
|
|
||||||
currentStatus = "complete";
|
|
||||||
} else if (this.isPaused) {
|
|
||||||
currentStatus = "paused";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
folderName: currentFolderName,
|
|
||||||
fileSize: totalFileSize,
|
|
||||||
progress: totalFileSize > 0 ? totalBytesDownloaded / totalFileSize : 0,
|
|
||||||
downloadSpeed: currentDownloadSpeed,
|
|
||||||
numPeers: 0,
|
|
||||||
numSeeds: 0,
|
|
||||||
status: currentStatus,
|
|
||||||
bytesDownloaded: totalBytesDownloaded,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private reset(): void {
|
|
||||||
this.currentOptions = null;
|
|
||||||
this.currentUrlIndex = 0;
|
|
||||||
this.completedDownloads = [];
|
|
||||||
this.totalSize = null;
|
|
||||||
this.isDownloading = false;
|
|
||||||
this.isPaused = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user