mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-19 17:23:57 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89bfb517fb | ||
|
|
e1a1136e05 | ||
|
|
4c6f87f6e7 | ||
|
|
3613ad156b | ||
|
|
e50cb74d1d | ||
|
|
36800c6368 | ||
|
|
f67395c94c | ||
|
|
f8b9fe80fd | ||
|
|
e211517e24 | ||
|
|
538d3e5982 | ||
|
|
60e0b39f86 | ||
|
|
789bccf77a | ||
|
|
ce3ed6f17c |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydralauncher",
|
"name": "hydralauncher",
|
||||||
"version": "3.1.0",
|
"version": "3.1.2",
|
||||||
"description": "Hydra",
|
"description": "Hydra",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Los Broxas",
|
"author": "Los Broxas",
|
||||||
|
|||||||
@@ -27,18 +27,27 @@ if start_download_payload:
|
|||||||
if initial_download['url'].startswith('magnet'):
|
if initial_download['url'].startswith('magnet'):
|
||||||
torrent_downloader = TorrentDownloader(torrent_session)
|
torrent_downloader = TorrentDownloader(torrent_session)
|
||||||
downloads[initial_download['game_id']] = torrent_downloader
|
downloads[initial_download['game_id']] = torrent_downloader
|
||||||
torrent_downloader.start_download(initial_download['url'], initial_download['save_path'], "")
|
try:
|
||||||
|
torrent_downloader.start_download(initial_download['url'], initial_download['save_path'], "")
|
||||||
|
except Exception as e:
|
||||||
|
print("Error starting torrent download", e)
|
||||||
else:
|
else:
|
||||||
http_downloader = HttpDownloader()
|
http_downloader = HttpDownloader()
|
||||||
downloads[initial_download['game_id']] = http_downloader
|
downloads[initial_download['game_id']] = http_downloader
|
||||||
http_downloader.start_download(initial_download['url'], initial_download['save_path'], initial_download.get('header'))
|
try:
|
||||||
|
http_downloader.start_download(initial_download['url'], initial_download['save_path'], initial_download.get('header'))
|
||||||
|
except Exception as e:
|
||||||
|
print("Error starting http download", e)
|
||||||
|
|
||||||
if start_seeding_payload:
|
if start_seeding_payload:
|
||||||
initial_seeding = json.loads(urllib.parse.unquote(start_seeding_payload))
|
initial_seeding = json.loads(urllib.parse.unquote(start_seeding_payload))
|
||||||
for seed in initial_seeding:
|
for seed in initial_seeding:
|
||||||
torrent_downloader = TorrentDownloader(torrent_session)
|
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
||||||
downloads[seed['game_id']] = torrent_downloader
|
downloads[seed['game_id']] = torrent_downloader
|
||||||
torrent_downloader.start_download(seed['url'], seed['save_path'], "")
|
try:
|
||||||
|
torrent_downloader.start_download(seed['url'], seed['save_path'], "")
|
||||||
|
except Exception as e:
|
||||||
|
print("Error starting seeding", e)
|
||||||
|
|
||||||
def validate_rpc_password():
|
def validate_rpc_password():
|
||||||
"""Middleware to validate RPC password."""
|
"""Middleware to validate RPC password."""
|
||||||
@@ -156,7 +165,7 @@ def action():
|
|||||||
if downloader:
|
if downloader:
|
||||||
downloader.cancel_download()
|
downloader.cancel_download()
|
||||||
elif action == 'resume_seeding':
|
elif action == 'resume_seeding':
|
||||||
torrent_downloader = TorrentDownloader(torrent_session)
|
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
||||||
downloads[game_id] = torrent_downloader
|
downloads[game_id] = torrent_downloader
|
||||||
torrent_downloader.start_download(data['url'], data['save_path'], "")
|
torrent_downloader.start_download(data['url'], data['save_path'], "")
|
||||||
elif action == 'pause_seeding':
|
elif action == 'pause_seeding':
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import libtorrent as lt
|
import libtorrent as lt
|
||||||
|
|
||||||
class TorrentDownloader:
|
class TorrentDownloader:
|
||||||
def __init__(self, torrent_session):
|
def __init__(self, torrent_session, flags = lt.torrent_flags.auto_managed):
|
||||||
self.torrent_handle = None
|
self.torrent_handle = None
|
||||||
self.session = torrent_session
|
self.session = torrent_session
|
||||||
|
self.flags = flags
|
||||||
self.trackers = [
|
self.trackers = [
|
||||||
"udp://tracker.opentrackr.org:1337/announce",
|
"udp://tracker.opentrackr.org:1337/announce",
|
||||||
"http://tracker.opentrackr.org:1337/announce",
|
"http://tracker.opentrackr.org:1337/announce",
|
||||||
@@ -102,9 +103,8 @@ class TorrentDownloader:
|
|||||||
]
|
]
|
||||||
|
|
||||||
def start_download(self, magnet: str, save_path: str, header: str):
|
def start_download(self, magnet: str, save_path: str, header: str):
|
||||||
params = {'url': magnet, 'save_path': save_path, 'trackers': self.trackers}
|
params = {'url': magnet, 'save_path': save_path, 'trackers': self.trackers, 'flags': self.flags}
|
||||||
self.torrent_handle = self.session.add_torrent(params)
|
self.torrent_handle = self.session.add_torrent(params)
|
||||||
self.torrent_handle.set_flags(lt.torrent_flags.auto_managed)
|
|
||||||
self.torrent_handle.resume()
|
self.torrent_handle.resume()
|
||||||
|
|
||||||
def pause_download(self):
|
def pause_download(self):
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ fs.readdir(dist, async (err, files) => {
|
|||||||
Bucket: process.env.S3_BUILDS_BUCKET_NAME,
|
Bucket: process.env.S3_BUILDS_BUCKET_NAME,
|
||||||
Key: fileName,
|
Key: fileName,
|
||||||
Body: fs.createReadStream(path.resolve(dist, file)),
|
Body: fs.createReadStream(path.resolve(dist, file)),
|
||||||
|
// 3 days
|
||||||
|
Expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 3),
|
||||||
});
|
});
|
||||||
|
|
||||||
await s3.send(command);
|
await s3.send(command);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { gameRepository } from "../../repository";
|
import { gameRepository } from "../../repository";
|
||||||
import { DownloadManager } from "@main/services";
|
import { DownloadManager } from "@main/services";
|
||||||
|
import { Downloader } from "@shared";
|
||||||
|
|
||||||
const resumeGameSeed = async (
|
const resumeGameSeed = async (
|
||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
@@ -10,7 +11,7 @@ const resumeGameSeed = async (
|
|||||||
where: {
|
where: {
|
||||||
id: gameId,
|
id: gameId,
|
||||||
isDeleted: false,
|
isDeleted: false,
|
||||||
downloader: 1,
|
downloader: Downloader.Torrent,
|
||||||
progress: 1,
|
progress: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { RealDebridClient } from "./services/download/real-debrid";
|
|||||||
import { HydraApi } from "./services/hydra-api";
|
import { HydraApi } from "./services/hydra-api";
|
||||||
import { uploadGamesBatch } from "./services/library-sync";
|
import { uploadGamesBatch } from "./services/library-sync";
|
||||||
import { Aria2 } from "./services/aria2";
|
import { Aria2 } from "./services/aria2";
|
||||||
|
import { Downloader } from "@shared";
|
||||||
|
import { IsNull, Not } from "typeorm";
|
||||||
|
|
||||||
const loadState = async (userPreferences: UserPreferences | null) => {
|
const loadState = async (userPreferences: UserPreferences | null) => {
|
||||||
import("./events");
|
import("./events");
|
||||||
@@ -37,8 +39,9 @@ const loadState = async (userPreferences: UserPreferences | null) => {
|
|||||||
const seedList = await gameRepository.find({
|
const seedList = await gameRepository.find({
|
||||||
where: {
|
where: {
|
||||||
shouldSeed: true,
|
shouldSeed: true,
|
||||||
downloader: 1,
|
downloader: Downloader.Torrent,
|
||||||
progress: 1,
|
progress: 1,
|
||||||
|
uri: Not(IsNull()),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -100,8 +100,6 @@ export class DownloadManager {
|
|||||||
public static async watchDownloads() {
|
public static async watchDownloads() {
|
||||||
const status = await this.getDownloadStatus();
|
const status = await this.getDownloadStatus();
|
||||||
|
|
||||||
// status = await RealDebridDownloader.getStatus();
|
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
const { gameId, progress } = status;
|
const { gameId, progress } = status;
|
||||||
const game = await gameRepository.findOne({
|
const game = await gameRepository.findOne({
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ log.errorHandler.startCatching({
|
|||||||
|
|
||||||
log.initialize();
|
log.initialize();
|
||||||
|
|
||||||
export const pythonInstanceLogger = log.scope("python-instance");
|
export const pythonRpcLogger = log.scope("python-rpc");
|
||||||
export const logger = log.scope("main");
|
export const logger = log.scope("main");
|
||||||
export const achievementsLogger = log.scope("achievements");
|
export const achievementsLogger = log.scope("achievements");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import fs from "node:fs";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
|
|
||||||
import { logger } from "./logger";
|
import { pythonRpcLogger } from "./logger";
|
||||||
import { Readable } from "node:stream";
|
import { Readable } from "node:stream";
|
||||||
import { app, dialog } from "electron";
|
import { app, dialog } from "electron";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export class PythonRPC {
|
|||||||
if (!readable) return;
|
if (!readable) return;
|
||||||
|
|
||||||
readable.setEncoding("utf-8");
|
readable.setEncoding("utf-8");
|
||||||
readable.on("data", logger.log);
|
readable.on("data", pythonRpcLogger.log);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static spawn(
|
public static spawn(
|
||||||
@@ -100,7 +100,7 @@ export class PythonRPC {
|
|||||||
|
|
||||||
public static kill() {
|
public static kill() {
|
||||||
if (this.pythonProcess) {
|
if (this.pythonProcess) {
|
||||||
logger.log("Killing python process");
|
pythonRpcLogger.log("Killing python process");
|
||||||
this.pythonProcess.kill();
|
this.pythonProcess.kill();
|
||||||
this.pythonProcess = null;
|
this.pythonProcess = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { Pagination } from "./pagination";
|
|||||||
import { useCatalogue } from "@renderer/hooks/use-catalogue";
|
import { useCatalogue } from "@renderer/hooks/use-catalogue";
|
||||||
import { GameItem } from "./game-item";
|
import { GameItem } from "./game-item";
|
||||||
import { FilterItem } from "./filter-item";
|
import { FilterItem } from "./filter-item";
|
||||||
|
import { debounce } from "lodash-es";
|
||||||
|
|
||||||
const filterCategoryColors = {
|
const filterCategoryColors = {
|
||||||
genres: "hsl(262deg 50% 47%)",
|
genres: "hsl(262deg 50% 47%)",
|
||||||
@@ -58,26 +59,36 @@ export default function Catalogue() {
|
|||||||
|
|
||||||
const { getRepacksForObjectId } = useRepacks();
|
const { getRepacksForObjectId } = useRepacks();
|
||||||
|
|
||||||
|
const debouncedSearch = useRef(
|
||||||
|
debounce(async (filters, pageSize, offset) => {
|
||||||
|
const abortController = new AbortController();
|
||||||
|
abortControllerRef.current = abortController;
|
||||||
|
|
||||||
|
const response = await window.electron.searchGames(
|
||||||
|
filters,
|
||||||
|
pageSize,
|
||||||
|
offset
|
||||||
|
);
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) return;
|
||||||
|
|
||||||
|
setResults(response.edges);
|
||||||
|
setItemsCount(response.count);
|
||||||
|
setIsLoading(false);
|
||||||
|
}, 500)
|
||||||
|
).current;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setResults([]);
|
setResults([]);
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
abortControllerRef.current?.abort();
|
abortControllerRef.current?.abort();
|
||||||
|
|
||||||
const abortController = new AbortController();
|
debouncedSearch(filters, PAGE_SIZE, (page - 1) * PAGE_SIZE);
|
||||||
abortControllerRef.current = abortController;
|
|
||||||
|
|
||||||
window.electron
|
return () => {
|
||||||
.searchGames(filters, PAGE_SIZE, (page - 1) * PAGE_SIZE)
|
debouncedSearch.cancel();
|
||||||
.then((response) => {
|
};
|
||||||
if (abortController.signal.aborted) {
|
}, [filters, page, debouncedSearch]);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setResults(response.edges);
|
|
||||||
setItemsCount(response.count);
|
|
||||||
setIsLoading(false);
|
|
||||||
});
|
|
||||||
}, [filters, page, dispatch]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
downloadSourcesTable.toArray().then((sources) => {
|
downloadSourcesTable.toArray().then((sources) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user