mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
update merged performer upon batch update (#5664)
* update merged performer upon batch update * Handle aliases and name for merged performer * Refactor merge performer code Log when merging performers --------- Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
@@ -49,6 +49,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
...URLFragment
|
...URLFragment
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/performer"
|
"github.com/stashapp/stash/pkg/performer"
|
||||||
"github.com/stashapp/stash/pkg/scraper/stashbox"
|
"github.com/stashapp/stash/pkg/scraper/stashbox"
|
||||||
|
"github.com/stashapp/stash/pkg/sliceutil"
|
||||||
"github.com/stashapp/stash/pkg/studio"
|
"github.com/stashapp/stash/pkg/studio"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -119,6 +120,18 @@ func (t *StashBoxBatchTagTask) findStashBoxPerformer(ctx context.Context) (*mode
|
|||||||
}
|
}
|
||||||
if remoteID != "" {
|
if remoteID != "" {
|
||||||
performer, err = client.FindStashBoxPerformerByID(ctx, remoteID)
|
performer, err = client.FindStashBoxPerformerByID(ctx, remoteID)
|
||||||
|
|
||||||
|
if performer != nil && performer.RemoteMergedIntoId != nil {
|
||||||
|
mergedPerformer, err := t.handleMergedPerformer(ctx, performer, client)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if mergedPerformer != nil {
|
||||||
|
logger.Infof("Performer id %s merged into %s, updating local performer", remoteID, *performer.RemoteMergedIntoId)
|
||||||
|
performer = mergedPerformer
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var name string
|
var name string
|
||||||
@@ -133,6 +146,21 @@ func (t *StashBoxBatchTagTask) findStashBoxPerformer(ctx context.Context) (*mode
|
|||||||
return performer, err
|
return performer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *StashBoxBatchTagTask) handleMergedPerformer(ctx context.Context, performer *models.ScrapedPerformer, client *stashbox.Client) (mergedPerformer *models.ScrapedPerformer, err error) {
|
||||||
|
mergedPerformer, err = client.FindStashBoxPerformerByID(ctx, *performer.RemoteMergedIntoId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("loading merged performer %s from stashbox", *performer.RemoteMergedIntoId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mergedPerformer.StoredID != nil && *mergedPerformer.StoredID != *performer.StoredID {
|
||||||
|
logger.Warnf("Performer %s merged into %s, but both exist locally, not merging", *performer.StoredID, *mergedPerformer.StoredID)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedPerformer.StoredID = performer.StoredID
|
||||||
|
return mergedPerformer, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *StashBoxBatchTagTask) processMatchedPerformer(ctx context.Context, p *models.ScrapedPerformer, excluded map[string]bool) {
|
func (t *StashBoxBatchTagTask) processMatchedPerformer(ctx context.Context, p *models.ScrapedPerformer, excluded map[string]bool) {
|
||||||
// Refreshing an existing performer
|
// Refreshing an existing performer
|
||||||
if t.performer != nil {
|
if t.performer != nil {
|
||||||
@@ -156,6 +184,19 @@ func (t *StashBoxBatchTagTask) processMatchedPerformer(ctx context.Context, p *m
|
|||||||
|
|
||||||
partial := p.ToPartial(t.box.Endpoint, excluded, existingStashIDs)
|
partial := p.ToPartial(t.box.Endpoint, excluded, existingStashIDs)
|
||||||
|
|
||||||
|
// if we're setting the performer's aliases, and not the name, then filter out the name
|
||||||
|
// from the aliases to avoid duplicates
|
||||||
|
// add the name to the aliases if it's not already there
|
||||||
|
if partial.Aliases != nil && !partial.Name.Set {
|
||||||
|
partial.Aliases.Values = sliceutil.Filter(partial.Aliases.Values, func(s string) bool {
|
||||||
|
return s != t.performer.Name
|
||||||
|
})
|
||||||
|
|
||||||
|
if p.Name != nil && t.performer.Name != *p.Name {
|
||||||
|
partial.Aliases.Values = sliceutil.AppendUnique(partial.Aliases.Values, *p.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := performer.ValidateUpdate(ctx, t.performer.ID, partial, qb); err != nil {
|
if err := performer.ValidateUpdate(ctx, t.performer.ID, partial, qb); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,13 +128,15 @@ type ScrapedPerformer struct {
|
|||||||
Aliases *string `json:"aliases"`
|
Aliases *string `json:"aliases"`
|
||||||
Tags []*ScrapedTag `json:"tags"`
|
Tags []*ScrapedTag `json:"tags"`
|
||||||
// This should be a base64 encoded data URL
|
// This should be a base64 encoded data URL
|
||||||
Image *string `json:"image"` // deprecated: use Images
|
Image *string `json:"image"` // deprecated: use Images
|
||||||
Images []string `json:"images"`
|
Images []string `json:"images"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
DeathDate *string `json:"death_date"`
|
DeathDate *string `json:"death_date"`
|
||||||
HairColor *string `json:"hair_color"`
|
HairColor *string `json:"hair_color"`
|
||||||
Weight *string `json:"weight"`
|
Weight *string `json:"weight"`
|
||||||
RemoteSiteID *string `json:"remote_site_id"`
|
RemoteSiteID *string `json:"remote_site_id"`
|
||||||
|
RemoteDeleted bool `json:"remote_deleted"`
|
||||||
|
RemoteMergedIntoId *string `json:"remote_merged_into_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ScrapedPerformer) IsScrapedContent() {}
|
func (ScrapedPerformer) IsScrapedContent() {}
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ type PerformerFragment struct {
|
|||||||
Aliases []string "json:\"aliases\" graphql:\"aliases\""
|
Aliases []string "json:\"aliases\" graphql:\"aliases\""
|
||||||
Gender *GenderEnum "json:\"gender,omitempty\" graphql:\"gender\""
|
Gender *GenderEnum "json:\"gender,omitempty\" graphql:\"gender\""
|
||||||
MergedIds []string "json:\"merged_ids\" graphql:\"merged_ids\""
|
MergedIds []string "json:\"merged_ids\" graphql:\"merged_ids\""
|
||||||
|
Deleted bool "json:\"deleted\" graphql:\"deleted\""
|
||||||
|
MergedIntoID *string "json:\"merged_into_id,omitempty\" graphql:\"merged_into_id\""
|
||||||
Urls []*URLFragment "json:\"urls\" graphql:\"urls\""
|
Urls []*URLFragment "json:\"urls\" graphql:\"urls\""
|
||||||
Images []*ImageFragment "json:\"images\" graphql:\"images\""
|
Images []*ImageFragment "json:\"images\" graphql:\"images\""
|
||||||
BirthDate *string "json:\"birth_date,omitempty\" graphql:\"birth_date\""
|
BirthDate *string "json:\"birth_date,omitempty\" graphql:\"birth_date\""
|
||||||
@@ -249,6 +251,18 @@ func (t *PerformerFragment) GetMergedIds() []string {
|
|||||||
}
|
}
|
||||||
return t.MergedIds
|
return t.MergedIds
|
||||||
}
|
}
|
||||||
|
func (t *PerformerFragment) GetDeleted() bool {
|
||||||
|
if t == nil {
|
||||||
|
t = &PerformerFragment{}
|
||||||
|
}
|
||||||
|
return t.Deleted
|
||||||
|
}
|
||||||
|
func (t *PerformerFragment) GetMergedIntoID() *string {
|
||||||
|
if t == nil {
|
||||||
|
t = &PerformerFragment{}
|
||||||
|
}
|
||||||
|
return t.MergedIntoID
|
||||||
|
}
|
||||||
func (t *PerformerFragment) GetUrls() []*URLFragment {
|
func (t *PerformerFragment) GetUrls() []*URLFragment {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
t = &PerformerFragment{}
|
t = &PerformerFragment{}
|
||||||
@@ -860,6 +874,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -993,6 +1009,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -1126,6 +1144,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -1259,6 +1279,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -1331,6 +1353,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -1408,6 +1432,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
@@ -1546,6 +1572,8 @@ fragment PerformerFragment on Performer {
|
|||||||
aliases
|
aliases
|
||||||
gender
|
gender
|
||||||
merged_ids
|
merged_ids
|
||||||
|
deleted
|
||||||
|
merged_into_id
|
||||||
urls {
|
urls {
|
||||||
... URLFragment
|
... URLFragment
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,16 +297,18 @@ func performerFragmentToScrapedPerformer(p graphql.PerformerFragment) *models.Sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
sp := &models.ScrapedPerformer{
|
sp := &models.ScrapedPerformer{
|
||||||
Name: &p.Name,
|
Name: &p.Name,
|
||||||
Disambiguation: p.Disambiguation,
|
Disambiguation: p.Disambiguation,
|
||||||
Country: p.Country,
|
Country: p.Country,
|
||||||
Measurements: formatMeasurements(*p.Measurements),
|
Measurements: formatMeasurements(*p.Measurements),
|
||||||
CareerLength: formatCareerLength(p.CareerStartYear, p.CareerEndYear),
|
CareerLength: formatCareerLength(p.CareerStartYear, p.CareerEndYear),
|
||||||
Tattoos: formatBodyModifications(p.Tattoos),
|
Tattoos: formatBodyModifications(p.Tattoos),
|
||||||
Piercings: formatBodyModifications(p.Piercings),
|
Piercings: formatBodyModifications(p.Piercings),
|
||||||
Twitter: findURL(p.Urls, "TWITTER"),
|
Twitter: findURL(p.Urls, "TWITTER"),
|
||||||
RemoteSiteID: &p.ID,
|
RemoteSiteID: &p.ID,
|
||||||
Images: images,
|
RemoteDeleted: p.Deleted,
|
||||||
|
RemoteMergedIntoId: p.MergedIntoID,
|
||||||
|
Images: images,
|
||||||
// TODO - tags not currently supported
|
// TODO - tags not currently supported
|
||||||
// graphql schema change to accommodate this. Leave off for now.
|
// graphql schema change to accommodate this. Leave off for now.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user