mirror of
https://github.com/simon-ding/polaris.git
synced 2026-02-06 15:10:49 +08:00
feat: episode status
This commit is contained in:
5
db/db.go
5
db/db.go
@@ -431,3 +431,8 @@ func (c *Client) UpdateEpisodeFile(seriesID int, seasonNum, episodeNum int, file
|
||||
}
|
||||
return ep.Update().SetFileInStorage(file).Exec(context.TODO())
|
||||
}
|
||||
|
||||
|
||||
func (c *Client) SetEpisodeStatus(id int, status episode.Status) error {
|
||||
return c.ent.Episode.Update().Where(episode.ID(id)).SetStatus(status).Exec(context.TODO())
|
||||
}
|
||||
@@ -29,6 +29,8 @@ type Episode struct {
|
||||
Overview string `json:"overview,omitempty"`
|
||||
// AirDate holds the value of the "air_date" field.
|
||||
AirDate string `json:"air_date,omitempty"`
|
||||
// Status holds the value of the "status" field.
|
||||
Status episode.Status `json:"status,omitempty"`
|
||||
// FileInStorage holds the value of the "file_in_storage" field.
|
||||
FileInStorage string `json:"file_in_storage,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
@@ -64,7 +66,7 @@ func (*Episode) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case episode.FieldID, episode.FieldSeriesID, episode.FieldSeasonNumber, episode.FieldEpisodeNumber:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate, episode.FieldFileInStorage:
|
||||
case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate, episode.FieldStatus, episode.FieldFileInStorage:
|
||||
values[i] = new(sql.NullString)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
@@ -123,6 +125,12 @@ func (e *Episode) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
e.AirDate = value.String
|
||||
}
|
||||
case episode.FieldStatus:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field status", values[i])
|
||||
} else if value.Valid {
|
||||
e.Status = episode.Status(value.String)
|
||||
}
|
||||
case episode.FieldFileInStorage:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field file_in_storage", values[i])
|
||||
@@ -188,6 +196,9 @@ func (e *Episode) String() string {
|
||||
builder.WriteString("air_date=")
|
||||
builder.WriteString(e.AirDate)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("status=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.Status))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("file_in_storage=")
|
||||
builder.WriteString(e.FileInStorage)
|
||||
builder.WriteByte(')')
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
package episode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
@@ -24,6 +26,8 @@ const (
|
||||
FieldOverview = "overview"
|
||||
// FieldAirDate holds the string denoting the air_date field in the database.
|
||||
FieldAirDate = "air_date"
|
||||
// FieldStatus holds the string denoting the status field in the database.
|
||||
FieldStatus = "status"
|
||||
// FieldFileInStorage holds the string denoting the file_in_storage field in the database.
|
||||
FieldFileInStorage = "file_in_storage"
|
||||
// EdgeSeries holds the string denoting the series edge name in mutations.
|
||||
@@ -48,6 +52,7 @@ var Columns = []string{
|
||||
FieldTitle,
|
||||
FieldOverview,
|
||||
FieldAirDate,
|
||||
FieldStatus,
|
||||
FieldFileInStorage,
|
||||
}
|
||||
|
||||
@@ -61,6 +66,33 @@ func ValidColumn(column string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Status defines the type for the "status" enum field.
|
||||
type Status string
|
||||
|
||||
// StatusMissing is the default value of the Status enum.
|
||||
const DefaultStatus = StatusMissing
|
||||
|
||||
// Status values.
|
||||
const (
|
||||
StatusMissing Status = "missing"
|
||||
StatusDownloading Status = "downloading"
|
||||
StatusDownloaded Status = "downloaded"
|
||||
)
|
||||
|
||||
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 StatusMissing, StatusDownloading, StatusDownloaded:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("episode: invalid enum value for status field: %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
// OrderOption defines the ordering options for the Episode queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
@@ -99,6 +131,11 @@ func ByAirDate(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAirDate, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStatus orders the results by the status field.
|
||||
func ByStatus(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStatus, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileInStorage orders the results by the file_in_storage field.
|
||||
func ByFileInStorage(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFileInStorage, opts...).ToFunc()
|
||||
|
||||
@@ -394,6 +394,26 @@ func AirDateContainsFold(v string) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldContainsFold(FieldAirDate, v))
|
||||
}
|
||||
|
||||
// StatusEQ applies the EQ predicate on the "status" field.
|
||||
func StatusEQ(v Status) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldEQ(FieldStatus, v))
|
||||
}
|
||||
|
||||
// StatusNEQ applies the NEQ predicate on the "status" field.
|
||||
func StatusNEQ(v Status) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldNEQ(FieldStatus, v))
|
||||
}
|
||||
|
||||
// StatusIn applies the In predicate on the "status" field.
|
||||
func StatusIn(vs ...Status) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldIn(FieldStatus, vs...))
|
||||
}
|
||||
|
||||
// StatusNotIn applies the NotIn predicate on the "status" field.
|
||||
func StatusNotIn(vs ...Status) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldNotIn(FieldStatus, vs...))
|
||||
}
|
||||
|
||||
// FileInStorageEQ applies the EQ predicate on the "file_in_storage" field.
|
||||
func FileInStorageEQ(v string) predicate.Episode {
|
||||
return predicate.Episode(sql.FieldEQ(FieldFileInStorage, v))
|
||||
|
||||
@@ -64,6 +64,20 @@ func (ec *EpisodeCreate) SetAirDate(s string) *EpisodeCreate {
|
||||
return ec
|
||||
}
|
||||
|
||||
// SetStatus sets the "status" field.
|
||||
func (ec *EpisodeCreate) SetStatus(e episode.Status) *EpisodeCreate {
|
||||
ec.mutation.SetStatus(e)
|
||||
return ec
|
||||
}
|
||||
|
||||
// SetNillableStatus sets the "status" field if the given value is not nil.
|
||||
func (ec *EpisodeCreate) SetNillableStatus(e *episode.Status) *EpisodeCreate {
|
||||
if e != nil {
|
||||
ec.SetStatus(*e)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
// SetFileInStorage sets the "file_in_storage" field.
|
||||
func (ec *EpisodeCreate) SetFileInStorage(s string) *EpisodeCreate {
|
||||
ec.mutation.SetFileInStorage(s)
|
||||
@@ -90,6 +104,7 @@ func (ec *EpisodeCreate) Mutation() *EpisodeMutation {
|
||||
|
||||
// Save creates the Episode in the database.
|
||||
func (ec *EpisodeCreate) Save(ctx context.Context) (*Episode, error) {
|
||||
ec.defaults()
|
||||
return withHooks(ctx, ec.sqlSave, ec.mutation, ec.hooks)
|
||||
}
|
||||
|
||||
@@ -115,6 +130,14 @@ func (ec *EpisodeCreate) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (ec *EpisodeCreate) defaults() {
|
||||
if _, ok := ec.mutation.Status(); !ok {
|
||||
v := episode.DefaultStatus
|
||||
ec.mutation.SetStatus(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (ec *EpisodeCreate) check() error {
|
||||
if _, ok := ec.mutation.SeasonNumber(); !ok {
|
||||
@@ -132,6 +155,14 @@ func (ec *EpisodeCreate) check() error {
|
||||
if _, ok := ec.mutation.AirDate(); !ok {
|
||||
return &ValidationError{Name: "air_date", err: errors.New(`ent: missing required field "Episode.air_date"`)}
|
||||
}
|
||||
if _, ok := ec.mutation.Status(); !ok {
|
||||
return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "Episode.status"`)}
|
||||
}
|
||||
if v, ok := ec.mutation.Status(); ok {
|
||||
if err := episode.StatusValidator(v); err != nil {
|
||||
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Episode.status": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -178,6 +209,10 @@ func (ec *EpisodeCreate) createSpec() (*Episode, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(episode.FieldAirDate, field.TypeString, value)
|
||||
_node.AirDate = value
|
||||
}
|
||||
if value, ok := ec.mutation.Status(); ok {
|
||||
_spec.SetField(episode.FieldStatus, field.TypeEnum, value)
|
||||
_node.Status = value
|
||||
}
|
||||
if value, ok := ec.mutation.FileInStorage(); ok {
|
||||
_spec.SetField(episode.FieldFileInStorage, field.TypeString, value)
|
||||
_node.FileInStorage = value
|
||||
@@ -220,6 +255,7 @@ func (ecb *EpisodeCreateBulk) Save(ctx context.Context) ([]*Episode, error) {
|
||||
for i := range ecb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := ecb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*EpisodeMutation)
|
||||
if !ok {
|
||||
|
||||
@@ -132,6 +132,20 @@ func (eu *EpisodeUpdate) SetNillableAirDate(s *string) *EpisodeUpdate {
|
||||
return eu
|
||||
}
|
||||
|
||||
// SetStatus sets the "status" field.
|
||||
func (eu *EpisodeUpdate) SetStatus(e episode.Status) *EpisodeUpdate {
|
||||
eu.mutation.SetStatus(e)
|
||||
return eu
|
||||
}
|
||||
|
||||
// SetNillableStatus sets the "status" field if the given value is not nil.
|
||||
func (eu *EpisodeUpdate) SetNillableStatus(e *episode.Status) *EpisodeUpdate {
|
||||
if e != nil {
|
||||
eu.SetStatus(*e)
|
||||
}
|
||||
return eu
|
||||
}
|
||||
|
||||
// SetFileInStorage sets the "file_in_storage" field.
|
||||
func (eu *EpisodeUpdate) SetFileInStorage(s string) *EpisodeUpdate {
|
||||
eu.mutation.SetFileInStorage(s)
|
||||
@@ -195,7 +209,20 @@ func (eu *EpisodeUpdate) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (eu *EpisodeUpdate) check() error {
|
||||
if v, ok := eu.mutation.Status(); ok {
|
||||
if err := episode.StatusValidator(v); err != nil {
|
||||
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Episode.status": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (eu *EpisodeUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if err := eu.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(episode.Table, episode.Columns, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt))
|
||||
if ps := eu.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
@@ -225,6 +252,9 @@ func (eu *EpisodeUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := eu.mutation.AirDate(); ok {
|
||||
_spec.SetField(episode.FieldAirDate, field.TypeString, value)
|
||||
}
|
||||
if value, ok := eu.mutation.Status(); ok {
|
||||
_spec.SetField(episode.FieldStatus, field.TypeEnum, value)
|
||||
}
|
||||
if value, ok := eu.mutation.FileInStorage(); ok {
|
||||
_spec.SetField(episode.FieldFileInStorage, field.TypeString, value)
|
||||
}
|
||||
@@ -384,6 +414,20 @@ func (euo *EpisodeUpdateOne) SetNillableAirDate(s *string) *EpisodeUpdateOne {
|
||||
return euo
|
||||
}
|
||||
|
||||
// SetStatus sets the "status" field.
|
||||
func (euo *EpisodeUpdateOne) SetStatus(e episode.Status) *EpisodeUpdateOne {
|
||||
euo.mutation.SetStatus(e)
|
||||
return euo
|
||||
}
|
||||
|
||||
// SetNillableStatus sets the "status" field if the given value is not nil.
|
||||
func (euo *EpisodeUpdateOne) SetNillableStatus(e *episode.Status) *EpisodeUpdateOne {
|
||||
if e != nil {
|
||||
euo.SetStatus(*e)
|
||||
}
|
||||
return euo
|
||||
}
|
||||
|
||||
// SetFileInStorage sets the "file_in_storage" field.
|
||||
func (euo *EpisodeUpdateOne) SetFileInStorage(s string) *EpisodeUpdateOne {
|
||||
euo.mutation.SetFileInStorage(s)
|
||||
@@ -460,7 +504,20 @@ func (euo *EpisodeUpdateOne) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (euo *EpisodeUpdateOne) check() error {
|
||||
if v, ok := euo.mutation.Status(); ok {
|
||||
if err := episode.StatusValidator(v); err != nil {
|
||||
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Episode.status": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (euo *EpisodeUpdateOne) sqlSave(ctx context.Context) (_node *Episode, err error) {
|
||||
if err := euo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(episode.Table, episode.Columns, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt))
|
||||
id, ok := euo.mutation.ID()
|
||||
if !ok {
|
||||
@@ -507,6 +564,9 @@ func (euo *EpisodeUpdateOne) sqlSave(ctx context.Context) (_node *Episode, err e
|
||||
if value, ok := euo.mutation.AirDate(); ok {
|
||||
_spec.SetField(episode.FieldAirDate, field.TypeString, value)
|
||||
}
|
||||
if value, ok := euo.mutation.Status(); ok {
|
||||
_spec.SetField(episode.FieldStatus, field.TypeEnum, value)
|
||||
}
|
||||
if value, ok := euo.mutation.FileInStorage(); ok {
|
||||
_spec.SetField(episode.FieldFileInStorage, field.TypeString, value)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ var (
|
||||
{Name: "title", Type: field.TypeString},
|
||||
{Name: "overview", Type: field.TypeString},
|
||||
{Name: "air_date", Type: field.TypeString},
|
||||
{Name: "status", Type: field.TypeEnum, Enums: []string{"missing", "downloading", "downloaded"}, Default: "missing"},
|
||||
{Name: "file_in_storage", Type: field.TypeString, Nullable: true},
|
||||
{Name: "series_id", Type: field.TypeInt, Nullable: true},
|
||||
}
|
||||
@@ -48,7 +49,7 @@ var (
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "episodes_series_episodes",
|
||||
Columns: []*schema.Column{EpisodesColumns[7]},
|
||||
Columns: []*schema.Column{EpisodesColumns[8]},
|
||||
RefColumns: []*schema.Column{SeriesColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
|
||||
@@ -918,6 +918,7 @@ type EpisodeMutation struct {
|
||||
title *string
|
||||
overview *string
|
||||
air_date *string
|
||||
status *episode.Status
|
||||
file_in_storage *string
|
||||
clearedFields map[string]struct{}
|
||||
series *int
|
||||
@@ -1294,6 +1295,42 @@ func (m *EpisodeMutation) ResetAirDate() {
|
||||
m.air_date = nil
|
||||
}
|
||||
|
||||
// SetStatus sets the "status" field.
|
||||
func (m *EpisodeMutation) SetStatus(e episode.Status) {
|
||||
m.status = &e
|
||||
}
|
||||
|
||||
// Status returns the value of the "status" field in the mutation.
|
||||
func (m *EpisodeMutation) Status() (r episode.Status, exists bool) {
|
||||
v := m.status
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldStatus returns the old "status" 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) OldStatus(ctx context.Context) (v episode.Status, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldStatus is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
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 OldStatus: %w", err)
|
||||
}
|
||||
return oldValue.Status, nil
|
||||
}
|
||||
|
||||
// ResetStatus resets all changes to the "status" field.
|
||||
func (m *EpisodeMutation) ResetStatus() {
|
||||
m.status = nil
|
||||
}
|
||||
|
||||
// SetFileInStorage sets the "file_in_storage" field.
|
||||
func (m *EpisodeMutation) SetFileInStorage(s string) {
|
||||
m.file_in_storage = &s
|
||||
@@ -1404,7 +1441,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.series != nil {
|
||||
fields = append(fields, episode.FieldSeriesID)
|
||||
}
|
||||
@@ -1423,6 +1460,9 @@ func (m *EpisodeMutation) Fields() []string {
|
||||
if m.air_date != nil {
|
||||
fields = append(fields, episode.FieldAirDate)
|
||||
}
|
||||
if m.status != nil {
|
||||
fields = append(fields, episode.FieldStatus)
|
||||
}
|
||||
if m.file_in_storage != nil {
|
||||
fields = append(fields, episode.FieldFileInStorage)
|
||||
}
|
||||
@@ -1446,6 +1486,8 @@ func (m *EpisodeMutation) Field(name string) (ent.Value, bool) {
|
||||
return m.Overview()
|
||||
case episode.FieldAirDate:
|
||||
return m.AirDate()
|
||||
case episode.FieldStatus:
|
||||
return m.Status()
|
||||
case episode.FieldFileInStorage:
|
||||
return m.FileInStorage()
|
||||
}
|
||||
@@ -1469,6 +1511,8 @@ func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value,
|
||||
return m.OldOverview(ctx)
|
||||
case episode.FieldAirDate:
|
||||
return m.OldAirDate(ctx)
|
||||
case episode.FieldStatus:
|
||||
return m.OldStatus(ctx)
|
||||
case episode.FieldFileInStorage:
|
||||
return m.OldFileInStorage(ctx)
|
||||
}
|
||||
@@ -1522,6 +1566,13 @@ func (m *EpisodeMutation) SetField(name string, value ent.Value) error {
|
||||
}
|
||||
m.SetAirDate(v)
|
||||
return nil
|
||||
case episode.FieldStatus:
|
||||
v, ok := value.(episode.Status)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetStatus(v)
|
||||
return nil
|
||||
case episode.FieldFileInStorage:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
@@ -1638,6 +1689,9 @@ func (m *EpisodeMutation) ResetField(name string) error {
|
||||
case episode.FieldAirDate:
|
||||
m.ResetAirDate()
|
||||
return nil
|
||||
case episode.FieldStatus:
|
||||
m.ResetStatus()
|
||||
return nil
|
||||
case episode.FieldFileInStorage:
|
||||
m.ResetFileInStorage()
|
||||
return nil
|
||||
|
||||
@@ -45,6 +45,8 @@ func init() {
|
||||
downloadclientsDescTags := downloadclientsFields[10].Descriptor()
|
||||
// downloadclients.DefaultTags holds the default value on creation for the tags field.
|
||||
downloadclients.DefaultTags = downloadclientsDescTags.Default.(string)
|
||||
episodeFields := schema.Episode{}.Fields()
|
||||
_ = episodeFields
|
||||
indexersFields := schema.Indexers{}.Fields()
|
||||
_ = indexersFields
|
||||
// indexersDescEnableRss is the schema descriptor for enable_rss field.
|
||||
|
||||
@@ -20,6 +20,7 @@ func (Episode) Fields() []ent.Field {
|
||||
field.String("title"),
|
||||
field.String("overview"),
|
||||
field.String("air_date"),
|
||||
field.Enum("status").Values("missing", "downloading", "downloaded").Default("missing"),
|
||||
field.String("file_in_storage").Optional(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"polaris/db"
|
||||
"polaris/ent"
|
||||
"polaris/ent/episode"
|
||||
"polaris/ent/history"
|
||||
"polaris/log"
|
||||
"polaris/pkg/torznab"
|
||||
@@ -123,6 +124,7 @@ func (s *Server) searchAndDownload(seriesId, seasonNum, episodeNum int) (*string
|
||||
Status: history.StatusRunning,
|
||||
Saved: torrent.Save(),
|
||||
})
|
||||
s.db.SetEpisodeStatus(ep.ID, episode.StatusDownloading)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "save record")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"path/filepath"
|
||||
"polaris/ent"
|
||||
"polaris/ent/episode"
|
||||
"polaris/ent/history"
|
||||
storage1 "polaris/ent/storage"
|
||||
"polaris/log"
|
||||
@@ -17,7 +18,7 @@ import (
|
||||
|
||||
func (s *Server) scheduler() {
|
||||
s.mustAddCron("@every 1m", s.checkTasks)
|
||||
s.mustAddCron("@every 10m", s.checkAllFiles)
|
||||
//s.mustAddCron("@every 1h", s.checkAllFiles)
|
||||
s.cron.Start()
|
||||
}
|
||||
|
||||
@@ -59,10 +60,13 @@ func (s *Server) moveCompletedTask(id int) (err error) {
|
||||
defer func () {
|
||||
if err != nil {
|
||||
s.db.SetHistoryStatus(r.ID, history.StatusFail)
|
||||
s.db.SetEpisodeStatus(r.EpisodeID, episode.StatusMissing)
|
||||
} else {
|
||||
torrent.Remove()
|
||||
delete(s.tasks, r.ID)
|
||||
s.db.SetHistoryStatus(r.ID, history.StatusSuccess)
|
||||
s.db.SetEpisodeStatus(r.EpisodeID, episode.StatusDownloaded)
|
||||
|
||||
torrent.Remove()
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@ class ActivityPage extends ConsumerWidget {
|
||||
DataCell(Text("${activity.date!.toLocal()}")),
|
||||
DataCell(() {
|
||||
if (activity.status == "uploading") {
|
||||
return const MyProgressIndicator(
|
||||
size: 20,
|
||||
);
|
||||
return const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator());
|
||||
} else if (activity.status == "fail") {
|
||||
return const Icon(
|
||||
Icons.close,
|
||||
|
||||
@@ -102,6 +102,7 @@ class Episodes {
|
||||
String? airDate;
|
||||
int? seasonNumber;
|
||||
String? overview;
|
||||
String? status;
|
||||
|
||||
Episodes(
|
||||
{this.id,
|
||||
@@ -110,6 +111,7 @@ class Episodes {
|
||||
this.title,
|
||||
this.airDate,
|
||||
this.seasonNumber,
|
||||
this.status,
|
||||
this.overview});
|
||||
|
||||
Episodes.fromJson(Map<String, dynamic> json) {
|
||||
@@ -119,6 +121,7 @@ class Episodes {
|
||||
title = json['title'];
|
||||
airDate = json['air_date'];
|
||||
seasonNumber = json['season_number'];
|
||||
status = json['status'];
|
||||
overview = json['overview'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,30 +46,24 @@ class _TvDetailsPageState extends ConsumerState<TvDetailsPage> {
|
||||
builder: (context, snapshot) {
|
||||
return seriesDetails.when(
|
||||
data: (details) {
|
||||
Map<int, List<Widget>> m = Map();
|
||||
Map<int, List<DataRow>> m = Map();
|
||||
for (final ep in details.episodes!) {
|
||||
var w = Container(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 70,
|
||||
child: Text("第 ${ep.episodeNumber} 集"),
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Opacity(
|
||||
var row = DataRow(cells: [
|
||||
DataCell(Text("${ep.episodeNumber}")),
|
||||
DataCell(Text("${ep.title}")),
|
||||
DataCell(Opacity(
|
||||
opacity: 0.5,
|
||||
child: Text("${ep.airDate}"),
|
||||
),
|
||||
),
|
||||
Text("${ep.title}", textAlign: TextAlign.left),
|
||||
const Expanded(child: Text("")),
|
||||
IconButton(
|
||||
)),
|
||||
DataCell(ep.status == "dwnloading"
|
||||
? const Icon(Icons.cloud_download)
|
||||
: (ep.status == "dwnloaded"
|
||||
? const Icon(Icons.cloud_done)
|
||||
: const Icon(Icons.cloud_off))),
|
||||
DataCell(IconButton(
|
||||
onPressed: () async {
|
||||
var f = ref
|
||||
.read(
|
||||
seriesDetailsProvider(seriesId).notifier)
|
||||
.read(seriesDetailsProvider(seriesId).notifier)
|
||||
.searchAndDownload(seriesId, ep.seasonNumber!,
|
||||
ep.episodeNumber!);
|
||||
setState(() {
|
||||
@@ -80,23 +74,31 @@ class _TvDetailsPageState extends ConsumerState<TvDetailsPage> {
|
||||
Utils.showSnakeBar(context, "开始下载: $name");
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.search))
|
||||
],
|
||||
),
|
||||
);
|
||||
icon: const Icon(Icons.search)))
|
||||
]);
|
||||
|
||||
if (m[ep.seasonNumber] == null) {
|
||||
m[ep.seasonNumber!] = List.empty(growable: true);
|
||||
}
|
||||
m[ep.seasonNumber!]!.add(w);
|
||||
m[ep.seasonNumber!]!.add(row);
|
||||
}
|
||||
List<ExpansionTile> list = List.empty(growable: true);
|
||||
for (final k in m.keys.toList().reversed) {
|
||||
var seasonList = ExpansionTile(
|
||||
tilePadding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||
childrenPadding: const EdgeInsets.fromLTRB(50, 0, 50, 0),
|
||||
initiallyExpanded: k == 0 ? false : true,
|
||||
//childrenPadding: const EdgeInsets.fromLTRB(50, 0, 50, 0),
|
||||
initiallyExpanded: false,
|
||||
title: k == 0 ? const Text("特集") : Text("第 $k 季"),
|
||||
children: m[k]!,
|
||||
expandedCrossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
DataTable(columns: const [
|
||||
DataColumn(label: Text("#")),
|
||||
DataColumn(label: SizedBox(width: 500, child: Text("标题"),)),
|
||||
DataColumn(label: Text("播出时间")),
|
||||
DataColumn(label: Text("状态")),
|
||||
DataColumn(label: Text("操作"))
|
||||
], rows: m[k]!),
|
||||
],
|
||||
);
|
||||
list.add(seasonList);
|
||||
}
|
||||
@@ -145,7 +147,6 @@ class _TvDetailsPageState extends ConsumerState<TvDetailsPage> {
|
||||
Text("$error"),
|
||||
loading: () =>
|
||||
const MyProgressIndicator()),
|
||||
|
||||
],
|
||||
),
|
||||
const Divider(thickness: 1, height: 1),
|
||||
|
||||
Reference in New Issue
Block a user