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:
WithoutPants
2023-07-12 11:51:52 +10:00
committed by GitHub
parent 76a4bfa49a
commit 67d4f9729a
50 changed files with 978 additions and 205 deletions

View File

@@ -10,7 +10,7 @@ import (
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/scene"
"github.com/stashapp/stash/pkg/scraper"
"github.com/stashapp/stash/pkg/sliceutil/intslice"
"github.com/stashapp/stash/pkg/sliceutil"
"github.com/stashapp/stash/pkg/txn"
"github.com/stashapp/stash/pkg/utils"
)
@@ -226,7 +226,7 @@ func (t *SceneIdentifier) getSceneUpdater(ctx context.Context, s *models.Scene,
return nil, fmt.Errorf("error converting tag ID %s: %w", *options.SkipSingleNamePerformerTag, err)
}
tagIDs = intslice.IntAppendUnique(tagIDs, int(tagID))
tagIDs = sliceutil.AppendUnique(tagIDs, int(tagID))
}
if tagIDs != nil {
ret.Partial.TagIDs = &models.UpdateIDs{
@@ -260,6 +260,9 @@ func (t *SceneIdentifier) modifyScene(ctx context.Context, txnManager txn.Manage
var updater *scene.UpdateSet
if err := txn.WithTxn(ctx, txnManager, func(ctx context.Context) error {
// load scene relationships
if err := s.LoadURLs(ctx, t.SceneReaderUpdater); err != nil {
return err
}
if err := s.LoadPerformerIDs(ctx, t.SceneReaderUpdater); err != nil {
return err
}
@@ -320,7 +323,7 @@ func (t *SceneIdentifier) addTagToScene(ctx context.Context, txnManager txn.Mana
}
existing := s.TagIDs.List()
if intslice.IntInclude(existing, tagID) {
if sliceutil.Include(existing, tagID) {
// skip if the scene was already tagged
return nil
}
@@ -376,9 +379,27 @@ func getScenePartial(scene *models.Scene, scraped *scraper.ScrapedScene, fieldOp
partial.Details = models.NewOptionalString(*scraped.Details)
}
}
if scraped.URL != nil && (scene.URL != *scraped.URL) {
if shouldSetSingleValueField(fieldOptions["url"], scene.URL != "") {
partial.URL = models.NewOptionalString(*scraped.URL)
if len(scraped.URLs) > 0 && shouldSetSingleValueField(fieldOptions["url"], false) {
// if overwrite, then set over the top
switch getFieldStrategy(fieldOptions["url"]) {
case FieldStrategyOverwrite:
// only overwrite if not equal
if len(sliceutil.Exclude(scene.URLs.List(), scraped.URLs)) != 0 {
partial.URLs = &models.UpdateStrings{
Values: scraped.URLs,
Mode: models.RelationshipUpdateModeSet,
}
}
case FieldStrategyMerge:
// if merge, add if not already present
urls := sliceutil.AppendUniques(scene.URLs.List(), scraped.URLs)
if len(urls) != len(scene.URLs.List()) {
partial.URLs = &models.UpdateStrings{
Values: urls,
Mode: models.RelationshipUpdateModeSet,
}
}
}
}
if scraped.Director != nil && (scene.Director != *scraped.Director) {
@@ -399,7 +420,7 @@ func getScenePartial(scene *models.Scene, scraped *scraper.ScrapedScene, fieldOp
return partial
}
func shouldSetSingleValueField(strategy *FieldOptions, hasExistingValue bool) bool {
func getFieldStrategy(strategy *FieldOptions) FieldStrategy {
// if unset then default to MERGE
fs := FieldStrategyMerge
@@ -407,6 +428,13 @@ func shouldSetSingleValueField(strategy *FieldOptions, hasExistingValue bool) bo
fs = strategy.Strategy
}
return fs
}
func shouldSetSingleValueField(strategy *FieldOptions, hasExistingValue bool) bool {
// if unset then default to MERGE
fs := getFieldStrategy(strategy)
if fs == FieldStrategyIgnore {
return false
}