feat(downloads): ordered preferred_methods list honored for web tasks

The agent ignored its config.toml method preference for web-driven downloads
(only the local `unarr download` command read it), and resolveMethod tried
torrent first in auto mode — so a 'debrid only' user still got torrent tasks.

- config: preferred_methods (ordered list, e.g. ["debrid","usenet"]) with
  MethodOrder() resolution; back-compat with the singular preferred_method.
  Methods absent from the list are disabled (debrid-only never torrents).
- resolveMethod/tryFallback honor the config order (gating, no fallback to a
  method outside the list) over the per-task preference.
- report preferred_methods on register so the web honors it (resolves debrid,
  gates the P2P stream fallback).
- enable the usenet downloader when usenet is listed (it was never enabled).
- config_menu: ordered presets (debrid-only, debrid→torrent, debrid→usenet…).

Tests: resolveMethod gating + fallback within/outside the list.
This commit is contained in:
Deivid Soto 2026-06-14 12:51:32 +02:00
parent 523ecc724a
commit c7ee0c0a28
8 changed files with 256 additions and 45 deletions

View file

@ -248,6 +248,7 @@ func runDaemonStart() error {
HWDevices: hwDiag.Devices,
AutoUpgrade: cfg.Daemon.AutoUpgradeEnabled(),
Downlink: cfg.Daemon.Downlink,
PreferredMethods: cfg.Download.MethodOrder(),
}
// Create HTTP client with mirror failover so a `.com` block-out rolls
@ -381,6 +382,17 @@ func runDaemonStart() error {
// Create debrid downloader
debridDl := engine.NewDebridDownloader()
usenetDl := engine.NewUsenetDownloader(agentClient)
// Enable usenet when the user explicitly lists it in preferred_methods — the
// downloader gates on this flag, so without it a "usenet" preference would
// resolve to nothing. (Auto users keep the historical behaviour.)
methodOrder := cfg.Download.MethodOrder()
for _, m := range methodOrder {
if m == "usenet" {
usenetDl.SetEnabled(true)
log.Printf("[usenet] enabled via preferred_methods")
break
}
}
// Pre-flight disk reserve: refuse a download that would leave less than this
// many bytes free, so a download never fills the filesystem to 0 mid-write.
@ -392,9 +404,10 @@ func runDaemonStart() error {
// Create download manager
manager := engine.NewManager(engine.ManagerConfig{
MaxConcurrent: cfg.Download.MaxConcurrent,
OutputDir: cfg.Download.Dir,
Notifications: cfg.Notifications.Enabled,
MaxConcurrent: cfg.Download.MaxConcurrent,
OutputDir: cfg.Download.Dir,
Notifications: cfg.Notifications.Enabled,
PreferredMethods: methodOrder,
Organize: engine.OrganizeConfig{
Enabled: cfg.Organize.Enabled,
MoviesDir: cfg.Organize.MoviesDir,