Merge pull request #1906 from Wkeynhk/main

Buzzheavier fix
This commit is contained in:
Chubby Granny Chaser
2025-12-27 00:47:44 +00:00
committed by GitHub

View File

@@ -29,24 +29,30 @@ import { BuzzheavierApi, FuckingFastApi } from "@main/services/hosters";
export class DownloadManager {
private static downloadingGameId: string | null = null;
private static extractFilename(
url: string,
originalUrl?: string
): string | undefined {
if (originalUrl?.includes("#")) {
const hashPart = originalUrl.split("#")[1];
if (hashPart && !hashPart.startsWith("http")) return hashPart;
private static extractFilename(url: string, originalUrl?: string): string | undefined {
if (originalUrl?.includes('#')) {
const hashPart = originalUrl.split('#')[1];
if (hashPart && !hashPart.startsWith('http') && hashPart.includes('.')) {
return hashPart;
}
}
if (url.includes("#")) {
const hashPart = url.split("#")[1];
if (hashPart && !hashPart.startsWith("http")) return hashPart;
if (url.includes('#')) {
const hashPart = url.split('#')[1];
if (hashPart && !hashPart.startsWith('http') && hashPart.includes('.')) {
return hashPart;
}
}
try {
const urlObj = new URL(url);
const filename = urlObj.pathname.split("/").pop();
if (filename?.length) return filename;
const pathname = urlObj.pathname;
const pathParts = pathname.split('/');
const filename = pathParts[pathParts.length - 1];
if (filename?.includes('.') && filename.length > 0) {
return decodeURIComponent(filename);
}
} catch {
// Invalid URL
}
@@ -55,22 +61,17 @@ export class DownloadManager {
}
private static sanitizeFilename(filename: string): string {
return filename.replace(/[<>:"/\\|?*]/g, "_");
return filename.replaceAll(/[<>:"/\\|?*]/g, '_');
}
private static createDownloadPayload(
directUrl: string,
originalUrl: string,
downloadId: string,
savePath: string
) {
const filename = this.extractFilename(directUrl, originalUrl);
const sanitizedFilename = filename
? this.sanitizeFilename(filename)
: undefined;
private static createDownloadPayload(directUrl: string, originalUrl: string, downloadId: string, savePath: string) {
const filename = this.extractFilename(originalUrl, directUrl) || this.extractFilename(directUrl);
const sanitizedFilename = filename ? this.sanitizeFilename(filename) : undefined;
if (sanitizedFilename) {
logger.log(`[DownloadManager] Using filename: ${sanitizedFilename}`);
} else {
logger.log(`[DownloadManager] No filename extracted, aria2 will use default`);
}
return {
@@ -108,9 +109,7 @@ export class DownloadManager {
}
private static async getDownloadStatus() {
const response = await PythonRPC.rpc.get<LibtorrentPayload | null>(
"/status"
);
const response = await PythonRPC.rpc.get<LibtorrentPayload | null>("/status");
if (response.data === null || !this.downloadingGameId) return null;
const downloadId = this.downloadingGameId;
@@ -126,8 +125,7 @@ export class DownloadManager {
status,
} = response.data;
const isDownloadingMetadata =
status === LibtorrentStatus.DownloadingMetadata;
const isDownloadingMetadata = status === LibtorrentStatus.DownloadingMetadata;
const isCheckingFiles = status === LibtorrentStatus.CheckingFiles;
const download = await downloadsSublevel.get(downloadId);
@@ -192,10 +190,7 @@ export class DownloadManager {
if (progress === 1 && download) {
publishDownloadCompleteNotification(game);
if (
userPreferences?.seedAfterDownloadComplete &&
download.downloader === Downloader.Torrent
) {
if (userPreferences?.seedAfterDownloadComplete && download.downloader === Downloader.Torrent) {
await downloadsSublevel.put(gameId, {
...download,
status: "seeding",
@@ -216,22 +211,13 @@ export class DownloadManager {
}
if (shouldExtract) {
const gameFilesManager = new GameFilesManager(
game.shop,
game.objectId
);
const gameFilesManager = new GameFilesManager(game.shop, game.objectId);
if (
FILE_EXTENSIONS_TO_EXTRACT.some((ext) =>
download.folderName?.endsWith(ext)
)
) {
if (FILE_EXTENSIONS_TO_EXTRACT.some((ext) => download.folderName?.endsWith(ext))) {
gameFilesManager.extractDownloadedFile();
} else {
gameFilesManager
.extractFilesInDirectory(
path.join(download.downloadPath, download.folderName!)
)
.extractFilesInDirectory(path.join(download.downloadPath, download.folderName))
.then(() => gameFilesManager.setExtractionComplete());
}
}
@@ -239,13 +225,11 @@ export class DownloadManager {
const downloads = await downloadsSublevel
.values()
.all()
.then((games) =>
sortBy(
games.filter((game) => game.status === "paused" && game.queued),
"timestamp",
"DESC"
)
);
.then((games) => sortBy(
games.filter((game) => game.status === "paused" && game.queued),
"timestamp",
"DESC"
));
const [nextItemOnQueue] = downloads;
@@ -272,9 +256,7 @@ export class DownloadManager {
if (!download) return;
const totalSize = await getDirSize(
path.join(download.downloadPath, status.folderName)
);
const totalSize = await getDirSize(path.join(download.downloadPath, status.folderName));
if (totalSize < status.fileSize) {
await this.cancelDownload(status.gameId);
@@ -295,10 +277,7 @@ export class DownloadManager {
static async pauseDownload(downloadKey = this.downloadingGameId) {
await PythonRPC.rpc
.post("/action", {
action: "pause",
game_id: downloadKey,
} as PauseDownloadPayload)
.post("/action", { action: "pause", game_id: downloadKey } as PauseDownloadPayload)
.catch(() => {});
if (downloadKey === this.downloadingGameId) {
@@ -389,44 +368,24 @@ export class DownloadManager {
};
}
case Downloader.Buzzheavier: {
logger.log(
`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`
);
logger.log(`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`);
try {
const directUrl = await BuzzheavierApi.getDirectLink(download.uri);
logger.log(`[DownloadManager] Buzzheavier direct URL obtained`);
return this.createDownloadPayload(
directUrl,
download.uri,
downloadId,
download.downloadPath
);
return this.createDownloadPayload(directUrl, download.uri, downloadId, download.downloadPath);
} catch (error) {
logger.error(
`[DownloadManager] Error processing Buzzheavier download:`,
error
);
logger.error(`[DownloadManager] Error processing Buzzheavier download:`, error);
throw error;
}
}
case Downloader.FuckingFast: {
logger.log(
`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`
);
logger.log(`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`);
try {
const directUrl = await FuckingFastApi.getDirectLink(download.uri);
logger.log(`[DownloadManager] FuckingFast direct URL obtained`);
return this.createDownloadPayload(
directUrl,
download.uri,
downloadId,
download.downloadPath
);
return this.createDownloadPayload(directUrl, download.uri, downloadId, download.downloadPath);
} catch (error) {
logger.error(
`[DownloadManager] Error processing FuckingFast download:`,
error
);
logger.error(`[DownloadManager] Error processing FuckingFast download:`, error);
throw error;
}
}
@@ -471,9 +430,7 @@ export class DownloadManager {
};
}
case Downloader.Hydra: {
const downloadUrl = await HydraDebridClient.getDownloadUrl(
download.uri
);
const downloadUrl = await HydraDebridClient.getDownloadUrl(download.uri);
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnHydra);
return {