feat: add ablity to pause and resume the seeding process

This commit is contained in:
Hachi-R 2024-11-08 21:29:40 -03:00
parent c556a00e4a
commit b32952f076
11 changed files with 120 additions and 0 deletions

View file

@ -32,6 +32,8 @@ import "./torrenting/cancel-game-download";
import "./torrenting/pause-game-download";
import "./torrenting/resume-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/update-user-preferences";
import "./user-preferences/auto-launch";

View 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);

View 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);

View file

@ -18,6 +18,8 @@ import {
LibtorrentStatus,
LibtorrentPayload,
ProcessPayload,
PauseSeedingPayload,
ResumeSeedingPayload,
} from "./types";
import { pythonInstanceLogger as logger } from "../logger";
@ -133,6 +135,26 @@ export class PythonInstance {
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() {
await this.rpc
.post("/action", {

View file

@ -37,3 +37,11 @@ export interface ProcessPayload {
exe: string;
pid: number;
}
export interface PauseSeedingPayload {
game_id: number;
}
export interface ResumeSeedingPayload {
game_id: number;
}

View file

@ -26,6 +26,10 @@ contextBridge.exposeInMainWorld("electron", {
ipcRenderer.invoke("pauseGameDownload", gameId),
resumeGameDownload: (gameId: number) =>
ipcRenderer.invoke("resumeGameDownload", gameId),
pauseGameSeed: (gameId: number) =>
ipcRenderer.invoke("pauseGameSeed", gameId),
resumeGameSeed: (gameId: number) =>
ipcRenderer.invoke("resumeGameSeed", gameId),
onDownloadProgress: (cb: (value: DownloadProgress) => void) => {
const listener = (
_event: Electron.IpcRendererEvent,

View file

@ -46,6 +46,8 @@ declare global {
cancelGameDownload: (gameId: number) => Promise<void>;
pauseGameDownload: (gameId: number) => Promise<void>;
resumeGameDownload: (gameId: number) => Promise<void>;
pauseGameSeed: (gameId: number) => Promise<void>;
resumeGameSeed: (gameId: number) => Promise<void>;
onDownloadProgress: (
cb: (value: DownloadProgress) => void
) => () => Electron.IpcRenderer;

View file

@ -66,6 +66,16 @@ export function useDownload() {
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 = () => {
if (!lastPacket || lastPacket.timeRemaining < 0) return "";
@ -96,6 +106,8 @@ export function useDownload() {
removeGameFromLibrary,
removeGameInstaller,
isGameDeleting,
pauseSeeding,
resumeSeeding,
clearDownload: () => dispatch(clearDownload()),
setLastPacket: (packet: DownloadProgress) =>
dispatch(setLastPacket(packet)),

View file

@ -7,6 +7,7 @@ export type GameStatus =
| "paused"
| "error"
| "complete"
| "seeding"
| "removed";
export type GameShop = "steam" | "epic";

View file

@ -121,6 +121,10 @@ class Handler(BaseHTTPRequestHandler):
elif data['action'] == 'kill-torrent':
torrent_downloader.abort_session()
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.end_headers()

View file

@ -189,3 +189,16 @@ class TorrentDownloader:
response.append(torrent_info)
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()