chore: do some work

This commit is contained in:
Simon Ding
2024-07-06 10:59:30 +08:00
parent c703552267
commit 7d9dc17f87
14 changed files with 245 additions and 23 deletions

View File

@@ -65,12 +65,12 @@ func (c *Client) GetLanguage() string {
return lang
}
func (c *Client) AddWatchlist(path string, detail *tmdb.TVDetails) error {
func (c *Client) AddWatchlist(path string, detail *tmdb.TVDetails) (*ent.Series, error) {
count := c.ent.Series.Query().Where(series.TmdbID(int(detail.ID))).CountX(context.Background())
if (count > 0) {
return fmt.Errorf("tv series %s already in watchlist", detail.Name)
return nil, fmt.Errorf("tv series %s already in watchlist", detail.Name)
}
_, err := c.ent.Series.Create().
r, err := c.ent.Series.Create().
SetTmdbID(int(detail.ID)).
SetPath(path).
SetOverview(detail.Overview).
@@ -78,7 +78,7 @@ func (c *Client) AddWatchlist(path string, detail *tmdb.TVDetails) error {
SetOriginalName(detail.OriginalName).
SetPosterPath(detail.PosterPath).
Save(context.TODO())
return err
return r, err
}
func (c *Client) GetWatchlist() []*ent.Series {
@@ -90,14 +90,14 @@ func (c *Client) GetWatchlist() []*ent.Series {
return list
}
func (c *Client) SaveEposideDetail(tmdbId int, d *tmdb.TVEpisodeDetails) error {
func (c *Client) SaveEposideDetail(d *ent.Epidodes) error {
_, err := c.ent.Epidodes.Create().
SetAirDate(d.AirDate).
SetSeasonNumber(d.SeasonNumber).
SetEpisodeNumber(d.EpisodeNumber).
SetSeriesID(tmdbId).
SetSeriesID(d.SeriesID).
SetOverview(d.Overview).
SetTitle(d.Name).Save(context.TODO())
SetTitle(d.Title).Save(context.TODO())
return err
}

View File

@@ -84,6 +84,7 @@ var (
{Name: "overview", Type: field.TypeString},
{Name: "path", Type: field.TypeString},
{Name: "poster_path", Type: field.TypeString, Nullable: true},
{Name: "created_at", Type: field.TypeTime},
}
// SeriesTable holds the schema information for the "series" table.
SeriesTable = &schema.Table{

View File

@@ -2750,6 +2750,7 @@ type SeriesMutation struct {
overview *string
_path *string
poster_path *string
created_at *time.Time
clearedFields map[string]struct{}
done bool
oldValue func(context.Context) (*Series, error)
@@ -3152,6 +3153,42 @@ func (m *SeriesMutation) ResetPosterPath() {
delete(m.clearedFields, series.FieldPosterPath)
}
// SetCreatedAt sets the "created_at" field.
func (m *SeriesMutation) SetCreatedAt(t time.Time) {
m.created_at = &t
}
// CreatedAt returns the value of the "created_at" field in the mutation.
func (m *SeriesMutation) CreatedAt() (r time.Time, exists bool) {
v := m.created_at
if v == nil {
return
}
return *v, true
}
// OldCreatedAt returns the old "created_at" 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) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldCreatedAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
}
return oldValue.CreatedAt, nil
}
// ResetCreatedAt resets all changes to the "created_at" field.
func (m *SeriesMutation) ResetCreatedAt() {
m.created_at = nil
}
// Where appends a list predicates to the SeriesMutation builder.
func (m *SeriesMutation) Where(ps ...predicate.Series) {
m.predicates = append(m.predicates, ps...)
@@ -3186,7 +3223,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, 7)
fields := make([]string, 0, 8)
if m.tmdb_id != nil {
fields = append(fields, series.FieldTmdbID)
}
@@ -3208,6 +3245,9 @@ func (m *SeriesMutation) Fields() []string {
if m.poster_path != nil {
fields = append(fields, series.FieldPosterPath)
}
if m.created_at != nil {
fields = append(fields, series.FieldCreatedAt)
}
return fields
}
@@ -3230,6 +3270,8 @@ func (m *SeriesMutation) Field(name string) (ent.Value, bool) {
return m.Path()
case series.FieldPosterPath:
return m.PosterPath()
case series.FieldCreatedAt:
return m.CreatedAt()
}
return nil, false
}
@@ -3253,6 +3295,8 @@ func (m *SeriesMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldPath(ctx)
case series.FieldPosterPath:
return m.OldPosterPath(ctx)
case series.FieldCreatedAt:
return m.OldCreatedAt(ctx)
}
return nil, fmt.Errorf("unknown Series field %s", name)
}
@@ -3311,6 +3355,13 @@ func (m *SeriesMutation) SetField(name string, value ent.Value) error {
}
m.SetPosterPath(v)
return nil
case series.FieldCreatedAt:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetCreatedAt(v)
return nil
}
return fmt.Errorf("unknown Series field %s", name)
}
@@ -3411,6 +3462,9 @@ func (m *SeriesMutation) ResetField(name string) error {
case series.FieldPosterPath:
m.ResetPosterPath()
return nil
case series.FieldCreatedAt:
m.ResetCreatedAt()
return nil
}
return fmt.Errorf("unknown Series field %s", name)
}

