diff --git a/db/db.go b/db/db.go index 4975eeb..70c09cd 100644 --- a/db/db.go +++ b/db/db.go @@ -382,11 +382,11 @@ func (c *Client) SetDefaultStorageByName(name string) error { func (c *Client) SaveHistoryRecord(h ent.History) (*ent.History, error) { return c.ent.History.Create().SetSeriesID(h.SeriesID).SetEpisodeID(h.EpisodeID).SetDate(time.Now()). - SetCompleted(h.Completed).SetTargetDir(h.TargetDir).SetSourceTitle(h.SourceTitle).SetSaved(h.Saved).Save(context.TODO()) + SetStatus(h.Status).SetTargetDir(h.TargetDir).SetSourceTitle(h.SourceTitle).SetSaved(h.Saved).Save(context.TODO()) } -func (c *Client) SetHistoryComplete(id int) error { - return c.ent.History.Update().Where(history.ID(id)).SetCompleted(true).Exec(context.TODO()) +func (c *Client) SetHistoryStatus(id int, status history.Status) error { + return c.ent.History.Update().Where(history.ID(id)).SetStatus(status).Exec(context.TODO()) } func (c *Client) GetHistories() ent.Histories { @@ -398,7 +398,8 @@ func (c *Client) GetHistories() ent.Histories { } func (c *Client) GetRunningHistories() ent.Histories { - h, err := c.ent.History.Query().Where(history.Completed(false)).All(context.TODO()) + h, err := c.ent.History.Query().Where(history.Or(history.StatusEQ(history.StatusRunning), + history.StatusEQ(history.StatusUploading))).All(context.TODO()) if err != nil { return nil } diff --git a/ent/history.go b/ent/history.go index 08e12cc..af264fc 100644 --- a/ent/history.go +++ b/ent/history.go @@ -27,8 +27,8 @@ type History struct { Date time.Time `json:"date,omitempty"` // TargetDir holds the value of the "target_dir" field. TargetDir string `json:"target_dir,omitempty"` - // Completed holds the value of the "completed" field. - Completed bool `json:"completed"` + // Status holds the value of the "status" field. + Status history.Status `json:"status,omitempty"` // Saved holds the value of the "saved" field. Saved string `json:"saved,omitempty"` selectValues sql.SelectValues @@ -39,11 +39,9 @@ func (*History) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case history.FieldCompleted: - values[i] = new(sql.NullBool) case history.FieldID, history.FieldSeriesID, history.FieldEpisodeID: values[i] = new(sql.NullInt64) - case history.FieldSourceTitle, history.FieldTargetDir, history.FieldSaved: + case history.FieldSourceTitle, history.FieldTargetDir, history.FieldStatus, history.FieldSaved: values[i] = new(sql.NullString) case history.FieldDate: values[i] = new(sql.NullTime) @@ -98,11 +96,11 @@ func (h *History) assignValues(columns []string, values []any) error { } else if value.Valid { h.TargetDir = value.String } - case history.FieldCompleted: - if value, ok := values[i].(*sql.NullBool); !ok { - return fmt.Errorf("unexpected type %T for field completed", values[i]) + case history.FieldStatus: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field status", values[i]) } else if value.Valid { - h.Completed = value.Bool + h.Status = history.Status(value.String) } case history.FieldSaved: if value, ok := values[i].(*sql.NullString); !ok { @@ -161,8 +159,8 @@ func (h *History) String() string { builder.WriteString("target_dir=") builder.WriteString(h.TargetDir) builder.WriteString(", ") - builder.WriteString("completed=") - builder.WriteString(fmt.Sprintf("%v", h.Completed)) + builder.WriteString("status=") + builder.WriteString(fmt.Sprintf("%v", h.Status)) builder.WriteString(", ") builder.WriteString("saved=") builder.WriteString(h.Saved) diff --git a/ent/history/history.go b/ent/history/history.go index 52cd34c..8305e05 100644 --- a/ent/history/history.go +++ b/ent/history/history.go @@ -3,6 +3,8 @@ package history import ( + "fmt" + "entgo.io/ent/dialect/sql" ) @@ -21,8 +23,8 @@ const ( FieldDate = "date" // FieldTargetDir holds the string denoting the target_dir field in the database. FieldTargetDir = "target_dir" - // FieldCompleted holds the string denoting the completed field in the database. - FieldCompleted = "completed" + // FieldStatus holds the string denoting the status field in the database. + FieldStatus = "status" // FieldSaved holds the string denoting the saved field in the database. FieldSaved = "saved" // Table holds the table name of the history in the database. @@ -37,7 +39,7 @@ var Columns = []string{ FieldSourceTitle, FieldDate, FieldTargetDir, - FieldCompleted, + FieldStatus, FieldSaved, } @@ -51,11 +53,31 @@ func ValidColumn(column string) bool { return false } -var ( - // DefaultCompleted holds the default value on creation for the "completed" field. - DefaultCompleted bool +// Status defines the type for the "status" enum field. +type Status string + +// Status values. +const ( + StatusRunning Status = "running" + StatusSuccess Status = "success" + StatusFail Status = "fail" + StatusUploading Status = "uploading" ) +func (s Status) String() string { + return string(s) +} + +// StatusValidator is a validator for the "status" field enum values. It is called by the builders before save. +func StatusValidator(s Status) error { + switch s { + case StatusRunning, StatusSuccess, StatusFail, StatusUploading: + return nil + default: + return fmt.Errorf("history: invalid enum value for status field: %q", s) + } +} + // OrderOption defines the ordering options for the History queries. type OrderOption func(*sql.Selector) @@ -89,9 +111,9 @@ func ByTargetDir(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldTargetDir, opts...).ToFunc() } -// ByCompleted orders the results by the completed field. -func ByCompleted(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldCompleted, opts...).ToFunc() +// ByStatus orders the results by the status field. +func ByStatus(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldStatus, opts...).ToFunc() } // BySaved orders the results by the saved field. diff --git a/ent/history/where.go b/ent/history/where.go index 80332d8..8f185f6 100644 --- a/ent/history/where.go +++ b/ent/history/where.go @@ -79,11 +79,6 @@ func TargetDir(v string) predicate.History { return predicate.History(sql.FieldEQ(FieldTargetDir, v)) } -// Completed applies equality check predicate on the "completed" field. It's identical to CompletedEQ. -func Completed(v bool) predicate.History { - return predicate.History(sql.FieldEQ(FieldCompleted, v)) -} - // Saved applies equality check predicate on the "saved" field. It's identical to SavedEQ. func Saved(v string) predicate.History { return predicate.History(sql.FieldEQ(FieldSaved, v)) @@ -339,14 +334,24 @@ func TargetDirContainsFold(v string) predicate.History { return predicate.History(sql.FieldContainsFold(FieldTargetDir, v)) } -// CompletedEQ applies the EQ predicate on the "completed" field. -func CompletedEQ(v bool) predicate.History { - return predicate.History(sql.FieldEQ(FieldCompleted, v)) +// StatusEQ applies the EQ predicate on the "status" field. +func StatusEQ(v Status) predicate.History { + return predicate.History(sql.FieldEQ(FieldStatus, v)) } -// CompletedNEQ applies the NEQ predicate on the "completed" field. -func CompletedNEQ(v bool) predicate.History { - return predicate.History(sql.FieldNEQ(FieldCompleted, v)) +// StatusNEQ applies the NEQ predicate on the "status" field. +func StatusNEQ(v Status) predicate.History { + return predicate.History(sql.FieldNEQ(FieldStatus, v)) +} + +// StatusIn applies the In predicate on the "status" field. +func StatusIn(vs ...Status) predicate.History { + return predicate.History(sql.FieldIn(FieldStatus, vs...)) +} + +// StatusNotIn applies the NotIn predicate on the "status" field. +func StatusNotIn(vs ...Status) predicate.History { + return predicate.History(sql.FieldNotIn(FieldStatus, vs...)) } // SavedEQ applies the EQ predicate on the "saved" field. diff --git a/ent/history_create.go b/ent/history_create.go index 2fa361f..09b405b 100644 --- a/ent/history_create.go +++ b/ent/history_create.go @@ -50,17 +50,9 @@ func (hc *HistoryCreate) SetTargetDir(s string) *HistoryCreate { return hc } -// SetCompleted sets the "completed" field. -func (hc *HistoryCreate) SetCompleted(b bool) *HistoryCreate { - hc.mutation.SetCompleted(b) - return hc -} - -// SetNillableCompleted sets the "completed" field if the given value is not nil. -func (hc *HistoryCreate) SetNillableCompleted(b *bool) *HistoryCreate { - if b != nil { - hc.SetCompleted(*b) - } +// SetStatus sets the "status" field. +func (hc *HistoryCreate) SetStatus(h history.Status) *HistoryCreate { + hc.mutation.SetStatus(h) return hc } @@ -85,7 +77,6 @@ func (hc *HistoryCreate) Mutation() *HistoryMutation { // Save creates the History in the database. func (hc *HistoryCreate) Save(ctx context.Context) (*History, error) { - hc.defaults() return withHooks(ctx, hc.sqlSave, hc.mutation, hc.hooks) } @@ -111,14 +102,6 @@ func (hc *HistoryCreate) ExecX(ctx context.Context) { } } -// defaults sets the default values of the builder before save. -func (hc *HistoryCreate) defaults() { - if _, ok := hc.mutation.Completed(); !ok { - v := history.DefaultCompleted - hc.mutation.SetCompleted(v) - } -} - // check runs all checks and user-defined validators on the builder. func (hc *HistoryCreate) check() error { if _, ok := hc.mutation.SeriesID(); !ok { @@ -136,8 +119,13 @@ func (hc *HistoryCreate) check() error { if _, ok := hc.mutation.TargetDir(); !ok { return &ValidationError{Name: "target_dir", err: errors.New(`ent: missing required field "History.target_dir"`)} } - if _, ok := hc.mutation.Completed(); !ok { - return &ValidationError{Name: "completed", err: errors.New(`ent: missing required field "History.completed"`)} + if _, ok := hc.mutation.Status(); !ok { + return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "History.status"`)} + } + if v, ok := hc.mutation.Status(); ok { + if err := history.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "History.status": %w`, err)} + } } return nil } @@ -185,9 +173,9 @@ func (hc *HistoryCreate) createSpec() (*History, *sqlgraph.CreateSpec) { _spec.SetField(history.FieldTargetDir, field.TypeString, value) _node.TargetDir = value } - if value, ok := hc.mutation.Completed(); ok { - _spec.SetField(history.FieldCompleted, field.TypeBool, value) - _node.Completed = value + if value, ok := hc.mutation.Status(); ok { + _spec.SetField(history.FieldStatus, field.TypeEnum, value) + _node.Status = value } if value, ok := hc.mutation.Saved(); ok { _spec.SetField(history.FieldSaved, field.TypeString, value) @@ -214,7 +202,6 @@ func (hcb *HistoryCreateBulk) Save(ctx context.Context) ([]*History, error) { for i := range hcb.builders { func(i int, root context.Context) { builder := hcb.builders[i] - builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*HistoryMutation) if !ok { diff --git a/ent/history_update.go b/ent/history_update.go index f451505..8ad0e98 100644 --- a/ent/history_update.go +++ b/ent/history_update.go @@ -112,16 +112,16 @@ func (hu *HistoryUpdate) SetNillableTargetDir(s *string) *HistoryUpdate { return hu } -// SetCompleted sets the "completed" field. -func (hu *HistoryUpdate) SetCompleted(b bool) *HistoryUpdate { - hu.mutation.SetCompleted(b) +// SetStatus sets the "status" field. +func (hu *HistoryUpdate) SetStatus(h history.Status) *HistoryUpdate { + hu.mutation.SetStatus(h) return hu } -// SetNillableCompleted sets the "completed" field if the given value is not nil. -func (hu *HistoryUpdate) SetNillableCompleted(b *bool) *HistoryUpdate { - if b != nil { - hu.SetCompleted(*b) +// SetNillableStatus sets the "status" field if the given value is not nil. +func (hu *HistoryUpdate) SetNillableStatus(h *history.Status) *HistoryUpdate { + if h != nil { + hu.SetStatus(*h) } return hu } @@ -178,7 +178,20 @@ func (hu *HistoryUpdate) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (hu *HistoryUpdate) check() error { + if v, ok := hu.mutation.Status(); ok { + if err := history.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "History.status": %w`, err)} + } + } + return nil +} + func (hu *HistoryUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := hu.check(); err != nil { + return n, err + } _spec := sqlgraph.NewUpdateSpec(history.Table, history.Columns, sqlgraph.NewFieldSpec(history.FieldID, field.TypeInt)) if ps := hu.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { @@ -208,8 +221,8 @@ func (hu *HistoryUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := hu.mutation.TargetDir(); ok { _spec.SetField(history.FieldTargetDir, field.TypeString, value) } - if value, ok := hu.mutation.Completed(); ok { - _spec.SetField(history.FieldCompleted, field.TypeBool, value) + if value, ok := hu.mutation.Status(); ok { + _spec.SetField(history.FieldStatus, field.TypeEnum, value) } if value, ok := hu.mutation.Saved(); ok { _spec.SetField(history.FieldSaved, field.TypeString, value) @@ -321,16 +334,16 @@ func (huo *HistoryUpdateOne) SetNillableTargetDir(s *string) *HistoryUpdateOne { return huo } -// SetCompleted sets the "completed" field. -func (huo *HistoryUpdateOne) SetCompleted(b bool) *HistoryUpdateOne { - huo.mutation.SetCompleted(b) +// SetStatus sets the "status" field. +func (huo *HistoryUpdateOne) SetStatus(h history.Status) *HistoryUpdateOne { + huo.mutation.SetStatus(h) return huo } -// SetNillableCompleted sets the "completed" field if the given value is not nil. -func (huo *HistoryUpdateOne) SetNillableCompleted(b *bool) *HistoryUpdateOne { - if b != nil { - huo.SetCompleted(*b) +// SetNillableStatus sets the "status" field if the given value is not nil. +func (huo *HistoryUpdateOne) SetNillableStatus(h *history.Status) *HistoryUpdateOne { + if h != nil { + huo.SetStatus(*h) } return huo } @@ -400,7 +413,20 @@ func (huo *HistoryUpdateOne) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (huo *HistoryUpdateOne) check() error { + if v, ok := huo.mutation.Status(); ok { + if err := history.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "History.status": %w`, err)} + } + } + return nil +} + func (huo *HistoryUpdateOne) sqlSave(ctx context.Context) (_node *History, err error) { + if err := huo.check(); err != nil { + return _node, err + } _spec := sqlgraph.NewUpdateSpec(history.Table, history.Columns, sqlgraph.NewFieldSpec(history.FieldID, field.TypeInt)) id, ok := huo.mutation.ID() if !ok { @@ -447,8 +473,8 @@ func (huo *HistoryUpdateOne) sqlSave(ctx context.Context) (_node *History, err e if value, ok := huo.mutation.TargetDir(); ok { _spec.SetField(history.FieldTargetDir, field.TypeString, value) } - if value, ok := huo.mutation.Completed(); ok { - _spec.SetField(history.FieldCompleted, field.TypeBool, value) + if value, ok := huo.mutation.Status(); ok { + _spec.SetField(history.FieldStatus, field.TypeEnum, value) } if value, ok := huo.mutation.Saved(); ok { _spec.SetField(history.FieldSaved, field.TypeString, value) diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index 6f49a50..1b61545 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -62,7 +62,7 @@ var ( {Name: "source_title", Type: field.TypeString}, {Name: "date", Type: field.TypeTime}, {Name: "target_dir", Type: field.TypeString}, - {Name: "completed", Type: field.TypeBool, Default: false}, + {Name: "status", Type: field.TypeEnum, Enums: []string{"running", "success", "fail", "uploading"}}, {Name: "saved", Type: field.TypeString, Nullable: true}, } // HistoriesTable holds the schema information for the "histories" table. diff --git a/ent/mutation.go b/ent/mutation.go index 9aee043..794d69e 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -1732,7 +1732,7 @@ type HistoryMutation struct { source_title *string date *time.Time target_dir *string - completed *bool + status *history.Status saved *string clearedFields map[string]struct{} done bool @@ -2058,40 +2058,40 @@ func (m *HistoryMutation) ResetTargetDir() { m.target_dir = nil } -// SetCompleted sets the "completed" field. -func (m *HistoryMutation) SetCompleted(b bool) { - m.completed = &b +// SetStatus sets the "status" field. +func (m *HistoryMutation) SetStatus(h history.Status) { + m.status = &h } -// Completed returns the value of the "completed" field in the mutation. -func (m *HistoryMutation) Completed() (r bool, exists bool) { - v := m.completed +// Status returns the value of the "status" field in the mutation. +func (m *HistoryMutation) Status() (r history.Status, exists bool) { + v := m.status if v == nil { return } return *v, true } -// OldCompleted returns the old "completed" field's value of the History entity. +// OldStatus returns the old "status" field's value of the History entity. // If the History 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 *HistoryMutation) OldCompleted(ctx context.Context) (v bool, err error) { +func (m *HistoryMutation) OldStatus(ctx context.Context) (v history.Status, err error) { if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldCompleted is only allowed on UpdateOne operations") + return v, errors.New("OldStatus is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, errors.New("OldCompleted requires an ID field in the mutation") + return v, errors.New("OldStatus requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldCompleted: %w", err) + return v, fmt.Errorf("querying old value for OldStatus: %w", err) } - return oldValue.Completed, nil + return oldValue.Status, nil } -// ResetCompleted resets all changes to the "completed" field. -func (m *HistoryMutation) ResetCompleted() { - m.completed = nil +// ResetStatus resets all changes to the "status" field. +func (m *HistoryMutation) ResetStatus() { + m.status = nil } // SetSaved sets the "saved" field. @@ -2193,8 +2193,8 @@ func (m *HistoryMutation) Fields() []string { if m.target_dir != nil { fields = append(fields, history.FieldTargetDir) } - if m.completed != nil { - fields = append(fields, history.FieldCompleted) + if m.status != nil { + fields = append(fields, history.FieldStatus) } if m.saved != nil { fields = append(fields, history.FieldSaved) @@ -2217,8 +2217,8 @@ func (m *HistoryMutation) Field(name string) (ent.Value, bool) { return m.Date() case history.FieldTargetDir: return m.TargetDir() - case history.FieldCompleted: - return m.Completed() + case history.FieldStatus: + return m.Status() case history.FieldSaved: return m.Saved() } @@ -2240,8 +2240,8 @@ func (m *HistoryMutation) OldField(ctx context.Context, name string) (ent.Value, return m.OldDate(ctx) case history.FieldTargetDir: return m.OldTargetDir(ctx) - case history.FieldCompleted: - return m.OldCompleted(ctx) + case history.FieldStatus: + return m.OldStatus(ctx) case history.FieldSaved: return m.OldSaved(ctx) } @@ -2288,12 +2288,12 @@ func (m *HistoryMutation) SetField(name string, value ent.Value) error { } m.SetTargetDir(v) return nil - case history.FieldCompleted: - v, ok := value.(bool) + case history.FieldStatus: + v, ok := value.(history.Status) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } - m.SetCompleted(v) + m.SetStatus(v) return nil case history.FieldSaved: v, ok := value.(string) @@ -2402,8 +2402,8 @@ func (m *HistoryMutation) ResetField(name string) error { case history.FieldTargetDir: m.ResetTargetDir() return nil - case history.FieldCompleted: - m.ResetCompleted() + case history.FieldStatus: + m.ResetStatus() return nil case history.FieldSaved: m.ResetSaved() diff --git a/ent/runtime.go b/ent/runtime.go index d520efb..d6f0af2 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -4,7 +4,6 @@ package ent import ( "polaris/ent/downloadclients" - "polaris/ent/history" "polaris/ent/indexers" "polaris/ent/schema" "polaris/ent/series" @@ -46,12 +45,6 @@ func init() { downloadclientsDescTags := downloadclientsFields[10].Descriptor() // downloadclients.DefaultTags holds the default value on creation for the tags field. downloadclients.DefaultTags = downloadclientsDescTags.Default.(string) - historyFields := schema.History{}.Fields() - _ = historyFields - // historyDescCompleted is the schema descriptor for completed field. - historyDescCompleted := historyFields[5].Descriptor() - // history.DefaultCompleted holds the default value on creation for the completed field. - history.DefaultCompleted = historyDescCompleted.Default.(bool) indexersFields := schema.Indexers{}.Fields() _ = indexersFields // indexersDescEnableRss is the schema descriptor for enable_rss field. diff --git a/ent/schema/history.go b/ent/schema/history.go index d6e94ac..0920a9e 100644 --- a/ent/schema/history.go +++ b/ent/schema/history.go @@ -18,7 +18,7 @@ func (History) Fields() []ent.Field { field.String("source_title"), field.Time("date"), field.String("target_dir"), - field.Bool("completed").Default(false).StructTag("json:\"completed\""), + field.Enum("status").Values("running", "success", "fail", "uploading"), field.String("saved").Optional(), } } diff --git a/server/activity.go b/server/activity.go index f991b82..95b1c51 100644 --- a/server/activity.go +++ b/server/activity.go @@ -11,7 +11,6 @@ import ( type Activity struct { *ent.History - InBackgroud bool `json:"in_backgroud"` Progress int `json:"progress"` } @@ -26,12 +25,6 @@ func (s *Server) GetAllActivities(c *gin.Context) (interface{}, error) { if h.ID == id && task.Exists() { a.Progress = task.Progress() } - if h.ID == id && task.Processing { - a.InBackgroud = true - } - } - if a.Completed { - a.Progress = 100 } activities = append(activities, a) } diff --git a/server/resources.go b/server/resources.go index d981f98..083d04a 100644 --- a/server/resources.go +++ b/server/resources.go @@ -4,6 +4,7 @@ import ( "fmt" "polaris/db" "polaris/ent" + "polaris/ent/history" "polaris/log" "polaris/pkg/torznab" "polaris/pkg/transmission" @@ -119,7 +120,7 @@ func (s *Server) searchAndDownload(seriesId, seasonNum, episodeNum int) (*string EpisodeID: ep.ID, SourceTitle: r1.Name, TargetDir: dir, - Completed: false, + Status: history.StatusRunning, Saved: torrent.Save(), }) if err != nil { diff --git a/server/scheduler.go b/server/scheduler.go index d8eb6f6..e1a5c59 100644 --- a/server/scheduler.go +++ b/server/scheduler.go @@ -3,6 +3,7 @@ package server import ( "path/filepath" "polaris/ent" + "polaris/ent/history" storage1 "polaris/ent/storage" "polaris/log" "polaris/pkg" @@ -34,14 +35,9 @@ func (s *Server) checkTasks() { log.Infof("task no longer exists: %v", id) continue } - if t.Processing { - continue - } - log.Infof("task (%s) percentage done: %d%%", t.Name(), t.Progress()) if t.Progress() == 100 { log.Infof("task is done: %v", t.Name()) - t.Processing = true go func() { if err := s.moveCompletedTask(id); err != nil { log.Infof("post tasks for id %v fail: %v", id, err) @@ -51,9 +47,22 @@ func (s *Server) checkTasks() { } } -func (s *Server) moveCompletedTask(id int) error { +func (s *Server) moveCompletedTask(id int) (err error) { torrent := s.tasks[id] r := s.db.GetHistory(id) + if r.Status == history.StatusUploading { + log.Infof("task %d is laready uploading, skip", id) + return nil + } + s.db.SetHistoryStatus(r.ID, history.StatusUploading) + + defer func () { + if err != nil { + s.db.SetHistoryStatus(r.ID, history.StatusFail) + } else { + s.db.SetHistoryStatus(r.ID, history.StatusSuccess) + } + }() series := s.db.GetSeriesDetails(r.SeriesID) if series == nil { @@ -86,7 +95,7 @@ func (s *Server) moveCompletedTask(id int) error { log.Infof("move downloaded files to target dir success, file: %v, target dir: %v", torrent.Name(), r.TargetDir) torrent.Remove() delete(s.tasks, r.ID) - s.db.SetHistoryComplete(r.ID) + s.db.SetHistoryStatus(r.ID, history.StatusSuccess) return nil } @@ -168,6 +177,6 @@ func (s *Server) checkFileExists(series *ent.Series) error { } type Task struct { - Processing bool + //Processing bool pkg.Torrent } diff --git a/ui/lib/activity.dart b/ui/lib/activity.dart index 0e5d922..ba6787c 100644 --- a/ui/lib/activity.dart +++ b/ui/lib/activity.dart @@ -30,21 +30,25 @@ class ActivityPage extends ConsumerWidget { DataCell(Text("${activity.sourceTitle}")), DataCell(Text("${activity.date!.toLocal()}")), DataCell(() { - if (activity.inBackgroud == true) { + if (activity.status == "uploading") { return const MyProgressIndicator( size: 20, ); - } - - if (activity.completed != true && activity.progress == 0) { + }else if (activity.status == "fail") { return const Icon( Icons.close, color: Colors.red, ); + } else if (activity.status == "success") { + return const Icon( + Icons.check, + color: Colors.green, + ); } + double p = activity.progress == null ? 0:activity.progress!.toDouble() / 100; return MyProgressIndicator( - value: activity.progress!.toDouble() / 100, + value: p, size: 20, ); }()), diff --git a/ui/lib/providers/activity.dart b/ui/lib/providers/activity.dart index c5aafce..b5ad52d 100644 --- a/ui/lib/providers/activity.dart +++ b/ui/lib/providers/activity.dart @@ -43,9 +43,8 @@ class Activity { required this.sourceTitle, required this.date, required this.targetDir, - required this.completed, + required this.status, required this.saved, - required this.inBackgroud, required this.progress }); @@ -55,9 +54,8 @@ class Activity { final String? sourceTitle; final DateTime? date; final String? targetDir; - final bool? completed; + final String? status; final String? saved; - final bool? inBackgroud; final int? progress; factory Activity.fromJson(Map json) { @@ -68,9 +66,8 @@ class Activity { sourceTitle: json["source_title"], date: DateTime.tryParse(json["date"] ?? ""), targetDir: json["target_dir"], - completed: json["completed"], + status: json["status"], saved: json["saved"], - inBackgroud: json["in_backgroud"], progress: json["progress"] ); }