From c3687b8fa568b37ed748dedf090f46b41482c91d Mon Sep 17 00:00:00 2001 From: Ludvig Lundgren Date: Sun, 13 Feb 2022 18:24:41 +0100 Subject: [PATCH] fix: download clients rule checking (#137) * fix: download client rules exit * feat: improve re-announce --- internal/action/qbittorrent.go | 51 ++++++++++++++++++++-------------- internal/action/run.go | 6 ++-- pkg/qbittorrent/methods.go | 40 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/internal/action/qbittorrent.go b/internal/action/qbittorrent.go index 03aa2ac..c20cee0 100644 --- a/internal/action/qbittorrent.go +++ b/internal/action/qbittorrent.go @@ -10,7 +10,7 @@ import ( "github.com/rs/zerolog/log" ) -const ReannounceMaxAttempts = 30 +const ReannounceMaxAttempts = 50 const ReannounceInterval = 7000 func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, hash string, torrentFile string) error { @@ -92,7 +92,7 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, // check for active downloads and other rules if client.Settings.Rules.Enabled && !action.IgnoreRules { - activeDownloads, err := qbt.GetTorrentsFilter(qbittorrent.TorrentFilterDownloading) + activeDownloads, err := qbt.GetTorrentsActiveDownloads() if err != nil { log.Error().Stack().Err(err).Msg("could not fetch downloading torrents") return false, nil, err @@ -119,6 +119,9 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, } log.Debug().Msg("active downloads are slower than set limit, lets add it") + } else { + log.Debug().Msg("max active downloads reached, skipping") + return false, nil, nil } } } @@ -132,10 +135,12 @@ func checkTrackerStatus(qb qbittorrent.Client, hash string) error { attempts := 0 // initial sleep to give tracker a head start - time.Sleep(2 * time.Second) + time.Sleep(4 * time.Second) for attempts < ReannounceMaxAttempts { - log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts) + if attempts > 0 { + log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts) + } trackers, err := qb.GetTorrentTrackers(hash) if err != nil { @@ -145,30 +150,34 @@ func checkTrackerStatus(qb qbittorrent.Client, hash string) error { // check if status not working or something else working := findTrackerStatus(trackers, qbittorrent.TrackerStatusOK) - - if !working { - log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts) - err = qb.ReAnnounceTorrents([]string{hash}) - if err != nil { - log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash) - return err + if working { + if attempts > 0 { + log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash) } - attempts++ - - // add delay for next run - time.Sleep(ReannounceInterval * time.Millisecond) - - continue - } else { - log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash) - announceOK = true - break + + // if working lets return + return nil } + + log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts) + err = qb.ReAnnounceTorrents([]string{hash}) + if err != nil { + log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash) + return err + } + + attempts++ + + // add delay for next run + time.Sleep(ReannounceInterval * time.Millisecond) + + continue } // add extra delay before delete + // TODO add setting: delete on failure to reannounce time.Sleep(30 * time.Second) if !announceOK { diff --git a/internal/action/run.go b/internal/action/run.go index 454b885..04666a1 100644 --- a/internal/action/run.go +++ b/internal/action/run.go @@ -92,7 +92,8 @@ func (s *service) runAction(action domain.Action, release domain.Release) error return err } if !canDownload { - rejections = []string{"deluge busy"} + rejections = []string{"max active downloads reached, skipping"} + break } if release.TorrentTmpFile == "" { @@ -120,7 +121,8 @@ func (s *service) runAction(action domain.Action, release domain.Release) error return err } if !canDownload { - rejections = []string{"qBittorrent busy"} + rejections = []string{"max active downloads reached, skipping"} + break } if release.TorrentTmpFile == "" { diff --git a/pkg/qbittorrent/methods.go b/pkg/qbittorrent/methods.go index f59c710..cd6fca2 100644 --- a/pkg/qbittorrent/methods.go +++ b/pkg/qbittorrent/methods.go @@ -112,6 +112,46 @@ func (c *Client) GetTorrentsFilter(filter TorrentFilter) ([]Torrent, error) { return torrents, nil } +func (c *Client) GetTorrentsActiveDownloads() ([]Torrent, error) { + var filter = TorrentFilterDownloading + + v := url.Values{} + v.Add("filter", string(filter)) + params := v.Encode() + + resp, err := c.get("torrents/info?"+params, nil) + if err != nil { + log.Error().Err(err).Msgf("get filtered torrents error: %v", filter) + return nil, err + } + + defer resp.Body.Close() + + body, readErr := ioutil.ReadAll(resp.Body) + if readErr != nil { + log.Error().Err(err).Msgf("get filtered torrents read error: %v", filter) + return nil, readErr + } + + var torrents []Torrent + err = json.Unmarshal(body, &torrents) + if err != nil { + log.Error().Err(err).Msgf("get filtered torrents unmarshal error: %v", filter) + return nil, err + } + + res := make([]Torrent, 0) + for _, torrent := range torrents { + // qbit counts paused torrents as downloading as well by default + // so only add torrents with state downloading, and not pausedDl, stalledDl etc + if torrent.State == TorrentStateDownloading { + res = append(res, torrent) + } + } + + return res, nil +} + func (c *Client) GetTorrentsRaw() (string, error) { resp, err := c.get("torrents/info", nil) if err != nil {