feat: adding initial torrent as arg command

This commit is contained in:
Chubby Granny Chaser 2024-06-27 19:26:04 +01:00
parent a0cc15b5d8
commit 41dc504660
No known key found for this signature in database
4 changed files with 80 additions and 68 deletions

View File

@ -2,6 +2,7 @@ import path from "node:path";
import cp from "node:child_process";
import fs from "node:fs";
import { app, dialog } from "electron";
import type { StartDownloadPayload } from "./types";
const binaryNameByPlatform: Partial<Record<NodeJS.Platform, string>> = {
darwin: "hydra-download-manager",
@ -12,9 +13,13 @@ const binaryNameByPlatform: Partial<Record<NodeJS.Platform, string>> = {
export const BITTORRENT_PORT = "5881";
export const RPC_PORT = "8084";
const commonArgs = [BITTORRENT_PORT, RPC_PORT];
export const startTorrentClient = (args: StartDownloadPayload) => {
const commonArgs = [
BITTORRENT_PORT,
RPC_PORT,
encodeURIComponent(JSON.stringify(args)),
];
export const startTorrentClient = () => {
if (app.isPackaged) {
const binaryName = binaryNameByPlatform[process.platform]!;
const binaryPath = path.join(

View File

@ -7,59 +7,24 @@ import { DownloadProgress } from "@types";
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
import { calculateETA } from "./helpers";
import axios from "axios";
import { sleep } from "@main/helpers";
import { logger } from "../logger";
enum LibtorrentStatus {
CheckingFiles = 1,
DownloadingMetadata = 2,
Downloading = 3,
Finished = 4,
Seeding = 5,
}
interface LibtorrentPayload {
progress: number;
numPeers: number;
numSeeds: number;
downloadSpeed: number;
bytesDownloaded: number;
fileSize: number;
folderName: string;
status: LibtorrentStatus;
gameId: number;
}
import {
type CancelDownloadPayload,
type StartDownloadPayload,
type PauseDownloadPayload,
LibtorrentStatus,
LibtorrentPayload,
} from "./types";
export class TorrentDownloader {
private static torrentClient: cp.ChildProcess | null = null;
private static downloadingGameId = -1;
private static rpc = axios.create({
baseURL: `http://localhost:${RPC_PORT}`,
});
private static async healthCheck(retries = 15) {
try {
await this.rpc.get("/healthcheck");
} catch (err) {
if (retries === 0) {
throw new Error("Failed to connect to libtorrent client");
}
await sleep(1000);
return this.healthCheck(retries - 1);
}
}
private static async spawn() {
try {
this.torrentClient = startTorrentClient();
await this.healthCheck();
logger.log("libtorrent client started");
} catch (err) {
logger.error(err);
}
private static spawn(args: StartDownloadPayload) {
this.torrentClient = startTorrentClient(args);
}
public static kill() {
@ -71,7 +36,6 @@ export class TorrentDownloader {
}
public static async getStatus() {
if (!this.torrentClient) this.spawn();
if (this.downloadingGameId === -1) return null;
const response = await this.rpc.get<LibtorrentPayload | null>("/status");
@ -134,36 +98,42 @@ export class TorrentDownloader {
}
static async pauseDownload() {
if (!this.torrentClient) await this.spawn();
await this.rpc.post("/action", {
action: "pause",
game_id: this.downloadingGameId,
});
await this.rpc
.post("/action", {
action: "pause",
game_id: this.downloadingGameId,
} as PauseDownloadPayload)
.catch(() => {});
this.downloadingGameId = -1;
}
static async startDownload(game: Game) {
if (!this.torrentClient) await this.spawn();
await this.rpc.post("/action", {
action: "start",
game_id: game.id,
magnet: game.uri,
save_path: game.downloadPath,
});
if (!this.torrentClient) {
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) {
if (!this.torrentClient) await this.spawn();
await this.rpc.post("/action", {
action: "cancel",
game_id: gameId,
});
await this.rpc
.post("/action", {
action: "cancel",
game_id: gameId,
} as CancelDownloadPayload)
.catch(() => {});
this.downloadingGameId = -1;
}

View File

@ -0,0 +1,33 @@
export interface StartDownloadPayload {
game_id: number;
magnet: string;
save_path: string;
}
export interface PauseDownloadPayload {
game_id: number;
}
export interface CancelDownloadPayload {
game_id: number;
}
export enum LibtorrentStatus {
CheckingFiles = 1,
DownloadingMetadata = 2,
Downloading = 3,
Finished = 4,
Seeding = 5,
}
export interface LibtorrentPayload {
progress: number;
numPeers: number;
numSeeds: number;
downloadSpeed: number;
bytesDownloaded: number;
fileSize: number;
folderName: string;
status: LibtorrentStatus;
gameId: number;
}

View File

@ -4,9 +4,11 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import threading
import time
import urllib.parse
torrent_port = sys.argv[1]
http_port = sys.argv[2]
initial_download = json.loads(urllib.parse.unquote(sys.argv[3]))
class Downloader:
def __init__(self):
@ -62,6 +64,8 @@ class Downloader:
downloader = Downloader()
downloader.start_download(initial_download['game_id'], initial_download['magnet'], initial_download['save_path'])
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/status":