mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-18 07:30:29 +00:00
fix(persistence): also try a numeric colon prefix as a plain path
'1999: A Different Life/01.mp3' parsed as library 1999 plus a truncated path and matched nothing. The prefix is ambiguous, so search both ways. Also buffer the json branch of 'missing list', which wrote a syscall per row.
This commit is contained in:
parent
b57bf54b26
commit
9f216f624a
@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
@ -84,18 +85,19 @@ func runMissingList(ctx context.Context) {
|
||||
// writeMissingList streams the cursor so a library with many missing files doesn't get loaded into memory
|
||||
func writeMissingList(w io.Writer, format string, mfs model.MediaFileCursor) error {
|
||||
if format == "json" {
|
||||
_, _ = io.WriteString(w, "[")
|
||||
bw := bufio.NewWriter(w)
|
||||
_, _ = io.WriteString(bw, "[")
|
||||
sep := ""
|
||||
for mf, err := range mfs {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
j, _ := json.Marshal(displayMissingFile{ID: mf.ID, LibraryID: mf.LibraryID, Title: mf.Title, Album: mf.Album, Artist: mf.Artist, Path: mf.Path})
|
||||
_, _ = fmt.Fprintf(w, "%s%s", sep, j)
|
||||
_, _ = fmt.Fprintf(bw, "%s%s", sep, j)
|
||||
sep = ","
|
||||
}
|
||||
_, err := io.WriteString(w, "]\n")
|
||||
return err
|
||||
_, _ = io.WriteString(bw, "]\n")
|
||||
return bw.Flush()
|
||||
}
|
||||
|
||||
cw := csv.NewWriter(w)
|
||||
|
||||
@ -362,11 +362,11 @@ func (r *mediaFileRepository) FindByPaths(paths []string) (model.MediaFiles, err
|
||||
var unqualified []string
|
||||
|
||||
for _, path := range paths {
|
||||
// A colon only qualifies the path when what precedes it is a library id ("Bach: Goldberg/01.mp3" is a plain path)
|
||||
// A numeric prefix is ambiguous: "1:foo.mp3" qualifies a library, but "1999: A Life/01.mp3"
|
||||
// is a plain path. Search both ways rather than guessing.
|
||||
if id, rest, ok := strings.Cut(path, ":"); ok {
|
||||
if libraryID, err := strconv.Atoi(id); err == nil {
|
||||
byLibrary[libraryID] = append(byLibrary[libraryID], rest)
|
||||
continue
|
||||
}
|
||||
}
|
||||
unqualified = append(unqualified, path)
|
||||
|
||||
@ -993,6 +993,7 @@ var _ = Describe("MediaRepository", func() {
|
||||
// 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"},
|
||||
{ID: "findpath-6", LibraryID: 1, Path: "1999: A Different Life/01.mp3", Title: "Numeric colon"},
|
||||
}
|
||||
for _, mf := range testFiles {
|
||||
Expect(mr.Put(&mf)).To(Succeed())
|
||||
@ -1012,6 +1013,13 @@ var _ = Describe("MediaRepository", func() {
|
||||
Expect(results[0].ID).To(Equal("findpath-5"))
|
||||
})
|
||||
|
||||
It("finds a plain path whose colon prefix looks like a library id", func() {
|
||||
results, err := mr.FindByPaths([]string{"1999: A Different Life/01.mp3"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(results).To(HaveLen(1))
|
||||
Expect(results[0].ID).To(Equal("findpath-6"))
|
||||
})
|
||||
|
||||
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())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user