mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-15 08:23:02 -03:00
refactor: enhance download management by adding filename resolution and extraction handling in DownloadManage
This commit is contained in:
@@ -75,6 +75,34 @@ export class DownloadManager {
|
|||||||
return filename.replaceAll(/[<>:"/\\|?*]/g, "_");
|
return filename.replaceAll(/[<>:"/\\|?*]/g, "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static resolveFilename(
|
||||||
|
resumingFilename: string | undefined,
|
||||||
|
originalUrl: string,
|
||||||
|
downloadUrl: string
|
||||||
|
): string | undefined {
|
||||||
|
if (resumingFilename) return resumingFilename;
|
||||||
|
|
||||||
|
const extracted =
|
||||||
|
this.extractFilename(originalUrl, downloadUrl) ||
|
||||||
|
this.extractFilename(downloadUrl);
|
||||||
|
|
||||||
|
return extracted ? this.sanitizeFilename(extracted) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static buildDownloadOptions(
|
||||||
|
url: string,
|
||||||
|
savePath: string,
|
||||||
|
filename: string | undefined,
|
||||||
|
headers?: Record<string, string>
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
url,
|
||||||
|
savePath,
|
||||||
|
filename,
|
||||||
|
headers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static createDownloadPayload(
|
private static createDownloadPayload(
|
||||||
directUrl: string,
|
directUrl: string,
|
||||||
originalUrl: string,
|
originalUrl: string,
|
||||||
@@ -286,100 +314,127 @@ export class DownloadManager {
|
|||||||
|
|
||||||
public static async watchDownloads() {
|
public static async watchDownloads() {
|
||||||
const status = await this.getDownloadStatus();
|
const status = await this.getDownloadStatus();
|
||||||
|
if (!status) return;
|
||||||
|
|
||||||
if (status) {
|
const { gameId, progress } = status;
|
||||||
const { gameId, progress } = status;
|
const [download, game] = await Promise.all([
|
||||||
|
downloadsSublevel.get(gameId),
|
||||||
|
gamesSublevel.get(gameId),
|
||||||
|
]);
|
||||||
|
|
||||||
const [download, game] = await Promise.all([
|
if (!download || !game) return;
|
||||||
downloadsSublevel.get(gameId),
|
|
||||||
gamesSublevel.get(gameId),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!download || !game) return;
|
this.sendProgressUpdate(progress, status, game);
|
||||||
|
|
||||||
const userPreferences = await db.get<string, UserPreferences | null>(
|
if (progress === 1) {
|
||||||
levelKeys.userPreferences,
|
await this.handleDownloadCompletion(download, game, gameId);
|
||||||
{ valueEncoding: "json" }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static sendProgressUpdate(
|
||||||
|
progress: number,
|
||||||
|
status: DownloadProgress,
|
||||||
|
game: any
|
||||||
|
) {
|
||||||
|
if (WindowManager.mainWindow) {
|
||||||
|
WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress);
|
||||||
|
WindowManager.mainWindow.webContents.send(
|
||||||
|
"on-download-progress",
|
||||||
|
structuredClone({ ...status, game })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async handleDownloadCompletion(
|
||||||
|
download: Download,
|
||||||
|
game: any,
|
||||||
|
gameId: string
|
||||||
|
) {
|
||||||
|
publishDownloadCompleteNotification(game);
|
||||||
|
|
||||||
|
const userPreferences = await db.get<string, UserPreferences | null>(
|
||||||
|
levelKeys.userPreferences,
|
||||||
|
{ valueEncoding: "json" }
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.updateDownloadStatus(
|
||||||
|
download,
|
||||||
|
gameId,
|
||||||
|
userPreferences?.seedAfterDownloadComplete
|
||||||
|
);
|
||||||
|
|
||||||
|
if (download.automaticallyExtract) {
|
||||||
|
this.handleExtraction(download, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.processNextQueuedDownload();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async updateDownloadStatus(
|
||||||
|
download: Download,
|
||||||
|
gameId: string,
|
||||||
|
shouldSeed?: boolean
|
||||||
|
) {
|
||||||
|
const shouldExtract = download.automaticallyExtract;
|
||||||
|
|
||||||
|
if (shouldSeed && download.downloader === Downloader.Torrent) {
|
||||||
|
await downloadsSublevel.put(gameId, {
|
||||||
|
...download,
|
||||||
|
status: "seeding",
|
||||||
|
shouldSeed: true,
|
||||||
|
queued: false,
|
||||||
|
extracting: shouldExtract,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await downloadsSublevel.put(gameId, {
|
||||||
|
...download,
|
||||||
|
status: "complete",
|
||||||
|
shouldSeed: false,
|
||||||
|
queued: false,
|
||||||
|
extracting: shouldExtract,
|
||||||
|
});
|
||||||
|
this.cancelDownload(gameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static handleExtraction(download: Download, game: any) {
|
||||||
|
const gameFilesManager = new GameFilesManager(game.shop, game.objectId);
|
||||||
|
|
||||||
|
if (
|
||||||
|
FILE_EXTENSIONS_TO_EXTRACT.some((ext) =>
|
||||||
|
download.folderName?.endsWith(ext)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
gameFilesManager.extractDownloadedFile();
|
||||||
|
} else if (download.folderName) {
|
||||||
|
gameFilesManager
|
||||||
|
.extractFilesInDirectory(
|
||||||
|
path.join(download.downloadPath, download.folderName)
|
||||||
|
)
|
||||||
|
.then(() => gameFilesManager.setExtractionComplete());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async processNextQueuedDownload() {
|
||||||
|
const downloads = await downloadsSublevel
|
||||||
|
.values()
|
||||||
|
.all()
|
||||||
|
.then((games) =>
|
||||||
|
sortBy(
|
||||||
|
games.filter((game) => game.status === "paused" && game.queued),
|
||||||
|
"timestamp",
|
||||||
|
"DESC"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (WindowManager.mainWindow && download) {
|
const [nextItemOnQueue] = downloads;
|
||||||
WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress);
|
|
||||||
WindowManager.mainWindow.webContents.send(
|
|
||||||
"on-download-progress",
|
|
||||||
structuredClone({ ...status, game })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const shouldExtract = download.automaticallyExtract;
|
if (nextItemOnQueue) {
|
||||||
|
this.resumeDownload(nextItemOnQueue);
|
||||||
if (progress === 1 && download) {
|
} else {
|
||||||
publishDownloadCompleteNotification(game);
|
this.downloadingGameId = null;
|
||||||
|
this.usingJsDownloader = false;
|
||||||
if (
|
this.jsDownloader = null;
|
||||||
userPreferences?.seedAfterDownloadComplete &&
|
|
||||||
download.downloader === Downloader.Torrent
|
|
||||||
) {
|
|
||||||
await downloadsSublevel.put(gameId, {
|
|
||||||
...download,
|
|
||||||
status: "seeding",
|
|
||||||
shouldSeed: true,
|
|
||||||
queued: false,
|
|
||||||
extracting: shouldExtract,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await downloadsSublevel.put(gameId, {
|
|
||||||
...download,
|
|
||||||
status: "complete",
|
|
||||||
shouldSeed: false,
|
|
||||||
queued: false,
|
|
||||||
extracting: shouldExtract,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.cancelDownload(gameId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldExtract) {
|
|
||||||
const gameFilesManager = new GameFilesManager(
|
|
||||||
game.shop,
|
|
||||||
game.objectId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
FILE_EXTENSIONS_TO_EXTRACT.some((ext) =>
|
|
||||||
download.folderName?.endsWith(ext)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
gameFilesManager.extractDownloadedFile();
|
|
||||||
} else if (download.folderName) {
|
|
||||||
gameFilesManager
|
|
||||||
.extractFilesInDirectory(
|
|
||||||
path.join(download.downloadPath, download.folderName)
|
|
||||||
)
|
|
||||||
.then(() => gameFilesManager.setExtractionComplete());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const downloads = await downloadsSublevel
|
|
||||||
.values()
|
|
||||||
.all()
|
|
||||||
.then((games) =>
|
|
||||||
sortBy(
|
|
||||||
games.filter((game) => game.status === "paused" && game.queued),
|
|
||||||
"timestamp",
|
|
||||||
"DESC"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const [nextItemOnQueue] = downloads;
|
|
||||||
|
|
||||||
if (nextItemOnQueue) {
|
|
||||||
this.resumeDownload(nextItemOnQueue);
|
|
||||||
} else {
|
|
||||||
this.downloadingGameId = null;
|
|
||||||
this.usingJsDownloader = false;
|
|
||||||
this.jsDownloader = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,173 +539,235 @@ export class DownloadManager {
|
|||||||
filename?: string;
|
filename?: string;
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
} | null> {
|
} | null> {
|
||||||
// If resuming and we already have a folderName, use it to ensure we find the partial file
|
|
||||||
const resumingFilename = download.folderName || undefined;
|
const resumingFilename = download.folderName || undefined;
|
||||||
|
|
||||||
switch (download.downloader) {
|
switch (download.downloader) {
|
||||||
case Downloader.Gofile: {
|
case Downloader.Gofile:
|
||||||
const id = download.uri.split("/").pop();
|
return this.getGofileDownloadOptions(download, resumingFilename);
|
||||||
const token = await GofileApi.authorize();
|
case Downloader.PixelDrain:
|
||||||
const downloadLink = await GofileApi.getDownloadLink(id!);
|
return this.getPixelDrainDownloadOptions(download, resumingFilename);
|
||||||
await GofileApi.checkDownloadUrl(downloadLink);
|
case Downloader.Qiwi:
|
||||||
const filename =
|
return this.getQiwiDownloadOptions(download, resumingFilename);
|
||||||
resumingFilename ||
|
case Downloader.Datanodes:
|
||||||
this.extractFilename(download.uri, downloadLink) ||
|
return this.getDatanodesDownloadOptions(download, resumingFilename);
|
||||||
this.extractFilename(downloadLink);
|
case Downloader.Buzzheavier:
|
||||||
|
return this.getBuzzheavierDownloadOptions(download, resumingFilename);
|
||||||
return {
|
case Downloader.FuckingFast:
|
||||||
url: downloadLink,
|
return this.getFuckingFastDownloadOptions(download, resumingFilename);
|
||||||
savePath: download.downloadPath,
|
case Downloader.Mediafire:
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
return this.getMediafireDownloadOptions(download, resumingFilename);
|
||||||
headers: { Cookie: `accountToken=${token}` },
|
case Downloader.RealDebrid:
|
||||||
};
|
return this.getRealDebridDownloadOptions(download, resumingFilename);
|
||||||
}
|
case Downloader.TorBox:
|
||||||
case Downloader.PixelDrain: {
|
return this.getTorBoxDownloadOptions(download, resumingFilename);
|
||||||
const id = download.uri.split("/").pop();
|
case Downloader.Hydra:
|
||||||
const downloadUrl = await PixelDrainApi.getDownloadUrl(id!);
|
return this.getHydraDownloadOptions(download, resumingFilename);
|
||||||
const filename =
|
case Downloader.VikingFile:
|
||||||
resumingFilename ||
|
return this.getVikingFileDownloadOptions(download, resumingFilename);
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.Qiwi: {
|
|
||||||
const downloadUrl = await QiwiApi.getDownloadUrl(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.Datanodes: {
|
|
||||||
const downloadUrl = await DatanodesApi.getDownloadUrl(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.Buzzheavier: {
|
|
||||||
logger.log(
|
|
||||||
`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`
|
|
||||||
);
|
|
||||||
const directUrl = await BuzzheavierApi.getDirectLink(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, directUrl) ||
|
|
||||||
this.extractFilename(directUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: directUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.FuckingFast: {
|
|
||||||
logger.log(
|
|
||||||
`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`
|
|
||||||
);
|
|
||||||
const directUrl = await FuckingFastApi.getDirectLink(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, directUrl) ||
|
|
||||||
this.extractFilename(directUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: directUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.Mediafire: {
|
|
||||||
const downloadUrl = await MediafireApi.getDownloadUrl(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.RealDebrid: {
|
|
||||||
const downloadUrl = await RealDebridClient.getDownloadUrl(download.uri);
|
|
||||||
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnRealDebrid);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.TorBox: {
|
|
||||||
const { name, url } = await TorBoxClient.getDownloadInfo(download.uri);
|
|
||||||
if (!url) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
url,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: resumingFilename || name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.Hydra: {
|
|
||||||
const downloadUrl = await HydraDebridClient.getDownloadUrl(
|
|
||||||
download.uri
|
|
||||||
);
|
|
||||||
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnHydra);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case Downloader.VikingFile: {
|
|
||||||
logger.log(
|
|
||||||
`[DownloadManager] Processing VikingFile download for URI: ${download.uri}`
|
|
||||||
);
|
|
||||||
const downloadUrl = await VikingFileApi.getDownloadUrl(download.uri);
|
|
||||||
const filename =
|
|
||||||
resumingFilename ||
|
|
||||||
this.extractFilename(download.uri, downloadUrl) ||
|
|
||||||
this.extractFilename(downloadUrl);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: downloadUrl,
|
|
||||||
savePath: download.downloadPath,
|
|
||||||
filename: filename ? this.sanitizeFilename(filename) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async getGofileDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const id = download.uri.split("/").pop();
|
||||||
|
const token = await GofileApi.authorize();
|
||||||
|
const downloadLink = await GofileApi.getDownloadLink(id!);
|
||||||
|
await GofileApi.checkDownloadUrl(downloadLink);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadLink
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadLink,
|
||||||
|
download.downloadPath,
|
||||||
|
filename,
|
||||||
|
{ Cookie: `accountToken=${token}` }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getPixelDrainDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const id = download.uri.split("/").pop();
|
||||||
|
const downloadUrl = await PixelDrainApi.getDownloadUrl(id!);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getQiwiDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const downloadUrl = await QiwiApi.getDownloadUrl(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getDatanodesDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const downloadUrl = await DatanodesApi.getDownloadUrl(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getBuzzheavierDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
logger.log(
|
||||||
|
`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`
|
||||||
|
);
|
||||||
|
const directUrl = await BuzzheavierApi.getDirectLink(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
directUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
directUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getFuckingFastDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
logger.log(
|
||||||
|
`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`
|
||||||
|
);
|
||||||
|
const directUrl = await FuckingFastApi.getDirectLink(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
directUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
directUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getMediafireDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const downloadUrl = await MediafireApi.getDownloadUrl(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getRealDebridDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const downloadUrl = await RealDebridClient.getDownloadUrl(download.uri);
|
||||||
|
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnRealDebrid);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getTorBoxDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const { name, url } = await TorBoxClient.getDownloadInfo(download.uri);
|
||||||
|
if (!url) return null;
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
url,
|
||||||
|
download.downloadPath,
|
||||||
|
resumingFilename || name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getHydraDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
const downloadUrl = await HydraDebridClient.getDownloadUrl(download.uri);
|
||||||
|
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnHydra);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async getVikingFileDownloadOptions(
|
||||||
|
download: Download,
|
||||||
|
resumingFilename?: string
|
||||||
|
) {
|
||||||
|
logger.log(
|
||||||
|
`[DownloadManager] Processing VikingFile download for URI: ${download.uri}`
|
||||||
|
);
|
||||||
|
const downloadUrl = await VikingFileApi.getDownloadUrl(download.uri);
|
||||||
|
const filename = this.resolveFilename(
|
||||||
|
resumingFilename,
|
||||||
|
download.uri,
|
||||||
|
downloadUrl
|
||||||
|
);
|
||||||
|
return this.buildDownloadOptions(
|
||||||
|
downloadUrl,
|
||||||
|
download.downloadPath,
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static async getDownloadPayload(download: Download) {
|
private static async getDownloadPayload(download: Download) {
|
||||||
const downloadId = levelKeys.game(download.shop, download.objectId);
|
const downloadId = levelKeys.game(download.shop, download.objectId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user