2022-03-09 01:01:56 +00:00
|
|
|
package match
|
|
|
|
|
2022-05-19 07:49:32 +00:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/stashapp/stash/pkg/models"
|
|
|
|
)
|
2022-03-09 01:01:56 +00:00
|
|
|
|
|
|
|
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.
|
2023-09-01 00:39:29 +00:00
|
|
|
func getSingleLetterPerformers(ctx context.Context, c *Cache, reader models.PerformerAutoTagQueryer) ([]*models.Performer, error) {
|
2022-03-09 01:01:56 +00:00
|
|
|
if c == nil {
|
|
|
|
c = &Cache{}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.singleCharPerformers == nil {
|
|
|
|
pp := -1
|
2022-05-19 07:49:32 +00:00
|
|
|
performers, _, err := reader.Query(ctx, &models.PerformerFilterType{
|
2022-03-09 01:01:56 +00:00
|
|
|
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.
|
2023-09-01 00:39:29 +00:00
|
|
|
func getSingleLetterStudios(ctx context.Context, c *Cache, reader models.StudioAutoTagQueryer) ([]*models.Studio, error) {
|
2022-03-09 01:01:56 +00:00
|
|
|
if c == nil {
|
|
|
|
c = &Cache{}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.singleCharStudios == nil {
|
|
|
|
pp := -1
|
2022-05-19 07:49:32 +00:00
|
|
|
studios, _, err := reader.Query(ctx, &models.StudioFilterType{
|
2022-03-09 01:01:56 +00:00
|
|
|
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.
|
2023-09-01 00:39:29 +00:00
|
|
|
func getSingleLetterTags(ctx context.Context, c *Cache, reader models.TagAutoTagQueryer) ([]*models.Tag, error) {
|
2022-03-09 01:01:56 +00:00
|
|
|
if c == nil {
|
|
|
|
c = &Cache{}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.singleCharTags == nil {
|
|
|
|
pp := -1
|
2022-05-19 07:49:32 +00:00
|
|
|
tags, _, err := reader.Query(ctx, &models.TagFilterType{
|
2022-03-09 01:01:56 +00:00
|
|
|
Name: &models.StringCriterionInput{
|
|
|
|
Value: singleFirstCharacterRegex,
|
|
|
|
Modifier: models.CriterionModifierMatchesRegex,
|
|
|
|
},
|
2024-06-11 01:34:38 +00:00
|
|
|
OperatorFilter: models.OperatorFilter[models.TagFilterType]{
|
|
|
|
Or: &models.TagFilterType{
|
|
|
|
Aliases: &models.StringCriterionInput{
|
|
|
|
Value: singleFirstCharacterRegex,
|
|
|
|
Modifier: models.CriterionModifierMatchesRegex,
|
|
|
|
},
|
2022-03-09 01:01:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, &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
|
|
|
|
}
|