mirror of
				https://github.com/hydralauncher/hydra.git
				synced 2025-03-09 15:40:26 +00:00 
			
		
		
		
	feat: get process list from rpc
This commit is contained in:
		
							parent
							
								
									0c1a75eedd
								
							
						
					
					
						commit
						75c8f69e81
					
				
					 10 changed files with 57 additions and 49 deletions
				
			
		
							
								
								
									
										148
									
								
								src/main/services/download/rpc-manager.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								src/main/services/download/rpc-manager.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,148 @@ | |||
| import cp from "node:child_process"; | ||||
| 
 | ||||
| import { Game } from "@main/entity"; | ||||
| import { RPC_PASSWORD, RPC_PORT, startTorrentClient } from "./torrent-client"; | ||||
| import { gameRepository } from "@main/repository"; | ||||
| import { DownloadProgress } from "@types"; | ||||
| import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; | ||||
| import { calculateETA } from "./helpers"; | ||||
| import axios from "axios"; | ||||
| import { | ||||
|   CancelDownloadPayload, | ||||
|   StartDownloadPayload, | ||||
|   PauseDownloadPayload, | ||||
|   LibtorrentStatus, | ||||
|   LibtorrentPayload, | ||||
| } from "./types"; | ||||
| 
 | ||||
| export class RPCManager { | ||||
|   private static rpcProcess: cp.ChildProcess | null = null; | ||||
|   private static downloadingGameId = -1; | ||||
| 
 | ||||
|   private static rpc = axios.create({ | ||||
|     baseURL: `http://localhost:${RPC_PORT}`, | ||||
|     headers: { | ||||
|       "x-hydra-rpc-password": RPC_PASSWORD, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   public static spawn(args?: StartDownloadPayload) { | ||||
|     this.rpcProcess = startTorrentClient(args); | ||||
|   } | ||||
| 
 | ||||
|   public static kill() { | ||||
|     if (this.rpcProcess) { | ||||
|       this.rpcProcess.kill(); | ||||
|       this.rpcProcess = null; | ||||
|       this.downloadingGameId = -1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public static async getProccessList() { | ||||
|     return (await this.rpc.get<string[] | null>("/process-list")).data; | ||||
|   } | ||||
| 
 | ||||
|   public static async getStatus() { | ||||
|     if (this.downloadingGameId === -1) return null; | ||||
| 
 | ||||
|     const response = await this.rpc.get<LibtorrentPayload | null>("/status"); | ||||
| 
 | ||||
|     if (response.data === null) return null; | ||||
| 
 | ||||
|     try { | ||||
|       const { | ||||
|         progress, | ||||
|         numPeers, | ||||
|         numSeeds, | ||||
|         downloadSpeed, | ||||
|         bytesDownloaded, | ||||
|         fileSize, | ||||
|         folderName, | ||||
|         status, | ||||
|         gameId, | ||||
|       } = response.data; | ||||
| 
 | ||||
|       this.downloadingGameId = gameId; | ||||
| 
 | ||||
|       const isDownloadingMetadata = | ||||
|         status === LibtorrentStatus.DownloadingMetadata; | ||||
| 
 | ||||
|       const isCheckingFiles = status === LibtorrentStatus.CheckingFiles; | ||||
| 
 | ||||
|       if (!isDownloadingMetadata && !isCheckingFiles) { | ||||
|         const update: QueryDeepPartialEntity<Game> = { | ||||
|           bytesDownloaded, | ||||
|           fileSize, | ||||
|           progress, | ||||
|           status: "active", | ||||
|         }; | ||||
| 
 | ||||
|         await gameRepository.update( | ||||
|           { id: gameId }, | ||||
|           { | ||||
|             ...update, | ||||
|             folderName, | ||||
|           } | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       if (progress === 1 && !isCheckingFiles) { | ||||
|         this.downloadingGameId = -1; | ||||
|       } | ||||
| 
 | ||||
|       return { | ||||
|         numPeers, | ||||
|         numSeeds, | ||||
|         downloadSpeed, | ||||
|         timeRemaining: calculateETA(fileSize, bytesDownloaded, downloadSpeed), | ||||
|         isDownloadingMetadata, | ||||
|         isCheckingFiles, | ||||
|         progress, | ||||
|         gameId, | ||||
|       } as DownloadProgress; | ||||
|     } catch (err) { | ||||
|       return null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   static async pauseDownload() { | ||||
|     await this.rpc | ||||
|       .post("/action", { | ||||
|         action: "pause", | ||||
|         game_id: this.downloadingGameId, | ||||
|       } as PauseDownloadPayload) | ||||
|       .catch(() => {}); | ||||
| 
 | ||||
|     this.downloadingGameId = -1; | ||||
|   } | ||||
| 
 | ||||
|   static async startDownload(game: Game) { | ||||
|     if (!this.rpcProcess) { | ||||
|       this.spawn({ | ||||
|         game_id: game.id, | ||||
|         magnet: game.uri!, | ||||
|         save_path: game.downloadPath!, | ||||
|       }); | ||||
|     } else { | ||||
|       await this.rpc.post("/action", { | ||||
|         action: "start", | ||||
|         game_id: game.id, | ||||
|         magnet: game.uri, | ||||
|         save_path: game.downloadPath, | ||||
|       } as StartDownloadPayload); | ||||
|     } | ||||
| 
 | ||||
|     this.downloadingGameId = game.id; | ||||
|   } | ||||
| 
 | ||||
|   static async cancelDownload(gameId: number) { | ||||
|     await this.rpc | ||||
|       .post("/action", { | ||||
|         action: "cancel", | ||||
|         game_id: gameId, | ||||
|       } as CancelDownloadPayload) | ||||
|       .catch(() => {}); | ||||
| 
 | ||||
|     this.downloadingGameId = -1; | ||||
|   } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue