diff --git a/db/const.go b/db/const.go index 04f126a..8b48b2a 100644 --- a/db/const.go +++ b/db/const.go @@ -37,15 +37,3 @@ const ( func (r ResolutionType) String() string { return string(r) } - -const ( - ImplLocal = "local" - ImplWebdav = "webdav" -) - -func StorageImplementations() []string { - return []string{ - ImplLocal, - ImplWebdav, - } -} \ No newline at end of file diff --git a/db/db.go b/db/db.go index e839308..5e7d29a 100644 --- a/db/db.go +++ b/db/db.go @@ -14,7 +14,6 @@ import ( "polaris/ent/settings" "polaris/ent/storage" "polaris/log" - "slices" "time" "entgo.io/ent/dialect" @@ -238,45 +237,48 @@ func (c *Client) DeleteDownloadCLient(id int) { // Storage is the model entity for the Storage schema. type StorageInfo struct { - Name string `json:"name"` - Implementation string `json:"implementation"` - Path string `json:"path"` - User string `json:"user"` - Password string `json:"password"` - Default bool `json:"default"` + Name string `json:"name"` + Implementation string `json:"implementation"` + Settings map[string]string `json:"settings"` + Default bool `json:"default"` } -func (c *Client) AddStorage(s StorageInfo) error { - if !slices.Contains(StorageImplementations(), s.Implementation) { - return fmt.Errorf("implementation not supported: %v", s.Implementation) +type LocalDirSetting struct { + Path string `json:"path"` +} + +type WebdavSetting struct { + URL string `json:"url"` + Path string `json:"path"` + User string `json:"user"` + Password string `json:"password"` +} + +func (c *Client) AddStorage(st *StorageInfo) error { + + data, err := json.Marshal(st.Settings) + if err != nil { + return errors.Wrap(err, "json marshal") } - count := c.ent.Storage.Query().Where(storage.Name(s.Name)).CountX(context.TODO()) + + count := c.ent.Storage.Query().Where(storage.Name(st.Name)).CountX(context.TODO()) if count > 0 { //storage already exist, edit exist one - return c.ent.Storage.Update().Where(storage.Name(s.Name)). - SetImplementation(s.Implementation). - SetPath(s.Path). - SetUser(s.User). - SetDefault(s.Default). - SetPassword(s.Password).Exec(context.TODO()) + return c.ent.Storage.Update().Where(storage.Name(st.Name)). + SetImplementation(storage.Implementation(st.Implementation)). + SetSettings(string(data)).Exec(context.TODO()) } countAll := c.ent.Storage.Query().CountX(context.TODO()) if countAll == 0 { - log.Infof("first storage, make it default: %s", s.Name) - s.Default = true + log.Infof("first storage, make it default: %s", st.Name) + st.Default = true } - _, err := c.ent.Storage.Create().SetName(s.Name). - SetImplementation(s.Implementation). - SetPath(s.Path). - SetUser(s.User). - SetDefault(s.Default). - SetPassword(s.Password).Save(context.TODO()) + _, err = c.ent.Storage.Create().SetName(st.Name). + SetImplementation(storage.Implementation(st.Implementation)). + SetSettings(string(data)).SetDefault(st.Default).Save(context.TODO()) if err != nil { return err } - if s.Default { - return c.SetDefaultStorageByName(s.Name) - } return nil } @@ -289,13 +291,37 @@ func (c *Client) GetAllStorage() []*ent.Storage { return data } -func (c *Client) GetStorage(id int) *ent.Storage { +type Storage struct { + ent.Storage +} + +func (s *Storage) ToLocalSetting() LocalDirSetting { + if s.Implementation != storage.ImplementationLocal { + panic("not local storage") + } + var localSetting LocalDirSetting + json.Unmarshal([]byte(s.Settings), &localSetting) + return localSetting +} + +func (s *Storage) ToWebDavSetting() WebdavSetting { + if s.Implementation != storage.ImplementationWebdav { + panic("not webdav storage") + } + var webdavSetting WebdavSetting + json.Unmarshal([]byte(s.Settings), &webdavSetting) + return webdavSetting + +} + +func (c *Client) GetStorage(id int) *Storage { r, err := c.ent.Storage.Query().Where(storage.ID(id)).First(context.TODO()) if err != nil { //use default storage - return c.ent.Storage.Query().Where(storage.Default(true)).FirstX(context.TODO()) + r := c.ent.Storage.Query().Where(storage.Default(true)).FirstX(context.TODO()) + return &Storage{*r} } - return r + return &Storage{*r} } func (c *Client) DeleteStorage(id int) error { diff --git a/ent/episode.go b/ent/episode.go index 5b61187..03b48c4 100644 --- a/ent/episode.go +++ b/ent/episode.go @@ -22,13 +22,15 @@ type Episode struct { // SeasonNumber holds the value of the "season_number" field. SeasonNumber int `json:"season_number"` // EpisodeNumber holds the value of the "episode_number" field. - EpisodeNumber int `json:"episode_number,omitempty"` + EpisodeNumber int `json:"episode_number"` // Title holds the value of the "title" field. Title string `json:"title,omitempty"` // Overview holds the value of the "overview" field. Overview string `json:"overview,omitempty"` // AirDate holds the value of the "air_date" field. AirDate string `json:"air_date,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. // The values are being populated by the EpisodeQuery when eager-loading is set. Edges EpisodeEdges `json:"edges"` @@ -62,7 +64,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: + case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate, episode.FieldFileInStorage: values[i] = new(sql.NullString) default: values[i] = new(sql.UnknownType) @@ -121,6 +123,12 @@ func (e *Episode) assignValues(columns []string, values []any) error { } else if value.Valid { e.AirDate = 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]) + } else if value.Valid { + e.FileInStorage = value.String + } default: e.selectValues.Set(columns[i], values[i]) } @@ -179,6 +187,9 @@ func (e *Episode) String() string { builder.WriteString(", ") builder.WriteString("air_date=") builder.WriteString(e.AirDate) + builder.WriteString(", ") + builder.WriteString("file_in_storage=") + builder.WriteString(e.FileInStorage) builder.WriteByte(')') return builder.String() } diff --git a/ent/episode/episode.go b/ent/episode/episode.go index 1abcdd2..076ebeb 100644 --- a/ent/episode/episode.go +++ b/ent/episode/episode.go @@ -24,6 +24,8 @@ const ( FieldOverview = "overview" // FieldAirDate holds the string denoting the air_date field in the database. FieldAirDate = "air_date" + // 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. EdgeSeries = "series" // Table holds the table name of the episode in the database. @@ -46,6 +48,7 @@ var Columns = []string{ FieldTitle, FieldOverview, FieldAirDate, + FieldFileInStorage, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -96,6 +99,11 @@ func ByAirDate(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldAirDate, opts...).ToFunc() } +// ByFileInStorage orders the results by the file_in_storage field. +func ByFileInStorage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFileInStorage, opts...).ToFunc() +} + // BySeriesField orders the results by series field. func BySeriesField(field string, opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { diff --git a/ent/episode/where.go b/ent/episode/where.go index bf00b43..3cc002c 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)) } +// FileInStorage applies equality check predicate on the "file_in_storage" field. It's identical to FileInStorageEQ. +func FileInStorage(v string) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldFileInStorage, v)) +} + // SeriesIDEQ applies the EQ predicate on the "series_id" field. func SeriesIDEQ(v int) predicate.Episode { return predicate.Episode(sql.FieldEQ(FieldSeriesID, v)) @@ -389,6 +394,81 @@ func AirDateContainsFold(v string) predicate.Episode { return predicate.Episode(sql.FieldContainsFold(FieldAirDate, v)) } +// FileInStorageEQ applies the EQ predicate on the "file_in_storage" field. +func FileInStorageEQ(v string) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldFileInStorage, v)) +} + +// FileInStorageNEQ applies the NEQ predicate on the "file_in_storage" field. +func FileInStorageNEQ(v string) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldFileInStorage, v)) +} + +// FileInStorageIn applies the In predicate on the "file_in_storage" field. +func FileInStorageIn(vs ...string) predicate.Episode { + return predicate.Episode(sql.FieldIn(FieldFileInStorage, vs...)) +} + +// FileInStorageNotIn applies the NotIn predicate on the "file_in_storage" field. +func FileInStorageNotIn(vs ...string) predicate.Episode { + return predicate.Episode(sql.FieldNotIn(FieldFileInStorage, vs...)) +} + +// FileInStorageGT applies the GT predicate on the "file_in_storage" field. +func FileInStorageGT(v string) predicate.Episode { + return predicate.Episode(sql.FieldGT(FieldFileInStorage, v)) +} + +// FileInStorageGTE applies the GTE predicate on the "file_in_storage" field. +func FileInStorageGTE(v string) predicate.Episode { + return predicate.Episode(sql.FieldGTE(FieldFileInStorage, v)) +} + +// FileInStorageLT applies the LT predicate on the "file_in_storage" field. +func FileInStorageLT(v string) predicate.Episode { + return predicate.Episode(sql.FieldLT(FieldFileInStorage, v)) +} + +// FileInStorageLTE applies the LTE predicate on the "file_in_storage" field. +func FileInStorageLTE(v string) predicate.Episode { + return predicate.Episode(sql.FieldLTE(FieldFileInStorage, v)) +} + +// FileInStorageContains applies the Contains predicate on the "file_in_storage" field. +func FileInStorageContains(v string) predicate.Episode { + return predicate.Episode(sql.FieldContains(FieldFileInStorage, v)) +} + +// FileInStorageHasPrefix applies the HasPrefix predicate on the "file_in_storage" field. +func FileInStorageHasPrefix(v string) predicate.Episode { + return predicate.Episode(sql.FieldHasPrefix(FieldFileInStorage, v)) +} + +// FileInStorageHasSuffix applies the HasSuffix predicate on the "file_in_storage" field. +func FileInStorageHasSuffix(v string) predicate.Episode { + return predicate.Episode(sql.FieldHasSuffix(FieldFileInStorage, v)) +} + +// FileInStorageIsNil applies the IsNil predicate on the "file_in_storage" field. +func FileInStorageIsNil() predicate.Episode { + return predicate.Episode(sql.FieldIsNull(FieldFileInStorage)) +} + +// FileInStorageNotNil applies the NotNil predicate on the "file_in_storage" field. +func FileInStorageNotNil() predicate.Episode { + return predicate.Episode(sql.FieldNotNull(FieldFileInStorage)) +} + +// FileInStorageEqualFold applies the EqualFold predicate on the "file_in_storage" field. +func FileInStorageEqualFold(v string) predicate.Episode { + return predicate.Episode(sql.FieldEqualFold(FieldFileInStorage, v)) +} + +// FileInStorageContainsFold applies the ContainsFold predicate on the "file_in_storage" field. +func FileInStorageContainsFold(v string) predicate.Episode { + return predicate.Episode(sql.FieldContainsFold(FieldFileInStorage, v)) +} + // HasSeries applies the HasEdge predicate on the "series" edge. func HasSeries() predicate.Episode { return predicate.Episode(func(s *sql.Selector) { diff --git a/ent/episode_create.go b/ent/episode_create.go index 18a5a4c..516e9b2 100644 --- a/ent/episode_create.go +++ b/ent/episode_create.go @@ -64,6 +64,20 @@ func (ec *EpisodeCreate) SetAirDate(s string) *EpisodeCreate { return ec } +// SetFileInStorage sets the "file_in_storage" field. +func (ec *EpisodeCreate) SetFileInStorage(s string) *EpisodeCreate { + ec.mutation.SetFileInStorage(s) + return ec +} + +// SetNillableFileInStorage sets the "file_in_storage" field if the given value is not nil. +func (ec *EpisodeCreate) SetNillableFileInStorage(s *string) *EpisodeCreate { + if s != nil { + ec.SetFileInStorage(*s) + } + return ec +} + // SetSeries sets the "series" edge to the Series entity. func (ec *EpisodeCreate) SetSeries(s *Series) *EpisodeCreate { return ec.SetSeriesID(s.ID) @@ -164,6 +178,10 @@ func (ec *EpisodeCreate) createSpec() (*Episode, *sqlgraph.CreateSpec) { _spec.SetField(episode.FieldAirDate, field.TypeString, value) _node.AirDate = value } + if value, ok := ec.mutation.FileInStorage(); ok { + _spec.SetField(episode.FieldFileInStorage, field.TypeString, value) + _node.FileInStorage = value + } if nodes := ec.mutation.SeriesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/ent/episode_update.go b/ent/episode_update.go index e0e9150..2829865 100644 --- a/ent/episode_update.go +++ b/ent/episode_update.go @@ -132,6 +132,26 @@ func (eu *EpisodeUpdate) SetNillableAirDate(s *string) *EpisodeUpdate { return eu } +// SetFileInStorage sets the "file_in_storage" field. +func (eu *EpisodeUpdate) SetFileInStorage(s string) *EpisodeUpdate { + eu.mutation.SetFileInStorage(s) + return eu +} + +// SetNillableFileInStorage sets the "file_in_storage" field if the given value is not nil. +func (eu *EpisodeUpdate) SetNillableFileInStorage(s *string) *EpisodeUpdate { + if s != nil { + eu.SetFileInStorage(*s) + } + return eu +} + +// ClearFileInStorage clears the value of the "file_in_storage" field. +func (eu *EpisodeUpdate) ClearFileInStorage() *EpisodeUpdate { + eu.mutation.ClearFileInStorage() + return eu +} + // SetSeries sets the "series" edge to the Series entity. func (eu *EpisodeUpdate) SetSeries(s *Series) *EpisodeUpdate { return eu.SetSeriesID(s.ID) @@ -205,6 +225,12 @@ 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.FileInStorage(); ok { + _spec.SetField(episode.FieldFileInStorage, field.TypeString, value) + } + if eu.mutation.FileInStorageCleared() { + _spec.ClearField(episode.FieldFileInStorage, field.TypeString) + } if eu.mutation.SeriesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -358,6 +384,26 @@ func (euo *EpisodeUpdateOne) SetNillableAirDate(s *string) *EpisodeUpdateOne { return euo } +// SetFileInStorage sets the "file_in_storage" field. +func (euo *EpisodeUpdateOne) SetFileInStorage(s string) *EpisodeUpdateOne { + euo.mutation.SetFileInStorage(s) + return euo +} + +// SetNillableFileInStorage sets the "file_in_storage" field if the given value is not nil. +func (euo *EpisodeUpdateOne) SetNillableFileInStorage(s *string) *EpisodeUpdateOne { + if s != nil { + euo.SetFileInStorage(*s) + } + return euo +} + +// ClearFileInStorage clears the value of the "file_in_storage" field. +func (euo *EpisodeUpdateOne) ClearFileInStorage() *EpisodeUpdateOne { + euo.mutation.ClearFileInStorage() + return euo +} + // SetSeries sets the "series" edge to the Series entity. func (euo *EpisodeUpdateOne) SetSeries(s *Series) *EpisodeUpdateOne { return euo.SetSeriesID(s.ID) @@ -461,6 +507,12 @@ 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.FileInStorage(); ok { + _spec.SetField(episode.FieldFileInStorage, field.TypeString, value) + } + if euo.mutation.FileInStorageCleared() { + _spec.ClearField(episode.FieldFileInStorage, field.TypeString) + } if euo.mutation.SeriesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index 76cb6e0..6f49a50 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -37,6 +37,7 @@ var ( {Name: "title", Type: field.TypeString}, {Name: "overview", Type: field.TypeString}, {Name: "air_date", Type: field.TypeString}, + {Name: "file_in_storage", Type: field.TypeString, Nullable: true}, {Name: "series_id", Type: field.TypeInt, Nullable: true}, } // EpisodesTable holds the schema information for the "episodes" table. @@ -47,7 +48,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "episodes_series_episodes", - Columns: []*schema.Column{EpisodesColumns[6]}, + Columns: []*schema.Column{EpisodesColumns[7]}, RefColumns: []*schema.Column{SeriesColumns[0]}, OnDelete: schema.SetNull, }, @@ -99,6 +100,7 @@ var ( {Name: "air_date", Type: field.TypeString, Default: ""}, {Name: "resolution", Type: field.TypeString, Default: ""}, {Name: "storage_id", Type: field.TypeInt, Nullable: true}, + {Name: "target_dir", Type: field.TypeString, Nullable: true}, } // SeriesTable holds the schema information for the "series" table. SeriesTable = &schema.Table{ @@ -122,10 +124,8 @@ var ( StoragesColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "name", Type: field.TypeString, Unique: true}, - {Name: "implementation", Type: field.TypeString}, - {Name: "path", Type: field.TypeString}, - {Name: "user", Type: field.TypeString, Nullable: true}, - {Name: "password", Type: field.TypeString, Nullable: true}, + {Name: "implementation", Type: field.TypeEnum, Enums: []string{"webdav", "local"}}, + {Name: "settings", Type: field.TypeString, Nullable: true}, {Name: "deleted", Type: field.TypeBool, Default: false}, {Name: "default", Type: field.TypeBool, Default: false}, } diff --git a/ent/mutation.go b/ent/mutation.go index 5d341f8..9aee043 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -918,6 +918,7 @@ type EpisodeMutation struct { title *string overview *string air_date *string + file_in_storage *string clearedFields map[string]struct{} series *int clearedseries bool @@ -1293,6 +1294,55 @@ func (m *EpisodeMutation) ResetAirDate() { m.air_date = nil } +// SetFileInStorage sets the "file_in_storage" field. +func (m *EpisodeMutation) SetFileInStorage(s string) { + m.file_in_storage = &s +} + +// FileInStorage returns the value of the "file_in_storage" field in the mutation. +func (m *EpisodeMutation) FileInStorage() (r string, exists bool) { + v := m.file_in_storage + if v == nil { + return + } + return *v, true +} + +// OldFileInStorage returns the old "file_in_storage" 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) OldFileInStorage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFileInStorage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFileInStorage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFileInStorage: %w", err) + } + return oldValue.FileInStorage, nil +} + +// ClearFileInStorage clears the value of the "file_in_storage" field. +func (m *EpisodeMutation) ClearFileInStorage() { + m.file_in_storage = nil + m.clearedFields[episode.FieldFileInStorage] = struct{}{} +} + +// FileInStorageCleared returns if the "file_in_storage" field was cleared in this mutation. +func (m *EpisodeMutation) FileInStorageCleared() bool { + _, ok := m.clearedFields[episode.FieldFileInStorage] + return ok +} + +// ResetFileInStorage resets all changes to the "file_in_storage" field. +func (m *EpisodeMutation) ResetFileInStorage() { + m.file_in_storage = nil + delete(m.clearedFields, episode.FieldFileInStorage) +} + // ClearSeries clears the "series" edge to the Series entity. func (m *EpisodeMutation) ClearSeries() { m.clearedseries = true @@ -1354,7 +1404,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, 6) + fields := make([]string, 0, 7) if m.series != nil { fields = append(fields, episode.FieldSeriesID) } @@ -1373,6 +1423,9 @@ func (m *EpisodeMutation) Fields() []string { if m.air_date != nil { fields = append(fields, episode.FieldAirDate) } + if m.file_in_storage != nil { + fields = append(fields, episode.FieldFileInStorage) + } return fields } @@ -1393,6 +1446,8 @@ func (m *EpisodeMutation) Field(name string) (ent.Value, bool) { return m.Overview() case episode.FieldAirDate: return m.AirDate() + case episode.FieldFileInStorage: + return m.FileInStorage() } return nil, false } @@ -1414,6 +1469,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.FieldFileInStorage: + return m.OldFileInStorage(ctx) } return nil, fmt.Errorf("unknown Episode field %s", name) } @@ -1465,6 +1522,13 @@ func (m *EpisodeMutation) SetField(name string, value ent.Value) error { } m.SetAirDate(v) return nil + case episode.FieldFileInStorage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFileInStorage(v) + return nil } return fmt.Errorf("unknown Episode field %s", name) } @@ -1525,6 +1589,9 @@ func (m *EpisodeMutation) ClearedFields() []string { if m.FieldCleared(episode.FieldSeriesID) { fields = append(fields, episode.FieldSeriesID) } + if m.FieldCleared(episode.FieldFileInStorage) { + fields = append(fields, episode.FieldFileInStorage) + } return fields } @@ -1542,6 +1609,9 @@ func (m *EpisodeMutation) ClearField(name string) error { case episode.FieldSeriesID: m.ClearSeriesID() return nil + case episode.FieldFileInStorage: + m.ClearFileInStorage() + return nil } return fmt.Errorf("unknown Episode nullable field %s", name) } @@ -1568,6 +1638,9 @@ func (m *EpisodeMutation) ResetField(name string) error { case episode.FieldAirDate: m.ResetAirDate() return nil + case episode.FieldFileInStorage: + m.ResetFileInStorage() + return nil } return fmt.Errorf("unknown Episode field %s", name) } @@ -2984,6 +3057,7 @@ type SeriesMutation struct { resolution *string storage_id *int addstorage_id *int + target_dir *string clearedFields map[string]struct{} episodes map[int]struct{} removedepisodes map[int]struct{} @@ -3567,6 +3641,55 @@ func (m *SeriesMutation) ResetStorageID() { delete(m.clearedFields, series.FieldStorageID) } +// SetTargetDir sets the "target_dir" field. +func (m *SeriesMutation) SetTargetDir(s string) { + m.target_dir = &s +} + +// TargetDir returns the value of the "target_dir" field in the mutation. +func (m *SeriesMutation) TargetDir() (r string, exists bool) { + v := m.target_dir + if v == nil { + return + } + return *v, true +} + +// OldTargetDir returns the old "target_dir" field's value of the Series entity. +// If the Series 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 *SeriesMutation) OldTargetDir(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTargetDir is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTargetDir requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTargetDir: %w", err) + } + return oldValue.TargetDir, nil +} + +// ClearTargetDir clears the value of the "target_dir" field. +func (m *SeriesMutation) ClearTargetDir() { + m.target_dir = nil + m.clearedFields[series.FieldTargetDir] = struct{}{} +} + +// TargetDirCleared returns if the "target_dir" field was cleared in this mutation. +func (m *SeriesMutation) TargetDirCleared() bool { + _, ok := m.clearedFields[series.FieldTargetDir] + return ok +} + +// ResetTargetDir resets all changes to the "target_dir" field. +func (m *SeriesMutation) ResetTargetDir() { + m.target_dir = nil + delete(m.clearedFields, series.FieldTargetDir) +} + // AddEpisodeIDs adds the "episodes" edge to the Episode entity by ids. func (m *SeriesMutation) AddEpisodeIDs(ids ...int) { if m.episodes == nil { @@ -3655,7 +3778,7 @@ func (m *SeriesMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *SeriesMutation) Fields() []string { - fields := make([]string, 0, 11) + fields := make([]string, 0, 12) if m.tmdb_id != nil { fields = append(fields, series.FieldTmdbID) } @@ -3689,6 +3812,9 @@ func (m *SeriesMutation) Fields() []string { if m.storage_id != nil { fields = append(fields, series.FieldStorageID) } + if m.target_dir != nil { + fields = append(fields, series.FieldTargetDir) + } return fields } @@ -3719,6 +3845,8 @@ func (m *SeriesMutation) Field(name string) (ent.Value, bool) { return m.Resolution() case series.FieldStorageID: return m.StorageID() + case series.FieldTargetDir: + return m.TargetDir() } return nil, false } @@ -3750,6 +3878,8 @@ func (m *SeriesMutation) OldField(ctx context.Context, name string) (ent.Value, return m.OldResolution(ctx) case series.FieldStorageID: return m.OldStorageID(ctx) + case series.FieldTargetDir: + return m.OldTargetDir(ctx) } return nil, fmt.Errorf("unknown Series field %s", name) } @@ -3836,6 +3966,13 @@ func (m *SeriesMutation) SetField(name string, value ent.Value) error { } m.SetStorageID(v) return nil + case series.FieldTargetDir: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTargetDir(v) + return nil } return fmt.Errorf("unknown Series field %s", name) } @@ -3902,6 +4039,9 @@ func (m *SeriesMutation) ClearedFields() []string { if m.FieldCleared(series.FieldStorageID) { fields = append(fields, series.FieldStorageID) } + if m.FieldCleared(series.FieldTargetDir) { + fields = append(fields, series.FieldTargetDir) + } return fields } @@ -3925,6 +4065,9 @@ func (m *SeriesMutation) ClearField(name string) error { case series.FieldStorageID: m.ClearStorageID() return nil + case series.FieldTargetDir: + m.ClearTargetDir() + return nil } return fmt.Errorf("unknown Series nullable field %s", name) } @@ -3966,6 +4109,9 @@ func (m *SeriesMutation) ResetField(name string) error { case series.FieldStorageID: m.ResetStorageID() return nil + case series.FieldTargetDir: + m.ResetTargetDir() + return nil } return fmt.Errorf("unknown Series field %s", name) } @@ -4441,10 +4587,8 @@ type StorageMutation struct { typ string id *int name *string - implementation *string - _path *string - user *string - password *string + implementation *storage.Implementation + settings *string deleted *bool _default *bool clearedFields map[string]struct{} @@ -4588,12 +4732,12 @@ func (m *StorageMutation) ResetName() { } // SetImplementation sets the "implementation" field. -func (m *StorageMutation) SetImplementation(s string) { +func (m *StorageMutation) SetImplementation(s storage.Implementation) { m.implementation = &s } // Implementation returns the value of the "implementation" field in the mutation. -func (m *StorageMutation) Implementation() (r string, exists bool) { +func (m *StorageMutation) Implementation() (r storage.Implementation, exists bool) { v := m.implementation if v == nil { return @@ -4604,7 +4748,7 @@ func (m *StorageMutation) Implementation() (r string, exists bool) { // OldImplementation returns the old "implementation" field's value of the Storage entity. // If the Storage 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 *StorageMutation) OldImplementation(ctx context.Context) (v string, err error) { +func (m *StorageMutation) OldImplementation(ctx context.Context) (v storage.Implementation, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldImplementation is only allowed on UpdateOne operations") } @@ -4623,138 +4767,53 @@ func (m *StorageMutation) ResetImplementation() { m.implementation = nil } -// SetPath sets the "path" field. -func (m *StorageMutation) SetPath(s string) { - m._path = &s +// SetSettings sets the "settings" field. +func (m *StorageMutation) SetSettings(s string) { + m.settings = &s } -// Path returns the value of the "path" field in the mutation. -func (m *StorageMutation) Path() (r string, exists bool) { - v := m._path +// Settings returns the value of the "settings" field in the mutation. +func (m *StorageMutation) Settings() (r string, exists bool) { + v := m.settings if v == nil { return } return *v, true } -// OldPath returns the old "path" field's value of the Storage entity. +// OldSettings returns the old "settings" field's value of the Storage entity. // If the Storage 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 *StorageMutation) OldPath(ctx context.Context) (v string, err error) { +func (m *StorageMutation) OldSettings(ctx context.Context) (v string, err error) { if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldPath is only allowed on UpdateOne operations") + return v, errors.New("OldSettings is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, errors.New("OldPath requires an ID field in the mutation") + return v, errors.New("OldSettings requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldPath: %w", err) + return v, fmt.Errorf("querying old value for OldSettings: %w", err) } - return oldValue.Path, nil + return oldValue.Settings, nil } -// ResetPath resets all changes to the "path" field. -func (m *StorageMutation) ResetPath() { - m._path = nil +// ClearSettings clears the value of the "settings" field. +func (m *StorageMutation) ClearSettings() { + m.settings = nil + m.clearedFields[storage.FieldSettings] = struct{}{} } -// SetUser sets the "user" field. -func (m *StorageMutation) SetUser(s string) { - m.user = &s -} - -// User returns the value of the "user" field in the mutation. -func (m *StorageMutation) User() (r string, exists bool) { - v := m.user - if v == nil { - return - } - return *v, true -} - -// OldUser returns the old "user" field's value of the Storage entity. -// If the Storage 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 *StorageMutation) OldUser(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldUser is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldUser requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldUser: %w", err) - } - return oldValue.User, nil -} - -// ClearUser clears the value of the "user" field. -func (m *StorageMutation) ClearUser() { - m.user = nil - m.clearedFields[storage.FieldUser] = struct{}{} -} - -// UserCleared returns if the "user" field was cleared in this mutation. -func (m *StorageMutation) UserCleared() bool { - _, ok := m.clearedFields[storage.FieldUser] +// SettingsCleared returns if the "settings" field was cleared in this mutation. +func (m *StorageMutation) SettingsCleared() bool { + _, ok := m.clearedFields[storage.FieldSettings] return ok } -// ResetUser resets all changes to the "user" field. -func (m *StorageMutation) ResetUser() { - m.user = nil - delete(m.clearedFields, storage.FieldUser) -} - -// SetPassword sets the "password" field. -func (m *StorageMutation) SetPassword(s string) { - m.password = &s -} - -// Password returns the value of the "password" field in the mutation. -func (m *StorageMutation) Password() (r string, exists bool) { - v := m.password - if v == nil { - return - } - return *v, true -} - -// OldPassword returns the old "password" field's value of the Storage entity. -// If the Storage 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 *StorageMutation) OldPassword(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldPassword is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldPassword requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldPassword: %w", err) - } - return oldValue.Password, nil -} - -// ClearPassword clears the value of the "password" field. -func (m *StorageMutation) ClearPassword() { - m.password = nil - m.clearedFields[storage.FieldPassword] = struct{}{} -} - -// PasswordCleared returns if the "password" field was cleared in this mutation. -func (m *StorageMutation) PasswordCleared() bool { - _, ok := m.clearedFields[storage.FieldPassword] - return ok -} - -// ResetPassword resets all changes to the "password" field. -func (m *StorageMutation) ResetPassword() { - m.password = nil - delete(m.clearedFields, storage.FieldPassword) +// ResetSettings resets all changes to the "settings" field. +func (m *StorageMutation) ResetSettings() { + m.settings = nil + delete(m.clearedFields, storage.FieldSettings) } // SetDeleted sets the "deleted" field. @@ -4863,21 +4922,15 @@ func (m *StorageMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *StorageMutation) Fields() []string { - fields := make([]string, 0, 7) + fields := make([]string, 0, 5) if m.name != nil { fields = append(fields, storage.FieldName) } if m.implementation != nil { fields = append(fields, storage.FieldImplementation) } - if m._path != nil { - fields = append(fields, storage.FieldPath) - } - if m.user != nil { - fields = append(fields, storage.FieldUser) - } - if m.password != nil { - fields = append(fields, storage.FieldPassword) + if m.settings != nil { + fields = append(fields, storage.FieldSettings) } if m.deleted != nil { fields = append(fields, storage.FieldDeleted) @@ -4897,12 +4950,8 @@ func (m *StorageMutation) Field(name string) (ent.Value, bool) { return m.Name() case storage.FieldImplementation: return m.Implementation() - case storage.FieldPath: - return m.Path() - case storage.FieldUser: - return m.User() - case storage.FieldPassword: - return m.Password() + case storage.FieldSettings: + return m.Settings() case storage.FieldDeleted: return m.Deleted() case storage.FieldDefault: @@ -4920,12 +4969,8 @@ func (m *StorageMutation) OldField(ctx context.Context, name string) (ent.Value, return m.OldName(ctx) case storage.FieldImplementation: return m.OldImplementation(ctx) - case storage.FieldPath: - return m.OldPath(ctx) - case storage.FieldUser: - return m.OldUser(ctx) - case storage.FieldPassword: - return m.OldPassword(ctx) + case storage.FieldSettings: + return m.OldSettings(ctx) case storage.FieldDeleted: return m.OldDeleted(ctx) case storage.FieldDefault: @@ -4947,32 +4992,18 @@ func (m *StorageMutation) SetField(name string, value ent.Value) error { m.SetName(v) return nil case storage.FieldImplementation: - v, ok := value.(string) + v, ok := value.(storage.Implementation) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } m.SetImplementation(v) return nil - case storage.FieldPath: + case storage.FieldSettings: v, ok := value.(string) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } - m.SetPath(v) - return nil - case storage.FieldUser: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetUser(v) - return nil - case storage.FieldPassword: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetPassword(v) + m.SetSettings(v) return nil case storage.FieldDeleted: v, ok := value.(bool) @@ -5018,11 +5049,8 @@ func (m *StorageMutation) AddField(name string, value ent.Value) error { // mutation. func (m *StorageMutation) ClearedFields() []string { var fields []string - if m.FieldCleared(storage.FieldUser) { - fields = append(fields, storage.FieldUser) - } - if m.FieldCleared(storage.FieldPassword) { - fields = append(fields, storage.FieldPassword) + if m.FieldCleared(storage.FieldSettings) { + fields = append(fields, storage.FieldSettings) } return fields } @@ -5038,11 +5066,8 @@ func (m *StorageMutation) FieldCleared(name string) bool { // error if the field is not defined in the schema. func (m *StorageMutation) ClearField(name string) error { switch name { - case storage.FieldUser: - m.ClearUser() - return nil - case storage.FieldPassword: - m.ClearPassword() + case storage.FieldSettings: + m.ClearSettings() return nil } return fmt.Errorf("unknown Storage nullable field %s", name) @@ -5058,14 +5083,8 @@ func (m *StorageMutation) ResetField(name string) error { case storage.FieldImplementation: m.ResetImplementation() return nil - case storage.FieldPath: - m.ResetPath() - return nil - case storage.FieldUser: - m.ResetUser() - return nil - case storage.FieldPassword: - m.ResetPassword() + case storage.FieldSettings: + m.ResetSettings() return nil case storage.FieldDeleted: m.ResetDeleted() diff --git a/ent/runtime.go b/ent/runtime.go index 026a4e8..d520efb 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -75,11 +75,11 @@ func init() { storageFields := schema.Storage{}.Fields() _ = storageFields // storageDescDeleted is the schema descriptor for deleted field. - storageDescDeleted := storageFields[5].Descriptor() + storageDescDeleted := storageFields[3].Descriptor() // storage.DefaultDeleted holds the default value on creation for the deleted field. storage.DefaultDeleted = storageDescDeleted.Default.(bool) // storageDescDefault is the schema descriptor for default field. - storageDescDefault := storageFields[6].Descriptor() + storageDescDefault := storageFields[4].Descriptor() // storage.DefaultDefault holds the default value on creation for the default field. storage.DefaultDefault = storageDescDefault.Default.(bool) } diff --git a/ent/schema/episode.go b/ent/schema/episode.go index b3e2d22..144d1e0 100644 --- a/ent/schema/episode.go +++ b/ent/schema/episode.go @@ -16,10 +16,11 @@ func (Episode) Fields() []ent.Field { return []ent.Field{ field.Int("series_id").Optional(), field.Int("season_number").StructTag("json:\"season_number\""), - field.Int("episode_number"), + field.Int("episode_number").StructTag("json:\"episode_number\""), field.String("title"), field.String("overview"), field.String("air_date"), + field.String("file_in_storage").Optional(), } } diff --git a/ent/schema/series.go b/ent/schema/series.go index c069ea5..8402b85 100644 --- a/ent/schema/series.go +++ b/ent/schema/series.go @@ -27,6 +27,7 @@ func (Series) Fields() []ent.Field { field.String("air_date").Default(""), field.String("resolution").Default(""), field.Int("storage_id").Optional(), + field.String("target_dir").Optional(), } } diff --git a/ent/schema/storage.go b/ent/schema/storage.go index 44d2979..3de5c31 100644 --- a/ent/schema/storage.go +++ b/ent/schema/storage.go @@ -14,10 +14,8 @@ type Storage struct { func (Storage) Fields() []ent.Field { return []ent.Field{ field.String("name").Unique(), - field.String("implementation"), - field.String("path"), - field.String("user").Optional(), - field.String("password").Optional(), + field.Enum("implementation").Values("webdav", "local"), + field.String("settings").Optional(), field.Bool("deleted").Default(false), field.Bool("default").Default(false), } diff --git a/ent/series.go b/ent/series.go index 03ec556..6c06f3b 100644 --- a/ent/series.go +++ b/ent/series.go @@ -39,6 +39,8 @@ type Series struct { Resolution string `json:"resolution,omitempty"` // StorageID holds the value of the "storage_id" field. StorageID int `json:"storage_id,omitempty"` + // TargetDir holds the value of the "target_dir" field. + TargetDir string `json:"target_dir,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the SeriesQuery when eager-loading is set. Edges SeriesEdges `json:"edges"` @@ -70,7 +72,7 @@ func (*Series) scanValues(columns []string) ([]any, error) { switch columns[i] { case series.FieldID, series.FieldTmdbID, series.FieldStorageID: values[i] = new(sql.NullInt64) - case series.FieldImdbID, series.FieldNameCn, series.FieldNameEn, series.FieldOriginalName, series.FieldOverview, series.FieldPosterPath, series.FieldAirDate, series.FieldResolution: + case series.FieldImdbID, series.FieldNameCn, series.FieldNameEn, series.FieldOriginalName, series.FieldOverview, series.FieldPosterPath, series.FieldAirDate, series.FieldResolution, series.FieldTargetDir: values[i] = new(sql.NullString) case series.FieldCreatedAt: values[i] = new(sql.NullTime) @@ -161,6 +163,12 @@ func (s *Series) assignValues(columns []string, values []any) error { } else if value.Valid { s.StorageID = int(value.Int64) } + case series.FieldTargetDir: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field target_dir", values[i]) + } else if value.Valid { + s.TargetDir = value.String + } default: s.selectValues.Set(columns[i], values[i]) } @@ -234,6 +242,9 @@ func (s *Series) String() string { builder.WriteString(", ") builder.WriteString("storage_id=") builder.WriteString(fmt.Sprintf("%v", s.StorageID)) + builder.WriteString(", ") + builder.WriteString("target_dir=") + builder.WriteString(s.TargetDir) builder.WriteByte(')') return builder.String() } diff --git a/ent/series/series.go b/ent/series/series.go index 6797d38..2a9c2aa 100644 --- a/ent/series/series.go +++ b/ent/series/series.go @@ -36,6 +36,8 @@ const ( FieldResolution = "resolution" // FieldStorageID holds the string denoting the storage_id field in the database. FieldStorageID = "storage_id" + // FieldTargetDir holds the string denoting the target_dir field in the database. + FieldTargetDir = "target_dir" // EdgeEpisodes holds the string denoting the episodes edge name in mutations. EdgeEpisodes = "episodes" // Table holds the table name of the series in the database. @@ -63,6 +65,7 @@ var Columns = []string{ FieldAirDate, FieldResolution, FieldStorageID, + FieldTargetDir, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -147,6 +150,11 @@ func ByStorageID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldStorageID, opts...).ToFunc() } +// ByTargetDir orders the results by the target_dir field. +func ByTargetDir(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTargetDir, opts...).ToFunc() +} + // ByEpisodesCount orders the results by episodes count. func ByEpisodesCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { diff --git a/ent/series/where.go b/ent/series/where.go index ef14a67..44bbf35 100644 --- a/ent/series/where.go +++ b/ent/series/where.go @@ -110,6 +110,11 @@ func StorageID(v int) predicate.Series { return predicate.Series(sql.FieldEQ(FieldStorageID, v)) } +// TargetDir applies equality check predicate on the "target_dir" field. It's identical to TargetDirEQ. +func TargetDir(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldTargetDir, v)) +} + // TmdbIDEQ applies the EQ predicate on the "tmdb_id" field. func TmdbIDEQ(v int) predicate.Series { return predicate.Series(sql.FieldEQ(FieldTmdbID, v)) @@ -780,6 +785,81 @@ func StorageIDNotNil() predicate.Series { return predicate.Series(sql.FieldNotNull(FieldStorageID)) } +// TargetDirEQ applies the EQ predicate on the "target_dir" field. +func TargetDirEQ(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldTargetDir, v)) +} + +// TargetDirNEQ applies the NEQ predicate on the "target_dir" field. +func TargetDirNEQ(v string) predicate.Series { + return predicate.Series(sql.FieldNEQ(FieldTargetDir, v)) +} + +// TargetDirIn applies the In predicate on the "target_dir" field. +func TargetDirIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldIn(FieldTargetDir, vs...)) +} + +// TargetDirNotIn applies the NotIn predicate on the "target_dir" field. +func TargetDirNotIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldNotIn(FieldTargetDir, vs...)) +} + +// TargetDirGT applies the GT predicate on the "target_dir" field. +func TargetDirGT(v string) predicate.Series { + return predicate.Series(sql.FieldGT(FieldTargetDir, v)) +} + +// TargetDirGTE applies the GTE predicate on the "target_dir" field. +func TargetDirGTE(v string) predicate.Series { + return predicate.Series(sql.FieldGTE(FieldTargetDir, v)) +} + +// TargetDirLT applies the LT predicate on the "target_dir" field. +func TargetDirLT(v string) predicate.Series { + return predicate.Series(sql.FieldLT(FieldTargetDir, v)) +} + +// TargetDirLTE applies the LTE predicate on the "target_dir" field. +func TargetDirLTE(v string) predicate.Series { + return predicate.Series(sql.FieldLTE(FieldTargetDir, v)) +} + +// TargetDirContains applies the Contains predicate on the "target_dir" field. +func TargetDirContains(v string) predicate.Series { + return predicate.Series(sql.FieldContains(FieldTargetDir, v)) +} + +// TargetDirHasPrefix applies the HasPrefix predicate on the "target_dir" field. +func TargetDirHasPrefix(v string) predicate.Series { + return predicate.Series(sql.FieldHasPrefix(FieldTargetDir, v)) +} + +// TargetDirHasSuffix applies the HasSuffix predicate on the "target_dir" field. +func TargetDirHasSuffix(v string) predicate.Series { + return predicate.Series(sql.FieldHasSuffix(FieldTargetDir, v)) +} + +// TargetDirIsNil applies the IsNil predicate on the "target_dir" field. +func TargetDirIsNil() predicate.Series { + return predicate.Series(sql.FieldIsNull(FieldTargetDir)) +} + +// TargetDirNotNil applies the NotNil predicate on the "target_dir" field. +func TargetDirNotNil() predicate.Series { + return predicate.Series(sql.FieldNotNull(FieldTargetDir)) +} + +// TargetDirEqualFold applies the EqualFold predicate on the "target_dir" field. +func TargetDirEqualFold(v string) predicate.Series { + return predicate.Series(sql.FieldEqualFold(FieldTargetDir, v)) +} + +// TargetDirContainsFold applies the ContainsFold predicate on the "target_dir" field. +func TargetDirContainsFold(v string) predicate.Series { + return predicate.Series(sql.FieldContainsFold(FieldTargetDir, v)) +} + // HasEpisodes applies the HasEdge predicate on the "episodes" edge. func HasEpisodes() predicate.Series { return predicate.Series(func(s *sql.Selector) { diff --git a/ent/series_create.go b/ent/series_create.go index 617d51a..70caad1 100644 --- a/ent/series_create.go +++ b/ent/series_create.go @@ -135,6 +135,20 @@ func (sc *SeriesCreate) SetNillableStorageID(i *int) *SeriesCreate { return sc } +// SetTargetDir sets the "target_dir" field. +func (sc *SeriesCreate) SetTargetDir(s string) *SeriesCreate { + sc.mutation.SetTargetDir(s) + return sc +} + +// SetNillableTargetDir sets the "target_dir" field if the given value is not nil. +func (sc *SeriesCreate) SetNillableTargetDir(s *string) *SeriesCreate { + if s != nil { + sc.SetTargetDir(*s) + } + return sc +} + // AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. func (sc *SeriesCreate) AddEpisodeIDs(ids ...int) *SeriesCreate { sc.mutation.AddEpisodeIDs(ids...) @@ -295,6 +309,10 @@ func (sc *SeriesCreate) createSpec() (*Series, *sqlgraph.CreateSpec) { _spec.SetField(series.FieldStorageID, field.TypeInt, value) _node.StorageID = value } + if value, ok := sc.mutation.TargetDir(); ok { + _spec.SetField(series.FieldTargetDir, field.TypeString, value) + _node.TargetDir = value + } if nodes := sc.mutation.EpisodesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/ent/series_update.go b/ent/series_update.go index 6068d28..1fd8de3 100644 --- a/ent/series_update.go +++ b/ent/series_update.go @@ -215,6 +215,26 @@ func (su *SeriesUpdate) ClearStorageID() *SeriesUpdate { return su } +// SetTargetDir sets the "target_dir" field. +func (su *SeriesUpdate) SetTargetDir(s string) *SeriesUpdate { + su.mutation.SetTargetDir(s) + return su +} + +// SetNillableTargetDir sets the "target_dir" field if the given value is not nil. +func (su *SeriesUpdate) SetNillableTargetDir(s *string) *SeriesUpdate { + if s != nil { + su.SetTargetDir(*s) + } + return su +} + +// ClearTargetDir clears the value of the "target_dir" field. +func (su *SeriesUpdate) ClearTargetDir() *SeriesUpdate { + su.mutation.ClearTargetDir() + return su +} + // AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. func (su *SeriesUpdate) AddEpisodeIDs(ids ...int) *SeriesUpdate { su.mutation.AddEpisodeIDs(ids...) @@ -340,6 +360,12 @@ func (su *SeriesUpdate) sqlSave(ctx context.Context) (n int, err error) { if su.mutation.StorageIDCleared() { _spec.ClearField(series.FieldStorageID, field.TypeInt) } + if value, ok := su.mutation.TargetDir(); ok { + _spec.SetField(series.FieldTargetDir, field.TypeString, value) + } + if su.mutation.TargetDirCleared() { + _spec.ClearField(series.FieldTargetDir, field.TypeString) + } if su.mutation.EpisodesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -591,6 +617,26 @@ func (suo *SeriesUpdateOne) ClearStorageID() *SeriesUpdateOne { return suo } +// SetTargetDir sets the "target_dir" field. +func (suo *SeriesUpdateOne) SetTargetDir(s string) *SeriesUpdateOne { + suo.mutation.SetTargetDir(s) + return suo +} + +// SetNillableTargetDir sets the "target_dir" field if the given value is not nil. +func (suo *SeriesUpdateOne) SetNillableTargetDir(s *string) *SeriesUpdateOne { + if s != nil { + suo.SetTargetDir(*s) + } + return suo +} + +// ClearTargetDir clears the value of the "target_dir" field. +func (suo *SeriesUpdateOne) ClearTargetDir() *SeriesUpdateOne { + suo.mutation.ClearTargetDir() + return suo +} + // AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. func (suo *SeriesUpdateOne) AddEpisodeIDs(ids ...int) *SeriesUpdateOne { suo.mutation.AddEpisodeIDs(ids...) @@ -746,6 +792,12 @@ func (suo *SeriesUpdateOne) sqlSave(ctx context.Context) (_node *Series, err err if suo.mutation.StorageIDCleared() { _spec.ClearField(series.FieldStorageID, field.TypeInt) } + if value, ok := suo.mutation.TargetDir(); ok { + _spec.SetField(series.FieldTargetDir, field.TypeString, value) + } + if suo.mutation.TargetDirCleared() { + _spec.ClearField(series.FieldTargetDir, field.TypeString) + } if suo.mutation.EpisodesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/ent/storage.go b/ent/storage.go index 760e8d1..08a2632 100644 --- a/ent/storage.go +++ b/ent/storage.go @@ -19,13 +19,9 @@ type Storage struct { // Name holds the value of the "name" field. Name string `json:"name,omitempty"` // Implementation holds the value of the "implementation" field. - Implementation string `json:"implementation,omitempty"` - // Path holds the value of the "path" field. - Path string `json:"path,omitempty"` - // User holds the value of the "user" field. - User string `json:"user,omitempty"` - // Password holds the value of the "password" field. - Password string `json:"password,omitempty"` + Implementation storage.Implementation `json:"implementation,omitempty"` + // Settings holds the value of the "settings" field. + Settings string `json:"settings,omitempty"` // Deleted holds the value of the "deleted" field. Deleted bool `json:"deleted,omitempty"` // Default holds the value of the "default" field. @@ -42,7 +38,7 @@ func (*Storage) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullBool) case storage.FieldID: values[i] = new(sql.NullInt64) - case storage.FieldName, storage.FieldImplementation, storage.FieldPath, storage.FieldUser, storage.FieldPassword: + case storage.FieldName, storage.FieldImplementation, storage.FieldSettings: values[i] = new(sql.NullString) default: values[i] = new(sql.UnknownType) @@ -75,25 +71,13 @@ func (s *Storage) assignValues(columns []string, values []any) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field implementation", values[i]) } else if value.Valid { - s.Implementation = value.String + s.Implementation = storage.Implementation(value.String) } - case storage.FieldPath: + case storage.FieldSettings: if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field path", values[i]) + return fmt.Errorf("unexpected type %T for field settings", values[i]) } else if value.Valid { - s.Path = value.String - } - case storage.FieldUser: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field user", values[i]) - } else if value.Valid { - s.User = value.String - } - case storage.FieldPassword: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field password", values[i]) - } else if value.Valid { - s.Password = value.String + s.Settings = value.String } case storage.FieldDeleted: if value, ok := values[i].(*sql.NullBool); !ok { @@ -147,16 +131,10 @@ func (s *Storage) String() string { builder.WriteString(s.Name) builder.WriteString(", ") builder.WriteString("implementation=") - builder.WriteString(s.Implementation) + builder.WriteString(fmt.Sprintf("%v", s.Implementation)) builder.WriteString(", ") - builder.WriteString("path=") - builder.WriteString(s.Path) - builder.WriteString(", ") - builder.WriteString("user=") - builder.WriteString(s.User) - builder.WriteString(", ") - builder.WriteString("password=") - builder.WriteString(s.Password) + builder.WriteString("settings=") + builder.WriteString(s.Settings) builder.WriteString(", ") builder.WriteString("deleted=") builder.WriteString(fmt.Sprintf("%v", s.Deleted)) diff --git a/ent/storage/storage.go b/ent/storage/storage.go index e1d0985..0c397a1 100644 --- a/ent/storage/storage.go +++ b/ent/storage/storage.go @@ -3,6 +3,8 @@ package storage import ( + "fmt" + "entgo.io/ent/dialect/sql" ) @@ -15,12 +17,8 @@ const ( FieldName = "name" // FieldImplementation holds the string denoting the implementation field in the database. FieldImplementation = "implementation" - // FieldPath holds the string denoting the path field in the database. - FieldPath = "path" - // FieldUser holds the string denoting the user field in the database. - FieldUser = "user" - // FieldPassword holds the string denoting the password field in the database. - FieldPassword = "password" + // FieldSettings holds the string denoting the settings field in the database. + FieldSettings = "settings" // FieldDeleted holds the string denoting the deleted field in the database. FieldDeleted = "deleted" // FieldDefault holds the string denoting the default field in the database. @@ -34,9 +32,7 @@ var Columns = []string{ FieldID, FieldName, FieldImplementation, - FieldPath, - FieldUser, - FieldPassword, + FieldSettings, FieldDeleted, FieldDefault, } @@ -58,6 +54,29 @@ var ( DefaultDefault bool ) +// Implementation defines the type for the "implementation" enum field. +type Implementation string + +// Implementation values. +const ( + ImplementationWebdav Implementation = "webdav" + ImplementationLocal Implementation = "local" +) + +func (i Implementation) String() string { + return string(i) +} + +// ImplementationValidator is a validator for the "implementation" field enum values. It is called by the builders before save. +func ImplementationValidator(i Implementation) error { + switch i { + case ImplementationWebdav, ImplementationLocal: + return nil + default: + return fmt.Errorf("storage: invalid enum value for implementation field: %q", i) + } +} + // OrderOption defines the ordering options for the Storage queries. type OrderOption func(*sql.Selector) @@ -76,19 +95,9 @@ func ByImplementation(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldImplementation, opts...).ToFunc() } -// ByPath orders the results by the path field. -func ByPath(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldPath, opts...).ToFunc() -} - -// ByUser orders the results by the user field. -func ByUser(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldUser, opts...).ToFunc() -} - -// ByPassword orders the results by the password field. -func ByPassword(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldPassword, opts...).ToFunc() +// BySettings orders the results by the settings field. +func BySettings(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSettings, opts...).ToFunc() } // ByDeleted orders the results by the deleted field. diff --git a/ent/storage/where.go b/ent/storage/where.go index bf7a36d..6b8e2b0 100644 --- a/ent/storage/where.go +++ b/ent/storage/where.go @@ -58,24 +58,9 @@ func Name(v string) predicate.Storage { return predicate.Storage(sql.FieldEQ(FieldName, v)) } -// Implementation applies equality check predicate on the "implementation" field. It's identical to ImplementationEQ. -func Implementation(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldImplementation, v)) -} - -// Path applies equality check predicate on the "path" field. It's identical to PathEQ. -func Path(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldPath, v)) -} - -// User applies equality check predicate on the "user" field. It's identical to UserEQ. -func User(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldUser, v)) -} - -// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ. -func Password(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldPassword, v)) +// Settings applies equality check predicate on the "settings" field. It's identical to SettingsEQ. +func Settings(v string) predicate.Storage { + return predicate.Storage(sql.FieldEQ(FieldSettings, v)) } // Deleted applies equality check predicate on the "deleted" field. It's identical to DeletedEQ. @@ -154,283 +139,98 @@ func NameContainsFold(v string) predicate.Storage { } // ImplementationEQ applies the EQ predicate on the "implementation" field. -func ImplementationEQ(v string) predicate.Storage { +func ImplementationEQ(v Implementation) predicate.Storage { return predicate.Storage(sql.FieldEQ(FieldImplementation, v)) } // ImplementationNEQ applies the NEQ predicate on the "implementation" field. -func ImplementationNEQ(v string) predicate.Storage { +func ImplementationNEQ(v Implementation) predicate.Storage { return predicate.Storage(sql.FieldNEQ(FieldImplementation, v)) } // ImplementationIn applies the In predicate on the "implementation" field. -func ImplementationIn(vs ...string) predicate.Storage { +func ImplementationIn(vs ...Implementation) predicate.Storage { return predicate.Storage(sql.FieldIn(FieldImplementation, vs...)) } // ImplementationNotIn applies the NotIn predicate on the "implementation" field. -func ImplementationNotIn(vs ...string) predicate.Storage { +func ImplementationNotIn(vs ...Implementation) predicate.Storage { return predicate.Storage(sql.FieldNotIn(FieldImplementation, vs...)) } -// ImplementationGT applies the GT predicate on the "implementation" field. -func ImplementationGT(v string) predicate.Storage { - return predicate.Storage(sql.FieldGT(FieldImplementation, v)) +// SettingsEQ applies the EQ predicate on the "settings" field. +func SettingsEQ(v string) predicate.Storage { + return predicate.Storage(sql.FieldEQ(FieldSettings, v)) } -// ImplementationGTE applies the GTE predicate on the "implementation" field. -func ImplementationGTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldGTE(FieldImplementation, v)) +// SettingsNEQ applies the NEQ predicate on the "settings" field. +func SettingsNEQ(v string) predicate.Storage { + return predicate.Storage(sql.FieldNEQ(FieldSettings, v)) } -// ImplementationLT applies the LT predicate on the "implementation" field. -func ImplementationLT(v string) predicate.Storage { - return predicate.Storage(sql.FieldLT(FieldImplementation, v)) +// SettingsIn applies the In predicate on the "settings" field. +func SettingsIn(vs ...string) predicate.Storage { + return predicate.Storage(sql.FieldIn(FieldSettings, vs...)) } -// ImplementationLTE applies the LTE predicate on the "implementation" field. -func ImplementationLTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldLTE(FieldImplementation, v)) +// SettingsNotIn applies the NotIn predicate on the "settings" field. +func SettingsNotIn(vs ...string) predicate.Storage { + return predicate.Storage(sql.FieldNotIn(FieldSettings, vs...)) } -// ImplementationContains applies the Contains predicate on the "implementation" field. -func ImplementationContains(v string) predicate.Storage { - return predicate.Storage(sql.FieldContains(FieldImplementation, v)) +// SettingsGT applies the GT predicate on the "settings" field. +func SettingsGT(v string) predicate.Storage { + return predicate.Storage(sql.FieldGT(FieldSettings, v)) } -// ImplementationHasPrefix applies the HasPrefix predicate on the "implementation" field. -func ImplementationHasPrefix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasPrefix(FieldImplementation, v)) +// SettingsGTE applies the GTE predicate on the "settings" field. +func SettingsGTE(v string) predicate.Storage { + return predicate.Storage(sql.FieldGTE(FieldSettings, v)) } -// ImplementationHasSuffix applies the HasSuffix predicate on the "implementation" field. -func ImplementationHasSuffix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasSuffix(FieldImplementation, v)) +// SettingsLT applies the LT predicate on the "settings" field. +func SettingsLT(v string) predicate.Storage { + return predicate.Storage(sql.FieldLT(FieldSettings, v)) } -// ImplementationEqualFold applies the EqualFold predicate on the "implementation" field. -func ImplementationEqualFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldEqualFold(FieldImplementation, v)) +// SettingsLTE applies the LTE predicate on the "settings" field. +func SettingsLTE(v string) predicate.Storage { + return predicate.Storage(sql.FieldLTE(FieldSettings, v)) } -// ImplementationContainsFold applies the ContainsFold predicate on the "implementation" field. -func ImplementationContainsFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldContainsFold(FieldImplementation, v)) +// SettingsContains applies the Contains predicate on the "settings" field. +func SettingsContains(v string) predicate.Storage { + return predicate.Storage(sql.FieldContains(FieldSettings, v)) } -// PathEQ applies the EQ predicate on the "path" field. -func PathEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldPath, v)) +// SettingsHasPrefix applies the HasPrefix predicate on the "settings" field. +func SettingsHasPrefix(v string) predicate.Storage { + return predicate.Storage(sql.FieldHasPrefix(FieldSettings, v)) } -// PathNEQ applies the NEQ predicate on the "path" field. -func PathNEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldNEQ(FieldPath, v)) +// SettingsHasSuffix applies the HasSuffix predicate on the "settings" field. +func SettingsHasSuffix(v string) predicate.Storage { + return predicate.Storage(sql.FieldHasSuffix(FieldSettings, v)) } -// PathIn applies the In predicate on the "path" field. -func PathIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldIn(FieldPath, vs...)) +// SettingsIsNil applies the IsNil predicate on the "settings" field. +func SettingsIsNil() predicate.Storage { + return predicate.Storage(sql.FieldIsNull(FieldSettings)) } -// PathNotIn applies the NotIn predicate on the "path" field. -func PathNotIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldNotIn(FieldPath, vs...)) +// SettingsNotNil applies the NotNil predicate on the "settings" field. +func SettingsNotNil() predicate.Storage { + return predicate.Storage(sql.FieldNotNull(FieldSettings)) } -// PathGT applies the GT predicate on the "path" field. -func PathGT(v string) predicate.Storage { - return predicate.Storage(sql.FieldGT(FieldPath, v)) +// SettingsEqualFold applies the EqualFold predicate on the "settings" field. +func SettingsEqualFold(v string) predicate.Storage { + return predicate.Storage(sql.FieldEqualFold(FieldSettings, v)) } -// PathGTE applies the GTE predicate on the "path" field. -func PathGTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldGTE(FieldPath, v)) -} - -// PathLT applies the LT predicate on the "path" field. -func PathLT(v string) predicate.Storage { - return predicate.Storage(sql.FieldLT(FieldPath, v)) -} - -// PathLTE applies the LTE predicate on the "path" field. -func PathLTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldLTE(FieldPath, v)) -} - -// PathContains applies the Contains predicate on the "path" field. -func PathContains(v string) predicate.Storage { - return predicate.Storage(sql.FieldContains(FieldPath, v)) -} - -// PathHasPrefix applies the HasPrefix predicate on the "path" field. -func PathHasPrefix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasPrefix(FieldPath, v)) -} - -// PathHasSuffix applies the HasSuffix predicate on the "path" field. -func PathHasSuffix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasSuffix(FieldPath, v)) -} - -// PathEqualFold applies the EqualFold predicate on the "path" field. -func PathEqualFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldEqualFold(FieldPath, v)) -} - -// PathContainsFold applies the ContainsFold predicate on the "path" field. -func PathContainsFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldContainsFold(FieldPath, v)) -} - -// UserEQ applies the EQ predicate on the "user" field. -func UserEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldUser, v)) -} - -// UserNEQ applies the NEQ predicate on the "user" field. -func UserNEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldNEQ(FieldUser, v)) -} - -// UserIn applies the In predicate on the "user" field. -func UserIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldIn(FieldUser, vs...)) -} - -// UserNotIn applies the NotIn predicate on the "user" field. -func UserNotIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldNotIn(FieldUser, vs...)) -} - -// UserGT applies the GT predicate on the "user" field. -func UserGT(v string) predicate.Storage { - return predicate.Storage(sql.FieldGT(FieldUser, v)) -} - -// UserGTE applies the GTE predicate on the "user" field. -func UserGTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldGTE(FieldUser, v)) -} - -// UserLT applies the LT predicate on the "user" field. -func UserLT(v string) predicate.Storage { - return predicate.Storage(sql.FieldLT(FieldUser, v)) -} - -// UserLTE applies the LTE predicate on the "user" field. -func UserLTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldLTE(FieldUser, v)) -} - -// UserContains applies the Contains predicate on the "user" field. -func UserContains(v string) predicate.Storage { - return predicate.Storage(sql.FieldContains(FieldUser, v)) -} - -// UserHasPrefix applies the HasPrefix predicate on the "user" field. -func UserHasPrefix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasPrefix(FieldUser, v)) -} - -// UserHasSuffix applies the HasSuffix predicate on the "user" field. -func UserHasSuffix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasSuffix(FieldUser, v)) -} - -// UserIsNil applies the IsNil predicate on the "user" field. -func UserIsNil() predicate.Storage { - return predicate.Storage(sql.FieldIsNull(FieldUser)) -} - -// UserNotNil applies the NotNil predicate on the "user" field. -func UserNotNil() predicate.Storage { - return predicate.Storage(sql.FieldNotNull(FieldUser)) -} - -// UserEqualFold applies the EqualFold predicate on the "user" field. -func UserEqualFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldEqualFold(FieldUser, v)) -} - -// UserContainsFold applies the ContainsFold predicate on the "user" field. -func UserContainsFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldContainsFold(FieldUser, v)) -} - -// PasswordEQ applies the EQ predicate on the "password" field. -func PasswordEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldEQ(FieldPassword, v)) -} - -// PasswordNEQ applies the NEQ predicate on the "password" field. -func PasswordNEQ(v string) predicate.Storage { - return predicate.Storage(sql.FieldNEQ(FieldPassword, v)) -} - -// PasswordIn applies the In predicate on the "password" field. -func PasswordIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldIn(FieldPassword, vs...)) -} - -// PasswordNotIn applies the NotIn predicate on the "password" field. -func PasswordNotIn(vs ...string) predicate.Storage { - return predicate.Storage(sql.FieldNotIn(FieldPassword, vs...)) -} - -// PasswordGT applies the GT predicate on the "password" field. -func PasswordGT(v string) predicate.Storage { - return predicate.Storage(sql.FieldGT(FieldPassword, v)) -} - -// PasswordGTE applies the GTE predicate on the "password" field. -func PasswordGTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldGTE(FieldPassword, v)) -} - -// PasswordLT applies the LT predicate on the "password" field. -func PasswordLT(v string) predicate.Storage { - return predicate.Storage(sql.FieldLT(FieldPassword, v)) -} - -// PasswordLTE applies the LTE predicate on the "password" field. -func PasswordLTE(v string) predicate.Storage { - return predicate.Storage(sql.FieldLTE(FieldPassword, v)) -} - -// PasswordContains applies the Contains predicate on the "password" field. -func PasswordContains(v string) predicate.Storage { - return predicate.Storage(sql.FieldContains(FieldPassword, v)) -} - -// PasswordHasPrefix applies the HasPrefix predicate on the "password" field. -func PasswordHasPrefix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasPrefix(FieldPassword, v)) -} - -// PasswordHasSuffix applies the HasSuffix predicate on the "password" field. -func PasswordHasSuffix(v string) predicate.Storage { - return predicate.Storage(sql.FieldHasSuffix(FieldPassword, v)) -} - -// PasswordIsNil applies the IsNil predicate on the "password" field. -func PasswordIsNil() predicate.Storage { - return predicate.Storage(sql.FieldIsNull(FieldPassword)) -} - -// PasswordNotNil applies the NotNil predicate on the "password" field. -func PasswordNotNil() predicate.Storage { - return predicate.Storage(sql.FieldNotNull(FieldPassword)) -} - -// PasswordEqualFold applies the EqualFold predicate on the "password" field. -func PasswordEqualFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldEqualFold(FieldPassword, v)) -} - -// PasswordContainsFold applies the ContainsFold predicate on the "password" field. -func PasswordContainsFold(v string) predicate.Storage { - return predicate.Storage(sql.FieldContainsFold(FieldPassword, v)) +// SettingsContainsFold applies the ContainsFold predicate on the "settings" field. +func SettingsContainsFold(v string) predicate.Storage { + return predicate.Storage(sql.FieldContainsFold(FieldSettings, v)) } // DeletedEQ applies the EQ predicate on the "deleted" field. diff --git a/ent/storage_create.go b/ent/storage_create.go index 6b86d12..38f29ec 100644 --- a/ent/storage_create.go +++ b/ent/storage_create.go @@ -26,41 +26,21 @@ func (sc *StorageCreate) SetName(s string) *StorageCreate { } // SetImplementation sets the "implementation" field. -func (sc *StorageCreate) SetImplementation(s string) *StorageCreate { +func (sc *StorageCreate) SetImplementation(s storage.Implementation) *StorageCreate { sc.mutation.SetImplementation(s) return sc } -// SetPath sets the "path" field. -func (sc *StorageCreate) SetPath(s string) *StorageCreate { - sc.mutation.SetPath(s) +// SetSettings sets the "settings" field. +func (sc *StorageCreate) SetSettings(s string) *StorageCreate { + sc.mutation.SetSettings(s) return sc } -// SetUser sets the "user" field. -func (sc *StorageCreate) SetUser(s string) *StorageCreate { - sc.mutation.SetUser(s) - return sc -} - -// SetNillableUser sets the "user" field if the given value is not nil. -func (sc *StorageCreate) SetNillableUser(s *string) *StorageCreate { +// SetNillableSettings sets the "settings" field if the given value is not nil. +func (sc *StorageCreate) SetNillableSettings(s *string) *StorageCreate { if s != nil { - sc.SetUser(*s) - } - return sc -} - -// SetPassword sets the "password" field. -func (sc *StorageCreate) SetPassword(s string) *StorageCreate { - sc.mutation.SetPassword(s) - return sc -} - -// SetNillablePassword sets the "password" field if the given value is not nil. -func (sc *StorageCreate) SetNillablePassword(s *string) *StorageCreate { - if s != nil { - sc.SetPassword(*s) + sc.SetSettings(*s) } return sc } @@ -146,8 +126,10 @@ func (sc *StorageCreate) check() error { if _, ok := sc.mutation.Implementation(); !ok { return &ValidationError{Name: "implementation", err: errors.New(`ent: missing required field "Storage.implementation"`)} } - if _, ok := sc.mutation.Path(); !ok { - return &ValidationError{Name: "path", err: errors.New(`ent: missing required field "Storage.path"`)} + if v, ok := sc.mutation.Implementation(); ok { + if err := storage.ImplementationValidator(v); err != nil { + return &ValidationError{Name: "implementation", err: fmt.Errorf(`ent: validator failed for field "Storage.implementation": %w`, err)} + } } if _, ok := sc.mutation.Deleted(); !ok { return &ValidationError{Name: "deleted", err: errors.New(`ent: missing required field "Storage.deleted"`)} @@ -186,20 +168,12 @@ func (sc *StorageCreate) createSpec() (*Storage, *sqlgraph.CreateSpec) { _node.Name = value } if value, ok := sc.mutation.Implementation(); ok { - _spec.SetField(storage.FieldImplementation, field.TypeString, value) + _spec.SetField(storage.FieldImplementation, field.TypeEnum, value) _node.Implementation = value } - if value, ok := sc.mutation.Path(); ok { - _spec.SetField(storage.FieldPath, field.TypeString, value) - _node.Path = value - } - if value, ok := sc.mutation.User(); ok { - _spec.SetField(storage.FieldUser, field.TypeString, value) - _node.User = value - } - if value, ok := sc.mutation.Password(); ok { - _spec.SetField(storage.FieldPassword, field.TypeString, value) - _node.Password = value + if value, ok := sc.mutation.Settings(); ok { + _spec.SetField(storage.FieldSettings, field.TypeString, value) + _node.Settings = value } if value, ok := sc.mutation.Deleted(); ok { _spec.SetField(storage.FieldDeleted, field.TypeBool, value) diff --git a/ent/storage_update.go b/ent/storage_update.go index 13aa551..c824fe8 100644 --- a/ent/storage_update.go +++ b/ent/storage_update.go @@ -42,70 +42,36 @@ func (su *StorageUpdate) SetNillableName(s *string) *StorageUpdate { } // SetImplementation sets the "implementation" field. -func (su *StorageUpdate) SetImplementation(s string) *StorageUpdate { +func (su *StorageUpdate) SetImplementation(s storage.Implementation) *StorageUpdate { su.mutation.SetImplementation(s) return su } // SetNillableImplementation sets the "implementation" field if the given value is not nil. -func (su *StorageUpdate) SetNillableImplementation(s *string) *StorageUpdate { +func (su *StorageUpdate) SetNillableImplementation(s *storage.Implementation) *StorageUpdate { if s != nil { su.SetImplementation(*s) } return su } -// SetPath sets the "path" field. -func (su *StorageUpdate) SetPath(s string) *StorageUpdate { - su.mutation.SetPath(s) +// SetSettings sets the "settings" field. +func (su *StorageUpdate) SetSettings(s string) *StorageUpdate { + su.mutation.SetSettings(s) return su } -// SetNillablePath sets the "path" field if the given value is not nil. -func (su *StorageUpdate) SetNillablePath(s *string) *StorageUpdate { +// SetNillableSettings sets the "settings" field if the given value is not nil. +func (su *StorageUpdate) SetNillableSettings(s *string) *StorageUpdate { if s != nil { - su.SetPath(*s) + su.SetSettings(*s) } return su } -// SetUser sets the "user" field. -func (su *StorageUpdate) SetUser(s string) *StorageUpdate { - su.mutation.SetUser(s) - return su -} - -// SetNillableUser sets the "user" field if the given value is not nil. -func (su *StorageUpdate) SetNillableUser(s *string) *StorageUpdate { - if s != nil { - su.SetUser(*s) - } - return su -} - -// ClearUser clears the value of the "user" field. -func (su *StorageUpdate) ClearUser() *StorageUpdate { - su.mutation.ClearUser() - return su -} - -// SetPassword sets the "password" field. -func (su *StorageUpdate) SetPassword(s string) *StorageUpdate { - su.mutation.SetPassword(s) - return su -} - -// SetNillablePassword sets the "password" field if the given value is not nil. -func (su *StorageUpdate) SetNillablePassword(s *string) *StorageUpdate { - if s != nil { - su.SetPassword(*s) - } - return su -} - -// ClearPassword clears the value of the "password" field. -func (su *StorageUpdate) ClearPassword() *StorageUpdate { - su.mutation.ClearPassword() +// ClearSettings clears the value of the "settings" field. +func (su *StorageUpdate) ClearSettings() *StorageUpdate { + su.mutation.ClearSettings() return su } @@ -169,7 +135,20 @@ func (su *StorageUpdate) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (su *StorageUpdate) check() error { + if v, ok := su.mutation.Implementation(); ok { + if err := storage.ImplementationValidator(v); err != nil { + return &ValidationError{Name: "implementation", err: fmt.Errorf(`ent: validator failed for field "Storage.implementation": %w`, err)} + } + } + return nil +} + func (su *StorageUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := su.check(); err != nil { + return n, err + } _spec := sqlgraph.NewUpdateSpec(storage.Table, storage.Columns, sqlgraph.NewFieldSpec(storage.FieldID, field.TypeInt)) if ps := su.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { @@ -182,22 +161,13 @@ func (su *StorageUpdate) sqlSave(ctx context.Context) (n int, err error) { _spec.SetField(storage.FieldName, field.TypeString, value) } if value, ok := su.mutation.Implementation(); ok { - _spec.SetField(storage.FieldImplementation, field.TypeString, value) + _spec.SetField(storage.FieldImplementation, field.TypeEnum, value) } - if value, ok := su.mutation.Path(); ok { - _spec.SetField(storage.FieldPath, field.TypeString, value) + if value, ok := su.mutation.Settings(); ok { + _spec.SetField(storage.FieldSettings, field.TypeString, value) } - if value, ok := su.mutation.User(); ok { - _spec.SetField(storage.FieldUser, field.TypeString, value) - } - if su.mutation.UserCleared() { - _spec.ClearField(storage.FieldUser, field.TypeString) - } - if value, ok := su.mutation.Password(); ok { - _spec.SetField(storage.FieldPassword, field.TypeString, value) - } - if su.mutation.PasswordCleared() { - _spec.ClearField(storage.FieldPassword, field.TypeString) + if su.mutation.SettingsCleared() { + _spec.ClearField(storage.FieldSettings, field.TypeString) } if value, ok := su.mutation.Deleted(); ok { _spec.SetField(storage.FieldDeleted, field.TypeBool, value) @@ -240,70 +210,36 @@ func (suo *StorageUpdateOne) SetNillableName(s *string) *StorageUpdateOne { } // SetImplementation sets the "implementation" field. -func (suo *StorageUpdateOne) SetImplementation(s string) *StorageUpdateOne { +func (suo *StorageUpdateOne) SetImplementation(s storage.Implementation) *StorageUpdateOne { suo.mutation.SetImplementation(s) return suo } // SetNillableImplementation sets the "implementation" field if the given value is not nil. -func (suo *StorageUpdateOne) SetNillableImplementation(s *string) *StorageUpdateOne { +func (suo *StorageUpdateOne) SetNillableImplementation(s *storage.Implementation) *StorageUpdateOne { if s != nil { suo.SetImplementation(*s) } return suo } -// SetPath sets the "path" field. -func (suo *StorageUpdateOne) SetPath(s string) *StorageUpdateOne { - suo.mutation.SetPath(s) +// SetSettings sets the "settings" field. +func (suo *StorageUpdateOne) SetSettings(s string) *StorageUpdateOne { + suo.mutation.SetSettings(s) return suo } -// SetNillablePath sets the "path" field if the given value is not nil. -func (suo *StorageUpdateOne) SetNillablePath(s *string) *StorageUpdateOne { +// SetNillableSettings sets the "settings" field if the given value is not nil. +func (suo *StorageUpdateOne) SetNillableSettings(s *string) *StorageUpdateOne { if s != nil { - suo.SetPath(*s) + suo.SetSettings(*s) } return suo } -// SetUser sets the "user" field. -func (suo *StorageUpdateOne) SetUser(s string) *StorageUpdateOne { - suo.mutation.SetUser(s) - return suo -} - -// SetNillableUser sets the "user" field if the given value is not nil. -func (suo *StorageUpdateOne) SetNillableUser(s *string) *StorageUpdateOne { - if s != nil { - suo.SetUser(*s) - } - return suo -} - -// ClearUser clears the value of the "user" field. -func (suo *StorageUpdateOne) ClearUser() *StorageUpdateOne { - suo.mutation.ClearUser() - return suo -} - -// SetPassword sets the "password" field. -func (suo *StorageUpdateOne) SetPassword(s string) *StorageUpdateOne { - suo.mutation.SetPassword(s) - return suo -} - -// SetNillablePassword sets the "password" field if the given value is not nil. -func (suo *StorageUpdateOne) SetNillablePassword(s *string) *StorageUpdateOne { - if s != nil { - suo.SetPassword(*s) - } - return suo -} - -// ClearPassword clears the value of the "password" field. -func (suo *StorageUpdateOne) ClearPassword() *StorageUpdateOne { - suo.mutation.ClearPassword() +// ClearSettings clears the value of the "settings" field. +func (suo *StorageUpdateOne) ClearSettings() *StorageUpdateOne { + suo.mutation.ClearSettings() return suo } @@ -380,7 +316,20 @@ func (suo *StorageUpdateOne) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (suo *StorageUpdateOne) check() error { + if v, ok := suo.mutation.Implementation(); ok { + if err := storage.ImplementationValidator(v); err != nil { + return &ValidationError{Name: "implementation", err: fmt.Errorf(`ent: validator failed for field "Storage.implementation": %w`, err)} + } + } + return nil +} + func (suo *StorageUpdateOne) sqlSave(ctx context.Context) (_node *Storage, err error) { + if err := suo.check(); err != nil { + return _node, err + } _spec := sqlgraph.NewUpdateSpec(storage.Table, storage.Columns, sqlgraph.NewFieldSpec(storage.FieldID, field.TypeInt)) id, ok := suo.mutation.ID() if !ok { @@ -410,22 +359,13 @@ func (suo *StorageUpdateOne) sqlSave(ctx context.Context) (_node *Storage, err e _spec.SetField(storage.FieldName, field.TypeString, value) } if value, ok := suo.mutation.Implementation(); ok { - _spec.SetField(storage.FieldImplementation, field.TypeString, value) + _spec.SetField(storage.FieldImplementation, field.TypeEnum, value) } - if value, ok := suo.mutation.Path(); ok { - _spec.SetField(storage.FieldPath, field.TypeString, value) + if value, ok := suo.mutation.Settings(); ok { + _spec.SetField(storage.FieldSettings, field.TypeString, value) } - if value, ok := suo.mutation.User(); ok { - _spec.SetField(storage.FieldUser, field.TypeString, value) - } - if suo.mutation.UserCleared() { - _spec.ClearField(storage.FieldUser, field.TypeString) - } - if value, ok := suo.mutation.Password(); ok { - _spec.SetField(storage.FieldPassword, field.TypeString, value) - } - if suo.mutation.PasswordCleared() { - _spec.ClearField(storage.FieldPassword, field.TypeString) + if suo.mutation.SettingsCleared() { + _spec.ClearField(storage.FieldSettings, field.TypeString) } if value, ok := suo.mutation.Deleted(); ok { _spec.SetField(storage.FieldDeleted, field.TypeBool, value) diff --git a/pkg/storage/local.go b/pkg/storage/local.go index 18f168d..aa784f5 100644 --- a/pkg/storage/local.go +++ b/pkg/storage/local.go @@ -14,8 +14,12 @@ type Storage interface { ReadDir(dir string) ([]fs.FileInfo, error) } -func NewLocalStorage(dir string) *LocalStorage { - return &LocalStorage{dir: dir} +func NewLocalStorage(dir string) (*LocalStorage, error) { + if _, err := os.Stat(dir); err != nil { + return nil, errors.Wrap(err, "stat") + } + + return &LocalStorage{dir: dir}, nil } type LocalStorage struct { diff --git a/server/scheduler.go b/server/scheduler.go index e2474d1..3cedc88 100644 --- a/server/scheduler.go +++ b/server/scheduler.go @@ -2,10 +2,10 @@ package server import ( "path/filepath" - "polaris/db" "polaris/log" "polaris/pkg" "polaris/pkg/storage" + storage1 "polaris/ent/storage" "github.com/pkg/errors" ) @@ -53,16 +53,21 @@ func (s *Server) moveCompletedTask(id int) error { series := s.db.GetSeriesDetails(r.SeriesID) st := s.db.GetStorage(series.StorageID) log.Infof("move task files to target dir: %v", r.TargetDir) - if st.Implementation == db.ImplWebdav { - storageImpl, err := storage.NewWebdavStorage(st.Path, st.User, st.Password) + if st.Implementation == storage1.ImplementationWebdav { + ws := st.ToWebDavSetting() + storageImpl, err := storage.NewWebdavStorage(ws.Path, ws.User, ws.Password) if err != nil { return errors.Wrap(err, "new webdav") } if err := storageImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil { return errors.Wrap(err, "move webdav") } - } else if st.Implementation == db.ImplLocal { - storageImpl := storage.NewLocalStorage(st.Path) + } else if st.Implementation == storage1.ImplementationLocal { + ls := st.ToLocalSetting() + storageImpl, err := storage.NewLocalStorage(ls.Path) + if err != nil { + return errors.Wrap(err, "new storage") + } if err := storageImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil { return errors.Wrap(err, "move webdav") @@ -76,6 +81,12 @@ func (s *Server) moveCompletedTask(id int) error { return nil } +func (s *Server) updateSeriesEpisodes(seriesId int) { + +} + +func (s *Server) checkFileExists() {} + type Task struct { Processing bool pkg.Torrent diff --git a/server/storage.go b/server/storage.go index b7a72a5..1af3144 100644 --- a/server/storage.go +++ b/server/storage.go @@ -22,7 +22,7 @@ func (s *Server) AddStorage(c *gin.Context) (interface{}, error) { } log.Infof("received add storage input: %v", in) - err := s.db.AddStorage(in) + err := s.db.AddStorage(&in) return nil, err } diff --git a/ui/lib/main.dart b/ui/lib/main.dart index 4b7f32f..38646a2 100644 --- a/ui/lib/main.dart +++ b/ui/lib/main.dart @@ -115,7 +115,23 @@ class MyApp extends StatelessWidget { return ProviderScope( child: MaterialApp.router( title: 'Polaris', + theme: ThemeData( + + // Define the default TextTheme. Use this to specify the default + // text styling for headlines, titles, bodies of text, and more. + // textTheme: const TextTheme( + // bodyLarge: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // bodyMedium: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // bodySmall: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // titleLarge: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // titleMedium: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // titleSmall: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // labelLarge: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // labelMedium: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // labelSmall: TextStyle(fontFamilyFallback: ["PingFang SC", "Heiti SC"]), + // ), + colorScheme: ColorScheme.fromSeed( seedColor: Colors.blue, brightness: Brightness.dark), useMaterial3: true, diff --git a/ui/lib/providers/settings.dart b/ui/lib/providers/settings.dart index 4f6c725..9f26cd8 100644 --- a/ui/lib/providers/settings.dart +++ b/ui/lib/providers/settings.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:quiver/strings.dart'; @@ -246,30 +247,21 @@ class StorageSettingData extends AsyncNotifier> { } class Storage { - Storage({ - this.id, - this.name, - this.implementation, - this.path, - this.user, - this.password, - }); + Storage({this.id, this.name, this.implementation, this.settings, this.isDefault}); final int? id; final String? name; final String? implementation; - final String? path; - final String? user; - final String? password; + final Map? settings; + final bool? isDefault; - factory Storage.fromJson(Map json) { + factory Storage.fromJson(Map json1) { return Storage( - id: json["id"], - name: json["name"], - implementation: json["implementation"], - path: json["path"], - user: json["user"], - password: json["password"], + id: json1["id"], + name: json1["name"], + implementation: json1["implementation"], + settings: json.decode(json1["settings"]), + isDefault: json1["default"] ); } @@ -277,8 +269,7 @@ class Storage { "id": id, "name": name, "implementation": implementation, - "path": path, - "user": user, - "password": password, + "settings": settings, + "default": isDefault, }; } diff --git a/ui/lib/search.dart b/ui/lib/search.dart index 3d53fda..836de74 100644 --- a/ui/lib/search.dart +++ b/ui/lib/search.dart @@ -106,73 +106,80 @@ class _SearchPageState extends ConsumerState { } Future _showSubmitDialog(BuildContext context, SearchResult item) { - String _resSelected = "1080p"; - int _storageSelected = 0; - var storage = ref.watch(storageSettingProvider); return showDialog( context: context, builder: (BuildContext context) { - return AlertDialog( - title: Text('添加剧集: ${item.name}'), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - DropdownMenu( - label: const Text("清晰度"), - initialSelection: _resSelected, - dropdownMenuEntries: const [ - DropdownMenuEntry(value: "720p", label: "720p"), - DropdownMenuEntry(value: "1080p", label: "1080p"), - DropdownMenuEntry(value: "4k", label: "4k"), - ], - onSelected: (value) { - setState(() { - _resSelected = value!; - }); - }, - ), - storage.when( - data: (v) { - return DropdownMenu( - label: const Text("存储位置"), - initialSelection: _storageSelected, - dropdownMenuEntries: v - .map((s) => - DropdownMenuEntry(label: s.name!, value: s.id)) - .toList(), - onSelected: (value) { - setState(() { - _storageSelected = value!; - }); + return StatefulBuilder( + builder: (context, setState) { + String _resSelected = "1080p"; + Storage? _storageSelected; + var storage = ref.watch(storageSettingProvider); + + return AlertDialog( + title: Text('添加剧集: ${item.name}'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + DropdownMenu( + label: const Text("清晰度"), + initialSelection: _resSelected, + dropdownMenuEntries: const [ + DropdownMenuEntry(value: "720p", label: "720p"), + DropdownMenuEntry(value: "1080p", label: "1080p"), + DropdownMenuEntry(value: "4k", label: "4k"), + ], + onSelected: (value) { + setState(() { + _resSelected = value!; + }); + }, + ), + storage.when( + data: (v) { + return DropdownMenu( + label: const Text("存储位置"), + initialSelection: _storageSelected, + dropdownMenuEntries: v + .map((s) => + DropdownMenuEntry(label: s.name!, value: s)) + .toList(), + onSelected: (value) { + setState(() { + _storageSelected = value; + }); + }, + ); }, - ); + error: (err, trace) => Text("$err"), + loading: () => const MyProgressIndicator()), + ], + ), + actions: [ + TextButton( + style: TextButton.styleFrom( + textStyle: Theme.of(context).textTheme.labelLarge, + ), + child: const Text('取消'), + onPressed: () { + Navigator.of(context).pop(); }, - error: (err, trace) => Text("$err"), - loading: () => MyProgressIndicator()), - ], - ), - actions: [ - TextButton( - style: TextButton.styleFrom( - textStyle: Theme.of(context).textTheme.labelLarge, - ), - child: const Text('取消'), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - style: TextButton.styleFrom( - textStyle: Theme.of(context).textTheme.labelLarge, - ), - child: const Text('确定'), - onPressed: () { - ref.read(searchPageDataProvider.notifier).submit2Watchlist( - item.id!, _storageSelected, _resSelected); - Navigator.of(context).pop(); - }, - ), - ], + ), + TextButton( + style: TextButton.styleFrom( + textStyle: Theme.of(context).textTheme.labelLarge, + ), + child: const Text('确定'), + onPressed: () { + ref + .read(searchPageDataProvider.notifier) + .submit2Watchlist( + item.id!, _storageSelected!.id!, _resSelected); + Navigator.of(context).pop(); + }, + ), + ], + ); + }, ); }); } diff --git a/ui/lib/system_settings.dart b/ui/lib/system_settings.dart index cdc6a21..3366755 100644 --- a/ui/lib/system_settings.dart +++ b/ui/lib/system_settings.dart @@ -473,84 +473,121 @@ class _SystemSettingsPageState extends ConsumerState { Future showStorageDetails( AsyncSnapshot snapshot, BuildContext context, Storage s) { - var nameController = TextEditingController(text: s.name); - var implController = TextEditingController( - text: isBlank(s.implementation) ? "transmission" : s.implementation); - var pathController = TextEditingController(text: s.path); - var userController = TextEditingController(text: s.user); - var passController = TextEditingController(text: s.password); return showDialog( context: context, barrierDismissible: true, // user must tap button! builder: (BuildContext context) { - return AlertDialog( - title: const Text('存储'), - content: SingleChildScrollView( - child: ListBody( - children: [ - TextField( - decoration: const InputDecoration(labelText: "名称"), - controller: nameController, - ), - TextField( - decoration: const InputDecoration(labelText: "实现"), - controller: implController, - ), - TextField( - decoration: const InputDecoration(labelText: "路径"), - controller: pathController, - ), - TextField( - decoration: const InputDecoration(labelText: "用户"), - controller: userController, - ), - TextField( - decoration: const InputDecoration(labelText: "密码"), - controller: passController, - ), - ], - ), - ), - actions: [ - s.id == null - ? const Text("") - : TextButton( - onPressed: () { - var f = ref - .read(storageSettingProvider.notifier) - .deleteStorage(s.id!); + var nameController = TextEditingController(text: s.name); + var pathController = TextEditingController(); + var urlController = TextEditingController(); + var userController = TextEditingController(); + var passController = TextEditingController(); + if (s.settings != null) { + pathController.text = s.settings!["path"]; + urlController.text = s.settings!["url"]; + userController.text = s.settings!["user"]; + passController.text = s.settings!["password"]; + } + + String _selectImpl = s.implementation == null? "local": s.implementation!; + return StatefulBuilder(builder: (context, setState) { + return AlertDialog( + title: const Text('存储'), + content: SingleChildScrollView( + child: ListBody( + children: [ + DropdownMenu( + label: const Text("实现"), + onSelected: (value) { setState(() { - _pendingStorage = f; + _selectImpl = value!; }); - if (!showError(snapshot)) { - Navigator.of(context).pop(); - } }, - child: const Text('删除')), - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text('取消')), - TextButton( - child: const Text('确定'), - onPressed: () { - var f = ref.read(storageSettingProvider.notifier).addStorage( - Storage( - name: nameController.text, - implementation: implController.text, - path: pathController.text, - user: userController.text, - password: passController.text)); - setState(() { - _pendingStorage = f; - }); - if (!showError(snapshot)) { - Navigator.of(context).pop(); - } - }, + initialSelection: _selectImpl, + dropdownMenuEntries: const [ + DropdownMenuEntry(value: "local", label: "本地存储"), + DropdownMenuEntry(value: "webdav", label: "webdav") + ], + ), + TextField( + decoration: const InputDecoration(labelText: "名称"), + controller: nameController, + ), + _selectImpl == "local" + ? TextField( + decoration: const InputDecoration(labelText: "路径"), + controller: pathController, + ) + : Column( + children: [ + TextField( + decoration: const InputDecoration( + labelText: "Webdav网址"), + controller: urlController, + ), + TextField( + decoration: + const InputDecoration(labelText: "用户"), + controller: userController, + ), + TextField( + decoration: + const InputDecoration(labelText: "密码"), + controller: passController, + ), + TextField( + decoration: + const InputDecoration(labelText: "路径"), + controller: pathController, + ), + ], + ) + ], + ), ), - ], - ); + actions: [ + s.id == null + ? const Text("") + : TextButton( + onPressed: () { + var f = ref + .read(storageSettingProvider.notifier) + .deleteStorage(s.id!); + setState(() { + _pendingStorage = f; + }); + if (!showError(snapshot)) { + Navigator.of(context).pop(); + } + }, + child: const Text('删除')), + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('取消')), + TextButton( + child: const Text('确定'), + onPressed: () async { + ref + .read(storageSettingProvider.notifier) + .addStorage(Storage( + name: nameController.text, + implementation: _selectImpl, + settings: { + "path": pathController.text, + "url": urlController.text, + "user": userController.text, + "password": passController.text + }, + )); + if (!showError(snapshot)) { + Navigator.of(context).pop(); + } + }, + ), + ], + ); + }); }); }