mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Multiple scene URLs (#3852)
* Add URLs scene relationship * Update unit tests * Update scene edit and details pages * Update scrapers to use urls * Post-process scenes during query scrape * Update UI for URLs * Change urls label
This commit is contained in:
@@ -39,10 +39,12 @@ type SceneMovie struct {
|
||||
}
|
||||
|
||||
type Scene struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Studio string `json:"studio,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Studio string `json:"studio,omitempty"`
|
||||
// deprecated - for import only
|
||||
URL string `json:"url,omitempty"`
|
||||
URLs []string `json:"urls,omitempty"`
|
||||
Date string `json:"date,omitempty"`
|
||||
Rating int `json:"rating,omitempty"`
|
||||
Organized bool `json:"organized,omitempty"`
|
||||
|
||||
@@ -624,6 +624,29 @@ func (_m *SceneReaderWriter) GetTagIDs(ctx context.Context, relatedID int) ([]in
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetURLs provides a mock function with given fields: ctx, relatedID
|
||||
func (_m *SceneReaderWriter) GetURLs(ctx context.Context, relatedID int) ([]string, error) {
|
||||
ret := _m.Called(ctx, relatedID)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int) []string); ok {
|
||||
r0 = rf(ctx, relatedID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int) error); ok {
|
||||
r1 = rf(ctx, relatedID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// HasCover provides a mock function with given fields: ctx, sceneID
|
||||
func (_m *SceneReaderWriter) HasCover(ctx context.Context, sceneID int) (bool, error) {
|
||||
ret := _m.Called(ctx, sceneID)
|
||||
|
||||
@@ -17,7 +17,6 @@ type Scene struct {
|
||||
Code string `json:"code"`
|
||||
Details string `json:"details"`
|
||||
Director string `json:"director"`
|
||||
URL string `json:"url"`
|
||||
Date *Date `json:"date"`
|
||||
// Rating expressed in 1-100 scale
|
||||
Rating *int `json:"rating"`
|
||||
@@ -43,6 +42,7 @@ type Scene struct {
|
||||
PlayDuration float64 `json:"play_duration"`
|
||||
PlayCount int `json:"play_count"`
|
||||
|
||||
URLs RelatedStrings `json:"urls"`
|
||||
GalleryIDs RelatedIDs `json:"gallery_ids"`
|
||||
TagIDs RelatedIDs `json:"tag_ids"`
|
||||
PerformerIDs RelatedIDs `json:"performer_ids"`
|
||||
@@ -50,6 +50,12 @@ type Scene struct {
|
||||
StashIDs RelatedStashIDs `json:"stash_ids"`
|
||||
}
|
||||
|
||||
func (s *Scene) LoadURLs(ctx context.Context, l URLLoader) error {
|
||||
return s.URLs.load(func() ([]string, error) {
|
||||
return l.GetURLs(ctx, s.ID)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Scene) LoadFiles(ctx context.Context, l VideoFileLoader) error {
|
||||
return s.Files.load(func() ([]*file.VideoFile, error) {
|
||||
return l.GetFiles(ctx, s.ID)
|
||||
@@ -110,6 +116,10 @@ func (s *Scene) LoadStashIDs(ctx context.Context, l StashIDLoader) error {
|
||||
}
|
||||
|
||||
func (s *Scene) LoadRelationships(ctx context.Context, l SceneReader) error {
|
||||
if err := s.LoadURLs(ctx, l); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.LoadGalleryIDs(ctx, l); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -144,7 +154,6 @@ type ScenePartial struct {
|
||||
Code OptionalString
|
||||
Details OptionalString
|
||||
Director OptionalString
|
||||
URL OptionalString
|
||||
Date OptionalDate
|
||||
// Rating expressed in 1-100 scale
|
||||
Rating OptionalInt
|
||||
@@ -158,6 +167,7 @@ type ScenePartial struct {
|
||||
PlayCount OptionalInt
|
||||
LastPlayedAt OptionalTime
|
||||
|
||||
URLs *UpdateStrings
|
||||
GalleryIDs *UpdateIDs
|
||||
TagIDs *UpdateIDs
|
||||
PerformerIDs *UpdateIDs
|
||||
@@ -193,6 +203,7 @@ type SceneUpdateInput struct {
|
||||
Rating100 *int `json:"rating100"`
|
||||
OCounter *int `json:"o_counter"`
|
||||
Organized *bool `json:"organized"`
|
||||
Urls []string `json:"urls"`
|
||||
StudioID *string `json:"studio_id"`
|
||||
GalleryIds []string `json:"gallery_ids"`
|
||||
PerformerIds []string `json:"performer_ids"`
|
||||
@@ -227,7 +238,7 @@ func (s ScenePartial) UpdateInput(id int) SceneUpdateInput {
|
||||
Code: s.Code.Ptr(),
|
||||
Details: s.Details.Ptr(),
|
||||
Director: s.Director.Ptr(),
|
||||
URL: s.URL.Ptr(),
|
||||
Urls: s.URLs.Strings(),
|
||||
Date: dateStr,
|
||||
Rating100: s.Rating.Ptr(),
|
||||
Organized: s.Organized.Ptr(),
|
||||
|
||||
@@ -37,11 +37,14 @@ func TestScenePartial_UpdateInput(t *testing.T) {
|
||||
"full",
|
||||
id,
|
||||
ScenePartial{
|
||||
Title: NewOptionalString(title),
|
||||
Code: NewOptionalString(code),
|
||||
Details: NewOptionalString(details),
|
||||
Director: NewOptionalString(director),
|
||||
URL: NewOptionalString(url),
|
||||
Title: NewOptionalString(title),
|
||||
Code: NewOptionalString(code),
|
||||
Details: NewOptionalString(details),
|
||||
Director: NewOptionalString(director),
|
||||
URLs: &UpdateStrings{
|
||||
Values: []string{url},
|
||||
Mode: RelationshipUpdateModeSet,
|
||||
},
|
||||
Date: NewOptionalDate(dateObj),
|
||||
Rating: NewOptionalInt(rating100),
|
||||
Organized: NewOptionalBool(organized),
|
||||
@@ -53,7 +56,7 @@ func TestScenePartial_UpdateInput(t *testing.T) {
|
||||
Code: &code,
|
||||
Details: &details,
|
||||
Director: &director,
|
||||
URL: &url,
|
||||
Urls: []string{url},
|
||||
Date: &date,
|
||||
Rating: &ratingLegacy,
|
||||
Rating100: &rating100,
|
||||
|
||||
@@ -42,6 +42,10 @@ type AliasLoader interface {
|
||||
GetAliases(ctx context.Context, relatedID int) ([]string, error)
|
||||
}
|
||||
|
||||
type URLLoader interface {
|
||||
GetURLs(ctx context.Context, relatedID int) ([]string, error)
|
||||
}
|
||||
|
||||
// RelatedIDs represents a list of related IDs.
|
||||
// TODO - this can be made generic
|
||||
type RelatedIDs struct {
|
||||
|
||||
@@ -159,6 +159,7 @@ type SceneReader interface {
|
||||
FindByGalleryID(ctx context.Context, performerID int) ([]*Scene, error)
|
||||
FindDuplicates(ctx context.Context, distance int, durationDiff float64) ([][]*Scene, error)
|
||||
|
||||
URLLoader
|
||||
GalleryIDLoader
|
||||
PerformerIDLoader
|
||||
TagIDLoader
|
||||
|
||||
@@ -110,3 +110,11 @@ type UpdateStrings struct {
|
||||
Values []string `json:"values"`
|
||||
Mode RelationshipUpdateMode `json:"mode"`
|
||||
}
|
||||
|
||||
func (u *UpdateStrings) Strings() []string {
|
||||
if u == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return u.Values
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user