mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Prefer studio name later in filename (#2057)
This commit is contained in:
@@ -60,14 +60,12 @@ func (t *tagger) tagPerformers(performerReader models.PerformerReader, addFunc a
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *tagger) tagStudios(studioReader models.StudioReader, addFunc addLinkFunc) error {
|
func (t *tagger) tagStudios(studioReader models.StudioReader, addFunc addLinkFunc) error {
|
||||||
others, err := match.PathToStudios(t.Path, studioReader)
|
studio, err := match.PathToStudio(t.Path, studioReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add first studio
|
if studio != nil {
|
||||||
if len(others) > 0 {
|
|
||||||
studio := others[0]
|
|
||||||
added, err := addFunc(t.ID, studio.ID)
|
added, err := addFunc(t.ID, studio.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ func getPathWords(path string) []string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func nameMatchesPath(name, path string) bool {
|
// nameMatchesPath returns the index in the path for the right-most match.
|
||||||
|
// Returns -1 if not found.
|
||||||
|
func nameMatchesPath(name, path string) int {
|
||||||
// escape specific regex characters
|
// escape specific regex characters
|
||||||
name = regexp.QuoteMeta(name)
|
name = regexp.QuoteMeta(name)
|
||||||
|
|
||||||
@@ -72,7 +74,13 @@ func nameMatchesPath(name, path string) bool {
|
|||||||
reStr = `(?:^|_|[^\w\d])` + reStr + `(?:$|_|[^\w\d])`
|
reStr = `(?:^|_|[^\w\d])` + reStr + `(?:$|_|[^\w\d])`
|
||||||
|
|
||||||
re := regexp.MustCompile(reStr)
|
re := regexp.MustCompile(reStr)
|
||||||
return re.MatchString(path)
|
found := re.FindAllStringIndex(path, -1)
|
||||||
|
|
||||||
|
if found == nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return found[len(found)-1][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func PathToPerformers(path string, performerReader models.PerformerReader) ([]*models.Performer, error) {
|
func PathToPerformers(path string, performerReader models.PerformerReader) ([]*models.Performer, error) {
|
||||||
@@ -86,7 +94,7 @@ func PathToPerformers(path string, performerReader models.PerformerReader) ([]*m
|
|||||||
var ret []*models.Performer
|
var ret []*models.Performer
|
||||||
for _, p := range performers {
|
for _, p := range performers {
|
||||||
// TODO - commenting out alias handling until both sides work correctly
|
// TODO - commenting out alias handling until both sides work correctly
|
||||||
if nameMatchesPath(p.Name.String, path) { // || nameMatchesPath(p.Aliases.String, path) {
|
if nameMatchesPath(p.Name.String, path) != -1 { // || nameMatchesPath(p.Aliases.String, path) {
|
||||||
ret = append(ret, p)
|
ret = append(ret, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +102,10 @@ func PathToPerformers(path string, performerReader models.PerformerReader) ([]*m
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PathToStudios(path string, reader models.StudioReader) ([]*models.Studio, error) {
|
// PathToStudio returns the Studio that matches the given path.
|
||||||
|
// Where multiple matching studios are found, the one that matches the latest
|
||||||
|
// position in the path is returned.
|
||||||
|
func PathToStudio(path string, reader models.StudioReader) (*models.Studio, error) {
|
||||||
words := getPathWords(path)
|
words := getPathWords(path)
|
||||||
candidates, err := reader.QueryForAutoTag(words)
|
candidates, err := reader.QueryForAutoTag(words)
|
||||||
|
|
||||||
@@ -102,29 +113,26 @@ func PathToStudios(path string, reader models.StudioReader) ([]*models.Studio, e
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret []*models.Studio
|
var ret *models.Studio
|
||||||
|
index := -1
|
||||||
for _, c := range candidates {
|
for _, c := range candidates {
|
||||||
matches := false
|
matchIndex := nameMatchesPath(c.Name.String, path)
|
||||||
if nameMatchesPath(c.Name.String, path) {
|
if matchIndex != -1 && matchIndex > index {
|
||||||
matches = true
|
ret = c
|
||||||
|
index = matchIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matches {
|
aliases, err := reader.GetAliases(c.ID)
|
||||||
aliases, err := reader.GetAliases(c.ID)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, alias := range aliases {
|
|
||||||
if nameMatchesPath(alias, path) {
|
|
||||||
matches = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches {
|
for _, alias := range aliases {
|
||||||
ret = append(ret, c)
|
matchIndex = nameMatchesPath(alias, path)
|
||||||
|
if matchIndex != -1 && matchIndex > index {
|
||||||
|
ret = c
|
||||||
|
index = matchIndex
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +150,7 @@ func PathToTags(path string, tagReader models.TagReader) ([]*models.Tag, error)
|
|||||||
var ret []*models.Tag
|
var ret []*models.Tag
|
||||||
for _, t := range tags {
|
for _, t := range tags {
|
||||||
matches := false
|
matches := false
|
||||||
if nameMatchesPath(t.Name, path) {
|
if nameMatchesPath(t.Name, path) != -1 {
|
||||||
matches = true
|
matches = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +160,7 @@ func PathToTags(path string, tagReader models.TagReader) ([]*models.Tag, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, alias := range aliases {
|
for _, alias := range aliases {
|
||||||
if nameMatchesPath(alias, path) {
|
if nameMatchesPath(alias, path) != -1 {
|
||||||
matches = true
|
matches = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -223,7 +231,7 @@ func PathToScenes(name string, paths []string, sceneReader models.SceneReader) (
|
|||||||
|
|
||||||
var ret []*models.Scene
|
var ret []*models.Scene
|
||||||
for _, p := range scenes {
|
for _, p := range scenes {
|
||||||
if nameMatchesPath(name, p.Path) {
|
if nameMatchesPath(name, p.Path) != -1 {
|
||||||
ret = append(ret, p)
|
ret = append(ret, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,7 +295,7 @@ func PathToImages(name string, paths []string, imageReader models.ImageReader) (
|
|||||||
|
|
||||||
var ret []*models.Image
|
var ret []*models.Image
|
||||||
for _, p := range images {
|
for _, p := range images {
|
||||||
if nameMatchesPath(name, p.Path) {
|
if nameMatchesPath(name, p.Path) != -1 {
|
||||||
ret = append(ret, p)
|
ret = append(ret, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +359,7 @@ func PathToGalleries(name string, paths []string, galleryReader models.GalleryRe
|
|||||||
|
|
||||||
var ret []*models.Gallery
|
var ret []*models.Gallery
|
||||||
for _, p := range gallerys {
|
for _, p := range gallerys {
|
||||||
if nameMatchesPath(name, p.Path.String) {
|
if nameMatchesPath(name, p.Path.String) != -1 {
|
||||||
ret = append(ret, p)
|
ret = append(ret, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
pkg/match/path_test.go
Normal file
76
pkg/match/path_test.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package match
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func Test_nameMatchesPath(t *testing.T) {
|
||||||
|
const name = "first last"
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"exact",
|
||||||
|
name,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"partial",
|
||||||
|
"first",
|
||||||
|
-1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"separator",
|
||||||
|
"first.last",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"separator",
|
||||||
|
"first-last",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"separator",
|
||||||
|
"first_last",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"separators",
|
||||||
|
"first.-_ last",
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"within string",
|
||||||
|
"before_first last/after",
|
||||||
|
6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not within string",
|
||||||
|
"beforefirst last/after",
|
||||||
|
-1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not within string",
|
||||||
|
"before/first lastafter",
|
||||||
|
-1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not within string",
|
||||||
|
"first last1",
|
||||||
|
-1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not within string",
|
||||||
|
"1first last",
|
||||||
|
-1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := nameMatchesPath(name, tt.path); got != tt.want {
|
||||||
|
t.Errorf("nameMatchesPath() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,15 +46,15 @@ func autotagMatchPerformers(path string, performerReader models.PerformerReader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func autotagMatchStudio(path string, studioReader models.StudioReader) (*models.ScrapedStudio, error) {
|
func autotagMatchStudio(path string, studioReader models.StudioReader) (*models.ScrapedStudio, error) {
|
||||||
st, err := match.PathToStudios(path, studioReader)
|
studio, err := match.PathToStudio(path, studioReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error matching studios: %w", err)
|
return nil, fmt.Errorf("error matching studios: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(st) > 0 {
|
if studio != nil {
|
||||||
id := strconv.Itoa(st[0].ID)
|
id := strconv.Itoa(studio.ID)
|
||||||
return &models.ScrapedStudio{
|
return &models.ScrapedStudio{
|
||||||
Name: st[0].Name.String,
|
Name: studio.Name.String,
|
||||||
StoredID: &id,
|
StoredID: &id,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* Add forward jump 10 second button to video player. ([#1973](https://github.com/stashapp/stash/pull/1973))
|
* Add forward jump 10 second button to video player. ([#1973](https://github.com/stashapp/stash/pull/1973))
|
||||||
|
|
||||||
### 🎨 Improvements
|
### 🎨 Improvements
|
||||||
|
* Prefer right-most Studio match in the file path when autotagging. ([#2057](https://github.com/stashapp/stash/pull/2057))
|
||||||
* Added plugin hook for Tag merge operation. ([#2010](https://github.com/stashapp/stash/pull/2010))
|
* Added plugin hook for Tag merge operation. ([#2010](https://github.com/stashapp/stash/pull/2010))
|
||||||
|
|
||||||
### 🐛 Bug fixes
|
### 🐛 Bug fixes
|
||||||
|
|||||||
Reference in New Issue
Block a user