mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: add ablity to pause and resume the seeding process
This commit is contained in:
parent
c556a00e4a
commit
b32952f076
11 changed files with 120 additions and 0 deletions
|
@ -32,6 +32,8 @@ import "./torrenting/cancel-game-download";
|
||||||
import "./torrenting/pause-game-download";
|
import "./torrenting/pause-game-download";
|
||||||
import "./torrenting/resume-game-download";
|
import "./torrenting/resume-game-download";
|
||||||
import "./torrenting/start-game-download";
|
import "./torrenting/start-game-download";
|
||||||
|
import "./torrenting/pause-game-seed";
|
||||||
|
import "./torrenting/resume-game-seed";
|
||||||
import "./user-preferences/get-user-preferences";
|
import "./user-preferences/get-user-preferences";
|
||||||
import "./user-preferences/update-user-preferences";
|
import "./user-preferences/update-user-preferences";
|
||||||
import "./user-preferences/auto-launch";
|
import "./user-preferences/auto-launch";
|
||||||
|
|
21
src/main/events/torrenting/pause-game-seed.ts
Normal file
21
src/main/events/torrenting/pause-game-seed.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
import { DownloadManager } from "@main/services";
|
||||||
|
import { dataSource } from "@main/data-source";
|
||||||
|
import { Game } from "@main/entity";
|
||||||
|
|
||||||
|
const pauseGameSeed = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
gameId: number
|
||||||
|
) => {
|
||||||
|
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||||
|
|
||||||
|
await transactionalEntityManager
|
||||||
|
.getRepository(Game)
|
||||||
|
.update({ id: gameId }, { status: "complete", shouldSeed: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
await DownloadManager.pauseSeeding(gameId);
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("pauseGameSeed", pauseGameSeed);
|
31
src/main/events/torrenting/resume-game-seed.ts
Normal file
31
src/main/events/torrenting/resume-game-seed.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
import { gameRepository } from "../../repository";
|
||||||
|
|
||||||
|
import { DownloadManager } from "@main/services";
|
||||||
|
import { dataSource } from "@main/data-source";
|
||||||
|
import { Game } from "@main/entity";
|
||||||
|
|
||||||
|
const resumeGameSeed = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
gameId: number
|
||||||
|
) => {
|
||||||
|
const game = await gameRepository.findOne({
|
||||||
|
where: {
|
||||||
|
id: gameId,
|
||||||
|
isDeleted: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!game) return;
|
||||||
|
|
||||||
|
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||||
|
|
||||||
|
await transactionalEntityManager
|
||||||
|
.getRepository(Game)
|
||||||
|
.update({ id: gameId }, { status: "seeding", shouldSeed: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
await DownloadManager.resumeSeeding(gameId, game.uri!, game.downloadPath!);
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("resumeGameSeed", resumeGameSeed);
|
|
@ -18,6 +18,8 @@ import {
|
||||||
LibtorrentStatus,
|
LibtorrentStatus,
|
||||||
LibtorrentPayload,
|
LibtorrentPayload,
|
||||||
ProcessPayload,
|
ProcessPayload,
|
||||||
|
PauseSeedingPayload,
|
||||||
|
ResumeSeedingPayload,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { pythonInstanceLogger as logger } from "../logger";
|
import { pythonInstanceLogger as logger } from "../logger";
|
||||||
|
|
||||||
|
@ -133,6 +135,26 @@ export class PythonInstance {
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async pauseSeeding(gameId: number) {
|
||||||
|
await this.rpc
|
||||||
|
.post("/action", {
|
||||||
|
action: "pause-seeding",
|
||||||
|
game_id: gameId,
|
||||||
|
} as PauseSeedingPayload)
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async resumeSeeding(gameId: number, magnet: string, savePath: string) {
|
||||||
|
await this.rpc
|
||||||
|
.post("/action", {
|
||||||
|
action: "resume-seeding",
|
||||||
|
game_id: gameId,
|
||||||
|
magnet,
|
||||||
|
save_path: savePath,
|
||||||
|
} as ResumeSeedingPayload)
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
static async pauseDownload() {
|
static async pauseDownload() {
|
||||||
await this.rpc
|
await this.rpc
|
||||||
.post("/action", {
|
.post("/action", {
|
||||||
|
|
|
@ -37,3 +37,11 @@ export interface ProcessPayload {
|
||||||
exe: string;
|
exe: string;
|
||||||
pid: number;
|
pid: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PauseSeedingPayload {
|
||||||
|
game_id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResumeSeedingPayload {
|
||||||
|
game_id: number;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,10 @@ contextBridge.exposeInMainWorld("electron", {
|
||||||
ipcRenderer.invoke("pauseGameDownload", gameId),
|
ipcRenderer.invoke("pauseGameDownload", gameId),
|
||||||
resumeGameDownload: (gameId: number) =>
|
resumeGameDownload: (gameId: number) =>
|
||||||
ipcRenderer.invoke("resumeGameDownload", gameId),
|
ipcRenderer.invoke("resumeGameDownload", gameId),
|
||||||
|
pauseGameSeed: (gameId: number) =>
|
||||||
|
ipcRenderer.invoke("pauseGameSeed", gameId),
|
||||||
|
resumeGameSeed: (gameId: number) =>
|
||||||
|
ipcRenderer.invoke("resumeGameSeed", gameId),
|
||||||
onDownloadProgress: (cb: (value: DownloadProgress) => void) => {
|
onDownloadProgress: (cb: (value: DownloadProgress) => void) => {
|
||||||
const listener = (
|
const listener = (
|
||||||
_event: Electron.IpcRendererEvent,
|
_event: Electron.IpcRendererEvent,
|
||||||
|
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
|
@ -46,6 +46,8 @@ declare global {
|
||||||
cancelGameDownload: (gameId: number) => Promise<void>;
|
cancelGameDownload: (gameId: number) => Promise<void>;
|
||||||
pauseGameDownload: (gameId: number) => Promise<void>;
|
pauseGameDownload: (gameId: number) => Promise<void>;
|
||||||
resumeGameDownload: (gameId: number) => Promise<void>;
|
resumeGameDownload: (gameId: number) => Promise<void>;
|
||||||
|
pauseGameSeed: (gameId: number) => Promise<void>;
|
||||||
|
resumeGameSeed: (gameId: number) => Promise<void>;
|
||||||
onDownloadProgress: (
|
onDownloadProgress: (
|
||||||
cb: (value: DownloadProgress) => void
|
cb: (value: DownloadProgress) => void
|
||||||
) => () => Electron.IpcRenderer;
|
) => () => Electron.IpcRenderer;
|
||||||
|
|
|
@ -66,6 +66,16 @@ export function useDownload() {
|
||||||
updateLibrary();
|
updateLibrary();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const pauseSeeding = async (gameId: number) => {
|
||||||
|
await window.electron.pauseGameSeed(gameId);
|
||||||
|
await updateLibrary();
|
||||||
|
};
|
||||||
|
|
||||||
|
const resumeSeeding = async (gameId: number) => {
|
||||||
|
await window.electron.resumeGameSeed(gameId);
|
||||||
|
await updateLibrary();
|
||||||
|
};
|
||||||
|
|
||||||
const calculateETA = () => {
|
const calculateETA = () => {
|
||||||
if (!lastPacket || lastPacket.timeRemaining < 0) return "";
|
if (!lastPacket || lastPacket.timeRemaining < 0) return "";
|
||||||
|
|
||||||
|
@ -96,6 +106,8 @@ export function useDownload() {
|
||||||
removeGameFromLibrary,
|
removeGameFromLibrary,
|
||||||
removeGameInstaller,
|
removeGameInstaller,
|
||||||
isGameDeleting,
|
isGameDeleting,
|
||||||
|
pauseSeeding,
|
||||||
|
resumeSeeding,
|
||||||
clearDownload: () => dispatch(clearDownload()),
|
clearDownload: () => dispatch(clearDownload()),
|
||||||
setLastPacket: (packet: DownloadProgress) =>
|
setLastPacket: (packet: DownloadProgress) =>
|
||||||
dispatch(setLastPacket(packet)),
|
dispatch(setLastPacket(packet)),
|
||||||
|
|
|
@ -7,6 +7,7 @@ export type GameStatus =
|
||||||
| "paused"
|
| "paused"
|
||||||
| "error"
|
| "error"
|
||||||
| "complete"
|
| "complete"
|
||||||
|
| "seeding"
|
||||||
| "removed";
|
| "removed";
|
||||||
|
|
||||||
export type GameShop = "steam" | "epic";
|
export type GameShop = "steam" | "epic";
|
||||||
|
|
|
@ -121,6 +121,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||||
elif data['action'] == 'kill-torrent':
|
elif data['action'] == 'kill-torrent':
|
||||||
torrent_downloader.abort_session()
|
torrent_downloader.abort_session()
|
||||||
torrent_downloader = None
|
torrent_downloader = None
|
||||||
|
elif data['action'] == 'pause-seeding':
|
||||||
|
torrent_downloader.pause_seeding(data['game_id'])
|
||||||
|
elif data['action'] == 'resume-seeding':
|
||||||
|
torrent_downloader.resume_seeding(data['game_id'], data['magnet'], data['save_path'])
|
||||||
|
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
|
|
@ -189,3 +189,16 @@ class TorrentDownloader:
|
||||||
response.append(torrent_info)
|
response.append(torrent_info)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def pause_seeding(self, game_id: int):
|
||||||
|
torrent_handle = self.torrent_handles.get(game_id)
|
||||||
|
if torrent_handle:
|
||||||
|
torrent_handle.pause()
|
||||||
|
torrent_handle.unset_flags(lt.torrent_flags.auto_managed)
|
||||||
|
|
||||||
|
def resume_seeding(self, game_id: int, magnet: str, save_path: str):
|
||||||
|
params = {'url': magnet, 'save_path': save_path, 'trackers': self.trackers}
|
||||||
|
torrent_handle = self.session.add_torrent(params)
|
||||||
|
self.torrent_handles[game_id] = torrent_handle
|
||||||
|
torrent_handle.set_flags(lt.torrent_flags.auto_managed)
|
||||||
|
torrent_handle.resume()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue