diff --git a/pkg/doc.go b/pkg/doc.go index e256eb3..9409421 100644 --- a/pkg/doc.go +++ b/pkg/doc.go @@ -1,14 +1,14 @@ package pkg type Torrent interface { - Name() string - Progress() int + Name() (string, error) + Progress() (int, error) Stop() error Start() error Remove() error Save() string Exists() bool - SeedRatio() *float64 + SeedRatio() (float64, error) } diff --git a/pkg/transmission/transmission.go b/pkg/transmission/transmission.go index 09ddc2a..71e3b10 100644 --- a/pkg/transmission/transmission.go +++ b/pkg/transmission/transmission.go @@ -113,12 +113,15 @@ func (t *Torrent) reloadClient() error { return nil } -func (t *Torrent) getTorrent() transmissionrpc.Torrent { +func (t *Torrent) getTorrent() (transmissionrpc.Torrent, error) { r, err := t.c.TorrentGetAllForHashes(context.TODO(), []string{t.Hash}) if err != nil { log.Errorf("get torrent info for error: %v", err) } - return r[0] + if len(r) == 0 { + return transmissionrpc.Torrent{}, fmt.Errorf("no torrent") + } + return r[0], nil } func (t *Torrent) Exists() bool { @@ -129,37 +132,50 @@ func (t *Torrent) Exists() bool { return len(r) > 0 } -func (t *Torrent) Name() string { - if !t.Exists() { - return "" + +func (t *Torrent) Name() (string, error) { + tt, err := t.getTorrent() + if err != nil { + return "", err } - return *t.getTorrent().Name + return *tt.Name, nil } -func (t *Torrent) Progress() int { - if t.getTorrent().IsFinished != nil && *t.getTorrent().IsFinished { - return 100 +func (t *Torrent) Progress() (int, error) { + tt, err := t.getTorrent() + if err != nil { + return 0, err } - if t.getTorrent().PercentComplete != nil && *t.getTorrent().PercentComplete >= 1 { - return 100 + if tt.IsFinished != nil && *tt.IsFinished { + return 100, nil + } + if tt.PercentComplete != nil && *tt.PercentComplete >= 1 { + return 100, nil } - if t.getTorrent().PercentComplete != nil { - p := int(*t.getTorrent().PercentComplete * 100) + if tt.PercentComplete != nil { + p := int(*tt.PercentComplete * 100) if p == 100 { p = 99 } - return p + return p, nil } - return 0 + return 0, nil } func (t *Torrent) Stop() error { return t.c.TorrentStopHashes(context.TODO(), []string{t.Hash}) } -func (t *Torrent) SeedRatio() *float64 { - return t.getTorrent().UploadRatio +func (t *Torrent) SeedRatio() (float64, error) { + tt, err := t.getTorrent() + if err != nil { + return 0, err + } + if tt.UploadRatio == nil { + return 0, nil + } + return *tt.UploadRatio, nil } func (t *Torrent) Start() error { @@ -167,15 +183,22 @@ func (t *Torrent) Start() error { } func (t *Torrent) Remove() error { - tt := t.getTorrent() + tt, err := t.getTorrent() + if err != nil { + return errors.Wrap(err, "get torrent") + } return t.c.TorrentRemove(context.TODO(), transmissionrpc.TorrentRemovePayload{ IDs: []int64{*tt.ID}, DeleteLocalData: true, }) } -func (t *Torrent) Size() int { - return int(t.getTorrent().TotalSize.Byte()) +func (t *Torrent) Size() (int, error) { + tt, err := t.getTorrent() + if err != nil { + return 0, errors.Wrap(err, "get torrent") + } + return int(tt.TotalSize.Byte()), nil } func (t *Torrent) Save() string { diff --git a/server/activity.go b/server/activity.go index e59095c..171c697 100644 --- a/server/activity.go +++ b/server/activity.go @@ -16,7 +16,7 @@ import ( type Activity struct { *ent.History Progress int `json:"progress"` - SeedRatio float32 `json:"seed_ratio"` + SeedRatio float64 `json:"seed_ratio"` } func (s *Server) GetAllActivities(c *gin.Context) (interface{}, error) { @@ -30,8 +30,18 @@ func (s *Server) GetAllActivities(c *gin.Context) (interface{}, error) { } for id, task := range s.core.GetTasks() { if h.ID == id && task.Exists() { - a.Progress = task.Progress() - a.SeedRatio = float32(*task.SeedRatio()) + p, err := task.Progress() + if err != nil { + log.Warnf("get task progress error: %v", err) + } else { + a.Progress = p + } + r, err := task.SeedRatio() + if err != nil { + log.Warnf("get task seed ratio error: %v", err) + } else { + a.SeedRatio = r + } } } activities = append(activities, a) @@ -73,7 +83,6 @@ func (s *Server) RemoveActivity(c *gin.Context) (interface{}, error) { return nil, errors.Wrap(err, "db") } - if his.EpisodeID != 0 { if !s.db.IsEpisodeDownloadingOrDownloaded(his.EpisodeID) { s.db.SetEpisodeStatus(his.EpisodeID, episode.StatusMissing) @@ -108,7 +117,7 @@ func (s *Server) GetMediaDownloadHistory(c *gin.Context) (interface{}, error) { type TorrentInfo struct { Name string `json:"name"` - ID string `json:"id"` + ID string `json:"id"` SeedRatio float32 `json:"seed_ratio"` Progress int `json:"progress"` } @@ -127,10 +136,12 @@ func (s *Server) GetAllTorrents(c *gin.Context) (interface{}, error) { if !t.Exists() { continue } + name, _ := t.Name() + p, _ := t.Progress() infos = append(infos, TorrentInfo{ - Name: t.Name(), + Name: name, ID: t.Hash, - Progress: t.Progress(), + Progress: p, }) } return infos, nil diff --git a/server/core/integration.go b/server/core/integration.go index ffffedf..b7b0fae 100644 --- a/server/core/integration.go +++ b/server/core/integration.go @@ -257,7 +257,11 @@ func (c *Client) findEpisodeFilesPreMoving(historyId int) error { isSingleEpisode := his.EpisodeID > 0 downloadDir := c.db.GetDownloadDir() task := c.tasks[historyId] - target := filepath.Join(downloadDir, task.Name()) + name, err := task.Name() + if err != nil { + return err + } + target := filepath.Join(downloadDir, name) fi, err := os.Stat(target) if err != nil { return errors.Wrapf(err, "read dir %v", target) diff --git a/server/core/scheduler.go b/server/core/scheduler.go index 4e7022f..efcd98d 100644 --- a/server/core/scheduler.go +++ b/server/core/scheduler.go @@ -63,24 +63,33 @@ func (c *Client) checkTasks() error { delete(c.tasks, id) continue } - log.Infof("task (%s) percentage done: %d%%", t.Name(), t.Progress()) - if t.Progress() == 100 { + name, err := t.Name() + if err != nil { + return errors.Wrap(err, "get name") + } + + progress, err := t.Progress() + if err != nil { + return errors.Wrap(err, "get progress") + } + log.Infof("task (%s) percentage done: %d%%", name, progress) + if progress == 100 { if r.Status == history.StatusSeeding { //task already success, check seed ratio torrent := c.tasks[id] - ok := c.isSeedRatioLimitReached(r.IndexerID, torrent) + ratio, ok := c.isSeedRatioLimitReached(r.IndexerID, torrent) if ok { - log.Infof("torrent file seed ratio reached, remove: %v, current seed ratio: %v", torrent.Name(), *torrent.SeedRatio()) + log.Infof("torrent file seed ratio reached, remove: %v, current seed ratio: %v", name, ratio) torrent.Remove() delete(c.tasks, id) } else { - log.Infof("torrent file still sedding: %v, current seed ratio: %v", torrent.Name(), *torrent.SeedRatio()) + log.Infof("torrent file still sedding: %v, current seed ratio: %v", name, ratio) } continue } - log.Infof("task is done: %v", t.Name()) - c.sendMsg(fmt.Sprintf(message.DownloadComplete, t.Name())) + log.Infof("task is done: %v", name) + c.sendMsg(fmt.Sprintf(message.DownloadComplete, name)) go c.postTaskProcessing(id) } @@ -122,7 +131,10 @@ func (c *Client) moveCompletedTask(id int) (err1 error) { log.Errorf("get task download client error: %v, use default one", err) downloadclient = &ent.DownloadClients{RemoveCompletedDownloads: true, RemoveFailedDownloads: true} } - torrentName := torrent.Name() + torrentName, err := torrent.Name() + if err != nil { + return err + } defer func() { @@ -169,9 +181,9 @@ func (c *Client) moveCompletedTask(id int) (err1 error) { c.sendMsg(fmt.Sprintf(message.ProcessingComplete, torrentName)) //判断是否需要删除本地文件 - ok := c.isSeedRatioLimitReached(r.IndexerID, torrent) + r1, ok := c.isSeedRatioLimitReached(r.IndexerID, torrent) if downloadclient.RemoveCompletedDownloads && ok { - log.Debugf("download complete,remove torrent and files related, torrent: %v, seed ratio: %v", torrentName, *torrent.SeedRatio()) + log.Debugf("download complete,remove torrent and files related, torrent: %v, seed ratio: %v", torrentName, r1) c.db.SetHistoryStatus(r.ID, history.StatusSuccess) delete(c.tasks, r.ID) torrent.Remove() @@ -428,15 +440,15 @@ func (c *Client) checkSeiesNewSeason(media *ent.Media) error { return nil } -func (c *Client) isSeedRatioLimitReached(indexId int, t pkg.Torrent) bool { +func (c *Client) isSeedRatioLimitReached(indexId int, t pkg.Torrent)(float64,bool) { indexer, err := c.db.GetIndexer(indexId) if err != nil { - return true + return 0, true } - currentRatio := t.SeedRatio() - if currentRatio == nil { - log.Warnf("get current seed ratio error, current ratio is nil") - return indexer.SeedRatio == 0 + currentRatio, err := t.SeedRatio() + if err != nil { + log.Warnf("get current seed ratio error: %v", err) + return currentRatio, indexer.SeedRatio == 0 } - return *currentRatio >= float64(indexer.SeedRatio) + return currentRatio, currentRatio >= float64(indexer.SeedRatio) }