mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-10 03:57:39 +08:00
add tv detail page
This commit is contained in:
18
db/db.go
18
db/db.go
@@ -67,7 +67,7 @@ func (c *Client) GetLanguage() string {
|
|||||||
|
|
||||||
func (c *Client) AddWatchlist(path string, detail *tmdb.TVDetails, episodes []int) (*ent.Series, error) {
|
func (c *Client) AddWatchlist(path string, detail *tmdb.TVDetails, episodes []int) (*ent.Series, error) {
|
||||||
count := c.ent.Series.Query().Where(series.TmdbID(int(detail.ID))).CountX(context.Background())
|
count := c.ent.Series.Query().Where(series.TmdbID(int(detail.ID))).CountX(context.Background())
|
||||||
if (count > 0) {
|
if count > 0 {
|
||||||
return nil, fmt.Errorf("tv series %s already in watchlist", detail.Name)
|
return nil, fmt.Errorf("tv series %s already in watchlist", detail.Name)
|
||||||
}
|
}
|
||||||
r, err := c.ent.Series.Create().
|
r, err := c.ent.Series.Create().
|
||||||
@@ -91,6 +91,20 @@ func (c *Client) GetWatchlist() []*ent.Series {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SeriesDetails struct {
|
||||||
|
*ent.Series
|
||||||
|
Episodes []*ent.Episode `json:"episodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetSeriesDetails(id int) *SeriesDetails {
|
||||||
|
se := c.ent.Series.Query().Where(series.ID(id)).FirstX(context.TODO())
|
||||||
|
ep := se.QueryEpisodes().AllX(context.Background())
|
||||||
|
return &SeriesDetails{
|
||||||
|
Series: se,
|
||||||
|
Episodes: ep,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) SaveEposideDetail(d *ent.Episode) (int, error) {
|
func (c *Client) SaveEposideDetail(d *ent.Episode) (int, error) {
|
||||||
ep, err := c.ent.Episode.Create().
|
ep, err := c.ent.Episode.Create().
|
||||||
SetAirDate(d.AirDate).
|
SetAirDate(d.AirDate).
|
||||||
@@ -99,7 +113,7 @@ func (c *Client) SaveEposideDetail(d *ent.Episode) (int, error) {
|
|||||||
SetOverview(d.Overview).
|
SetOverview(d.Overview).
|
||||||
SetTitle(d.Title).Save(context.TODO())
|
SetTitle(d.Title).Save(context.TODO())
|
||||||
|
|
||||||
return ep.ID,err
|
return ep.ID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type TorznabSetting struct {
|
type TorznabSetting struct {
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ type Episode struct {
|
|||||||
config `json:"-"`
|
config `json:"-"`
|
||||||
// ID of the ent.
|
// ID of the ent.
|
||||||
ID int `json:"id,omitempty"`
|
ID int `json:"id,omitempty"`
|
||||||
|
// SeriesID holds the value of the "series_id" field.
|
||||||
|
SeriesID int `json:"series_id,omitempty"`
|
||||||
// SeasonNumber holds the value of the "season_number" field.
|
// SeasonNumber holds the value of the "season_number" field.
|
||||||
SeasonNumber int `json:"season_number,omitempty"`
|
SeasonNumber int `json:"season_number"`
|
||||||
// EpisodeNumber holds the value of the "episode_number" field.
|
// EpisodeNumber holds the value of the "episode_number" field.
|
||||||
EpisodeNumber int `json:"episode_number,omitempty"`
|
EpisodeNumber int `json:"episode_number,omitempty"`
|
||||||
// Title holds the value of the "title" field.
|
// Title holds the value of the "title" field.
|
||||||
@@ -29,9 +31,8 @@ type Episode struct {
|
|||||||
AirDate string `json:"air_date,omitempty"`
|
AirDate string `json:"air_date,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
// The values are being populated by the EpisodeQuery when eager-loading is set.
|
// The values are being populated by the EpisodeQuery when eager-loading is set.
|
||||||
Edges EpisodeEdges `json:"edges"`
|
Edges EpisodeEdges `json:"edges"`
|
||||||
series_episodes *int
|
selectValues sql.SelectValues
|
||||||
selectValues sql.SelectValues
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EpisodeEdges holds the relations/edges for other nodes in the graph.
|
// EpisodeEdges holds the relations/edges for other nodes in the graph.
|
||||||
@@ -59,12 +60,10 @@ func (*Episode) scanValues(columns []string) ([]any, error) {
|
|||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case episode.FieldID, episode.FieldSeasonNumber, episode.FieldEpisodeNumber:
|
case episode.FieldID, episode.FieldSeriesID, episode.FieldSeasonNumber, episode.FieldEpisodeNumber:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate:
|
case episode.FieldTitle, episode.FieldOverview, episode.FieldAirDate:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
case episode.ForeignKeys[0]: // series_episodes
|
|
||||||
values[i] = new(sql.NullInt64)
|
|
||||||
default:
|
default:
|
||||||
values[i] = new(sql.UnknownType)
|
values[i] = new(sql.UnknownType)
|
||||||
}
|
}
|
||||||
@@ -86,6 +85,12 @@ func (e *Episode) assignValues(columns []string, values []any) error {
|
|||||||
return fmt.Errorf("unexpected type %T for field id", value)
|
return fmt.Errorf("unexpected type %T for field id", value)
|
||||||
}
|
}
|
||||||
e.ID = int(value.Int64)
|
e.ID = int(value.Int64)
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field series_id", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
e.SeriesID = int(value.Int64)
|
||||||
|
}
|
||||||
case episode.FieldSeasonNumber:
|
case episode.FieldSeasonNumber:
|
||||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field season_number", values[i])
|
return fmt.Errorf("unexpected type %T for field season_number", values[i])
|
||||||
@@ -116,13 +121,6 @@ func (e *Episode) assignValues(columns []string, values []any) error {
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
e.AirDate = value.String
|
e.AirDate = value.String
|
||||||
}
|
}
|
||||||
case episode.ForeignKeys[0]:
|
|
||||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
|
||||||
return fmt.Errorf("unexpected type %T for edge-field series_episodes", value)
|
|
||||||
} else if value.Valid {
|
|
||||||
e.series_episodes = new(int)
|
|
||||||
*e.series_episodes = int(value.Int64)
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
e.selectValues.Set(columns[i], values[i])
|
e.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
@@ -164,6 +162,9 @@ func (e *Episode) String() string {
|
|||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
builder.WriteString("Episode(")
|
builder.WriteString("Episode(")
|
||||||
builder.WriteString(fmt.Sprintf("id=%v, ", e.ID))
|
builder.WriteString(fmt.Sprintf("id=%v, ", e.ID))
|
||||||
|
builder.WriteString("series_id=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", e.SeriesID))
|
||||||
|
builder.WriteString(", ")
|
||||||
builder.WriteString("season_number=")
|
builder.WriteString("season_number=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", e.SeasonNumber))
|
builder.WriteString(fmt.Sprintf("%v", e.SeasonNumber))
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const (
|
|||||||
Label = "episode"
|
Label = "episode"
|
||||||
// FieldID holds the string denoting the id field in the database.
|
// FieldID holds the string denoting the id field in the database.
|
||||||
FieldID = "id"
|
FieldID = "id"
|
||||||
|
// FieldSeriesID holds the string denoting the series_id field in the database.
|
||||||
|
FieldSeriesID = "series_id"
|
||||||
// FieldSeasonNumber holds the string denoting the season_number field in the database.
|
// FieldSeasonNumber holds the string denoting the season_number field in the database.
|
||||||
FieldSeasonNumber = "season_number"
|
FieldSeasonNumber = "season_number"
|
||||||
// FieldEpisodeNumber holds the string denoting the episode_number field in the database.
|
// FieldEpisodeNumber holds the string denoting the episode_number field in the database.
|
||||||
@@ -32,12 +34,13 @@ const (
|
|||||||
// It exists in this package in order to avoid circular dependency with the "series" package.
|
// It exists in this package in order to avoid circular dependency with the "series" package.
|
||||||
SeriesInverseTable = "series"
|
SeriesInverseTable = "series"
|
||||||
// SeriesColumn is the table column denoting the series relation/edge.
|
// SeriesColumn is the table column denoting the series relation/edge.
|
||||||
SeriesColumn = "series_episodes"
|
SeriesColumn = "series_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Columns holds all SQL columns for episode fields.
|
// Columns holds all SQL columns for episode fields.
|
||||||
var Columns = []string{
|
var Columns = []string{
|
||||||
FieldID,
|
FieldID,
|
||||||
|
FieldSeriesID,
|
||||||
FieldSeasonNumber,
|
FieldSeasonNumber,
|
||||||
FieldEpisodeNumber,
|
FieldEpisodeNumber,
|
||||||
FieldTitle,
|
FieldTitle,
|
||||||
@@ -45,12 +48,6 @@ var Columns = []string{
|
|||||||
FieldAirDate,
|
FieldAirDate,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "episodes"
|
|
||||||
// table and are not defined as standalone fields in the schema.
|
|
||||||
var ForeignKeys = []string{
|
|
||||||
"series_episodes",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||||
func ValidColumn(column string) bool {
|
func ValidColumn(column string) bool {
|
||||||
for i := range Columns {
|
for i := range Columns {
|
||||||
@@ -58,11 +55,6 @@ func ValidColumn(column string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range ForeignKeys {
|
|
||||||
if column == ForeignKeys[i] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +66,11 @@ func ByID(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BySeriesID orders the results by the series_id field.
|
||||||
|
func BySeriesID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldSeriesID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
// BySeasonNumber orders the results by the season_number field.
|
// BySeasonNumber orders the results by the season_number field.
|
||||||
func BySeasonNumber(opts ...sql.OrderTermOption) OrderOption {
|
func BySeasonNumber(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldSeasonNumber, opts...).ToFunc()
|
return sql.OrderByField(FieldSeasonNumber, opts...).ToFunc()
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ func IDLTE(id int) predicate.Episode {
|
|||||||
return predicate.Episode(sql.FieldLTE(FieldID, id))
|
return predicate.Episode(sql.FieldLTE(FieldID, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SeriesID applies equality check predicate on the "series_id" field. It's identical to SeriesIDEQ.
|
||||||
|
func SeriesID(v int) predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldEQ(FieldSeriesID, v))
|
||||||
|
}
|
||||||
|
|
||||||
// SeasonNumber applies equality check predicate on the "season_number" field. It's identical to SeasonNumberEQ.
|
// SeasonNumber applies equality check predicate on the "season_number" field. It's identical to SeasonNumberEQ.
|
||||||
func SeasonNumber(v int) predicate.Episode {
|
func SeasonNumber(v int) predicate.Episode {
|
||||||
return predicate.Episode(sql.FieldEQ(FieldSeasonNumber, v))
|
return predicate.Episode(sql.FieldEQ(FieldSeasonNumber, v))
|
||||||
@@ -79,6 +84,36 @@ func AirDate(v string) predicate.Episode {
|
|||||||
return predicate.Episode(sql.FieldEQ(FieldAirDate, v))
|
return predicate.Episode(sql.FieldEQ(FieldAirDate, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SeriesIDEQ applies the EQ predicate on the "series_id" field.
|
||||||
|
func SeriesIDEQ(v int) predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldEQ(FieldSeriesID, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDNEQ applies the NEQ predicate on the "series_id" field.
|
||||||
|
func SeriesIDNEQ(v int) predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldNEQ(FieldSeriesID, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDIn applies the In predicate on the "series_id" field.
|
||||||
|
func SeriesIDIn(vs ...int) predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldIn(FieldSeriesID, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDNotIn applies the NotIn predicate on the "series_id" field.
|
||||||
|
func SeriesIDNotIn(vs ...int) predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldNotIn(FieldSeriesID, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDIsNil applies the IsNil predicate on the "series_id" field.
|
||||||
|
func SeriesIDIsNil() predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldIsNull(FieldSeriesID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDNotNil applies the NotNil predicate on the "series_id" field.
|
||||||
|
func SeriesIDNotNil() predicate.Episode {
|
||||||
|
return predicate.Episode(sql.FieldNotNull(FieldSeriesID))
|
||||||
|
}
|
||||||
|
|
||||||
// SeasonNumberEQ applies the EQ predicate on the "season_number" field.
|
// SeasonNumberEQ applies the EQ predicate on the "season_number" field.
|
||||||
func SeasonNumberEQ(v int) predicate.Episode {
|
func SeasonNumberEQ(v int) predicate.Episode {
|
||||||
return predicate.Episode(sql.FieldEQ(FieldSeasonNumber, v))
|
return predicate.Episode(sql.FieldEQ(FieldSeasonNumber, v))
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ type EpisodeCreate struct {
|
|||||||
hooks []Hook
|
hooks []Hook
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSeriesID sets the "series_id" field.
|
||||||
|
func (ec *EpisodeCreate) SetSeriesID(i int) *EpisodeCreate {
|
||||||
|
ec.mutation.SetSeriesID(i)
|
||||||
|
return ec
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableSeriesID sets the "series_id" field if the given value is not nil.
|
||||||
|
func (ec *EpisodeCreate) SetNillableSeriesID(i *int) *EpisodeCreate {
|
||||||
|
if i != nil {
|
||||||
|
ec.SetSeriesID(*i)
|
||||||
|
}
|
||||||
|
return ec
|
||||||
|
}
|
||||||
|
|
||||||
// SetSeasonNumber sets the "season_number" field.
|
// SetSeasonNumber sets the "season_number" field.
|
||||||
func (ec *EpisodeCreate) SetSeasonNumber(i int) *EpisodeCreate {
|
func (ec *EpisodeCreate) SetSeasonNumber(i int) *EpisodeCreate {
|
||||||
ec.mutation.SetSeasonNumber(i)
|
ec.mutation.SetSeasonNumber(i)
|
||||||
@@ -50,20 +64,6 @@ func (ec *EpisodeCreate) SetAirDate(s string) *EpisodeCreate {
|
|||||||
return ec
|
return ec
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSeriesID sets the "series" edge to the Series entity by ID.
|
|
||||||
func (ec *EpisodeCreate) SetSeriesID(id int) *EpisodeCreate {
|
|
||||||
ec.mutation.SetSeriesID(id)
|
|
||||||
return ec
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNillableSeriesID sets the "series" edge to the Series entity by ID if the given value is not nil.
|
|
||||||
func (ec *EpisodeCreate) SetNillableSeriesID(id *int) *EpisodeCreate {
|
|
||||||
if id != nil {
|
|
||||||
ec = ec.SetSeriesID(*id)
|
|
||||||
}
|
|
||||||
return ec
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSeries sets the "series" edge to the Series entity.
|
// SetSeries sets the "series" edge to the Series entity.
|
||||||
func (ec *EpisodeCreate) SetSeries(s *Series) *EpisodeCreate {
|
func (ec *EpisodeCreate) SetSeries(s *Series) *EpisodeCreate {
|
||||||
return ec.SetSeriesID(s.ID)
|
return ec.SetSeriesID(s.ID)
|
||||||
@@ -178,7 +178,7 @@ func (ec *EpisodeCreate) createSpec() (*Episode, *sqlgraph.CreateSpec) {
|
|||||||
for _, k := range nodes {
|
for _, k := range nodes {
|
||||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
}
|
}
|
||||||
_node.series_episodes = &nodes[0]
|
_node.SeriesID = nodes[0]
|
||||||
_spec.Edges = append(_spec.Edges, edge)
|
_spec.Edges = append(_spec.Edges, edge)
|
||||||
}
|
}
|
||||||
return _node, _spec
|
return _node, _spec
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ type EpisodeQuery struct {
|
|||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.Episode
|
predicates []predicate.Episode
|
||||||
withSeries *SeriesQuery
|
withSeries *SeriesQuery
|
||||||
withFKs bool
|
|
||||||
// intermediate query (i.e. traversal path).
|
// intermediate query (i.e. traversal path).
|
||||||
sql *sql.Selector
|
sql *sql.Selector
|
||||||
path func(context.Context) (*sql.Selector, error)
|
path func(context.Context) (*sql.Selector, error)
|
||||||
@@ -298,12 +297,12 @@ func (eq *EpisodeQuery) WithSeries(opts ...func(*SeriesQuery)) *EpisodeQuery {
|
|||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// var v []struct {
|
// var v []struct {
|
||||||
// SeasonNumber int `json:"season_number,omitempty"`
|
// SeriesID int `json:"series_id,omitempty"`
|
||||||
// Count int `json:"count,omitempty"`
|
// Count int `json:"count,omitempty"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// client.Episode.Query().
|
// client.Episode.Query().
|
||||||
// GroupBy(episode.FieldSeasonNumber).
|
// GroupBy(episode.FieldSeriesID).
|
||||||
// Aggregate(ent.Count()).
|
// Aggregate(ent.Count()).
|
||||||
// Scan(ctx, &v)
|
// Scan(ctx, &v)
|
||||||
func (eq *EpisodeQuery) GroupBy(field string, fields ...string) *EpisodeGroupBy {
|
func (eq *EpisodeQuery) GroupBy(field string, fields ...string) *EpisodeGroupBy {
|
||||||
@@ -321,11 +320,11 @@ func (eq *EpisodeQuery) GroupBy(field string, fields ...string) *EpisodeGroupBy
|
|||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// var v []struct {
|
// var v []struct {
|
||||||
// SeasonNumber int `json:"season_number,omitempty"`
|
// SeriesID int `json:"series_id,omitempty"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// client.Episode.Query().
|
// client.Episode.Query().
|
||||||
// Select(episode.FieldSeasonNumber).
|
// Select(episode.FieldSeriesID).
|
||||||
// Scan(ctx, &v)
|
// Scan(ctx, &v)
|
||||||
func (eq *EpisodeQuery) Select(fields ...string) *EpisodeSelect {
|
func (eq *EpisodeQuery) Select(fields ...string) *EpisodeSelect {
|
||||||
eq.ctx.Fields = append(eq.ctx.Fields, fields...)
|
eq.ctx.Fields = append(eq.ctx.Fields, fields...)
|
||||||
@@ -369,18 +368,11 @@ func (eq *EpisodeQuery) prepareQuery(ctx context.Context) error {
|
|||||||
func (eq *EpisodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Episode, error) {
|
func (eq *EpisodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Episode, error) {
|
||||||
var (
|
var (
|
||||||
nodes = []*Episode{}
|
nodes = []*Episode{}
|
||||||
withFKs = eq.withFKs
|
|
||||||
_spec = eq.querySpec()
|
_spec = eq.querySpec()
|
||||||
loadedTypes = [1]bool{
|
loadedTypes = [1]bool{
|
||||||
eq.withSeries != nil,
|
eq.withSeries != nil,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if eq.withSeries != nil {
|
|
||||||
withFKs = true
|
|
||||||
}
|
|
||||||
if withFKs {
|
|
||||||
_spec.Node.Columns = append(_spec.Node.Columns, episode.ForeignKeys...)
|
|
||||||
}
|
|
||||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||||
return (*Episode).scanValues(nil, columns)
|
return (*Episode).scanValues(nil, columns)
|
||||||
}
|
}
|
||||||
@@ -412,10 +404,7 @@ func (eq *EpisodeQuery) loadSeries(ctx context.Context, query *SeriesQuery, node
|
|||||||
ids := make([]int, 0, len(nodes))
|
ids := make([]int, 0, len(nodes))
|
||||||
nodeids := make(map[int][]*Episode)
|
nodeids := make(map[int][]*Episode)
|
||||||
for i := range nodes {
|
for i := range nodes {
|
||||||
if nodes[i].series_episodes == nil {
|
fk := nodes[i].SeriesID
|
||||||
continue
|
|
||||||
}
|
|
||||||
fk := *nodes[i].series_episodes
|
|
||||||
if _, ok := nodeids[fk]; !ok {
|
if _, ok := nodeids[fk]; !ok {
|
||||||
ids = append(ids, fk)
|
ids = append(ids, fk)
|
||||||
}
|
}
|
||||||
@@ -432,7 +421,7 @@ func (eq *EpisodeQuery) loadSeries(ctx context.Context, query *SeriesQuery, node
|
|||||||
for _, n := range neighbors {
|
for _, n := range neighbors {
|
||||||
nodes, ok := nodeids[n.ID]
|
nodes, ok := nodeids[n.ID]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected foreign-key "series_episodes" returned %v`, n.ID)
|
return fmt.Errorf(`unexpected foreign-key "series_id" returned %v`, n.ID)
|
||||||
}
|
}
|
||||||
for i := range nodes {
|
for i := range nodes {
|
||||||
assign(nodes[i], n)
|
assign(nodes[i], n)
|
||||||
@@ -466,6 +455,9 @@ func (eq *EpisodeQuery) querySpec() *sqlgraph.QuerySpec {
|
|||||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if eq.withSeries != nil {
|
||||||
|
_spec.Node.AddColumnOnce(episode.FieldSeriesID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ps := eq.predicates; len(ps) > 0 {
|
if ps := eq.predicates; len(ps) > 0 {
|
||||||
_spec.Predicate = func(selector *sql.Selector) {
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
|||||||
@@ -28,6 +28,26 @@ func (eu *EpisodeUpdate) Where(ps ...predicate.Episode) *EpisodeUpdate {
|
|||||||
return eu
|
return eu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSeriesID sets the "series_id" field.
|
||||||
|
func (eu *EpisodeUpdate) SetSeriesID(i int) *EpisodeUpdate {
|
||||||
|
eu.mutation.SetSeriesID(i)
|
||||||
|
return eu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableSeriesID sets the "series_id" field if the given value is not nil.
|
||||||
|
func (eu *EpisodeUpdate) SetNillableSeriesID(i *int) *EpisodeUpdate {
|
||||||
|
if i != nil {
|
||||||
|
eu.SetSeriesID(*i)
|
||||||
|
}
|
||||||
|
return eu
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearSeriesID clears the value of the "series_id" field.
|
||||||
|
func (eu *EpisodeUpdate) ClearSeriesID() *EpisodeUpdate {
|
||||||
|
eu.mutation.ClearSeriesID()
|
||||||
|
return eu
|
||||||
|
}
|
||||||
|
|
||||||
// SetSeasonNumber sets the "season_number" field.
|
// SetSeasonNumber sets the "season_number" field.
|
||||||
func (eu *EpisodeUpdate) SetSeasonNumber(i int) *EpisodeUpdate {
|
func (eu *EpisodeUpdate) SetSeasonNumber(i int) *EpisodeUpdate {
|
||||||
eu.mutation.ResetSeasonNumber()
|
eu.mutation.ResetSeasonNumber()
|
||||||
@@ -112,20 +132,6 @@ func (eu *EpisodeUpdate) SetNillableAirDate(s *string) *EpisodeUpdate {
|
|||||||
return eu
|
return eu
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSeriesID sets the "series" edge to the Series entity by ID.
|
|
||||||
func (eu *EpisodeUpdate) SetSeriesID(id int) *EpisodeUpdate {
|
|
||||||
eu.mutation.SetSeriesID(id)
|
|
||||||
return eu
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNillableSeriesID sets the "series" edge to the Series entity by ID if the given value is not nil.
|
|
||||||
func (eu *EpisodeUpdate) SetNillableSeriesID(id *int) *EpisodeUpdate {
|
|
||||||
if id != nil {
|
|
||||||
eu = eu.SetSeriesID(*id)
|
|
||||||
}
|
|
||||||
return eu
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSeries sets the "series" edge to the Series entity.
|
// SetSeries sets the "series" edge to the Series entity.
|
||||||
func (eu *EpisodeUpdate) SetSeries(s *Series) *EpisodeUpdate {
|
func (eu *EpisodeUpdate) SetSeries(s *Series) *EpisodeUpdate {
|
||||||
return eu.SetSeriesID(s.ID)
|
return eu.SetSeriesID(s.ID)
|
||||||
@@ -248,6 +254,26 @@ type EpisodeUpdateOne struct {
|
|||||||
mutation *EpisodeMutation
|
mutation *EpisodeMutation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSeriesID sets the "series_id" field.
|
||||||
|
func (euo *EpisodeUpdateOne) SetSeriesID(i int) *EpisodeUpdateOne {
|
||||||
|
euo.mutation.SetSeriesID(i)
|
||||||
|
return euo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableSeriesID sets the "series_id" field if the given value is not nil.
|
||||||
|
func (euo *EpisodeUpdateOne) SetNillableSeriesID(i *int) *EpisodeUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
euo.SetSeriesID(*i)
|
||||||
|
}
|
||||||
|
return euo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearSeriesID clears the value of the "series_id" field.
|
||||||
|
func (euo *EpisodeUpdateOne) ClearSeriesID() *EpisodeUpdateOne {
|
||||||
|
euo.mutation.ClearSeriesID()
|
||||||
|
return euo
|
||||||
|
}
|
||||||
|
|
||||||
// SetSeasonNumber sets the "season_number" field.
|
// SetSeasonNumber sets the "season_number" field.
|
||||||
func (euo *EpisodeUpdateOne) SetSeasonNumber(i int) *EpisodeUpdateOne {
|
func (euo *EpisodeUpdateOne) SetSeasonNumber(i int) *EpisodeUpdateOne {
|
||||||
euo.mutation.ResetSeasonNumber()
|
euo.mutation.ResetSeasonNumber()
|
||||||
@@ -332,20 +358,6 @@ func (euo *EpisodeUpdateOne) SetNillableAirDate(s *string) *EpisodeUpdateOne {
|
|||||||
return euo
|
return euo
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSeriesID sets the "series" edge to the Series entity by ID.
|
|
||||||
func (euo *EpisodeUpdateOne) SetSeriesID(id int) *EpisodeUpdateOne {
|
|
||||||
euo.mutation.SetSeriesID(id)
|
|
||||||
return euo
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNillableSeriesID sets the "series" edge to the Series entity by ID if the given value is not nil.
|
|
||||||
func (euo *EpisodeUpdateOne) SetNillableSeriesID(id *int) *EpisodeUpdateOne {
|
|
||||||
if id != nil {
|
|
||||||
euo = euo.SetSeriesID(*id)
|
|
||||||
}
|
|
||||||
return euo
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSeries sets the "series" edge to the Series entity.
|
// SetSeries sets the "series" edge to the Series entity.
|
||||||
func (euo *EpisodeUpdateOne) SetSeries(s *Series) *EpisodeUpdateOne {
|
func (euo *EpisodeUpdateOne) SetSeries(s *Series) *EpisodeUpdateOne {
|
||||||
return euo.SetSeriesID(s.ID)
|
return euo.SetSeriesID(s.ID)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ var (
|
|||||||
{Name: "title", Type: field.TypeString},
|
{Name: "title", Type: field.TypeString},
|
||||||
{Name: "overview", Type: field.TypeString},
|
{Name: "overview", Type: field.TypeString},
|
||||||
{Name: "air_date", Type: field.TypeString},
|
{Name: "air_date", Type: field.TypeString},
|
||||||
{Name: "series_episodes", Type: field.TypeInt, Nullable: true},
|
{Name: "series_id", Type: field.TypeInt, Nullable: true},
|
||||||
}
|
}
|
||||||
// EpisodesTable holds the schema information for the "episodes" table.
|
// EpisodesTable holds the schema information for the "episodes" table.
|
||||||
EpisodesTable = &schema.Table{
|
EpisodesTable = &schema.Table{
|
||||||
|
|||||||
@@ -1022,6 +1022,55 @@ func (m *EpisodeMutation) IDs(ctx context.Context) ([]int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSeriesID sets the "series_id" field.
|
||||||
|
func (m *EpisodeMutation) SetSeriesID(i int) {
|
||||||
|
m.series = &i
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesID returns the value of the "series_id" field in the mutation.
|
||||||
|
func (m *EpisodeMutation) SeriesID() (r int, exists bool) {
|
||||||
|
v := m.series
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldSeriesID returns the old "series_id" 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) OldSeriesID(ctx context.Context) (v int, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldSeriesID is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldSeriesID requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldSeriesID: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.SeriesID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearSeriesID clears the value of the "series_id" field.
|
||||||
|
func (m *EpisodeMutation) ClearSeriesID() {
|
||||||
|
m.series = nil
|
||||||
|
m.clearedFields[episode.FieldSeriesID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeriesIDCleared returns if the "series_id" field was cleared in this mutation.
|
||||||
|
func (m *EpisodeMutation) SeriesIDCleared() bool {
|
||||||
|
_, ok := m.clearedFields[episode.FieldSeriesID]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSeriesID resets all changes to the "series_id" field.
|
||||||
|
func (m *EpisodeMutation) ResetSeriesID() {
|
||||||
|
m.series = nil
|
||||||
|
delete(m.clearedFields, episode.FieldSeriesID)
|
||||||
|
}
|
||||||
|
|
||||||
// SetSeasonNumber sets the "season_number" field.
|
// SetSeasonNumber sets the "season_number" field.
|
||||||
func (m *EpisodeMutation) SetSeasonNumber(i int) {
|
func (m *EpisodeMutation) SetSeasonNumber(i int) {
|
||||||
m.season_number = &i
|
m.season_number = &i
|
||||||
@@ -1242,27 +1291,15 @@ func (m *EpisodeMutation) ResetAirDate() {
|
|||||||
m.air_date = nil
|
m.air_date = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSeriesID sets the "series" edge to the Series entity by id.
|
|
||||||
func (m *EpisodeMutation) SetSeriesID(id int) {
|
|
||||||
m.series = &id
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearSeries clears the "series" edge to the Series entity.
|
// ClearSeries clears the "series" edge to the Series entity.
|
||||||
func (m *EpisodeMutation) ClearSeries() {
|
func (m *EpisodeMutation) ClearSeries() {
|
||||||
m.clearedseries = true
|
m.clearedseries = true
|
||||||
|
m.clearedFields[episode.FieldSeriesID] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeriesCleared reports if the "series" edge to the Series entity was cleared.
|
// SeriesCleared reports if the "series" edge to the Series entity was cleared.
|
||||||
func (m *EpisodeMutation) SeriesCleared() bool {
|
func (m *EpisodeMutation) SeriesCleared() bool {
|
||||||
return m.clearedseries
|
return m.SeriesIDCleared() || m.clearedseries
|
||||||
}
|
|
||||||
|
|
||||||
// SeriesID returns the "series" edge ID in the mutation.
|
|
||||||
func (m *EpisodeMutation) SeriesID() (id int, exists bool) {
|
|
||||||
if m.series != nil {
|
|
||||||
return *m.series, true
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeriesIDs returns the "series" edge IDs in the mutation.
|
// SeriesIDs returns the "series" edge IDs in the mutation.
|
||||||
@@ -1315,7 +1352,10 @@ func (m *EpisodeMutation) Type() string {
|
|||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *EpisodeMutation) Fields() []string {
|
func (m *EpisodeMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 5)
|
fields := make([]string, 0, 6)
|
||||||
|
if m.series != nil {
|
||||||
|
fields = append(fields, episode.FieldSeriesID)
|
||||||
|
}
|
||||||
if m.season_number != nil {
|
if m.season_number != nil {
|
||||||
fields = append(fields, episode.FieldSeasonNumber)
|
fields = append(fields, episode.FieldSeasonNumber)
|
||||||
}
|
}
|
||||||
@@ -1339,6 +1379,8 @@ func (m *EpisodeMutation) Fields() []string {
|
|||||||
// schema.
|
// schema.
|
||||||
func (m *EpisodeMutation) Field(name string) (ent.Value, bool) {
|
func (m *EpisodeMutation) Field(name string) (ent.Value, bool) {
|
||||||
switch name {
|
switch name {
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
return m.SeriesID()
|
||||||
case episode.FieldSeasonNumber:
|
case episode.FieldSeasonNumber:
|
||||||
return m.SeasonNumber()
|
return m.SeasonNumber()
|
||||||
case episode.FieldEpisodeNumber:
|
case episode.FieldEpisodeNumber:
|
||||||
@@ -1358,6 +1400,8 @@ func (m *EpisodeMutation) Field(name string) (ent.Value, bool) {
|
|||||||
// database failed.
|
// database failed.
|
||||||
func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
||||||
switch name {
|
switch name {
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
return m.OldSeriesID(ctx)
|
||||||
case episode.FieldSeasonNumber:
|
case episode.FieldSeasonNumber:
|
||||||
return m.OldSeasonNumber(ctx)
|
return m.OldSeasonNumber(ctx)
|
||||||
case episode.FieldEpisodeNumber:
|
case episode.FieldEpisodeNumber:
|
||||||
@@ -1377,6 +1421,13 @@ func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value,
|
|||||||
// type.
|
// type.
|
||||||
func (m *EpisodeMutation) SetField(name string, value ent.Value) error {
|
func (m *EpisodeMutation) SetField(name string, value ent.Value) error {
|
||||||
switch name {
|
switch name {
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
v, ok := value.(int)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetSeriesID(v)
|
||||||
|
return nil
|
||||||
case episode.FieldSeasonNumber:
|
case episode.FieldSeasonNumber:
|
||||||
v, ok := value.(int)
|
v, ok := value.(int)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -1468,7 +1519,11 @@ func (m *EpisodeMutation) AddField(name string, value ent.Value) error {
|
|||||||
// ClearedFields returns all nullable fields that were cleared during this
|
// ClearedFields returns all nullable fields that were cleared during this
|
||||||
// mutation.
|
// mutation.
|
||||||
func (m *EpisodeMutation) ClearedFields() []string {
|
func (m *EpisodeMutation) ClearedFields() []string {
|
||||||
return nil
|
var fields []string
|
||||||
|
if m.FieldCleared(episode.FieldSeriesID) {
|
||||||
|
fields = append(fields, episode.FieldSeriesID)
|
||||||
|
}
|
||||||
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldCleared returns a boolean indicating if a field with the given name was
|
// FieldCleared returns a boolean indicating if a field with the given name was
|
||||||
@@ -1481,6 +1536,11 @@ func (m *EpisodeMutation) FieldCleared(name string) bool {
|
|||||||
// ClearField clears the value of the field with the given name. It returns an
|
// ClearField clears the value of the field with the given name. It returns an
|
||||||
// error if the field is not defined in the schema.
|
// error if the field is not defined in the schema.
|
||||||
func (m *EpisodeMutation) ClearField(name string) error {
|
func (m *EpisodeMutation) ClearField(name string) error {
|
||||||
|
switch name {
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
m.ClearSeriesID()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return fmt.Errorf("unknown Episode nullable field %s", name)
|
return fmt.Errorf("unknown Episode nullable field %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,6 +1548,9 @@ func (m *EpisodeMutation) ClearField(name string) error {
|
|||||||
// It returns an error if the field is not defined in the schema.
|
// It returns an error if the field is not defined in the schema.
|
||||||
func (m *EpisodeMutation) ResetField(name string) error {
|
func (m *EpisodeMutation) ResetField(name string) error {
|
||||||
switch name {
|
switch name {
|
||||||
|
case episode.FieldSeriesID:
|
||||||
|
m.ResetSeriesID()
|
||||||
|
return nil
|
||||||
case episode.FieldSeasonNumber:
|
case episode.FieldSeasonNumber:
|
||||||
m.ResetSeasonNumber()
|
m.ResetSeasonNumber()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ type Episode struct {
|
|||||||
// Fields of the Episode.
|
// Fields of the Episode.
|
||||||
func (Episode) Fields() []ent.Field {
|
func (Episode) Fields() []ent.Field {
|
||||||
return []ent.Field{
|
return []ent.Field{
|
||||||
//field.Int("series_id"),
|
field.Int("series_id").Optional(),
|
||||||
field.Int("season_number"),
|
field.Int("season_number").StructTag("json:\"season_number\""),
|
||||||
field.Int("episode_number"),
|
field.Int("episode_number"),
|
||||||
field.String("title"),
|
field.String("title"),
|
||||||
field.String("overview"),
|
field.String("overview"),
|
||||||
@@ -28,7 +28,8 @@ func (Episode) Edges() []ent.Edge {
|
|||||||
return []ent.Edge{
|
return []ent.Edge{
|
||||||
edge.From("series", Series.Type).
|
edge.From("series", Series.Type).
|
||||||
Ref("episodes").
|
Ref("episodes").
|
||||||
Unique(),
|
Unique().
|
||||||
|
Field("series_id"),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const (
|
|||||||
// It exists in this package in order to avoid circular dependency with the "episode" package.
|
// It exists in this package in order to avoid circular dependency with the "episode" package.
|
||||||
EpisodesInverseTable = "episodes"
|
EpisodesInverseTable = "episodes"
|
||||||
// EpisodesColumn is the table column denoting the episodes relation/edge.
|
// EpisodesColumn is the table column denoting the episodes relation/edge.
|
||||||
EpisodesColumn = "series_episodes"
|
EpisodesColumn = "series_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Columns holds all SQL columns for series fields.
|
// Columns holds all SQL columns for series fields.
|
||||||
|
|||||||
@@ -412,7 +412,9 @@ func (sq *SeriesQuery) loadEpisodes(ctx context.Context, query *EpisodeQuery, no
|
|||||||
init(nodes[i])
|
init(nodes[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
query.withFKs = true
|
if len(query.ctx.Fields) > 0 {
|
||||||
|
query.ctx.AppendFieldOnce(episode.FieldSeriesID)
|
||||||
|
}
|
||||||
query.Where(predicate.Episode(func(s *sql.Selector) {
|
query.Where(predicate.Episode(func(s *sql.Selector) {
|
||||||
s.Where(sql.InValues(s.C(series.EpisodesColumn), fks...))
|
s.Where(sql.InValues(s.C(series.EpisodesColumn), fks...))
|
||||||
}))
|
}))
|
||||||
@@ -421,13 +423,10 @@ func (sq *SeriesQuery) loadEpisodes(ctx context.Context, query *EpisodeQuery, no
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, n := range neighbors {
|
for _, n := range neighbors {
|
||||||
fk := n.series_episodes
|
fk := n.SeriesID
|
||||||
if fk == nil {
|
node, ok := nodeids[fk]
|
||||||
return fmt.Errorf(`foreign-key "series_episodes" is nil for node %v`, n.ID)
|
|
||||||
}
|
|
||||||
node, ok := nodeids[*fk]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf(`unexpected referenced foreign-key "series_episodes" returned %v for node %v`, *fk, n.ID)
|
return fmt.Errorf(`unexpected referenced foreign-key "series_id" returned %v for node %v`, fk, n.ID)
|
||||||
}
|
}
|
||||||
assign(node, n)
|
assign(node, n)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ func (s *Server) Serve() error {
|
|||||||
tv.GET("/search", HttpHandler(s.SearchTvSeries))
|
tv.GET("/search", HttpHandler(s.SearchTvSeries))
|
||||||
tv.POST("/watchlist", HttpHandler(s.AddWatchlist))
|
tv.POST("/watchlist", HttpHandler(s.AddWatchlist))
|
||||||
tv.GET("/watchlist", HttpHandler(s.GetWatchlist))
|
tv.GET("/watchlist", HttpHandler(s.GetWatchlist))
|
||||||
|
tv.GET("/series/:id", HttpHandler(s.GetTvDetails))
|
||||||
}
|
}
|
||||||
indexer := api.Group("/indexer")
|
indexer := api.Group("/indexer")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"polaris/ent"
|
"polaris/ent"
|
||||||
"polaris/log"
|
"polaris/log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -81,5 +82,11 @@ func (s *Server) GetWatchlist(c *gin.Context) (interface{}, error) {
|
|||||||
|
|
||||||
|
|
||||||
func (s *Server) GetTvDetails(c *gin.Context) (interface{}, error) {
|
func (s *Server) GetTvDetails(c *gin.Context) (interface{}, error) {
|
||||||
return nil, nil
|
ids := c.Param("id")
|
||||||
|
id, err := strconv.Atoi(ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "convert")
|
||||||
|
}
|
||||||
|
detail := s.db.GetSeriesDetails(id)
|
||||||
|
return detail, nil
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ class APIs {
|
|||||||
static const searchUrl = "$_baseUrl/api/v1/tv/search";
|
static const searchUrl = "$_baseUrl/api/v1/tv/search";
|
||||||
static const settingsUrl = "$_baseUrl/api/v1/setting/do";
|
static const settingsUrl = "$_baseUrl/api/v1/setting/do";
|
||||||
static const watchlistUrl = "$_baseUrl/api/v1/tv/watchlist";
|
static const watchlistUrl = "$_baseUrl/api/v1/tv/watchlist";
|
||||||
|
static const seriesDetailUrl = "$_baseUrl/api/v1/tv/series/";
|
||||||
|
|
||||||
static const tmdbImgBaseUrl = "https://image.tmdb.org/t/p/w500/";
|
static const tmdbImgBaseUrl = "https://image.tmdb.org/t/p/w500/";
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:ui/navdrawer.dart';
|
import 'package:ui/navdrawer.dart';
|
||||||
import 'package:ui/search.dart';
|
import 'package:ui/search.dart';
|
||||||
import 'package:ui/system_settings.dart';
|
import 'package:ui/system_settings.dart';
|
||||||
|
import 'package:ui/tv_details.dart';
|
||||||
import 'package:ui/weclome.dart';
|
import 'package:ui/weclome.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -57,6 +58,10 @@ class MyApp extends StatelessWidget {
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: SystemSettingsPage.route,
|
path: SystemSettingsPage.route,
|
||||||
builder: (context, state) => SystemSettingsPage(),
|
builder: (context, state) => SystemSettingsPage(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: TvDetailsPage.route,
|
||||||
|
builder: (context, state) => TvDetailsPage(seriesId: state.pathParameters['id']!),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
|||||||
destinations: const <NavigationRailDestination>[
|
destinations: const <NavigationRailDestination>[
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
icon: Icon(Icons.live_tv),
|
icon: Icon(Icons.live_tv),
|
||||||
label: Text(' 电视剧'),
|
label: Text('电视剧'),
|
||||||
),
|
),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
icon: Icon(Icons.download),
|
icon: Icon(Icons.download),
|
||||||
|
|||||||
@@ -1,24 +1,197 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:ui/APIs.dart';
|
||||||
|
import 'package:ui/server_response.dart';
|
||||||
|
import 'package:ui/utils.dart';
|
||||||
|
|
||||||
class TvDetailsPage extends StatefulWidget {
|
class TvDetailsPage extends StatefulWidget {
|
||||||
@override
|
static const route = "/series/:id";
|
||||||
State<StatefulWidget> createState() {
|
|
||||||
// TODO: implement createState
|
static String toRoute(int id) {
|
||||||
throw UnimplementedError();
|
return "/series/$id";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String seriesId;
|
||||||
|
|
||||||
|
const TvDetailsPage({super.key, required this.seriesId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return _TvDetailsPageState(seriesId: seriesId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TvDetailsPageState extends State<TvDetailsPage> {
|
class _TvDetailsPageState extends State<TvDetailsPage> {
|
||||||
final int tvId = 1;
|
final String seriesId;
|
||||||
|
|
||||||
|
_TvDetailsPageState({required this.seriesId});
|
||||||
|
|
||||||
|
SeriesDetails? details;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// TODO: implement build
|
_querySeriesDetails(context);
|
||||||
throw Column(
|
|
||||||
children: [
|
|
||||||
|
|
||||||
|
if (details == null) {
|
||||||
|
return const Center(
|
||||||
|
child: Text("nothing here"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<int, List<Widget>> m = Map();
|
||||||
|
for (final ep in details!.episodes!) {
|
||||||
|
var w = Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
"第 ${ep.seasonNumber} 季,第 ${ep.episodeNumber} 集:${ep.title}",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (m[ep.seasonNumber] == null) {
|
||||||
|
m[ep.seasonNumber!] = List.empty(growable: true);
|
||||||
|
}
|
||||||
|
m[ep.seasonNumber!]!.add(w);
|
||||||
|
}
|
||||||
|
List<ExpansionTile> list = List.empty(growable: true);
|
||||||
|
for (final k in m.keys) {
|
||||||
|
bool _customTileExpanded = false;
|
||||||
|
var seasonList = ExpansionTile(
|
||||||
|
initiallyExpanded: true,
|
||||||
|
title: Text("第 $k 季"),
|
||||||
|
trailing: Icon(
|
||||||
|
_customTileExpanded
|
||||||
|
? Icons.arrow_drop_down_circle
|
||||||
|
: Icons.arrow_drop_down,
|
||||||
|
),
|
||||||
|
children: m[k]!,
|
||||||
|
onExpansionChanged: (bool expanded) {
|
||||||
|
setState(() {
|
||||||
|
_customTileExpanded = expanded;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
list.add(seasonList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
margin: const EdgeInsets.all(4),
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Flexible(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 150,
|
||||||
|
height: 200,
|
||||||
|
child: Image.network(
|
||||||
|
APIs.tmdbImgBaseUrl + details!.posterPath!,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"${details!.name}",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const Text(""),
|
||||||
|
Text(details!.overview!)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
children: list,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _querySeriesDetails(BuildContext context) async {
|
||||||
|
var resp = await Dio().get("${APIs.seriesDetailUrl}$seriesId");
|
||||||
|
var rsp = ServerResponse.fromJson(resp.data);
|
||||||
|
if (rsp.code != 0 && context.mounted) {
|
||||||
|
Utils.showAlertDialog(context, rsp.message);
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
details = SeriesDetails.fromJson(rsp.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SeriesDetails {
|
||||||
|
int? id;
|
||||||
|
int? tmdbId;
|
||||||
|
String? name;
|
||||||
|
String? originalName;
|
||||||
|
String? overview;
|
||||||
|
String? path;
|
||||||
|
String? posterPath;
|
||||||
|
String? createdAt;
|
||||||
|
List<Episodes>? episodes;
|
||||||
|
|
||||||
|
SeriesDetails(
|
||||||
|
{this.id,
|
||||||
|
this.tmdbId,
|
||||||
|
this.name,
|
||||||
|
this.originalName,
|
||||||
|
this.overview,
|
||||||
|
this.path,
|
||||||
|
this.posterPath,
|
||||||
|
this.createdAt,
|
||||||
|
this.episodes});
|
||||||
|
|
||||||
|
SeriesDetails.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
tmdbId = json['tmdb_id'];
|
||||||
|
name = json['name'];
|
||||||
|
originalName = json['original_name'];
|
||||||
|
overview = json['overview'];
|
||||||
|
path = json['path'];
|
||||||
|
posterPath = json['poster_path'];
|
||||||
|
createdAt = json['created_at'];
|
||||||
|
if (json['episodes'] != null) {
|
||||||
|
episodes = <Episodes>[];
|
||||||
|
json['episodes'].forEach((v) {
|
||||||
|
episodes!.add(Episodes.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Episodes {
|
||||||
|
int? id;
|
||||||
|
int? seriesId;
|
||||||
|
int? episodeNumber;
|
||||||
|
String? title;
|
||||||
|
String? airDate;
|
||||||
|
int? seasonNumber;
|
||||||
|
String? overview;
|
||||||
|
|
||||||
|
Episodes(
|
||||||
|
{this.id,
|
||||||
|
this.seriesId,
|
||||||
|
this.episodeNumber,
|
||||||
|
this.title,
|
||||||
|
this.airDate,
|
||||||
|
this.seasonNumber,
|
||||||
|
this.overview});
|
||||||
|
|
||||||
|
Episodes.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
seriesId = json['series_id'];
|
||||||
|
episodeNumber = json['episode_number'];
|
||||||
|
title = json['title'];
|
||||||
|
airDate = json['air_date'];
|
||||||
|
seasonNumber = json['season_number'];
|
||||||
|
overview = json['overview'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:ui/APIs.dart';
|
import 'package:ui/APIs.dart';
|
||||||
import 'package:ui/server_response.dart';
|
import 'package:ui/server_response.dart';
|
||||||
|
import 'package:ui/tv_details.dart';
|
||||||
|
|
||||||
class WelcomePage extends StatefulWidget {
|
class WelcomePage extends StatefulWidget {
|
||||||
const WelcomePage({super.key});
|
const WelcomePage({super.key});
|
||||||
@@ -20,44 +22,45 @@ class _WeclomePageState extends State<WelcomePage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_onRefresh();
|
_onRefresh();
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
itemCount: favList.length,
|
itemCount: favList.length,
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate:
|
||||||
crossAxisCount: 4),
|
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
var item = TvSeries.fromJson(favList[i]);
|
var item = TvSeries.fromJson(favList[i]);
|
||||||
return Container(
|
return Container(
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(4),
|
margin: const EdgeInsets.all(4),
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
//splashColor: Colors.blue.withAlpha(30),
|
//splashColor: Colors.blue.withAlpha(30),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
//showDialog(context: context, builder: builder)
|
context.go(TvDetailsPage.toRoute(item.id!));
|
||||||
},
|
//showDialog(context: context, builder: builder)
|
||||||
child: Column(
|
},
|
||||||
children: <Widget>[
|
child: Column(
|
||||||
Flexible(
|
children: <Widget>[
|
||||||
child: SizedBox(
|
Flexible(
|
||||||
width: 300,
|
child: SizedBox(
|
||||||
height: 600,
|
width: 300,
|
||||||
child: Image.network(
|
height: 600,
|
||||||
APIs.tmdbImgBaseUrl + item.posterPath!,
|
child: Image.network(
|
||||||
fit: BoxFit.contain,
|
APIs.tmdbImgBaseUrl + item.posterPath!,
|
||||||
),
|
fit: BoxFit.contain,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Flexible(
|
),
|
||||||
child: Text(
|
|
||||||
item.name!,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
)),
|
Flexible(
|
||||||
);
|
child: Text(
|
||||||
});
|
item.name!,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRefresh() async {
|
Future<void> _onRefresh() async {
|
||||||
|
|||||||
Reference in New Issue
Block a user