stash/pkg/match/cache.go

127 lines
3.3 KiB
Go

package match
import (
"context"
"github.com/stashapp/stash/pkg/models"
)
const singleFirstCharacterRegex = `^[\p{L}][.\-_ ]`
// Cache is used to cache queries that should not change across an autotag process.
type Cache struct {
singleCharPerformers []*models.Performer
singleCharStudios []*models.Studio
singleCharTags []*models.Tag
}
// getSingleLetterPerformers returns all performers with names that start with single character words.
// The autotag query splits the words into two-character words to query
// against. This means that performers with single-letter words in their names could potentially
// be missed.
// This query is expensive, so it's queried once and cached, if the cache if provided.
func getSingleLetterPerformers(ctx context.Context, c *Cache, reader models.PerformerAutoTagQueryer) ([]*models.Performer, error) {
if c == nil {
c = &Cache{}
}
if c.singleCharPerformers == nil {
pp := -1
performers, _, err := reader.Query(ctx, &models.PerformerFilterType{
Name: &models.StringCriterionInput{
Value: singleFirstCharacterRegex,
Modifier: models.CriterionModifierMatchesRegex,
},
}, &models.FindFilterType{
PerPage: &pp,
})
if err != nil {
return nil, err
}
if len(performers) == 0 {
// make singleWordPerformers not nil
c.singleCharPerformers = make([]*models.Performer, 0)
} else {
c.singleCharPerformers = performers
}
}
return c.singleCharPerformers, nil
}
// getSingleLetterStudios returns all studios with names that start with single character words.
// See getSingleLetterPerformers for details.
func getSingleLetterStudios(ctx context.Context, c *Cache, reader models.StudioAutoTagQueryer) ([]*models.Studio, error) {
if c == nil {
c = &Cache{}
}
if c.singleCharStudios == nil {
pp := -1
studios, _, err := reader.Query(ctx, &models.StudioFilterType{
Name: &models.StringCriterionInput{
Value: singleFirstCharacterRegex,
Modifier: models.CriterionModifierMatchesRegex,
},
}, &models.FindFilterType{
PerPage: &pp,
})
if err != nil {
return nil, err
}
if len(studios) == 0 {
// make singleWordStudios not nil
c.singleCharStudios = make([]*models.Studio, 0)
} else {
c.singleCharStudios = studios
}
}
return c.singleCharStudios, nil
}
// getSingleLetterTags returns all tags with names that start with single character words.
// See getSingleLetterPerformers for details.
func getSingleLetterTags(ctx context.Context, c *Cache, reader models.TagAutoTagQueryer) ([]*models.Tag, error) {
if c == nil {
c = &Cache{}
}
if c.singleCharTags == nil {
pp := -1
tags, _, err := reader.Query(ctx, &models.TagFilterType{
Name: &models.StringCriterionInput{
Value: singleFirstCharacterRegex,
Modifier: models.CriterionModifierMatchesRegex,
},
OperatorFilter: models.OperatorFilter[models.TagFilterType]{
Or: &models.TagFilterType{
Aliases: &models.StringCriterionInput{
Value: singleFirstCharacterRegex,
Modifier: models.CriterionModifierMatchesRegex,
},
},
},
}, &models.FindFilterType{
PerPage: &pp,
})
if err != nil {
return nil, err
}
if len(tags) == 0 {
// make singleWordTags not nil
c.singleCharTags = make([]*models.Tag, 0)
} else {
c.singleCharTags = tags
}
}
return c.singleCharTags, nil
}