mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
fix: moving downloader directly to parser
This commit is contained in:
parent
4d32ff2ac2
commit
866ee7b30d
21 changed files with 1207 additions and 1463 deletions
|
|
@ -18,7 +18,6 @@ import "./library/open-game";
|
|||
import "./library/open-game-installer";
|
||||
import "./library/remove-game";
|
||||
import "./library/remove-game-from-library";
|
||||
import "./misc/get-or-cache-image";
|
||||
import "./misc/open-external";
|
||||
import "./misc/show-open-dialog";
|
||||
import "./torrenting/cancel-game-download";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { gameRepository } from "@main/repository";
|
|||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { GameShop } from "@types";
|
||||
import { getImageBase64 } from "@main/helpers";
|
||||
import { getFileBase64 } from "@main/helpers";
|
||||
import { getSteamGameIconUrl } from "@main/services";
|
||||
|
||||
const addGameToLibrary = async (
|
||||
|
|
@ -31,7 +31,7 @@ const addGameToLibrary = async (
|
|||
}
|
||||
);
|
||||
} else {
|
||||
const iconUrl = await getImageBase64(await getSteamGameIconUrl(objectID));
|
||||
const iconUrl = await getFileBase64(await getSteamGameIconUrl(objectID));
|
||||
|
||||
return gameRepository.insert({
|
||||
title,
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { getFileBuffer } from "@main/helpers";
|
||||
import { logger } from "@main/services";
|
||||
import { imageCachePath } from "@main/constants";
|
||||
|
||||
const getOrCacheImage = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
url: string
|
||||
) => {
|
||||
if (!fs.existsSync(imageCachePath)) fs.mkdirSync(imageCachePath);
|
||||
|
||||
const extname = path.extname(url);
|
||||
|
||||
const checksum = crypto.createHash("sha256").update(url).digest("hex");
|
||||
const cachePath = path.join(imageCachePath, `${checksum}${extname}`);
|
||||
|
||||
const cache = fs.existsSync(cachePath);
|
||||
|
||||
if (cache) return `hydra://${cachePath}`;
|
||||
|
||||
getFileBuffer(url).then((buffer) =>
|
||||
fs.writeFile(cachePath, buffer, (err) => {
|
||||
if (err) {
|
||||
logger.error(`Failed to cache image`, err, {
|
||||
method: "getOrCacheImage",
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
registerEvent(getOrCacheImage, {
|
||||
name: "getOrCacheImage",
|
||||
});
|
||||
|
|
@ -5,7 +5,7 @@ import { GameStatus } from "@main/constants";
|
|||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { GameShop } from "@types";
|
||||
import { getImageBase64 } from "@main/helpers";
|
||||
import { getFileBase64 } from "@main/helpers";
|
||||
import { In } from "typeorm";
|
||||
|
||||
const startGameDownload = async (
|
||||
|
|
@ -72,7 +72,7 @@ const startGameDownload = async (
|
|||
|
||||
return game;
|
||||
} else {
|
||||
const iconUrl = await getImageBase64(await getSteamGameIconUrl(objectID));
|
||||
const iconUrl = await getFileBase64(await getSteamGameIconUrl(objectID));
|
||||
|
||||
const createdGame = await gameRepository.save({
|
||||
title,
|
||||
|
|
|
|||
|
|
@ -79,10 +79,24 @@ export const getFileBuffer = async (url: string) =>
|
|||
response.arrayBuffer().then((buffer) => Buffer.from(buffer))
|
||||
);
|
||||
|
||||
export const getImageBase64 = async (url: string) =>
|
||||
getFileBuffer(url).then((buffer) => {
|
||||
return `data:image/jpeg;base64,${Buffer.from(buffer).toString("base64")}`;
|
||||
});
|
||||
export const getFileBase64 = async (url: string) =>
|
||||
fetch(url, { method: "GET" }).then((response) =>
|
||||
response.arrayBuffer().then((buffer) => {
|
||||
const base64 = Buffer.from(buffer).toString("base64");
|
||||
const contentType = response.headers.get("content-type");
|
||||
|
||||
return `data:${contentType};base64,${base64}`;
|
||||
})
|
||||
);
|
||||
|
||||
export const steamUrlBuilder = {
|
||||
library: (objectID: string) =>
|
||||
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`,
|
||||
libraryHero: (objectID: string) =>
|
||||
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/library_hero.jpg`,
|
||||
logo: (objectID: string) =>
|
||||
`https://cdn.cloudflare.steamstatic.com/steam/apps/${objectID}/logo.png`,
|
||||
};
|
||||
|
||||
export * from "./formatters";
|
||||
export * from "./ps";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import path from "node:path";
|
||||
import cp from "node:child_process";
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import * as Sentry from "@sentry/electron/main";
|
||||
import { Notification, app, dialog } from "electron";
|
||||
|
|
@ -99,25 +98,6 @@ export class TorrentClient {
|
|||
return game.progress;
|
||||
}
|
||||
|
||||
private static createTempIcon(encodedIcon: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const hash = crypto.randomBytes(16).toString("hex");
|
||||
const iconPath = path.join(app.getPath("temp"), `${hash}.png`);
|
||||
|
||||
fs.writeFile(
|
||||
iconPath,
|
||||
Buffer.from(
|
||||
encodedIcon.replace("data:image/jpeg;base64,", ""),
|
||||
"base64"
|
||||
),
|
||||
(err) => {
|
||||
if (err) reject(err);
|
||||
resolve(iconPath);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public static async onSocketData(data: Buffer) {
|
||||
const message = Buffer.from(data).toString("utf-8");
|
||||
|
||||
|
|
@ -159,10 +139,7 @@ export class TorrentClient {
|
|||
});
|
||||
|
||||
if (userPreferences?.downloadNotificationsEnabled) {
|
||||
const iconPath = await this.createTempIcon(game.iconUrl);
|
||||
|
||||
new Notification({
|
||||
icon: iconPath,
|
||||
title: t("download_complete", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences.language,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BrowserWindow, Menu, Tray, app } from "electron";
|
||||
import { BrowserWindow, Menu, Notification, Tray, app } from "electron";
|
||||
import { is } from "@electron-toolkit/utils";
|
||||
import { t } from "i18next";
|
||||
import path from "node:path";
|
||||
|
|
@ -54,6 +54,10 @@ export class WindowManager {
|
|||
where: { id: 1 },
|
||||
});
|
||||
|
||||
this.mainWindow.on("ready-to-show", () => {
|
||||
if (!app.isPackaged) WindowManager.mainWindow?.webContents.openDevTools();
|
||||
});
|
||||
|
||||
this.mainWindow.on("close", () => {
|
||||
if (userPreferences?.preferQuitInsteadOfHiding) {
|
||||
app.quit();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import { parentPort } from "worker_threads";
|
||||
import parseTorrent from "parse-torrent";
|
||||
import { getFileBuffer } from "@main/helpers";
|
||||
|
||||
const port = parentPort;
|
||||
if (!port) throw new Error("IllegalState");
|
||||
|
||||
export const getFileBuffer = async (url: string) =>
|
||||
fetch(url, { method: "GET" }).then((response) =>
|
||||
response.arrayBuffer().then((buffer) => Buffer.from(buffer))
|
||||
);
|
||||
|
||||
port.on("message", async (url: string) => {
|
||||
const buffer = await getFileBuffer(url);
|
||||
const torrent = await parseTorrent(buffer);
|
||||
|
||||
port.postMessage(torrent);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue