refactor: enhance download management by validating URLs and adding file size handling

This commit is contained in:
Moyasee
2026-01-24 19:38:00 +02:00
parent fb1380356e
commit eea7148108
8 changed files with 153 additions and 46 deletions

View File

@@ -15,14 +15,7 @@ const deleteGameFolder = async (
const downloadKey = levelKeys.game(shop, objectId);
const download = await downloadsSublevel.get(downloadKey);
if (!download?.folderName) return;
const folderPath = path.join(
download.downloadPath ?? (await getDownloadsPath()),
download.folderName
);
const metaPath = `${folderPath}.meta`;
if (!download) return;
const deleteFile = async (filePath: string, isDirectory = false) => {
if (fs.existsSync(filePath)) {
@@ -47,8 +40,18 @@ const deleteGameFolder = async (
}
};
await deleteFile(folderPath, true);
await deleteFile(metaPath);
if (download.folderName) {
const folderPath = path.join(
download.downloadPath ?? (await getDownloadsPath()),
download.folderName
);
const metaPath = `${folderPath}.meta`;
await deleteFile(folderPath, true);
await deleteFile(metaPath);
}
await downloadsSublevel.del(downloadKey);
};

View File

@@ -1,6 +1,6 @@
import { registerEvent } from "../register-event";
import type { Download, StartGameDownloadPayload } from "@types";
import { HydraApi, logger } from "@main/services";
import { DownloadManager, HydraApi, logger } from "@main/services";
import { createGame } from "@main/services/library-sync";
import {
downloadsSublevel,
@@ -8,6 +8,8 @@ import {
gamesSublevel,
levelKeys,
} from "@main/level";
import { Downloader, DownloadError, parseBytes } from "@shared";
import { AxiosError } from "axios";
const addGameToQueue = async (
_event: Electron.IpcMainInvokeEvent,
@@ -21,10 +23,86 @@ const addGameToQueue = async (
downloader,
uri,
automaticallyExtract,
fileSize,
} = payload;
const gameKey = levelKeys.game(shop, objectId);
const download: Download = {
shop,
objectId,
status: "paused",
progress: 0,
bytesDownloaded: 0,
downloadPath,
downloader,
uri,
folderName: null,
fileSize: parseBytes(fileSize ?? null),
shouldSeed: false,
timestamp: Date.now(),
queued: true,
extracting: false,
automaticallyExtract,
extractionProgress: 0,
};
try {
await DownloadManager.validateDownloadUrl(download);
} catch (err: unknown) {
logger.error("Failed to validate download URL for queue", err);
if (err instanceof AxiosError) {
if (err.response?.status === 429 && downloader === Downloader.Gofile) {
return { ok: false, error: DownloadError.GofileQuotaExceeded };
}
if (
err.response?.status === 403 &&
downloader === Downloader.RealDebrid
) {
return {
ok: false,
error: DownloadError.RealDebridAccountNotAuthorized,
};
}
if (downloader === Downloader.TorBox) {
return { ok: false, error: err.response?.data?.detail };
}
}
if (err instanceof Error) {
if (downloader === Downloader.Buzzheavier) {
if (err.message.includes("Rate limit")) {
return { ok: false, error: "Buzzheavier: Rate limit exceeded" };
}
if (
err.message.includes("not found") ||
err.message.includes("deleted")
) {
return { ok: false, error: "Buzzheavier: File not found" };
}
}
if (downloader === Downloader.FuckingFast) {
if (err.message.includes("Rate limit")) {
return { ok: false, error: "FuckingFast: Rate limit exceeded" };
}
if (
err.message.includes("not found") ||
err.message.includes("deleted")
) {
return { ok: false, error: "FuckingFast: File not found" };
}
}
return { ok: false, error: err.message };
}
return { ok: false };
}
const game = await gamesSublevel.get(gameKey);
const gameAssets = await gamesShopAssetsSublevel.get(gameKey);
@@ -50,25 +128,6 @@ const addGameToQueue = async (
});
}
const download: Download = {
shop,
objectId,
status: "paused",
progress: 0,
bytesDownloaded: 0,
downloadPath,
downloader,
uri,
folderName: null,
fileSize: null,
shouldSeed: false,
timestamp: Date.now(),
queued: true,
extracting: false,
automaticallyExtract,
extractionProgress: 0,
};
try {
await downloadsSublevel.put(gameKey, download);

View File

@@ -2,7 +2,7 @@ import { registerEvent } from "../register-event";
import type { Download, StartGameDownloadPayload } from "@types";
import { DownloadManager, HydraApi, logger } from "@main/services";
import { createGame } from "@main/services/library-sync";
import { Downloader, DownloadError } from "@shared";
import { Downloader, DownloadError, parseBytes } from "@shared";
import {
downloadsSublevel,
gamesShopAssetsSublevel,
@@ -23,6 +23,7 @@ const startGameDownload = async (
downloader,
uri,
automaticallyExtract,
fileSize,
} = payload;
const gameKey = levelKeys.game(shop, objectId);
@@ -75,7 +76,7 @@ const startGameDownload = async (
downloader,
uri,
folderName: null,
fileSize: null,
fileSize: parseBytes(fileSize ?? null),
shouldSeed: false,
timestamp: Date.now(),
queued: true,