fix(persistence): stop FindByPaths dropping plain paths that contain a colon

Any colon was taken as the libraryID separator, and a non-numeric prefix
made the whole path vanish from the lookup. 'missing fix' then rejected the
very paths 'missing list' printed, and M3U imports silently skipped such
tracks. Only a numeric prefix qualifies a path now.
This commit is contained in:
Deluan 2026-09-12 01:13:42 -04:00
parent 497ab102f2
commit 809e1cd34d
2 changed files with 20 additions and 10 deletions

View File

@ -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{}

View File

@ -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())