From e26e86a63f4e2e777dd3218e2aa1d2b1ea73d8fe Mon Sep 17 00:00:00 2001 From: Simon Ding Date: Thu, 1 Aug 2024 19:52:40 +0800 Subject: [PATCH] feat: implement seed ratio check logic --- db/db.go | 13 ++++++++++ pkg/doc.go | 1 + pkg/transmission/transmission.go | 7 ++++++ server/scheduler.go | 41 ++++++++++++++++++++++++++++---- server/server.go | 12 +++++----- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/db/db.go b/db/db.go index 2a183eb..9921eff 100644 --- a/db/db.go +++ b/db/db.go @@ -275,6 +275,19 @@ func (c *Client) DeleteTorznab(id int) { c.ent.Indexers.Delete().Where(indexers.ID(id)).Exec(context.TODO()) } +func (c *Client) GetIndexer(id int) (*TorznabInfo, error) { + res, err := c.ent.Indexers.Query().Where(indexers.ID(id)).First(context.TODO()) + if err != nil { + return nil, err + } + var ss TorznabSetting + err = json.Unmarshal([]byte(res.Settings), &ss) + if err != nil { + + return nil, fmt.Errorf("unmarshal torznab %s error: %v", res.Name, err) + } + return &TorznabInfo{Indexers: res, TorznabSetting: ss}, nil +} type TorznabInfo struct { *ent.Indexers TorznabSetting diff --git a/pkg/doc.go b/pkg/doc.go index 46968b8..e256eb3 100644 --- a/pkg/doc.go +++ b/pkg/doc.go @@ -8,6 +8,7 @@ type Torrent interface { Remove() error Save() string Exists() bool + SeedRatio() *float64 } diff --git a/pkg/transmission/transmission.go b/pkg/transmission/transmission.go index ca9034a..3f1d8f8 100644 --- a/pkg/transmission/transmission.go +++ b/pkg/transmission/transmission.go @@ -130,6 +130,9 @@ func (t *Torrent) Exists() bool { } func (t *Torrent) Name() string { + if !t.Exists() { + return "" + } return *t.getTorrent().Name } @@ -155,6 +158,10 @@ func (t *Torrent) Stop() error { return t.c.TorrentStopIDs(context.TODO(), []int64{t.ID}) } +func (t *Torrent) SeedRatio() *float64 { + return t.getTorrent().UploadRatio +} + func (t *Torrent) Start() error { return t.c.TorrentStartIDs(context.TODO(), []int64{t.ID}) } diff --git a/server/scheduler.go b/server/scheduler.go index fbb5841..38e900f 100644 --- a/server/scheduler.go +++ b/server/scheduler.go @@ -44,6 +44,24 @@ func (s *Server) checkTasks() { } log.Infof("task (%s) percentage done: %d%%", t.Name(), t.Progress()) if t.Progress() == 100 { + r := s.db.GetHistory(id) + if r.Status == history.StatusSuccess { + //task already success, check seed ratio + torrent := s.tasks[id] + ok, err := s.isSeedRatioLimitReached(r.IndexerID, torrent) + if err != nil { + log.Warnf("getting torrent seed ratio : %v", err) + ok = false + } + if ok { + log.Infof("torrent file seed ratio reached, remove: %v", torrent.Name()) + torrent.Remove() + delete(s.tasks, id) + } else { + log.Infof("torrent file still sedding: %v", torrent.Name()) + } + continue + } log.Infof("task is done: %v", t.Name()) s.sendMsg(fmt.Sprintf(message.DownloadComplete, t.Name())) go func() { @@ -88,7 +106,7 @@ func (s *Server) moveCompletedTask(id int) (err1 error) { if downloadclient.RemoveFailedDownloads { log.Debugf("task failed, remove failed torrent and files related") delete(s.tasks, r.ID) - torrent.Remove() + torrent.Remove() } } }() @@ -114,7 +132,6 @@ func (s *Server) moveCompletedTask(id int) (err1 error) { log.Errorf("create .plexmatch file error: %v", err) } - s.db.SetHistoryStatus(r.ID, history.StatusSuccess) if r.EpisodeID != 0 { s.db.SetEpisodeStatus(r.EpisodeID, episode.StatusDownloaded) @@ -124,13 +141,17 @@ func (s *Server) moveCompletedTask(id int) (err1 error) { s.sendMsg(fmt.Sprintf(message.ProcessingComplete, torrentName)) //判断是否需要删除本地文件 - if downloadclient.RemoveCompletedDownloads { + ok, err := s.isSeedRatioLimitReached(r.IndexerID, torrent) + if err != nil { + log.Warnf("getting torrent seed ratio %s: %v", torrent.Name(), err) + ok = false + } + if downloadclient.RemoveCompletedDownloads && ok { log.Debugf("download complete,remove torrent and files related") delete(s.tasks, r.ID) torrent.Remove() } - log.Infof("move downloaded files to target dir success, file: %v, target dir: %v", torrentName, r.TargetDir) return nil } @@ -330,3 +351,15 @@ func (s *Server) checkSeiesNewSeason(media *ent.Media) error { } return nil } + +func (s *Server) isSeedRatioLimitReached(indexId int, t pkg.Torrent) (bool, error) { + indexer, err := s.db.GetIndexer(indexId) + if err != nil { + return false, err + } + currentRatio := t.SeedRatio() + if currentRatio == nil { + return false, errors.New("seed ratio not exist") + } + return *currentRatio >= float64(indexer.SeedRatio), nil +} diff --git a/server/server.go b/server/server.go index 3640f44..a0410ed 100644 --- a/server/server.go +++ b/server/server.go @@ -143,17 +143,17 @@ func (s *Server) MustTMDB() *tmdb.Client { } func (s *Server) reloadTasks() { - runningTasks := s.db.GetRunningHistories() - if len(runningTasks) == 0 { - return - } - for _, t := range runningTasks { - log.Infof("reloading task: %d %s", t.ID, t.SourceTitle) + allTasks := s.db.GetHistories() + for _, t := range allTasks { torrent, err := transmission.ReloadTorrent(t.Saved) if err != nil { log.Errorf("relaod task %s failed: %v", t.SourceTitle, err) continue } + if !torrent.Exists() { //只要种子还存在于客户端中,就重新加载,有可能是还在做种中 + continue + } + log.Infof("reloading task: %d %s", t.ID, t.SourceTitle) s.tasks[t.ID] = &Task{Torrent: torrent} } }