mirror of
https://github.com/navidrome/navidrome.git
synced 2026-03-04 06:35:52 +00:00
feat(artwork): add external image URL source to playlist artwork reader
Add fromPlaylistExternalImage source function that resolves playlist cover art from ExternalImageURL, supporting both HTTP(S) URLs (via the existing fromURL helper) and local file paths (via os.Open). Insert it in the Reader() fallback chain between sidecar and tiled cover.
This commit is contained in:
parent
c596aed591
commit
dc61dfd6d6
@ -318,6 +318,44 @@ var _ = Describe("Artwork", func() {
|
||||
Expect(path).To(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("fromPlaylistExternalImage", func() {
|
||||
It("opens local path from ExternalImageURL", func() {
|
||||
tmpDir := GinkgoT().TempDir()
|
||||
imgPath := filepath.Join(tmpDir, "cover.jpg")
|
||||
Expect(os.WriteFile(imgPath, []byte("external image data"), 0600)).To(Succeed())
|
||||
|
||||
reader := &playlistArtworkReader{
|
||||
pl: model.Playlist{ExternalImageURL: imgPath},
|
||||
}
|
||||
r, path, err := reader.fromPlaylistExternalImage(ctx)()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(r).ToNot(BeNil())
|
||||
Expect(path).To(Equal(imgPath))
|
||||
data, _ := io.ReadAll(r)
|
||||
Expect(string(data)).To(Equal("external image data"))
|
||||
r.Close()
|
||||
})
|
||||
|
||||
It("returns nil when ExternalImageURL is empty", func() {
|
||||
reader := &playlistArtworkReader{
|
||||
pl: model.Playlist{ExternalImageURL: ""},
|
||||
}
|
||||
r, path, err := reader.fromPlaylistExternalImage(ctx)()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(r).To(BeNil())
|
||||
Expect(path).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("returns error when local file does not exist", func() {
|
||||
reader := &playlistArtworkReader{
|
||||
pl: model.Playlist{ExternalImageURL: "/non/existent/path/cover.jpg"},
|
||||
}
|
||||
r, _, err := reader.fromPlaylistExternalImage(ctx)()
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(r).To(BeNil())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("resizedArtworkReader", func() {
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"image/draw"
|
||||
"image/png"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -67,6 +68,7 @@ func (a *playlistArtworkReader) Reader(ctx context.Context) (io.ReadCloser, stri
|
||||
return selectImageReader(ctx, a.artID,
|
||||
a.fromPlaylistUploadedImage(),
|
||||
a.fromPlaylistSidecar(),
|
||||
a.fromPlaylistExternalImage(ctx),
|
||||
a.fromGeneratedTiledCover(ctx),
|
||||
fromAlbumPlaceholder(),
|
||||
)
|
||||
@ -131,6 +133,26 @@ func (a *playlistArtworkReader) fromPlaylistSidecar() sourceFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *playlistArtworkReader) fromPlaylistExternalImage(ctx context.Context) sourceFunc {
|
||||
return func() (io.ReadCloser, string, error) {
|
||||
if a.pl.ExternalImageURL == "" {
|
||||
return nil, "", nil
|
||||
}
|
||||
if strings.HasPrefix(a.pl.ExternalImageURL, "http://") || strings.HasPrefix(a.pl.ExternalImageURL, "https://") {
|
||||
parsed, err := url.Parse(a.pl.ExternalImageURL)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return fromURL(ctx, parsed)
|
||||
}
|
||||
f, err := os.Open(a.pl.ExternalImageURL)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return f, a.pl.ExternalImageURL, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *playlistArtworkReader) fromGeneratedTiledCover(ctx context.Context) sourceFunc {
|
||||
return func() (io.ReadCloser, string, error) {
|
||||
tiles, err := a.loadTiles(ctx)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user