mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-25 20:01:03 +00:00
refactor: improve code formatting and logging consistency in download manager and buzzheavier services
This commit is contained in:
@@ -29,20 +29,23 @@ import { BuzzheavierApi, FuckingFastApi } from "@main/services/hosters";
|
|||||||
export class DownloadManager {
|
export class DownloadManager {
|
||||||
private static downloadingGameId: string | null = null;
|
private static downloadingGameId: string | null = null;
|
||||||
|
|
||||||
private static extractFilename(url: string, originalUrl?: string): string | undefined {
|
private static extractFilename(
|
||||||
if (originalUrl?.includes('#')) {
|
url: string,
|
||||||
const hashPart = originalUrl.split('#')[1];
|
originalUrl?: string
|
||||||
if (hashPart && !hashPart.startsWith('http')) return hashPart;
|
): string | undefined {
|
||||||
|
if (originalUrl?.includes("#")) {
|
||||||
|
const hashPart = originalUrl.split("#")[1];
|
||||||
|
if (hashPart && !hashPart.startsWith("http")) return hashPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.includes('#')) {
|
if (url.includes("#")) {
|
||||||
const hashPart = url.split('#')[1];
|
const hashPart = url.split("#")[1];
|
||||||
if (hashPart && !hashPart.startsWith('http')) return hashPart;
|
if (hashPart && !hashPart.startsWith("http")) return hashPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const urlObj = new URL(url);
|
const urlObj = new URL(url);
|
||||||
const filename = urlObj.pathname.split('/').pop();
|
const filename = urlObj.pathname.split("/").pop();
|
||||||
if (filename?.length) return filename;
|
if (filename?.length) return filename;
|
||||||
} catch {
|
} catch {
|
||||||
// Invalid URL
|
// Invalid URL
|
||||||
@@ -52,13 +55,20 @@ export class DownloadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static sanitizeFilename(filename: string): string {
|
private static sanitizeFilename(filename: string): string {
|
||||||
return filename.replace(/[<>:"/\\|?*]/g, '_');
|
return filename.replace(/[<>:"/\\|?*]/g, "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createDownloadPayload(directUrl: string, originalUrl: string, downloadId: string, savePath: string) {
|
private static createDownloadPayload(
|
||||||
|
directUrl: string,
|
||||||
|
originalUrl: string,
|
||||||
|
downloadId: string,
|
||||||
|
savePath: string
|
||||||
|
) {
|
||||||
const filename = this.extractFilename(directUrl, originalUrl);
|
const filename = this.extractFilename(directUrl, originalUrl);
|
||||||
const sanitizedFilename = filename ? this.sanitizeFilename(filename) : undefined;
|
const sanitizedFilename = filename
|
||||||
|
? this.sanitizeFilename(filename)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (sanitizedFilename) {
|
if (sanitizedFilename) {
|
||||||
logger.log(`[DownloadManager] Using filename: ${sanitizedFilename}`);
|
logger.log(`[DownloadManager] Using filename: ${sanitizedFilename}`);
|
||||||
}
|
}
|
||||||
@@ -98,7 +108,9 @@ export class DownloadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async getDownloadStatus() {
|
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;
|
if (response.data === null || !this.downloadingGameId) return null;
|
||||||
const downloadId = this.downloadingGameId;
|
const downloadId = this.downloadingGameId;
|
||||||
|
|
||||||
@@ -114,7 +126,8 @@ export class DownloadManager {
|
|||||||
status,
|
status,
|
||||||
} = response.data;
|
} = response.data;
|
||||||
|
|
||||||
const isDownloadingMetadata = status === LibtorrentStatus.DownloadingMetadata;
|
const isDownloadingMetadata =
|
||||||
|
status === LibtorrentStatus.DownloadingMetadata;
|
||||||
const isCheckingFiles = status === LibtorrentStatus.CheckingFiles;
|
const isCheckingFiles = status === LibtorrentStatus.CheckingFiles;
|
||||||
|
|
||||||
const download = await downloadsSublevel.get(downloadId);
|
const download = await downloadsSublevel.get(downloadId);
|
||||||
@@ -179,7 +192,10 @@ export class DownloadManager {
|
|||||||
if (progress === 1 && download) {
|
if (progress === 1 && download) {
|
||||||
publishDownloadCompleteNotification(game);
|
publishDownloadCompleteNotification(game);
|
||||||
|
|
||||||
if (userPreferences?.seedAfterDownloadComplete && download.downloader === Downloader.Torrent) {
|
if (
|
||||||
|
userPreferences?.seedAfterDownloadComplete &&
|
||||||
|
download.downloader === Downloader.Torrent
|
||||||
|
) {
|
||||||
await downloadsSublevel.put(gameId, {
|
await downloadsSublevel.put(gameId, {
|
||||||
...download,
|
...download,
|
||||||
status: "seeding",
|
status: "seeding",
|
||||||
@@ -200,13 +216,22 @@ export class DownloadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldExtract) {
|
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();
|
gameFilesManager.extractDownloadedFile();
|
||||||
} else {
|
} else {
|
||||||
gameFilesManager
|
gameFilesManager
|
||||||
.extractFilesInDirectory(path.join(download.downloadPath, download.folderName!))
|
.extractFilesInDirectory(
|
||||||
|
path.join(download.downloadPath, download.folderName!)
|
||||||
|
)
|
||||||
.then(() => gameFilesManager.setExtractionComplete());
|
.then(() => gameFilesManager.setExtractionComplete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,11 +239,13 @@ export class DownloadManager {
|
|||||||
const downloads = await downloadsSublevel
|
const downloads = await downloadsSublevel
|
||||||
.values()
|
.values()
|
||||||
.all()
|
.all()
|
||||||
.then((games) => sortBy(
|
.then((games) =>
|
||||||
games.filter((game) => game.status === "paused" && game.queued),
|
sortBy(
|
||||||
"timestamp",
|
games.filter((game) => game.status === "paused" && game.queued),
|
||||||
"DESC"
|
"timestamp",
|
||||||
));
|
"DESC"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
const [nextItemOnQueue] = downloads;
|
const [nextItemOnQueue] = downloads;
|
||||||
|
|
||||||
@@ -245,7 +272,9 @@ export class DownloadManager {
|
|||||||
|
|
||||||
if (!download) return;
|
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) {
|
if (totalSize < status.fileSize) {
|
||||||
await this.cancelDownload(status.gameId);
|
await this.cancelDownload(status.gameId);
|
||||||
@@ -266,7 +295,10 @@ export class DownloadManager {
|
|||||||
|
|
||||||
static async pauseDownload(downloadKey = this.downloadingGameId) {
|
static async pauseDownload(downloadKey = this.downloadingGameId) {
|
||||||
await PythonRPC.rpc
|
await PythonRPC.rpc
|
||||||
.post("/action", { action: "pause", game_id: downloadKey } as PauseDownloadPayload)
|
.post("/action", {
|
||||||
|
action: "pause",
|
||||||
|
game_id: downloadKey,
|
||||||
|
} as PauseDownloadPayload)
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
|
||||||
if (downloadKey === this.downloadingGameId) {
|
if (downloadKey === this.downloadingGameId) {
|
||||||
@@ -357,24 +389,44 @@ export class DownloadManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
case Downloader.Buzzheavier: {
|
case Downloader.Buzzheavier: {
|
||||||
logger.log(`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`);
|
logger.log(
|
||||||
|
`[DownloadManager] Processing Buzzheavier download for URI: ${download.uri}`
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
const directUrl = await BuzzheavierApi.getDirectLink(download.uri);
|
const directUrl = await BuzzheavierApi.getDirectLink(download.uri);
|
||||||
logger.log(`[DownloadManager] Buzzheavier direct URL obtained`);
|
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) {
|
} catch (error) {
|
||||||
logger.error(`[DownloadManager] Error processing Buzzheavier download:`, error);
|
logger.error(
|
||||||
|
`[DownloadManager] Error processing Buzzheavier download:`,
|
||||||
|
error
|
||||||
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Downloader.FuckingFast: {
|
case Downloader.FuckingFast: {
|
||||||
logger.log(`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`);
|
logger.log(
|
||||||
|
`[DownloadManager] Processing FuckingFast download for URI: ${download.uri}`
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
const directUrl = await FuckingFastApi.getDirectLink(download.uri);
|
const directUrl = await FuckingFastApi.getDirectLink(download.uri);
|
||||||
logger.log(`[DownloadManager] FuckingFast direct URL obtained`);
|
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) {
|
} catch (error) {
|
||||||
logger.error(`[DownloadManager] Error processing FuckingFast download:`, error);
|
logger.error(
|
||||||
|
`[DownloadManager] Error processing FuckingFast download:`,
|
||||||
|
error
|
||||||
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -419,7 +471,9 @@ export class DownloadManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
case Downloader.Hydra: {
|
case Downloader.Hydra: {
|
||||||
const downloadUrl = await HydraDebridClient.getDownloadUrl(download.uri);
|
const downloadUrl = await HydraDebridClient.getDownloadUrl(
|
||||||
|
download.uri
|
||||||
|
);
|
||||||
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnHydra);
|
if (!downloadUrl) throw new Error(DownloadError.NotCachedOnHydra);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ export class BuzzheavierApi {
|
|||||||
private static async getBuzzheavierDirectLink(url: string): Promise<string> {
|
private static async getBuzzheavierDirectLink(url: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const baseUrl = url.split("#")[0];
|
const baseUrl = url.split("#")[0];
|
||||||
logger.log(`[Buzzheavier] Starting download link extraction for: ${baseUrl}`);
|
logger.log(
|
||||||
|
`[Buzzheavier] Starting download link extraction for: ${baseUrl}`
|
||||||
|
);
|
||||||
|
|
||||||
await axios.get(baseUrl, {
|
await axios.get(baseUrl, {
|
||||||
headers: { "User-Agent": HOSTER_USER_AGENT },
|
headers: { "User-Agent": HOSTER_USER_AGENT },
|
||||||
@@ -46,7 +48,9 @@ export class BuzzheavierApi {
|
|||||||
const hxRedirect = headResponse.headers["hx-redirect"];
|
const hxRedirect = headResponse.headers["hx-redirect"];
|
||||||
logger.log(`[Buzzheavier] Received hx-redirect header: ${hxRedirect}`);
|
logger.log(`[Buzzheavier] Received hx-redirect header: ${hxRedirect}`);
|
||||||
if (!hxRedirect) {
|
if (!hxRedirect) {
|
||||||
logger.error(`[Buzzheavier] No hx-redirect header found. Status: ${headResponse.status}`);
|
logger.error(
|
||||||
|
`[Buzzheavier] No hx-redirect header found. Status: ${headResponse.status}`
|
||||||
|
);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Could not extract download link. File may be deleted or is a directory."
|
"Could not extract download link. File may be deleted or is a directory."
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user