diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index 0e1a2fec7..e34e8601f 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -362,19 +362,14 @@ func (r *mediaFileRepository) FindByPaths(paths []string) (model.MediaFiles, err var unqualified []string for _, path := range paths { - parts := strings.SplitN(path, ":", 2) - if len(parts) == 2 { - // Library-qualified path: "libraryID:path" - libraryID, err := strconv.Atoi(parts[0]) - if err != nil { - // Invalid format, skip + // A colon only qualifies the path when what precedes it is a library id ("Bach: Goldberg/01.mp3" is a plain path) + if id, rest, ok := strings.Cut(path, ":"); ok { + if libraryID, err := strconv.Atoi(id); err == nil { + byLibrary[libraryID] = append(byLibrary[libraryID], rest) continue } - byLibrary[libraryID] = append(byLibrary[libraryID], parts[1]) - } else { - // Unqualified path: search across all libraries - unqualified = append(unqualified, path) } + unqualified = append(unqualified, path) } query := Or{} diff --git a/persistence/mediafile_repository_test.go b/persistence/mediafile_repository_test.go index daf4de5b7..020488bc8 100644 --- a/persistence/mediafile_repository_test.go +++ b/persistence/mediafile_repository_test.go @@ -992,6 +992,7 @@ var _ = Describe("MediaRepository", func() { {ID: "findpath-3", LibraryID: 1, Path: "plex/02 - ACROSS.flac", Title: "Fullwidth"}, // French diacritic: è (U+00E8, can decompose to e + combining grave) {ID: "findpath-4", LibraryID: 1, Path: "artist/Michèle/song.mp3", Title: "French"}, + {ID: "findpath-5", LibraryID: 1, Path: "Bach: Goldberg Variations/01.mp3", Title: "Colon"}, } for _, mf := range testFiles { Expect(mr.Put(&mf)).To(Succeed()) @@ -1004,6 +1005,20 @@ var _ = Describe("MediaRepository", func() { } }) + It("treats a path whose prefix is not a library id as unqualified", func() { + results, err := mr.FindByPaths([]string{"Bach: Goldberg Variations/01.mp3"}) + Expect(err).ToNot(HaveOccurred()) + Expect(results).To(HaveLen(1)) + Expect(results[0].ID).To(Equal("findpath-5")) + }) + + It("splits only the first colon of a library-qualified path", func() { + results, err := mr.FindByPaths([]string{"1:Bach: Goldberg Variations/01.mp3"}) + Expect(err).ToNot(HaveOccurred()) + Expect(results).To(HaveLen(1)) + Expect(results[0].ID).To(Equal("findpath-5")) + }) + It("finds files by exact path", func() { results, err := mr.FindByPaths([]string{"1:artist/Album/track.mp3"}) Expect(err).ToNot(HaveOccurred())