Skip to content

feature: Add direct download#1778

Open
descention wants to merge 6 commits intohydralauncher:mainfrom
descention:feature/direct-download
Open

feature: Add direct download#1778
descention wants to merge 6 commits intohydralauncher:mainfrom
descention:feature/direct-download

Conversation

@descention
Copy link
Copy Markdown

@descention descention commented Jul 30, 2025

When submitting this pull request, I confirm the following (please check the boxes):

  • I have read and understood the Contributor Guidelines.
  • I have checked that there are no duplicate pull requests related to this request.
  • I have considered, and confirm that this submission is valuable to others.
  • I accept that this submission may not be used and the pull request may be closed at the discretion of the maintainers.

Fill in the PR content:

  • Add direct HTTPS download from custom sources

Use case

Services such as Drop-OSS and Gameyfin allow users to track their own collection of games. I want to use Hydra as a client for these services. Gameyfin doesn't have a client and is only a web service. Drop has a client but currently doesn't work on my OS.

I've included sample code in another comment for utilizing Gameyfin v1 as a download source.

Notes
The Contributor Guidelines link above doesn't lead to any guidelines.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Summary

This PR introduces direct HTTPS download capability to the Hydra launcher by adding a new Downloader.Direct option. The change expands the application's download sources beyond the existing file hosting services (Gofile, PixelDrain, Qiwi, etc.) and debrid services (RealDebrid, TorBox) to support downloading from any HTTPS URL.

The implementation involves three key changes:

  1. New Downloader Type: Adds Direct to the Downloader enum in src/shared/constants.ts
  2. URI Detection: Modifies getDownloadersForUri in src/shared/index.ts to detect HTTPS URLs and return [Downloader.Direct] as an available option
  3. Download Handling: Implements the Direct case in DownloadManager.getDownloadPayload method in src/main/services/download/download-manager.ts

The direct download implementation is intentionally simple - it passes the raw HTTPS URI directly to the Python RPC download system without any preprocessing, authentication, or API calls. Multiple connections are disabled (allow_multiple_connections: false) for direct downloads, likely to avoid overwhelming source servers that may not be designed for concurrent connections like commercial hosting services.

This change integrates seamlessly with the existing download infrastructure, following the same pattern as other downloader types where the download manager creates appropriate payloads for the Python RPC system to handle the actual download process.

Confidence score: 4/5

  • This is a safe addition that follows existing patterns and is unlikely to break current functionality
  • The implementation is straightforward and minimal, reducing the risk of introducing bugs
  • The URI detection logic needs attention as it's overly broad and could conflict with existing specific host handlers

3 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

@descention
Copy link
Copy Markdown
Author

descention commented Jul 30, 2025

I am stuck on what is supposed to happen after a zip gets downloaded and extracted. The game didn't have any of its execution content filled in and the setup.exe wasn't run.

This is my attempt to support Gameyfin as a source. I have python to take the gameyfin api and generate a download source.

from flask import Flask, jsonify
import requests

app = Flask(__name__)

BASE_URL = "https://gameyfin-instance.local/v1"

def fetch_games():
    response = requests.get(f"{BASE_URL}/games")
    if response.status_code != 200:
        return []
    return response.json()

def human_readable_size(bytes_size):
    for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
        if bytes_size < 1024:
            return f"{bytes_size:.1f} {unit}"
        bytes_size /= 1024
    return f"{bytes_size:.1f} PB"
    
def build_download_entry(game):
    return {
        "title": game.get("title", "Unknown Title"),
        "fileSize": human_readable_size(game.get("diskSize", 0)),
        "uris": [f"{BASE_URL}/games/game/{game.get('slug')}/download"],
        "uploadDate": game.get("addedToLibrary", "Unknown Date")
    }

def is_pc_game(game):
    platforms = game.get("platforms", [])
    return any(platform.get("slug") == "win" for platform in platforms)

@app.route("/downloads")
@app.route("/gameyfin.json")
def get_downloads():
    games = fetch_games()
    confirmed_pc_games = [
        game for game in games
        if game.get("confirmedMatch") and is_pc_game(game)
    ]
    output = {
        "name": "Gameyfin",
        "downloads": [build_download_entry(game) for game in confirmed_pc_games]
    }
    return jsonify(output)

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug=True)

@rdvo
Copy link
Copy Markdown

rdvo commented Aug 13, 2025

anyone considering adding NZB/usenet support ? upload a nzb or point to a nzb url?

@descention
Copy link
Copy Markdown
Author

anyone considering adding NZB/usenet support ? upload a nzb or point to a nzb url?

Probably a good idea for the feedback site. It's off topic for this PR.

@sonarqubecloud
Copy link
Copy Markdown

@chubbygrannychaser
Copy link
Copy Markdown
Contributor

@descention Do you still have any questions regarding this PR that I can help with before testing?

@sonarqubecloud
Copy link
Copy Markdown

@descention
Copy link
Copy Markdown
Author

@descention Do you still have any questions regarding this PR that I can help with before testing?

It needs a review. I'm not currently using this branch so while I did test it briefly, it could use more testers.

descention and others added 4 commits October 30, 2025 10:48
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@descention descention force-pushed the feature/direct-download branch from 4ca32c0 to 76cc4e1 Compare October 30, 2025 14:48
@sonarqubecloud
Copy link
Copy Markdown

@descention
Copy link
Copy Markdown
Author

descention commented Nov 5, 2025

After this is accepted, I will be working on adding a direct download API to Drop-OSS server that will utilize this functionality. I'll probably do the same I did for GameyFin and have a separate script generate the Hydra manifest.

@chubbygrannychaser
Copy link
Copy Markdown
Contributor

@descention I think this one is ready to be merged, could you just fix the conflicts?

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants