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");
|
||||
|
||||
// Only spawn aria2 if user explicitly disabled native HTTP downloader
|
||||
// Default is to use native HTTP downloader (aria2 is opt-in)
|
||||
if (userPreferences?.useNativeHttpDownloader === false) {
|
||||
Aria2.spawn();
|
||||
}
|
||||
Aria2.spawn();
|
||||
|
||||
if (userPreferences?.realDebridApiToken) {
|
||||
RealDebridClient.authorize(userPreferences.realDebridApiToken);
|
||||
|
||||
@@ -2,4 +2,3 @@ export * from "./download-manager";
|
||||
export * from "./real-debrid";
|
||||
export * from "./torbox";
|
||||
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