View File

@@ -6,6 +6,8 @@ import (
"polaris/ent/downloadclients"
"polaris/ent/indexers"
"polaris/ent/schema"
"polaris/ent/series"
"time"
)
// The init function reads all schema descriptors with runtime code
@@ -48,4 +50,10 @@ func init() {
indexersDescEnableRss := indexersFields[3].Descriptor()
// indexers.DefaultEnableRss holds the default value on creation for the enable_rss field.
indexers.DefaultEnableRss = indexersDescEnableRss.Default.(bool)
seriesFields := schema.Series{}.Fields()
_ = seriesFields
// seriesDescCreatedAt is the schema descriptor for created_at field.
seriesDescCreatedAt := seriesFields[7].Descriptor()
// series.DefaultCreatedAt holds the default value on creation for the created_at field.
series.DefaultCreatedAt = seriesDescCreatedAt.Default.(time.Time)
}

View File

@@ -1,6 +1,8 @@
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/schema/field"
)
@@ -20,6 +22,7 @@ func (Series) Fields() []ent.Field {
field.String("overview"),
field.String("path"),
field.String("poster_path").Optional(),
field.Time("created_at").Default(time.Now()),
}
}

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"polaris/ent/series"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
@@ -29,7 +30,9 @@ type Series struct {
// Path holds the value of the "path" field.
Path string `json:"path,omitempty"`
// PosterPath holds the value of the "poster_path" field.
PosterPath string `json:"poster_path,omitempty"`
PosterPath string `json:"poster_path,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
selectValues sql.SelectValues
}
@@ -42,6 +45,8 @@ func (*Series) scanValues(columns []string) ([]any, error) {
values[i] = new(sql.NullInt64)
case series.FieldImdbID, series.FieldTitle, series.FieldOriginalName, series.FieldOverview, series.FieldPath, series.FieldPosterPath:
values[i] = new(sql.NullString)
case series.FieldCreatedAt:
values[i] = new(sql.NullTime)
default:
values[i] = new(sql.UnknownType)
}
@@ -105,6 +110,12 @@ func (s *Series) assignValues(columns []string, values []any) error {
} else if value.Valid {
s.PosterPath = value.String
}
case series.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
s.CreatedAt = value.Time
}
default:
s.selectValues.Set(columns[i], values[i])
}
@@ -161,6 +172,9 @@ func (s *Series) String() string {
builder.WriteString(", ")
builder.WriteString("poster_path=")
builder.WriteString(s.PosterPath)
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(s.CreatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}

View File

@@ -3,6 +3,8 @@
package series
import (
"time"
"entgo.io/ent/dialect/sql"
)
@@ -25,6 +27,8 @@ const (
FieldPath = "path"
// FieldPosterPath holds the string denoting the poster_path field in the database.
FieldPosterPath = "poster_path"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// Table holds the table name of the series in the database.
Table = "series"
)
@@ -39,6 +43,7 @@ var Columns = []string{
FieldOverview,
FieldPath,
FieldPosterPath,
FieldCreatedAt,
}
// ValidColumn reports if the column name is valid (part of the table columns).
@@ -51,6 +56,11 @@ func ValidColumn(column string) bool {
return false
}
var (
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt time.Time
)
// OrderOption defines the ordering options for the Series queries.
type OrderOption func(*sql.Selector)
@@ -93,3 +103,8 @@ func ByPath(opts ...sql.OrderTermOption) OrderOption {
func ByPosterPath(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldPosterPath, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}

View File

@@ -4,6 +4,7 @@ package series
import (
"polaris/ent/predicate"
"time"
"entgo.io/ent/dialect/sql"
)
@@ -88,6 +89,11 @@ func PosterPath(v string) predicate.Series {
return predicate.Series(sql.FieldEQ(FieldPosterPath, v))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Series {
return predicate.Series(sql.FieldEQ(FieldCreatedAt, v))
}
// TmdbIDEQ applies the EQ predicate on the "tmdb_id" field.
func TmdbIDEQ(v int) predicate.Series {
return predicate.Series(sql.FieldEQ(FieldTmdbID, v))
@@ -538,6 +544,46 @@ func PosterPathContainsFold(v string) predicate.Series {
return predicate.Series(sql.FieldContainsFold(FieldPosterPath, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Series {
return predicate.Series(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.Series {
return predicate.Series(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.Series {
return predicate.Series(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.Series {
return predicate.Series(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.Series {
return predicate.Series(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.Series {
return predicate.Series(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.Series {
return predicate.Series(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.Series {
return predicate.Series(sql.FieldLTE(FieldCreatedAt, v))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Series) predicate.Series {
return predicate.Series(sql.AndPredicates(predicates...))

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"polaris/ent/series"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
@@ -77,6 +78,20 @@ func (sc *SeriesCreate) SetNillablePosterPath(s *string) *SeriesCreate {
return sc
}
// SetCreatedAt sets the "created_at" field.
func (sc *SeriesCreate) SetCreatedAt(t time.Time) *SeriesCreate {
sc.mutation.SetCreatedAt(t)
return sc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (sc *SeriesCreate) SetNillableCreatedAt(t *time.Time) *SeriesCreate {
if t != nil {
sc.SetCreatedAt(*t)
}
return sc
}
// Mutation returns the SeriesMutation object of the builder.
func (sc *SeriesCreate) Mutation() *SeriesMutation {
return sc.mutation
@@ -84,6 +99,7 @@ func (sc *SeriesCreate) Mutation() *SeriesMutation {
// Save creates the Series in the database.
func (sc *SeriesCreate) Save(ctx context.Context) (*Series, error) {
sc.defaults()
return withHooks(ctx, sc.sqlSave, sc.mutation, sc.hooks)
}
@@ -109,6 +125,14 @@ func (sc *SeriesCreate) ExecX(ctx context.Context) {
}
}
// defaults sets the default values of the builder before save.
func (sc *SeriesCreate) defaults() {
if _, ok := sc.mutation.CreatedAt(); !ok {
v := series.DefaultCreatedAt
sc.mutation.SetCreatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (sc *SeriesCreate) check() error {
if _, ok := sc.mutation.TmdbID(); !ok {
@@ -126,6 +150,9 @@ func (sc *SeriesCreate) check() error {
if _, ok := sc.mutation.Path(); !ok {
return &ValidationError{Name: "path", err: errors.New(`ent: missing required field "Series.path"`)}
}
if _, ok := sc.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Series.created_at"`)}
}
return nil
}
@@ -180,6 +207,10 @@ func (sc *SeriesCreate) createSpec() (*Series, *sqlgraph.CreateSpec) {
_spec.SetField(series.FieldPosterPath, field.TypeString, value)
_node.PosterPath = value
}
if value, ok := sc.mutation.CreatedAt(); ok {
_spec.SetField(series.FieldCreatedAt, field.TypeTime, value)
_node.CreatedAt = value
}
return _node, _spec
}
@@ -201,6 +232,7 @@ func (scb *SeriesCreateBulk) Save(ctx context.Context) ([]*Series, error) {
for i := range scb.builders {
func(i int, root context.Context) {
builder := scb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*SeriesMutation)
if !ok {

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"polaris/ent/predicate"
"polaris/ent/series"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
@@ -144,6 +145,20 @@ func (su *SeriesUpdate) ClearPosterPath() *SeriesUpdate {
return su
}
// SetCreatedAt sets the "created_at" field.
func (su *SeriesUpdate) SetCreatedAt(t time.Time) *SeriesUpdate {
su.mutation.SetCreatedAt(t)
return su
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (su *SeriesUpdate) SetNillableCreatedAt(t *time.Time) *SeriesUpdate {
if t != nil {
su.SetCreatedAt(*t)
}
return su
}
// Mutation returns the SeriesMutation object of the builder.
func (su *SeriesUpdate) Mutation() *SeriesMutation {
return su.mutation
@@ -215,6 +230,9 @@ func (su *SeriesUpdate) sqlSave(ctx context.Context) (n int, err error) {
if su.mutation.PosterPathCleared() {
_spec.ClearField(series.FieldPosterPath, field.TypeString)
}
if value, ok := su.mutation.CreatedAt(); ok {
_spec.SetField(series.FieldCreatedAt, field.TypeTime, value)
}
if n, err = sqlgraph.UpdateNodes(ctx, su.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{series.Label}
@@ -352,6 +370,20 @@ func (suo *SeriesUpdateOne) ClearPosterPath() *SeriesUpdateOne {
return suo
}
// SetCreatedAt sets the "created_at" field.
func (suo *SeriesUpdateOne) SetCreatedAt(t time.Time) *SeriesUpdateOne {
suo.mutation.SetCreatedAt(t)
return suo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (suo *SeriesUpdateOne) SetNillableCreatedAt(t *time.Time) *SeriesUpdateOne {
if t != nil {
suo.SetCreatedAt(*t)
}
return suo
}
// Mutation returns the SeriesMutation object of the builder.
func (suo *SeriesUpdateOne) Mutation() *SeriesMutation {
return suo.mutation
@@ -453,6 +485,9 @@ func (suo *SeriesUpdateOne) sqlSave(ctx context.Context) (_node *Series, err err
if suo.mutation.PosterPathCleared() {
_spec.ClearField(series.FieldPosterPath, field.TypeString)
}
if value, ok := suo.mutation.CreatedAt(); ok {
_spec.SetField(series.FieldCreatedAt, field.TypeTime, value)
}
_node = &Series{config: suo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues

View File

@@ -44,6 +44,10 @@ func (c *Client) GetEposideDetail(id, seasonNumber, eposideNumber int, language
return d, err
}
func (c *Client) GetSeasonDetails(id, seasonNumber int, language string) (*tmdb.TVSeasonDetails, error) {
return c.tmdbClient.GetTVSeasonDetails(id, seasonNumber, withLangOption(language))
}
func wrapLanguage(lang string) string {
if lang == "" {
lang = "zh-CN"

View File

@@ -1,6 +1,7 @@
package server
import (
"polaris/ent"
"polaris/log"
"github.com/gin-gonic/gin"
@@ -25,7 +26,7 @@ func (s *Server) SearchTvSeries(c *gin.Context) (interface{}, error) {
}
type addWatchlistIn struct {
ID int `json:"id" binding:"required"`
ID int `json:"id" binding:"required"`
RootFolder string `json:"folder" binding:"required"`
}
@@ -39,23 +40,32 @@ func (s *Server) AddWatchlist(c *gin.Context) (interface{}, error) {
return nil, errors.Wrap(err, "get tv detail")
}
log.Infof("find detail for tv id %d: %v", in.ID, detail)
if err := s.db.AddWatchlist(in.RootFolder, detail); err != nil {
wl, err := s.db.AddWatchlist(in.RootFolder, detail)
if err != nil {
return nil, errors.Wrap(err, "add to list")
}
log.Infof("save watchlist success: %s", detail.Name)
for _, season := range detail.Seasons {
seasonId := season.SeasonNumber
for i := 1; i <= season.EpisodeCount; i++ {
ep, err := s.MustTMDB().GetEposideDetail(int(detail.ID), seasonId, i, s.language)
se, err := s.MustTMDB().GetSeasonDetails(int(detail.ID), seasonId, s.language)
if err != nil {
log.Errorf("get season detail (%s) error: %v", detail.Name, err)
continue
}
for _, ep := range se.Episodes {
err = s.db.SaveEposideDetail(&ent.Epidodes{
SeriesID: wl.ID,
SeasonNumber: seasonId,
EpisodeNumber: ep.EpisodeNumber,
Title: ep.Name,
Overview: ep.Overview,
AirDate: ep.AirDate,
})
if err != nil {
log.Errorf("get eposide detail: %v", err)
return nil, errors.Wrap(err, "get eposide detail")
}
err = s.db.SaveEposideDetail(int(detail.ID), ep)
if err != nil {
return nil, errors.Wrap(err, "save episode")
log.Errorf("save episode info error: %v", err)
continue
}
}
}
@@ -66,4 +76,4 @@ func (s *Server) AddWatchlist(c *gin.Context) (interface{}, error) {
func (s *Server) GetWatchlist(c *gin.Context) (interface{}, error) {
list := s.db.GetWatchlist()
return list, nil
}
}

View File

@@ -69,7 +69,7 @@ class _SearchPageState extends State<SearchPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
m.name!,
"${m.name} (${m.firstAirDate?.split("-")[0]})",
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),

View File

@@ -37,7 +37,7 @@ class _SystemSettingsPageState extends State<SystemSettingsPage> {
labelText: "TMDB Api Key",
icon: Icon(Icons.key),
),
// 校验用户名
//
validator: (v) {
return v!.trim().isNotEmpty ? null : "ApiKey 不能为空";
},