Skip to content

Commit

Permalink
Add updated_at field to stash_id's (#5259)
Browse files Browse the repository at this point in the history
* Add updated_at field to stash_id's
* Only set updated at on stash ids when actually updating in identify

---------
Co-authored-by: WithoutPants <[email protected]>
  • Loading branch information
ikmckenz authored Oct 31, 2024
1 parent b1d5dc2 commit 180a0fa
Show file tree
Hide file tree
Showing 35 changed files with 336 additions and 132 deletions.
3 changes: 0 additions & 3 deletions gqlgen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ models:
model: github.com/stashapp/stash/internal/identify.FieldStrategy
ScraperSource:
model: github.com/stashapp/stash/pkg/scraper.Source
# rebind inputs to types
StashIDInput:
model: github.com/stashapp/stash/pkg/models.StashID
IdentifySourceInput:
model: github.com/stashapp/stash/internal/identify.Source
IdentifyFieldOptionsInput:
Expand Down
2 changes: 2 additions & 0 deletions graphql/schema/types/stash-box.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ input StashBoxInput {
type StashID {
endpoint: String!
stash_id: String!
updated_at: Time!
}

input StashIDInput {
endpoint: String!
stash_id: String!
updated_at: Time
}

input StashBoxFingerprintSubmissionInput {
Expand Down
4 changes: 2 additions & 2 deletions internal/api/changeset_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,13 @@ func (t changesetTranslator) updateStringsBulk(value *BulkUpdateStrings, field s
}
}

func (t changesetTranslator) updateStashIDs(value []models.StashID, field string) *models.UpdateStashIDs {
func (t changesetTranslator) updateStashIDs(value models.StashIDInputs, field string) *models.UpdateStashIDs {
if !t.hasField(field) {
return nil
}

return &models.UpdateStashIDs{
StashIDs: value,
StashIDs: value.ToStashIDs(),
Mode: models.RelationshipUpdateModeSet,
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/resolver_mutation_performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (r *mutationResolver) PerformerCreate(ctx context.Context, input models.Per
newPerformer.Height = input.HeightCm
newPerformer.Weight = input.Weight
newPerformer.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
newPerformer.StashIDs = models.NewRelatedStashIDs(input.StashIds)
newPerformer.StashIDs = models.NewRelatedStashIDs(models.StashIDInputs(input.StashIds).ToStashIDs())

newPerformer.URLs = models.NewRelatedStrings([]string{})
if input.URL != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/api/resolver_mutation_scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (r *mutationResolver) SceneCreate(ctx context.Context, input models.SceneCr
newScene.Director = translator.string(input.Director)
newScene.Rating = input.Rating100
newScene.Organized = translator.bool(input.Organized)
newScene.StashIDs = models.NewRelatedStashIDs(input.StashIds)
newScene.StashIDs = models.NewRelatedStashIDs(models.StashIDInputs(input.StashIds).ToStashIDs())

newScene.Date, err = translator.datePtr(input.Date)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/api/resolver_mutation_studio.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (r *mutationResolver) StudioCreate(ctx context.Context, input models.Studio
newStudio.Details = translator.string(input.Details)
newStudio.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
newStudio.Aliases = models.NewRelatedStrings(input.Aliases)
newStudio.StashIDs = models.NewRelatedStashIDs(input.StashIds)
newStudio.StashIDs = models.NewRelatedStashIDs(models.StashIDInputs(input.StashIds).ToStashIDs())

var err error

Expand Down
21 changes: 12 additions & 9 deletions internal/identify/identify.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,18 @@ func (t *SceneIdentifier) getSceneUpdater(ctx context.Context, s *models.Scene,
}
}

stashIDs, err := rel.stashIDs(ctx)
// SetCoverImage defaults to true if unset
if options.SetCoverImage == nil || *options.SetCoverImage {
ret.CoverImage, err = rel.cover(ctx)
if err != nil {
return nil, err
}
}

// if anything changed, also update the updated at time on the applicable stash id
changed := !ret.IsEmpty()

stashIDs, err := rel.stashIDs(ctx, changed)
if err != nil {
return nil, err
}
Expand All @@ -256,14 +267,6 @@ func (t *SceneIdentifier) getSceneUpdater(ctx context.Context, s *models.Scene,
}
}

// SetCoverImage defaults to true if unset
if options.SetCoverImage == nil || *options.SetCoverImage {
ret.CoverImage, err = rel.cover(ctx)
if err != nil {
return nil, err
}
}

return ret, nil
}

Expand Down
24 changes: 18 additions & 6 deletions internal/identify/scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"strconv"
"strings"
"time"

"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models"
Expand Down Expand Up @@ -182,7 +183,13 @@ func (g sceneRelationships) tags(ctx context.Context) ([]int, error) {
return tagIDs, nil
}

func (g sceneRelationships) stashIDs(ctx context.Context) ([]models.StashID, error) {
// stashIDs returns the updated stash IDs for the scene
// returns nil if not applicable or no changes were made
// if setUpdateTime is true, then the updated_at field will be set to the current time
// for the applicable matching stash ID
func (g sceneRelationships) stashIDs(ctx context.Context, setUpdateTime bool) ([]models.StashID, error) {
updateTime := time.Now()

remoteSiteID := g.result.result.RemoteSiteID
fieldStrategy := g.fieldOptions["stash_ids"]
target := g.scene
Expand All @@ -199,7 +206,7 @@ func (g sceneRelationships) stashIDs(ctx context.Context) ([]models.StashID, err
strategy = fieldStrategy.Strategy
}

var stashIDs []models.StashID
var stashIDs models.StashIDs
originalStashIDs := target.StashIDs.List()

if strategy == FieldStrategyMerge {
Expand All @@ -208,27 +215,32 @@ func (g sceneRelationships) stashIDs(ctx context.Context) ([]models.StashID, err
stashIDs = append(stashIDs, originalStashIDs...)
}

// find and update the stash id if it exists
for i, stashID := range stashIDs {
if endpoint == stashID.Endpoint {
// if stashID is the same, then don't set
if stashID.StashID == *remoteSiteID {
if !setUpdateTime && stashID.StashID == *remoteSiteID {
return nil, nil
}

// replace the stash id and return
stashID.StashID = *remoteSiteID
stashID.UpdatedAt = updateTime
stashIDs[i] = stashID
return stashIDs, nil
}
}

// not found, create new entry
stashIDs = append(stashIDs, models.StashID{
StashID: *remoteSiteID,
Endpoint: endpoint,
StashID: *remoteSiteID,
Endpoint: endpoint,
UpdatedAt: updateTime,
})

if sliceutil.SliceSame(originalStashIDs, stashIDs) {
// don't return if nothing was changed
// if we're setting update time, then we always return
if !setUpdateTime && stashIDs.HasSameStashIDs(originalStashIDs) {
return nil, nil
}

Expand Down
96 changes: 78 additions & 18 deletions internal/identify/scene_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"reflect"
"strconv"
"testing"
"time"

"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/models/mocks"
Expand Down Expand Up @@ -548,8 +549,9 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
ID: sceneWithStashID,
StashIDs: models.NewRelatedStashIDs([]models.StashID{
{
StashID: remoteSiteID,
Endpoint: existingEndpoint,
StashID: remoteSiteID,
Endpoint: existingEndpoint,
UpdatedAt: time.Time{},
},
}),
}
Expand All @@ -561,14 +563,17 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
fieldOptions: make(map[string]*FieldOptions),
}

setTime := time.Now()

tests := []struct {
name string
scene *models.Scene
fieldOptions *FieldOptions
endpoint string
remoteSiteID *string
want []models.StashID
wantErr bool
name string
scene *models.Scene
fieldOptions *FieldOptions
endpoint string
remoteSiteID *string
setUpdateTime bool
want []models.StashID
wantErr bool
}{
{
"ignore",
Expand All @@ -578,6 +583,7 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
},
newEndpoint,
&remoteSiteID,
false,
nil,
false,
},
Expand All @@ -587,6 +593,7 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
defaultOptions,
"",
&remoteSiteID,
false,
nil,
false,
},
Expand All @@ -596,6 +603,7 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
defaultOptions,
newEndpoint,
nil,
false,
nil,
false,
},
Expand All @@ -605,19 +613,38 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
defaultOptions,
existingEndpoint,
&remoteSiteID,
false,
nil,
false,
},
{
"merge existing set update time",
sceneWithStashIDs,
defaultOptions,
existingEndpoint,
&remoteSiteID,
true,
[]models.StashID{
{
StashID: remoteSiteID,
Endpoint: existingEndpoint,
UpdatedAt: setTime,
},
},
false,
},
{
"merge existing new value",
sceneWithStashIDs,
defaultOptions,
existingEndpoint,
&newRemoteSiteID,
false,
[]models.StashID{
{
StashID: newRemoteSiteID,
Endpoint: existingEndpoint,
StashID: newRemoteSiteID,
Endpoint: existingEndpoint,
UpdatedAt: setTime,
},
},
false,
Expand All @@ -628,14 +655,17 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
defaultOptions,
newEndpoint,
&newRemoteSiteID,
false,
[]models.StashID{
{
StashID: remoteSiteID,
Endpoint: existingEndpoint,
StashID: remoteSiteID,
Endpoint: existingEndpoint,
UpdatedAt: time.Time{},
},
{
StashID: newRemoteSiteID,
Endpoint: newEndpoint,
StashID: newRemoteSiteID,
Endpoint: newEndpoint,
UpdatedAt: setTime,
},
},
false,
Expand All @@ -648,10 +678,12 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
},
newEndpoint,
&newRemoteSiteID,
false,
[]models.StashID{
{
StashID: newRemoteSiteID,
Endpoint: newEndpoint,
StashID: newRemoteSiteID,
Endpoint: newEndpoint,
UpdatedAt: setTime,
},
},
false,
Expand All @@ -664,9 +696,28 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
},
existingEndpoint,
&remoteSiteID,
false,
nil,
false,
},
{
"overwrite same set update time",
sceneWithStashIDs,
&FieldOptions{
Strategy: FieldStrategyOverwrite,
},
existingEndpoint,
&remoteSiteID,
true,
[]models.StashID{
{
StashID: remoteSiteID,
Endpoint: existingEndpoint,
UpdatedAt: setTime,
},
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -681,11 +732,20 @@ func Test_sceneRelationships_stashIDs(t *testing.T) {
},
}

got, err := tr.stashIDs(testCtx)
got, err := tr.stashIDs(testCtx, tt.setUpdateTime)

if (err != nil) != tt.wantErr {
t.Errorf("sceneRelationships.stashIDs() error = %v, wantErr %v", err, tt.wantErr)
return
}

// massage updatedAt times to be consistent for comparison
for i := range got {
if !got[i].UpdatedAt.IsZero() {
got[i].UpdatedAt = setTime
}
}

if !reflect.DeepEqual(got, tt.want) {
t.Errorf("sceneRelationships.stashIDs() = %+v, want %+v", got, tt.want)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/models/model_scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ func (s ScenePartial) UpdateInput(id int) SceneUpdateInput {
dateStr = &v
}

var stashIDs []StashID
var stashIDs StashIDs
if s.StashIDs != nil {
stashIDs = s.StashIDs.StashIDs
stashIDs = StashIDs(s.StashIDs.StashIDs)
}

ret := SceneUpdateInput{
Expand All @@ -212,7 +212,7 @@ func (s ScenePartial) UpdateInput(id int) SceneUpdateInput {
PerformerIds: s.PerformerIDs.IDStrings(),
Movies: s.GroupIDs.SceneMovieInputs(),
TagIds: s.TagIDs.IDStrings(),
StashIds: stashIDs,
StashIds: stashIDs.ToStashIDInputs(),
}

return ret
Expand Down
Loading

0 comments on commit 180a0fa

Please sign in to comment.