diff --git a/ent/episode.go b/ent/episode.go index 8a662ad..4d1c55a 100644 --- a/ent/episode.go +++ b/ent/episode.go @@ -31,6 +31,8 @@ type Episode struct { AirDate string `json:"air_date,omitempty"` // Status holds the value of the "status" field. Status episode.Status `json:"status,omitempty"` + // Monitored holds the value of the "monitored" field. + Monitored bool `json:"monitored"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the EpisodeQuery when eager-loading is set. Edges EpisodeEdges `json:"edges"` @@ -62,6 +64,8 @@ func (*Episode) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { + case episode.FieldMonitored: + values[i] = new(sql.NullBool) case episode.FieldID, episode.FieldMediaID, episode.FieldSeasonNumber, episode.FieldEpisodeNumber: values[i] = new(sql.NullInt64) case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate, episode.FieldStatus: @@ -129,6 +133,12 @@ func (e *Episode) assignValues(columns []string, values []any) error { } else if value.Valid { e.Status = episode.Status(value.String) } + case episode.FieldMonitored: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field monitored", values[i]) + } else if value.Valid { + e.Monitored = value.Bool + } default: e.selectValues.Set(columns[i], values[i]) } @@ -190,6 +200,9 @@ func (e *Episode) String() string { builder.WriteString(", ") builder.WriteString("status=") builder.WriteString(fmt.Sprintf("%v", e.Status)) + builder.WriteString(", ") + builder.WriteString("monitored=") + builder.WriteString(fmt.Sprintf("%v", e.Monitored)) builder.WriteByte(')') return builder.String() } diff --git a/ent/episode/episode.go b/ent/episode/episode.go index f3d2c00..16713ae 100644 --- a/ent/episode/episode.go +++ b/ent/episode/episode.go @@ -28,6 +28,8 @@ const ( FieldAirDate = "air_date" // FieldStatus holds the string denoting the status field in the database. FieldStatus = "status" + // FieldMonitored holds the string denoting the monitored field in the database. + FieldMonitored = "monitored" // EdgeMedia holds the string denoting the media edge name in mutations. EdgeMedia = "media" // Table holds the table name of the episode in the database. @@ -51,6 +53,7 @@ var Columns = []string{ FieldOverview, FieldAirDate, FieldStatus, + FieldMonitored, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -63,6 +66,11 @@ func ValidColumn(column string) bool { return false } +var ( + // DefaultMonitored holds the default value on creation for the "monitored" field. + DefaultMonitored bool +) + // Status defines the type for the "status" enum field. type Status string @@ -133,6 +141,11 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldStatus, opts...).ToFunc() } +// ByMonitored orders the results by the monitored field. +func ByMonitored(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMonitored, opts...).ToFunc() +} + // ByMediaField orders the results by media field. func ByMediaField(field string, opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { diff --git a/ent/episode/where.go b/ent/episode/where.go index 64fb4a8..15b51da 100644 --- a/ent/episode/where.go +++ b/ent/episode/where.go @@ -84,6 +84,11 @@ func AirDate(v string) predicate.Episode { return predicate.Episode(sql.FieldEQ(FieldAirDate, v)) } +// Monitored applies equality check predicate on the "monitored" field. It's identical to MonitoredEQ. +func Monitored(v bool) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldMonitored, v)) +} + // MediaIDEQ applies the EQ predicate on the "media_id" field. func MediaIDEQ(v int) predicate.Episode { return predicate.Episode(sql.FieldEQ(FieldMediaID, v)) @@ -409,6 +414,16 @@ func StatusNotIn(vs ...Status) predicate.Episode { return predicate.Episode(sql.FieldNotIn(FieldStatus, vs...)) } +// MonitoredEQ applies the EQ predicate on the "monitored" field. +func MonitoredEQ(v bool) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldMonitored, v)) +} + +// MonitoredNEQ applies the NEQ predicate on the "monitored" field. +func MonitoredNEQ(v bool) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldMonitored, v)) +} + // HasMedia applies the HasEdge predicate on the "media" edge. func HasMedia() predicate.Episode { return predicate.Episode(func(s *sql.Selector) { diff --git a/ent/episode_create.go b/ent/episode_create.go index 55187ac..9458c97 100644 --- a/ent/episode_create.go +++ b/ent/episode_create.go @@ -78,6 +78,20 @@ func (ec *EpisodeCreate) SetNillableStatus(e *episode.Status) *EpisodeCreate { return ec } +// SetMonitored sets the "monitored" field. +func (ec *EpisodeCreate) SetMonitored(b bool) *EpisodeCreate { + ec.mutation.SetMonitored(b) + return ec +} + +// SetNillableMonitored sets the "monitored" field if the given value is not nil. +func (ec *EpisodeCreate) SetNillableMonitored(b *bool) *EpisodeCreate { + if b != nil { + ec.SetMonitored(*b) + } + return ec +} + // SetMedia sets the "media" edge to the Media entity. func (ec *EpisodeCreate) SetMedia(m *Media) *EpisodeCreate { return ec.SetMediaID(m.ID) @@ -122,6 +136,10 @@ func (ec *EpisodeCreate) defaults() { v := episode.DefaultStatus ec.mutation.SetStatus(v) } + if _, ok := ec.mutation.Monitored(); !ok { + v := episode.DefaultMonitored + ec.mutation.SetMonitored(v) + } } // check runs all checks and user-defined validators on the builder. @@ -149,6 +167,9 @@ func (ec *EpisodeCreate) check() error { return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Episode.status": %w`, err)} } } + if _, ok := ec.mutation.Monitored(); !ok { + return &ValidationError{Name: "monitored", err: errors.New(`ent: missing required field "Episode.monitored"`)} + } return nil } @@ -199,6 +220,10 @@ func (ec *EpisodeCreate) createSpec() (*Episode, *sqlgraph.CreateSpec) { _spec.SetField(episode.FieldStatus, field.TypeEnum, value) _node.Status = value } + if value, ok := ec.mutation.Monitored(); ok { + _spec.SetField(episode.FieldMonitored, field.TypeBool, value) + _node.Monitored = value + } if nodes := ec.mutation.MediaIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/ent/episode_update.go b/ent/episode_update.go index f8a21af..5f54f8e 100644 --- a/ent/episode_update.go +++ b/ent/episode_update.go @@ -146,6 +146,20 @@ func (eu *EpisodeUpdate) SetNillableStatus(e *episode.Status) *EpisodeUpdate { return eu } +// SetMonitored sets the "monitored" field. +func (eu *EpisodeUpdate) SetMonitored(b bool) *EpisodeUpdate { + eu.mutation.SetMonitored(b) + return eu +} + +// SetNillableMonitored sets the "monitored" field if the given value is not nil. +func (eu *EpisodeUpdate) SetNillableMonitored(b *bool) *EpisodeUpdate { + if b != nil { + eu.SetMonitored(*b) + } + return eu +} + // SetMedia sets the "media" edge to the Media entity. func (eu *EpisodeUpdate) SetMedia(m *Media) *EpisodeUpdate { return eu.SetMediaID(m.ID) @@ -235,6 +249,9 @@ func (eu *EpisodeUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := eu.mutation.Status(); ok { _spec.SetField(episode.FieldStatus, field.TypeEnum, value) } + if value, ok := eu.mutation.Monitored(); ok { + _spec.SetField(episode.FieldMonitored, field.TypeBool, value) + } if eu.mutation.MediaCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -402,6 +419,20 @@ func (euo *EpisodeUpdateOne) SetNillableStatus(e *episode.Status) *EpisodeUpdate return euo } +// SetMonitored sets the "monitored" field. +func (euo *EpisodeUpdateOne) SetMonitored(b bool) *EpisodeUpdateOne { + euo.mutation.SetMonitored(b) + return euo +} + +// SetNillableMonitored sets the "monitored" field if the given value is not nil. +func (euo *EpisodeUpdateOne) SetNillableMonitored(b *bool) *EpisodeUpdateOne { + if b != nil { + euo.SetMonitored(*b) + } + return euo +} + // SetMedia sets the "media" edge to the Media entity. func (euo *EpisodeUpdateOne) SetMedia(m *Media) *EpisodeUpdateOne { return euo.SetMediaID(m.ID) @@ -521,6 +552,9 @@ func (euo *EpisodeUpdateOne) sqlSave(ctx context.Context) (_node *Episode, err e if value, ok := euo.mutation.Status(); ok { _spec.SetField(episode.FieldStatus, field.TypeEnum, value) } + if value, ok := euo.mutation.Monitored(); ok { + _spec.SetField(episode.FieldMonitored, field.TypeBool, value) + } if euo.mutation.MediaCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index ed20a19..b3c8568 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -38,6 +38,7 @@ var ( {Name: "overview", Type: field.TypeString}, {Name: "air_date", Type: field.TypeString}, {Name: "status", Type: field.TypeEnum, Enums: []string{"missing", "downloading", "downloaded"}, Default: "missing"}, + {Name: "monitored", Type: field.TypeBool, Default: false}, {Name: "media_id", Type: field.TypeInt, Nullable: true}, } // EpisodesTable holds the schema information for the "episodes" table. @@ -48,7 +49,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "episodes_media_episodes", - Columns: []*schema.Column{EpisodesColumns[7]}, + Columns: []*schema.Column{EpisodesColumns[8]}, RefColumns: []*schema.Column{MediaColumns[0]}, OnDelete: schema.SetNull, }, diff --git a/ent/mutation.go b/ent/mutation.go index f06b5fc..ce77138 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -921,6 +921,7 @@ type EpisodeMutation struct { overview *string air_date *string status *episode.Status + monitored *bool clearedFields map[string]struct{} media *int clearedmedia bool @@ -1332,6 +1333,42 @@ func (m *EpisodeMutation) ResetStatus() { m.status = nil } +// SetMonitored sets the "monitored" field. +func (m *EpisodeMutation) SetMonitored(b bool) { + m.monitored = &b +} + +// Monitored returns the value of the "monitored" field in the mutation. +func (m *EpisodeMutation) Monitored() (r bool, exists bool) { + v := m.monitored + if v == nil { + return + } + return *v, true +} + +// OldMonitored returns the old "monitored" field's value of the Episode entity. +// If the Episode object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *EpisodeMutation) OldMonitored(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMonitored is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMonitored requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMonitored: %w", err) + } + return oldValue.Monitored, nil +} + +// ResetMonitored resets all changes to the "monitored" field. +func (m *EpisodeMutation) ResetMonitored() { + m.monitored = nil +} + // ClearMedia clears the "media" edge to the Media entity. func (m *EpisodeMutation) ClearMedia() { m.clearedmedia = true @@ -1393,7 +1430,7 @@ func (m *EpisodeMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *EpisodeMutation) Fields() []string { - fields := make([]string, 0, 7) + fields := make([]string, 0, 8) if m.media != nil { fields = append(fields, episode.FieldMediaID) } @@ -1415,6 +1452,9 @@ func (m *EpisodeMutation) Fields() []string { if m.status != nil { fields = append(fields, episode.FieldStatus) } + if m.monitored != nil { + fields = append(fields, episode.FieldMonitored) + } return fields } @@ -1437,6 +1477,8 @@ func (m *EpisodeMutation) Field(name string) (ent.Value, bool) { return m.AirDate() case episode.FieldStatus: return m.Status() + case episode.FieldMonitored: + return m.Monitored() } return nil, false } @@ -1460,6 +1502,8 @@ func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value, return m.OldAirDate(ctx) case episode.FieldStatus: return m.OldStatus(ctx) + case episode.FieldMonitored: + return m.OldMonitored(ctx) } return nil, fmt.Errorf("unknown Episode field %s", name) } @@ -1518,6 +1562,13 @@ func (m *EpisodeMutation) SetField(name string, value ent.Value) error { } m.SetStatus(v) return nil + case episode.FieldMonitored: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMonitored(v) + return nil } return fmt.Errorf("unknown Episode field %s", name) } @@ -1624,6 +1675,9 @@ func (m *EpisodeMutation) ResetField(name string) error { case episode.FieldStatus: m.ResetStatus() return nil + case episode.FieldMonitored: + m.ResetMonitored() + return nil } return fmt.Errorf("unknown Episode field %s", name) } diff --git a/ent/runtime.go b/ent/runtime.go index 1f5d7ce..8418bbe 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -4,6 +4,7 @@ package ent import ( "polaris/ent/downloadclients" + "polaris/ent/episode" "polaris/ent/history" "polaris/ent/indexers" "polaris/ent/media" @@ -49,6 +50,10 @@ func init() { downloadclients.DefaultTags = downloadclientsDescTags.Default.(string) episodeFields := schema.Episode{}.Fields() _ = episodeFields + // episodeDescMonitored is the schema descriptor for monitored field. + episodeDescMonitored := episodeFields[7].Descriptor() + // episode.DefaultMonitored holds the default value on creation for the monitored field. + episode.DefaultMonitored = episodeDescMonitored.Default.(bool) historyFields := schema.History{}.Fields() _ = historyFields // historyDescSize is the schema descriptor for size field. diff --git a/ent/schema/episode.go b/ent/schema/episode.go index fcca4b2..8cddf78 100644 --- a/ent/schema/episode.go +++ b/ent/schema/episode.go @@ -21,7 +21,7 @@ func (Episode) Fields() []ent.Field { field.String("overview"), field.String("air_date"), field.Enum("status").Values("missing", "downloading", "downloaded").Default("missing"), - field.Bool("monitored").Default(true).StructTag("json:\"monitored\""), //whether this episode is monitored + field.Bool("monitored").Default(false).StructTag("json:\"monitored\""), //whether this episode is monitored } } diff --git a/server/core/resources.go b/server/core/resources.go index 53ca176..b348831 100644 --- a/server/core/resources.go +++ b/server/core/resources.go @@ -112,7 +112,7 @@ func (c *Client) DownloadEpisodeTorrent(r1 torznab.Result, seriesId, seasonNum, } func (c *Client) SearchAndDownload(seriesId, seasonNum, episodeNum int) (*string, error) { - res, err := SearchEpisode(c.db, seriesId, seasonNum, episodeNum, true) + res, err := SearchTvSeries(c.db, seriesId, seasonNum, []int{episodeNum}, true) if err != nil { return nil, err } diff --git a/server/core/scheduler.go b/server/core/scheduler.go index e81d815..e0389bd 100644 --- a/server/core/scheduler.go +++ b/server/core/scheduler.go @@ -11,7 +11,6 @@ import ( "polaris/pkg" "polaris/pkg/notifier/message" "polaris/pkg/utils" - "time" "github.com/pkg/errors" ) @@ -140,7 +139,7 @@ func (c *Client) moveCompletedTask(id int) (err1 error) { c.sendMsg(fmt.Sprintf(message.ProcessingComplete, torrentName)) //判断是否需要删除本地文件 - ok, err := c.isSeedRatioLimitReached(r.IndexerID, torrent) + ok, err := c.isSeedRatioLimitReached(r.IndexerID, torrent) if err != nil { log.Warnf("getting torrent seed ratio %s: %v", torrent.Name(), err) ok = false @@ -217,15 +216,8 @@ func (c *Client) downloadTvSeries() { for _, series := range allSeries { tvDetail := c.db.GetMediaDetails(series.ID) for _, ep := range tvDetail.Episodes { - if !series.DownloadHistoryEpisodes { //设置不下载历史已播出剧集,只下载将来剧集 - t, err := time.Parse("2006-01-02", ep.AirDate) - if err != nil { - log.Error("air date not known, skip: %v", ep.Title) - continue - } - if series.CreatedAt.Sub(t) > 24*time.Hour { //剧集在加入watchlist之前,不去下载 - continue - } + if !ep.Monitored { //未监控的剧集不去下载 + continue } if ep.Status != episode.StatusMissing { //已经下载的不去下载 @@ -338,6 +330,7 @@ func (c *Client) checkSeiesNewSeason(media *ent.Media) error { Overview: ep.Overview, AirDate: ep.AirDate, Status: episode.StatusMissing, + Monitored: true, } c.db.SaveEposideDetail2(episode) } diff --git a/server/core/torrent.go b/server/core/torrent.go index 3858b4f..dc4101b 100644 --- a/server/core/torrent.go +++ b/server/core/torrent.go @@ -7,6 +7,7 @@ import ( "polaris/pkg/metadata" "polaris/pkg/torznab" "polaris/pkg/utils" + "slices" "sort" "strconv" "strings" @@ -15,30 +16,12 @@ import ( "github.com/pkg/errors" ) -func SearchSeasonPackage(db1 *db.Client, seriesId, seasonNum int, checkResolution bool) ([]torznab.Result, error) { - return SearchEpisode(db1, seriesId, seasonNum, -1, checkResolution) -} - -func isNumberedSeries(detail *db.MediaDetails) bool { - hasSeason2 := false - season2HasEpisode1 := false - for _, ep := range detail.Episodes { - if ep.SeasonNumber == 2 { - hasSeason2 = true - if ep.EpisodeNumber == 1 { - season2HasEpisode1 = true - } - - } - } - return hasSeason2 && !season2HasEpisode1 //only one 1st episode -} - -func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int, checkResolution bool) ([]torznab.Result, error) { +func SearchTvSeries(db1 *db.Client, seriesId, seasonNum int, episodes []int, checkResolution bool) ([]torznab.Result, error) { series := db1.GetMediaDetails(seriesId) if series == nil { return nil, fmt.Errorf("no tv series of id %v", seriesId) } + slices.Contains(episodes, 1) res := searchWithTorznab(db1, series.NameEn) resCn := searchWithTorznab(db1, series.NameCn) @@ -56,14 +39,14 @@ func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int, checkRes continue } } - if isNumberedSeries(series) && episodeNum == -1 { + if isNumberedSeries(series) && len(episodes) == 0 { //should not want season continue } - if episodeNum != -1 && meta.Episode != episodeNum { //not season pack, episode number equals + if len(episodes) > 0 && slices.Contains(episodes, meta.Episode) { //not season pack, episode number equals continue - }else if episodeNum == -1 && !meta.IsSeasonPack { //want season pack, but not season pack + }else if len(episodes) == 0 && !meta.IsSeasonPack { //want season pack, but not season pack continue } if checkResolution && meta.Resolution != series.Resolution.String() { @@ -82,6 +65,21 @@ func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int, checkRes } +func isNumberedSeries(detail *db.MediaDetails) bool { + hasSeason2 := false + season2HasEpisode1 := false + for _, ep := range detail.Episodes { + if ep.SeasonNumber == 2 { + hasSeason2 = true + if ep.EpisodeNumber == 1 { + season2HasEpisode1 = true + } + + } + } + return hasSeason2 && !season2HasEpisode1 //only one 1st episode +} + func SearchMovie(db1 *db.Client, movieId int, checkResolution bool) ([]torznab.Result, error) { movieDetail := db1.GetMediaDetails(movieId) if movieDetail == nil { diff --git a/server/resources.go b/server/resources.go index 9cc351c..002c2d3 100644 --- a/server/resources.go +++ b/server/resources.go @@ -13,7 +13,7 @@ import ( func (s *Server) searchAndDownloadSeasonPackage(seriesId, seasonNum int) (*string, error) { - res, err := core.SearchSeasonPackage(s.db, seriesId, seasonNum, true) + res, err := core.SearchTvSeries(s.db, seriesId, seasonNum, nil, true) if err != nil { return nil, err } @@ -46,13 +46,13 @@ func (s *Server) SearchAvailableTorrents(c *gin.Context) (interface{}, error) { if in.Episode == 0 { //search season package log.Infof("search series season package S%02d", in.Season) - res, err = core.SearchSeasonPackage(s.db, in.ID, in.Season, false) + res, err = core.SearchTvSeries(s.db, in.ID, in.Season, nil, false) if err != nil { return nil, errors.Wrap(err, "search season package") } } else { log.Infof("search series episode S%02dE%02d", in.Season, in.Episode) - res, err = core.SearchEpisode(s.db, in.ID, in.Season, in.Episode, false) + res, err = core.SearchTvSeries(s.db, in.ID, in.Season, []int{in.Episode}, false) if err != nil { if err.Error() == "no resource found" { return []string{}, nil diff --git a/server/watchlist.go b/server/watchlist.go index d375eca..2ecd6e8 100644 --- a/server/watchlist.go +++ b/server/watchlist.go @@ -102,12 +102,29 @@ func (s *Server) AddTv2Watchlist(c *gin.Context) (interface{}, error) { continue } for _, ep := range se.Episodes { + shouldMonitor := false + //如果设置下载往期剧集,则监控所有剧集。如果没有则监控未上映的剧集,考虑时差等问题留24h余量 + if in.DownloadHistoryEpisodes { + shouldMonitor = true + } else { + t, err := time.Parse("2006-01-02", ep.AirDate) + if err != nil { + log.Error("air date not known, will not monitor: %v", ep.AirDate) + + } else { + if time.Since(t) < 24*time.Hour { //monitor episode air 24h before now + shouldMonitor = true + } + } + } + epid, err := s.db.SaveEposideDetail(&ent.Episode{ SeasonNumber: seasonId, EpisodeNumber: ep.EpisodeNumber, Title: ep.Name, Overview: ep.Overview, AirDate: ep.AirDate, + Monitored: shouldMonitor, }) if err != nil { log.Errorf("save episode info error: %v", err) @@ -176,6 +193,7 @@ func (s *Server) AddMovie2Watchlist(c *gin.Context) (interface{}, error) { Title: "dummy episode for movies", Overview: "dummy episode for movies", AirDate: detail.ReleaseDate, + Monitored: true, }) if err != nil { return nil, errors.Wrap(err, "add dummy episode") @@ -249,8 +267,8 @@ func (s *Server) downloadImage(url string, mediaID int, name string) error { type MediaWithStatus struct { *ent.Media - MonitoredNum int `json:"monitored_num"` - DownloadedNum int `json:"downloaded_num"` + MonitoredNum int `json:"monitored_num"` + DownloadedNum int `json:"downloaded_num"` } //missing: episode aired missing @@ -263,7 +281,7 @@ func (s *Server) GetTvWatchlist(c *gin.Context) (interface{}, error) { res := make([]MediaWithStatus, len(list)) for i, item := range list { var ms = MediaWithStatus{ - Media: item, + Media: item, MonitoredNum: 0, DownloadedNum: 0, } @@ -271,30 +289,12 @@ func (s *Server) GetTvWatchlist(c *gin.Context) (interface{}, error) { details := s.db.GetMediaDetails(item.ID) for _, ep := range details.Episodes { - monitored := false - if ep.SeasonNumber == 0 { - continue - } - if item.DownloadHistoryEpisodes { - monitored = true - } else { - t, err := time.Parse("2006-01-02", ep.AirDate) - if err != nil { //airdate not exist, maybe airdate not set yet - monitored = true - } else { - if item.CreatedAt.Sub(t) > 24*time.Hour { //剧集在加入watchlist之前,不去下载 - continue - } - monitored = true - } - } - if monitored { + if ep.Monitored { ms.MonitoredNum++ - if ep.Status == episode.StatusDownloaded { - ms.DownloadedNum++ - } } - + if ep.Status == episode.StatusDownloaded { + ms.DownloadedNum++ + } } res[i] = ms } @@ -306,8 +306,8 @@ func (s *Server) GetMovieWatchlist(c *gin.Context) (interface{}, error) { res := make([]MediaWithStatus, len(list)) for i, item := range list { var ms = MediaWithStatus{ - Media: item, - MonitoredNum: 1, + Media: item, + MonitoredNum: 1, DownloadedNum: 0, } dummyEp, err := s.db.GetMovieDummyEpisode(item.ID)