diff --git a/python_rpc/main.py b/python_rpc/main.py index 060e01c2..028e9fa3 100644 --- a/python_rpc/main.py +++ b/python_rpc/main.py @@ -11,6 +11,7 @@ app = Flask(__name__) torrent_port = sys.argv[1] http_port = sys.argv[2] rpc_password = sys.argv[3] +start_download_payload = sys.argv[4] downloads = {} # This can be streamed down from Node @@ -18,6 +19,20 @@ downloading_game_id = -1 torrent_session = lt.session({'listen_interfaces': '0.0.0.0:{port}'.format(port=torrent_port)}) +if start_download_payload: + initial_download = json.loads(urllib.parse.unquote(start_download_payload)) + downloading_game_id = initial_download['game_id'] + + if initial_download['url'].startswith('magnet'): + torrent_downloader = TorrentDownloader(torrent_session) + downloads[initial_download['game_id']] = torrent_downloader + torrent_downloader.start_download(initial_download['url'], initial_download['save_path'], "") + else: + http_downloader = HttpDownloader() + downloads[initial_download['game_id']] = http_downloader + http_downloader.start_download(initial_download['url'], initial_download['save_path'], initial_download.get('header')) + + def validate_rpc_password(): """Middleware to validate RPC password.""" header_password = request.headers.get('x-hydra-rpc-password') diff --git a/src/main/main.ts b/src/main/main.ts index 18b61c37..c39a5196 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,11 +1,15 @@ -import { Ludusavi, startMainLoop } from "./services"; -import { userPreferencesRepository } from "./repository"; +import { DownloadManager, Ludusavi, startMainLoop } from "./services"; +import { + downloadQueueRepository, + userPreferencesRepository, +} from "./repository"; import { UserPreferences } from "./entity"; import { RealDebridClient } from "./services/download/real-debrid"; import { HydraApi } from "./services/hydra-api"; import { uploadGamesBatch } from "./services/library-sync"; -import { PythonRPC } from "./services/python-rpc"; import { Aria2 } from "./services/aria2"; +import { startSeedProcess } from "./services/seed"; +import { PythonRPC } from "./services/python-rpc"; const loadState = async (userPreferences: UserPreferences | null) => { import("./events"); @@ -22,7 +26,23 @@ const loadState = async (userPreferences: UserPreferences | null) => { uploadGamesBatch(); }); - PythonRPC.spawn(); + const [nextQueueItem] = await downloadQueueRepository.find({ + order: { + id: "DESC", + }, + relations: { + game: true, + }, + }); + + if (nextQueueItem?.game.status === "active") { + DownloadManager.startRPC(nextQueueItem.game); + } else { + PythonRPC.spawn(); + } + + await startSeedProcess(); + startMainLoop(); }; diff --git a/src/main/services/download/download-manager.ts b/src/main/services/download/download-manager.ts index a4106fef..78452380 100644 --- a/src/main/services/download/download-manager.ts +++ b/src/main/services/download/download-manager.ts @@ -23,6 +23,18 @@ import path from "path"; export class DownloadManager { private static downloadingGameId: number | null = null; + public static startRPC(game: Game) { + if (game && game.status === "active") { + PythonRPC.spawn({ + game_id: game.id, + url: game.uri!, + save_path: game.downloadPath!, + }); + + this.downloadingGameId = game.id; + } + } + private static async getDownloadStatus() { const response = await PythonRPC.rpc.get( "/status" diff --git a/src/main/services/python-rpc.ts b/src/main/services/python-rpc.ts index d8e09911..622fb4ce 100644 --- a/src/main/services/python-rpc.ts +++ b/src/main/services/python-rpc.ts @@ -8,7 +8,12 @@ import crypto from "node:crypto"; import { logger } from "./logger"; import { Readable } from "node:stream"; import { app, dialog } from "electron"; -import { startSeedProcess } from "./seed"; + +interface StartDownloadPayload { + game_id: number; + url: string; + save_path: string; +} const binaryNameByPlatform: Partial> = { darwin: "hydra-python-rpc", @@ -37,9 +42,15 @@ export class PythonRPC { readable.on("data", logger.log); } - public static spawn() { + public static spawn(initialDownload?: StartDownloadPayload) { console.log([this.BITTORRENT_PORT, this.RPC_PORT, this.RPC_PASSWORD]); - const commonArgs = [this.BITTORRENT_PORT, this.RPC_PORT, this.RPC_PASSWORD]; + + const commonArgs = [ + this.BITTORRENT_PORT, + this.RPC_PORT, + this.RPC_PASSWORD, + initialDownload ? JSON.stringify(initialDownload) : "", + ]; if (app.isPackaged) { const binaryName = binaryNameByPlatform[process.platform]!; @@ -84,8 +95,6 @@ export class PythonRPC { this.logStderr(childProcess.stderr); this.pythonProcess = childProcess; - - startSeedProcess(); } } diff --git a/src/main/services/seed.ts b/src/main/services/seed.ts index 26ac7fc6..89172f50 100644 --- a/src/main/services/seed.ts +++ b/src/main/services/seed.ts @@ -12,12 +12,10 @@ export const startSeedProcess = async () => { }); if (seedList.length === 0) return; - await sleep(1000); - // wait for python process to start seedList.map(async (game) => { await DownloadManager.startDownload(game); - await sleep(100); + await sleep(300); }); };