mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-03 00:33:49 +03:00
feat: adding initial torrent as arg command
This commit is contained in:
parent
a0cc15b5d8
commit
41dc504660
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
33
src/main/services/download/types.ts
Normal file
33
src/main/services/download/types.ts
Normal 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;
|
||||
}
|
@ -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":
|
||||
|
Loading…
Reference in New Issue
Block a user