From 37c837425c71f730be98584ddac1c80a7dd202cc Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 17 Jul 2026 18:58:09 -0400 Subject: [PATCH] feat(album): serve uploaded cover with highest priority --- core/artwork/reader_album.go | 7 +++++- core/artwork/reader_album_test.go | 42 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/core/artwork/reader_album.go b/core/artwork/reader_album.go index 8ad07773b..4ec01e22d 100644 --- a/core/artwork/reader_album.go +++ b/core/artwork/reader_album.go @@ -79,10 +79,15 @@ func (a *albumArtworkReader) LastUpdated() time.Time { } func (a *albumArtworkReader) Reader(ctx context.Context) (io.ReadCloser, string, error) { - var ff = a.fromCoverArtPriority(ctx, a.a.ffmpeg, conf.Server.CoverArtPriority) + ff := []sourceFunc{a.fromAlbumUploadedImage()} + ff = append(ff, a.fromCoverArtPriority(ctx, a.a.ffmpeg, conf.Server.CoverArtPriority)...) return selectImageReader(ctx, a.artID, ff...) } +func (a *albumArtworkReader) fromAlbumUploadedImage() sourceFunc { + return fromLocalFile(a.album.UploadedImagePath()) +} + func (a *albumArtworkReader) fromCoverArtPriority(ctx context.Context, ffmpeg ffmpeg.FFmpeg, priority string) []sourceFunc { var ff []sourceFunc for pattern := range strings.SplitSeq(strings.ToLower(priority), ",") { diff --git a/core/artwork/reader_album_test.go b/core/artwork/reader_album_test.go index fe4a1a545..71d833360 100644 --- a/core/artwork/reader_album_test.go +++ b/core/artwork/reader_album_test.go @@ -3,14 +3,56 @@ package artwork import ( "context" "errors" + "io" + "os" + "path/filepath" "time" + "github.com/navidrome/navidrome/conf" + "github.com/navidrome/navidrome/conf/configtest" "github.com/navidrome/navidrome/model" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("Album Artwork Reader", func() { + Describe("fromAlbumUploadedImage", func() { + var ( + tempDir string + reader *albumArtworkReader + ) + BeforeEach(func() { + DeferCleanup(configtest.SetupConfig()) + tempDir = GinkgoT().TempDir() + conf.Server.DataFolder = conf.NewDir(tempDir) + Expect(os.MkdirAll(filepath.Join(tempDir, "artwork", "album"), 0755)).To(Succeed()) + reader = &albumArtworkReader{} + }) + When("the album has an uploaded image", func() { + It("returns the uploaded image", func() { + imgPath := filepath.Join(tempDir, "artwork", "album", "al-1_test.jpg") + Expect(os.WriteFile(imgPath, []byte("uploaded album image"), 0600)).To(Succeed()) + reader.album = model.Album{ID: "al-1", UploadedImage: "al-1_test.jpg"} + r, path, err := reader.fromAlbumUploadedImage()() + Expect(err).ToNot(HaveOccurred()) + Expect(r).ToNot(BeNil()) + Expect(path).To(Equal(imgPath)) + data, err := io.ReadAll(r) + Expect(err).ToNot(HaveOccurred()) + Expect(string(data)).To(Equal("uploaded album image")) + r.Close() + }) + }) + When("the album has no uploaded image", func() { + It("returns a nil reader so the next source is tried", func() { + reader.album = model.Album{ID: "al-1"} + r, _, err := reader.fromAlbumUploadedImage()() + Expect(err).ToNot(HaveOccurred()) + Expect(r).To(BeNil()) + }) + }) + }) + Describe("loadAlbumFoldersPaths", func() { var ( ctx context.Context