mirror of
https://github.com/simon-ding/polaris.git
synced 2026-03-09 19:20:46 +08:00
feat: download movie every 1h
This commit is contained in:
@@ -169,6 +169,16 @@ func EpisodeIDLTE(v int) predicate.History {
|
||||
return predicate.History(sql.FieldLTE(FieldEpisodeID, v))
|
||||
}
|
||||
|
||||
// EpisodeIDIsNil applies the IsNil predicate on the "episode_id" field.
|
||||
func EpisodeIDIsNil() predicate.History {
|
||||
return predicate.History(sql.FieldIsNull(FieldEpisodeID))
|
||||
}
|
||||
|
||||
// EpisodeIDNotNil applies the NotNil predicate on the "episode_id" field.
|
||||
func EpisodeIDNotNil() predicate.History {
|
||||
return predicate.History(sql.FieldNotNull(FieldEpisodeID))
|
||||
}
|
||||
|
||||
// SourceTitleEQ applies the EQ predicate on the "source_title" field.
|
||||
func SourceTitleEQ(v string) predicate.History {
|
||||
return predicate.History(sql.FieldEQ(FieldSourceTitle, v))
|
||||
|
||||
@@ -32,6 +32,14 @@ func (hc *HistoryCreate) SetEpisodeID(i int) *HistoryCreate {
|
||||
return hc
|
||||
}
|
||||
|
||||
// SetNillableEpisodeID sets the "episode_id" field if the given value is not nil.
|
||||
func (hc *HistoryCreate) SetNillableEpisodeID(i *int) *HistoryCreate {
|
||||
if i != nil {
|
||||
hc.SetEpisodeID(*i)
|
||||
}
|
||||
return hc
|
||||
}
|
||||
|
||||
// SetSourceTitle sets the "source_title" field.
|
||||
func (hc *HistoryCreate) SetSourceTitle(s string) *HistoryCreate {
|
||||
hc.mutation.SetSourceTitle(s)
|
||||
@@ -130,9 +138,6 @@ func (hc *HistoryCreate) check() error {
|
||||
if _, ok := hc.mutation.MediaID(); !ok {
|
||||
return &ValidationError{Name: "media_id", err: errors.New(`ent: missing required field "History.media_id"`)}
|
||||
}
|
||||
if _, ok := hc.mutation.EpisodeID(); !ok {
|
||||
return &ValidationError{Name: "episode_id", err: errors.New(`ent: missing required field "History.episode_id"`)}
|
||||
}
|
||||
if _, ok := hc.mutation.SourceTitle(); !ok {
|
||||
return &ValidationError{Name: "source_title", err: errors.New(`ent: missing required field "History.source_title"`)}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,12 @@ func (hu *HistoryUpdate) AddEpisodeID(i int) *HistoryUpdate {
|
||||
return hu
|
||||
}
|
||||
|
||||
// ClearEpisodeID clears the value of the "episode_id" field.
|
||||
func (hu *HistoryUpdate) ClearEpisodeID() *HistoryUpdate {
|
||||
hu.mutation.ClearEpisodeID()
|
||||
return hu
|
||||
}
|
||||
|
||||
// SetSourceTitle sets the "source_title" field.
|
||||
func (hu *HistoryUpdate) SetSourceTitle(s string) *HistoryUpdate {
|
||||
hu.mutation.SetSourceTitle(s)
|
||||
@@ -233,6 +239,9 @@ func (hu *HistoryUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := hu.mutation.AddedEpisodeID(); ok {
|
||||
_spec.AddField(history.FieldEpisodeID, field.TypeInt, value)
|
||||
}
|
||||
if hu.mutation.EpisodeIDCleared() {
|
||||
_spec.ClearField(history.FieldEpisodeID, field.TypeInt)
|
||||
}
|
||||
if value, ok := hu.mutation.SourceTitle(); ok {
|
||||
_spec.SetField(history.FieldSourceTitle, field.TypeString, value)
|
||||
}
|
||||
@@ -319,6 +328,12 @@ func (huo *HistoryUpdateOne) AddEpisodeID(i int) *HistoryUpdateOne {
|
||||
return huo
|
||||
}
|
||||
|
||||
// ClearEpisodeID clears the value of the "episode_id" field.
|
||||
func (huo *HistoryUpdateOne) ClearEpisodeID() *HistoryUpdateOne {
|
||||
huo.mutation.ClearEpisodeID()
|
||||
return huo
|
||||
}
|
||||
|
||||
// SetSourceTitle sets the "source_title" field.
|
||||
func (huo *HistoryUpdateOne) SetSourceTitle(s string) *HistoryUpdateOne {
|
||||
huo.mutation.SetSourceTitle(s)
|
||||
@@ -512,6 +527,9 @@ func (huo *HistoryUpdateOne) sqlSave(ctx context.Context) (_node *History, err e
|
||||
if value, ok := huo.mutation.AddedEpisodeID(); ok {
|
||||
_spec.AddField(history.FieldEpisodeID, field.TypeInt, value)
|
||||
}
|
||||
if huo.mutation.EpisodeIDCleared() {
|
||||
_spec.ClearField(history.FieldEpisodeID, field.TypeInt)
|
||||
}
|
||||
if value, ok := huo.mutation.SourceTitle(); ok {
|
||||
_spec.SetField(history.FieldSourceTitle, field.TypeString, value)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ type Media struct {
|
||||
// AirDate holds the value of the "air_date" field.
|
||||
AirDate string `json:"air_date,omitempty"`
|
||||
// Resolution holds the value of the "resolution" field.
|
||||
Resolution string `json:"resolution,omitempty"`
|
||||
Resolution media.Resolution `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.
|
||||
@@ -155,7 +155,7 @@ func (m *Media) assignValues(columns []string, values []any) error {
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field resolution", values[i])
|
||||
} else if value.Valid {
|
||||
m.Resolution = value.String
|
||||
m.Resolution = media.Resolution(value.String)
|
||||
}
|
||||
case media.FieldStorageID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
@@ -238,7 +238,7 @@ func (m *Media) String() string {
|
||||
builder.WriteString(m.AirDate)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("resolution=")
|
||||
builder.WriteString(m.Resolution)
|
||||
builder.WriteString(fmt.Sprintf("%v", m.Resolution))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("storage_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", m.StorageID))
|
||||
|
||||
@@ -84,8 +84,6 @@ var (
|
||||
DefaultCreatedAt time.Time
|
||||
// DefaultAirDate holds the default value on creation for the "air_date" field.
|
||||
DefaultAirDate string
|
||||
// DefaultResolution holds the default value on creation for the "resolution" field.
|
||||
DefaultResolution string
|
||||
)
|
||||
|
||||
// MediaType defines the type for the "media_type" enum field.
|
||||
@@ -111,6 +109,33 @@ func MediaTypeValidator(mt MediaType) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Resolution defines the type for the "resolution" enum field.
|
||||
type Resolution string
|
||||
|
||||
// Resolution1080p is the default value of the Resolution enum.
|
||||
const DefaultResolution = Resolution1080p
|
||||
|
||||
// Resolution values.
|
||||
const (
|
||||
Resolution720p Resolution = "720p"
|
||||
Resolution1080p Resolution = "1080p"
|
||||
Resolution4k Resolution = "4k"
|
||||
)
|
||||
|
||||
func (r Resolution) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// ResolutionValidator is a validator for the "resolution" field enum values. It is called by the builders before save.
|
||||
func ResolutionValidator(r Resolution) error {
|
||||
switch r {
|
||||
case Resolution720p, Resolution1080p, Resolution4k:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("media: invalid enum value for resolution field: %q", r)
|
||||
}
|
||||
}
|
||||
|
||||
// OrderOption defines the ordering options for the Media queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
|
||||
@@ -95,11 +95,6 @@ func AirDate(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldEQ(FieldAirDate, v))
|
||||
}
|
||||
|
||||
// Resolution applies equality check predicate on the "resolution" field. It's identical to ResolutionEQ.
|
||||
func Resolution(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldEQ(FieldResolution, v))
|
||||
}
|
||||
|
||||
// StorageID applies equality check predicate on the "storage_id" field. It's identical to StorageIDEQ.
|
||||
func StorageID(v int) predicate.Media {
|
||||
return predicate.Media(sql.FieldEQ(FieldStorageID, v))
|
||||
@@ -611,70 +606,25 @@ func AirDateContainsFold(v string) predicate.Media {
|
||||
}
|
||||
|
||||
// ResolutionEQ applies the EQ predicate on the "resolution" field.
|
||||
func ResolutionEQ(v string) predicate.Media {
|
||||
func ResolutionEQ(v Resolution) predicate.Media {
|
||||
return predicate.Media(sql.FieldEQ(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionNEQ applies the NEQ predicate on the "resolution" field.
|
||||
func ResolutionNEQ(v string) predicate.Media {
|
||||
func ResolutionNEQ(v Resolution) predicate.Media {
|
||||
return predicate.Media(sql.FieldNEQ(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionIn applies the In predicate on the "resolution" field.
|
||||
func ResolutionIn(vs ...string) predicate.Media {
|
||||
func ResolutionIn(vs ...Resolution) predicate.Media {
|
||||
return predicate.Media(sql.FieldIn(FieldResolution, vs...))
|
||||
}
|
||||
|
||||
// ResolutionNotIn applies the NotIn predicate on the "resolution" field.
|
||||
func ResolutionNotIn(vs ...string) predicate.Media {
|
||||
func ResolutionNotIn(vs ...Resolution) predicate.Media {
|
||||
return predicate.Media(sql.FieldNotIn(FieldResolution, vs...))
|
||||
}
|
||||
|
||||
// ResolutionGT applies the GT predicate on the "resolution" field.
|
||||
func ResolutionGT(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldGT(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionGTE applies the GTE predicate on the "resolution" field.
|
||||
func ResolutionGTE(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldGTE(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionLT applies the LT predicate on the "resolution" field.
|
||||
func ResolutionLT(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldLT(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionLTE applies the LTE predicate on the "resolution" field.
|
||||
func ResolutionLTE(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldLTE(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionContains applies the Contains predicate on the "resolution" field.
|
||||
func ResolutionContains(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldContains(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionHasPrefix applies the HasPrefix predicate on the "resolution" field.
|
||||
func ResolutionHasPrefix(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldHasPrefix(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionHasSuffix applies the HasSuffix predicate on the "resolution" field.
|
||||
func ResolutionHasSuffix(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldHasSuffix(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionEqualFold applies the EqualFold predicate on the "resolution" field.
|
||||
func ResolutionEqualFold(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldEqualFold(FieldResolution, v))
|
||||
}
|
||||
|
||||
// ResolutionContainsFold applies the ContainsFold predicate on the "resolution" field.
|
||||
func ResolutionContainsFold(v string) predicate.Media {
|
||||
return predicate.Media(sql.FieldContainsFold(FieldResolution, v))
|
||||
}
|
||||
|
||||
// StorageIDEQ applies the EQ predicate on the "storage_id" field.
|
||||
func StorageIDEQ(v int) predicate.Media {
|
||||
return predicate.Media(sql.FieldEQ(FieldStorageID, v))
|
||||
|
||||
@@ -100,15 +100,15 @@ func (mc *MediaCreate) SetNillableAirDate(s *string) *MediaCreate {
|
||||
}
|
||||
|
||||
// SetResolution sets the "resolution" field.
|
||||
func (mc *MediaCreate) SetResolution(s string) *MediaCreate {
|
||||
mc.mutation.SetResolution(s)
|
||||
func (mc *MediaCreate) SetResolution(m media.Resolution) *MediaCreate {
|
||||
mc.mutation.SetResolution(m)
|
||||
return mc
|
||||
}
|
||||
|
||||
// SetNillableResolution sets the "resolution" field if the given value is not nil.
|
||||
func (mc *MediaCreate) SetNillableResolution(s *string) *MediaCreate {
|
||||
if s != nil {
|
||||
mc.SetResolution(*s)
|
||||
func (mc *MediaCreate) SetNillableResolution(m *media.Resolution) *MediaCreate {
|
||||
if m != nil {
|
||||
mc.SetResolution(*m)
|
||||
}
|
||||
return mc
|
||||
}
|
||||
@@ -239,6 +239,11 @@ func (mc *MediaCreate) check() error {
|
||||
if _, ok := mc.mutation.Resolution(); !ok {
|
||||
return &ValidationError{Name: "resolution", err: errors.New(`ent: missing required field "Media.resolution"`)}
|
||||
}
|
||||
if v, ok := mc.mutation.Resolution(); ok {
|
||||
if err := media.ResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "resolution", err: fmt.Errorf(`ent: validator failed for field "Media.resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -302,7 +307,7 @@ func (mc *MediaCreate) createSpec() (*Media, *sqlgraph.CreateSpec) {
|
||||
_node.AirDate = value
|
||||
}
|
||||
if value, ok := mc.mutation.Resolution(); ok {
|
||||
_spec.SetField(media.FieldResolution, field.TypeString, value)
|
||||
_spec.SetField(media.FieldResolution, field.TypeEnum, value)
|
||||
_node.Resolution = value
|
||||
}
|
||||
if value, ok := mc.mutation.StorageID(); ok {
|
||||
|
||||
@@ -169,15 +169,15 @@ func (mu *MediaUpdate) SetNillableAirDate(s *string) *MediaUpdate {
|
||||
}
|
||||
|
||||
// SetResolution sets the "resolution" field.
|
||||
func (mu *MediaUpdate) SetResolution(s string) *MediaUpdate {
|
||||
mu.mutation.SetResolution(s)
|
||||
func (mu *MediaUpdate) SetResolution(m media.Resolution) *MediaUpdate {
|
||||
mu.mutation.SetResolution(m)
|
||||
return mu
|
||||
}
|
||||
|
||||
// SetNillableResolution sets the "resolution" field if the given value is not nil.
|
||||
func (mu *MediaUpdate) SetNillableResolution(s *string) *MediaUpdate {
|
||||
if s != nil {
|
||||
mu.SetResolution(*s)
|
||||
func (mu *MediaUpdate) SetNillableResolution(m *media.Resolution) *MediaUpdate {
|
||||
if m != nil {
|
||||
mu.SetResolution(*m)
|
||||
}
|
||||
return mu
|
||||
}
|
||||
@@ -304,6 +304,11 @@ func (mu *MediaUpdate) check() error {
|
||||
return &ValidationError{Name: "media_type", err: fmt.Errorf(`ent: validator failed for field "Media.media_type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := mu.mutation.Resolution(); ok {
|
||||
if err := media.ResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "resolution", err: fmt.Errorf(`ent: validator failed for field "Media.resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -353,7 +358,7 @@ func (mu *MediaUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec.SetField(media.FieldAirDate, field.TypeString, value)
|
||||
}
|
||||
if value, ok := mu.mutation.Resolution(); ok {
|
||||
_spec.SetField(media.FieldResolution, field.TypeString, value)
|
||||
_spec.SetField(media.FieldResolution, field.TypeEnum, value)
|
||||
}
|
||||
if value, ok := mu.mutation.StorageID(); ok {
|
||||
_spec.SetField(media.FieldStorageID, field.TypeInt, value)
|
||||
@@ -575,15 +580,15 @@ func (muo *MediaUpdateOne) SetNillableAirDate(s *string) *MediaUpdateOne {
|
||||
}
|
||||
|
||||
// SetResolution sets the "resolution" field.
|
||||
func (muo *MediaUpdateOne) SetResolution(s string) *MediaUpdateOne {
|
||||
muo.mutation.SetResolution(s)
|
||||
func (muo *MediaUpdateOne) SetResolution(m media.Resolution) *MediaUpdateOne {
|
||||
muo.mutation.SetResolution(m)
|
||||
return muo
|
||||
}
|
||||
|
||||
// SetNillableResolution sets the "resolution" field if the given value is not nil.
|
||||
func (muo *MediaUpdateOne) SetNillableResolution(s *string) *MediaUpdateOne {
|
||||
if s != nil {
|
||||
muo.SetResolution(*s)
|
||||
func (muo *MediaUpdateOne) SetNillableResolution(m *media.Resolution) *MediaUpdateOne {
|
||||
if m != nil {
|
||||
muo.SetResolution(*m)
|
||||
}
|
||||
return muo
|
||||
}
|
||||
@@ -723,6 +728,11 @@ func (muo *MediaUpdateOne) check() error {
|
||||
return &ValidationError{Name: "media_type", err: fmt.Errorf(`ent: validator failed for field "Media.media_type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := muo.mutation.Resolution(); ok {
|
||||
if err := media.ResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "resolution", err: fmt.Errorf(`ent: validator failed for field "Media.resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -789,7 +799,7 @@ func (muo *MediaUpdateOne) sqlSave(ctx context.Context) (_node *Media, err error
|
||||
_spec.SetField(media.FieldAirDate, field.TypeString, value)
|
||||
}
|
||||
if value, ok := muo.mutation.Resolution(); ok {
|
||||
_spec.SetField(media.FieldResolution, field.TypeString, value)
|
||||
_spec.SetField(media.FieldResolution, field.TypeEnum, value)
|
||||
}
|
||||
if value, ok := muo.mutation.StorageID(); ok {
|
||||
_spec.SetField(media.FieldStorageID, field.TypeInt, value)
|
||||
|
||||
@@ -59,7 +59,7 @@ var (
|
||||
HistoriesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "media_id", Type: field.TypeInt},
|
||||
{Name: "episode_id", Type: field.TypeInt},
|
||||
{Name: "episode_id", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "source_title", Type: field.TypeString},
|
||||
{Name: "date", Type: field.TypeTime},
|
||||
{Name: "target_dir", Type: field.TypeString},
|
||||
@@ -100,7 +100,7 @@ var (
|
||||
{Name: "overview", Type: field.TypeString},
|
||||
{Name: "created_at", Type: field.TypeTime},
|
||||
{Name: "air_date", Type: field.TypeString, Default: ""},
|
||||
{Name: "resolution", Type: field.TypeString, Default: ""},
|
||||
{Name: "resolution", Type: field.TypeEnum, Enums: []string{"720p", "1080p", "4k"}, Default: "1080p"},
|
||||
{Name: "storage_id", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "target_dir", Type: field.TypeString, Nullable: true},
|
||||
}
|
||||
|
||||
@@ -2000,10 +2000,24 @@ func (m *HistoryMutation) AddedEpisodeID() (r int, exists bool) {
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ClearEpisodeID clears the value of the "episode_id" field.
|
||||
func (m *HistoryMutation) ClearEpisodeID() {
|
||||
m.episode_id = nil
|
||||
m.addepisode_id = nil
|
||||
m.clearedFields[history.FieldEpisodeID] = struct{}{}
|
||||
}
|
||||
|
||||
// EpisodeIDCleared returns if the "episode_id" field was cleared in this mutation.
|
||||
func (m *HistoryMutation) EpisodeIDCleared() bool {
|
||||
_, ok := m.clearedFields[history.FieldEpisodeID]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetEpisodeID resets all changes to the "episode_id" field.
|
||||
func (m *HistoryMutation) ResetEpisodeID() {
|
||||
m.episode_id = nil
|
||||
m.addepisode_id = nil
|
||||
delete(m.clearedFields, history.FieldEpisodeID)
|
||||
}
|
||||
|
||||
// SetSourceTitle sets the "source_title" field.
|
||||
@@ -2497,6 +2511,9 @@ func (m *HistoryMutation) AddField(name string, value ent.Value) error {
|
||||
// mutation.
|
||||
func (m *HistoryMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(history.FieldEpisodeID) {
|
||||
fields = append(fields, history.FieldEpisodeID)
|
||||
}
|
||||
if m.FieldCleared(history.FieldSaved) {
|
||||
fields = append(fields, history.FieldSaved)
|
||||
}
|
||||
@@ -2514,6 +2531,9 @@ func (m *HistoryMutation) FieldCleared(name string) bool {
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *HistoryMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case history.FieldEpisodeID:
|
||||
m.ClearEpisodeID()
|
||||
return nil
|
||||
case history.FieldSaved:
|
||||
m.ClearSaved()
|
||||
return nil
|
||||
@@ -3195,7 +3215,7 @@ type MediaMutation struct {
|
||||
overview *string
|
||||
created_at *time.Time
|
||||
air_date *string
|
||||
resolution *string
|
||||
resolution *media.Resolution
|
||||
storage_id *int
|
||||
addstorage_id *int
|
||||
target_dir *string
|
||||
@@ -3664,12 +3684,12 @@ func (m *MediaMutation) ResetAirDate() {
|
||||
}
|
||||
|
||||
// SetResolution sets the "resolution" field.
|
||||
func (m *MediaMutation) SetResolution(s string) {
|
||||
m.resolution = &s
|
||||
func (m *MediaMutation) SetResolution(value media.Resolution) {
|
||||
m.resolution = &value
|
||||
}
|
||||
|
||||
// Resolution returns the value of the "resolution" field in the mutation.
|
||||
func (m *MediaMutation) Resolution() (r string, exists bool) {
|
||||
func (m *MediaMutation) Resolution() (r media.Resolution, exists bool) {
|
||||
v := m.resolution
|
||||
if v == nil {
|
||||
return
|
||||
@@ -3680,7 +3700,7 @@ func (m *MediaMutation) Resolution() (r string, exists bool) {
|
||||
// OldResolution returns the old "resolution" field's value of the Media entity.
|
||||
// If the Media 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 *MediaMutation) OldResolution(ctx context.Context) (v string, err error) {
|
||||
func (m *MediaMutation) OldResolution(ctx context.Context) (v media.Resolution, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldResolution is only allowed on UpdateOne operations")
|
||||
}
|
||||
@@ -4081,7 +4101,7 @@ func (m *MediaMutation) SetField(name string, value ent.Value) error {
|
||||
m.SetAirDate(v)
|
||||
return nil
|
||||
case media.FieldResolution:
|
||||
v, ok := value.(string)
|
||||
v, ok := value.(media.Resolution)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
|
||||
@@ -70,10 +70,6 @@ func init() {
|
||||
mediaDescAirDate := mediaFields[8].Descriptor()
|
||||
// media.DefaultAirDate holds the default value on creation for the air_date field.
|
||||
media.DefaultAirDate = mediaDescAirDate.Default.(string)
|
||||
// mediaDescResolution is the schema descriptor for resolution field.
|
||||
mediaDescResolution := mediaFields[9].Descriptor()
|
||||
// media.DefaultResolution holds the default value on creation for the resolution field.
|
||||
media.DefaultResolution = mediaDescResolution.Default.(string)
|
||||
storageFields := schema.Storage{}.Fields()
|
||||
_ = storageFields
|
||||
// storageDescDeleted is the schema descriptor for deleted field.
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func SearchSeasonPackage(db1 *db.Client, seriesId, seasonNum int) ([]torznab.Result, error) {
|
||||
func SearchSeasonPackage(db1 *db.Client, seriesId, seasonNum int, checkResolution bool) ([]torznab.Result, error) {
|
||||
series := db1.GetMediaDetails(seriesId)
|
||||
if series == nil {
|
||||
return nil, fmt.Errorf("no tv series of id %v", seriesId)
|
||||
@@ -31,8 +31,12 @@ func SearchSeasonPackage(db1 *db.Client, seriesId, seasonNum int) ([]torznab.Res
|
||||
if !isNameAcceptable(r.Name, series.Media, seasonNum, -1) {
|
||||
continue
|
||||
}
|
||||
if checkResolution && IsWantedResolution(r.Name, series.Resolution) {
|
||||
continue
|
||||
}
|
||||
|
||||
filtered = append(filtered, r)
|
||||
|
||||
|
||||
}
|
||||
|
||||
if len(filtered) == 0 {
|
||||
@@ -41,7 +45,7 @@ func SearchSeasonPackage(db1 *db.Client, seriesId, seasonNum int) ([]torznab.Res
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int) ([]torznab.Result, error) {
|
||||
func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int, checkResolution bool) ([]torznab.Result, error) {
|
||||
series := db1.GetMediaDetails(seriesId)
|
||||
if series == nil {
|
||||
return nil, fmt.Errorf("no tv series of id %v", seriesId)
|
||||
@@ -58,6 +62,10 @@ func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int) ([]torzn
|
||||
if !isNameAcceptable(r.Name, series.Media, seasonNum, episodeNum) {
|
||||
continue
|
||||
}
|
||||
if checkResolution && IsWantedResolution(r.Name, series.Resolution) {
|
||||
continue
|
||||
}
|
||||
|
||||
filtered = append(filtered, r)
|
||||
}
|
||||
|
||||
@@ -65,7 +73,7 @@ func SearchEpisode(db1 *db.Client, seriesId, seasonNum, episodeNum int) ([]torzn
|
||||
|
||||
}
|
||||
|
||||
func SearchMovie(db1 *db.Client, movieId int) ([]torznab.Result, error) {
|
||||
func SearchMovie(db1 *db.Client, movieId int, checkResolution bool) ([]torznab.Result, error) {
|
||||
movieDetail := db1.GetMediaDetails(movieId)
|
||||
if movieDetail == nil {
|
||||
return nil, errors.New("no media found of id")
|
||||
@@ -84,6 +92,10 @@ func SearchMovie(db1 *db.Client, movieId int) ([]torznab.Result, error) {
|
||||
if !isNameAcceptable(r.Name, movieDetail.Media, -1, -1) {
|
||||
continue
|
||||
}
|
||||
if checkResolution && IsWantedResolution(r.Name, movieDetail.Resolution) {
|
||||
continue
|
||||
}
|
||||
|
||||
filtered = append(filtered, r)
|
||||
|
||||
}
|
||||
@@ -117,10 +129,6 @@ func searchWithTorznab(db *db.Client, q string) []torznab.Result {
|
||||
}
|
||||
|
||||
func isNameAcceptable(torrentName string, m *ent.Media, seasonNum, episodeNum int) bool {
|
||||
if !utils.ContainsIgnoreCase(torrentName,m.NameCn) && !utils.ContainsIgnoreCase(torrentName,m.NameEn) &&
|
||||
!utils.ContainsIgnoreCase(torrentName,m.OriginalName) {
|
||||
return false
|
||||
}
|
||||
if !utils.IsNameAcceptable(torrentName, m.NameCn) && !utils.IsNameAcceptable(torrentName, m.NameEn) && !utils.IsNameAcceptable(torrentName, m.OriginalName){
|
||||
return false //name not match
|
||||
}
|
||||
@@ -156,4 +164,16 @@ func isNameAcceptable(torrentName string, m *ent.Media, seasonNum, episodeNum in
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsWantedResolution(name string, res media.Resolution) bool {
|
||||
switch res {
|
||||
case media.Resolution720p:
|
||||
return utils.ContainsIgnoreCase(name, "720p")
|
||||
case media.Resolution1080p:
|
||||
return utils.ContainsIgnoreCase(name, "1080p")
|
||||
case media.Resolution4k:
|
||||
return utils.ContainsIgnoreCase(name, "4k") || utils.ContainsIgnoreCase(name, "2160p")
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (s *Server) searchAndDownloadSeasonPackage(seriesId, seasonNum int) (*strin
|
||||
return nil, errors.Wrap(err, "connect transmission")
|
||||
}
|
||||
|
||||
res, err := core.SearchSeasonPackage(s.db, seriesId, seasonNum)
|
||||
res, err := core.SearchSeasonPackage(s.db, seriesId, seasonNum, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -89,7 +89,6 @@ func (s *Server) searchAndDownloadSeasonPackage(seriesId, seasonNum int) (*strin
|
||||
return nil, errors.New("no enough space")
|
||||
}
|
||||
|
||||
|
||||
torrent, err := trc.Download(r1.Magnet, s.db.GetDownloadDir())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "downloading")
|
||||
@@ -139,7 +138,7 @@ func (s *Server) searchAndDownload(seriesId, seasonNum, episodeNum int) (*string
|
||||
return nil, errors.Errorf("no episode of season %d episode %d", seasonNum, episodeNum)
|
||||
}
|
||||
|
||||
res, err := core.SearchEpisode(s.db, seriesId, seasonNum, episodeNum)
|
||||
res, err := core.SearchEpisode(s.db, seriesId, seasonNum, episodeNum, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -179,13 +178,13 @@ type searchAndDownloadIn struct {
|
||||
Episode int `json:"episode"`
|
||||
}
|
||||
|
||||
func (s *Server) SearchAvailableEpisodeResource(c *gin.Context) (interface{}, error) {
|
||||
func (s *Server) SearchAvailableEpisodeResource(c *gin.Context) (interface{}, error) {
|
||||
var in searchAndDownloadIn
|
||||
if err := c.ShouldBindJSON(&in); err != nil {
|
||||
return nil, errors.Wrap(err, "bind json")
|
||||
}
|
||||
log.Infof("search episode resources link: %v", in)
|
||||
res, err := core.SearchEpisode(s.db, in.ID, in.Season, in.Episode)
|
||||
res, err := core.SearchEpisode(s.db, in.ID, in.Season, in.Episode, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "search episode")
|
||||
}
|
||||
@@ -254,7 +253,7 @@ func (s *Server) SearchAvailableMovies(c *gin.Context) (interface{}, error) {
|
||||
return nil, errors.New("no media found of id " + ids)
|
||||
}
|
||||
|
||||
res, err := core.SearchMovie(s.db, id)
|
||||
res, err := core.SearchMovie(s.db, id, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -277,7 +276,7 @@ func (s *Server) SearchAvailableMovies(c *gin.Context) (interface{}, error) {
|
||||
|
||||
type downloadTorrentIn struct {
|
||||
MediaID int `json:"media_id" binding:"required"`
|
||||
Link string `json:"link" binding:"required"`
|
||||
TorznabSearchResult
|
||||
}
|
||||
|
||||
func (s *Server) DownloadMovieTorrent(c *gin.Context) (interface{}, error) {
|
||||
@@ -303,26 +302,23 @@ func (s *Server) DownloadMovieTorrent(c *gin.Context) (interface{}, error) {
|
||||
torrent.Start()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
if !torrent.Exists() {
|
||||
continue
|
||||
}
|
||||
history, err := s.db.SaveHistoryRecord(ent.History{
|
||||
MediaID: media.ID,
|
||||
SourceTitle: torrent.Name(),
|
||||
TargetDir: "./",
|
||||
Status: history.StatusRunning,
|
||||
Size: torrent.Size(),
|
||||
Saved: torrent.Save(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("save history error: %v", err)
|
||||
}
|
||||
|
||||
s.tasks[history.ID] = &Task{Torrent: torrent}
|
||||
|
||||
break
|
||||
ep := media.Episodes[0]
|
||||
history, err := s.db.SaveHistoryRecord(ent.History{
|
||||
MediaID: media.ID,
|
||||
EpisodeID: ep.ID,
|
||||
SourceTitle: media.NameCn,
|
||||
TargetDir: "./",
|
||||
Status: history.StatusRunning,
|
||||
Size: in.Size,
|
||||
Saved: torrent.Save(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("save history error: %v", err)
|
||||
}
|
||||
|
||||
s.tasks[history.ID] = &Task{Torrent: torrent}
|
||||
|
||||
s.db.SetEpisodeStatus(ep.ID, episode.StatusDownloading)
|
||||
}()
|
||||
|
||||
log.Infof("success add %s to download task", media.NameEn)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"polaris/pkg"
|
||||
"polaris/pkg/storage"
|
||||
"polaris/pkg/utils"
|
||||
"polaris/server/core"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -19,6 +20,7 @@ func (s *Server) scheduler() {
|
||||
s.mustAddCron("@every 1m", s.checkTasks)
|
||||
//s.mustAddCron("@every 1h", s.checkAllFiles)
|
||||
s.mustAddCron("@every 1h", s.downloadTvSeries)
|
||||
s.mustAddCron("@every 1h", s.downloadMovie)
|
||||
s.cron.Start()
|
||||
}
|
||||
|
||||
@@ -241,3 +243,58 @@ func (s *Server) downloadTvSeries() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) downloadMovie() {
|
||||
log.Infof("begin check all movie resources")
|
||||
allSeries := s.db.GetMediaWatchlist(media.MediaTypeMovie)
|
||||
|
||||
for _, series := range allSeries {
|
||||
detail := s.db.GetMediaDetails(series.ID)
|
||||
if len(detail.Episodes) == 0 {
|
||||
log.Errorf("no related dummy episode: %v", detail.NameEn)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.downloadMovieSingleEpisode(detail.Episodes[0]); err != nil {
|
||||
log.Errorf("download movie error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) downloadMovieSingleEpisode(ep *ent.Episode) error {
|
||||
trc, err := s.getDownloadClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "connect transmission")
|
||||
}
|
||||
|
||||
res, err := core.SearchMovie(s.db, ep.MediaID, true)
|
||||
if err != nil {
|
||||
|
||||
return errors.Wrap(err, "search movie")
|
||||
}
|
||||
r1 := res[0]
|
||||
log.Infof("begin download torrent resource: %v", r1.Name)
|
||||
torrent, err := trc.Download(r1.Magnet, s.db.GetDownloadDir())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "downloading")
|
||||
}
|
||||
torrent.Start()
|
||||
|
||||
history, err := s.db.SaveHistoryRecord(ent.History{
|
||||
MediaID: ep.MediaID,
|
||||
EpisodeID: ep.ID,
|
||||
SourceTitle: r1.Name,
|
||||
TargetDir: "./",
|
||||
Status: history.StatusRunning,
|
||||
Size: r1.Size,
|
||||
Saved: torrent.Save(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("save history error: %v", err)
|
||||
}
|
||||
|
||||
s.tasks[history.ID] = &Task{Torrent: torrent}
|
||||
|
||||
s.db.SetEpisodeStatus(ep.ID, episode.StatusDownloading)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func (s *Server) AddTv2Watchlist(c *gin.Context) (interface{}, error) {
|
||||
OriginalName: detail.OriginalName,
|
||||
Overview: detail.Overview,
|
||||
AirDate: detail.FirstAirDate,
|
||||
Resolution: string(in.Resolution),
|
||||
Resolution: media.Resolution(in.Resolution),
|
||||
StorageID: in.StorageID,
|
||||
TargetDir: in.Folder,
|
||||
}, epIds)
|
||||
@@ -181,7 +181,7 @@ func (s *Server) AddMovie2Watchlist(c *gin.Context) (interface{}, error) {
|
||||
OriginalName: detail.OriginalTitle,
|
||||
Overview: detail.Overview,
|
||||
AirDate: detail.ReleaseDate,
|
||||
Resolution: string(in.Resolution),
|
||||
Resolution: media.Resolution(in.Resolution),
|
||||
StorageID: in.StorageID,
|
||||
TargetDir: "./",
|
||||
}, []int{epid})
|
||||
|
||||
Reference in New Issue
Block a user