diff --git a/core/artwork/artwork.go b/core/artwork/artwork.go index f6cc2a516..eeabfa5b9 100644 --- a/core/artwork/artwork.go +++ b/core/artwork/artwork.go @@ -70,7 +70,7 @@ func (a *artwork) getArtworkReader(ctx context.Context, artID model.ArtworkID, s case model.KindMediaFileArtwork: artReader, err = newMediafileArtworkReader(ctx, a, artID) default: - artReader, err = newEmptyIDReader(ctx, artID) + artReader, err = newPlaceholderReader(ctx, artID) } } return artReader, err diff --git a/core/artwork/reader_emptyid.go b/core/artwork/reader_emptyid.go index 951aa46a1..244082beb 100644 --- a/core/artwork/reader_emptyid.go +++ b/core/artwork/reader_emptyid.go @@ -10,26 +10,26 @@ import ( "github.com/navidrome/navidrome/model" ) -type emptyIDReader struct { +type placeholderReader struct { artID model.ArtworkID } -func newEmptyIDReader(_ context.Context, artID model.ArtworkID) (*emptyIDReader, error) { - a := &emptyIDReader{ +func newPlaceholderReader(_ context.Context, artID model.ArtworkID) (*placeholderReader, error) { + a := &placeholderReader{ artID: artID, } return a, nil } -func (a *emptyIDReader) LastUpdated() time.Time { +func (a *placeholderReader) LastUpdated() time.Time { return time.Now() // Basically make it non-cacheable } -func (a *emptyIDReader) Key() string { +func (a *placeholderReader) Key() string { return fmt.Sprintf("0.%d.0.%d", a.LastUpdated().UnixMilli(), conf.Server.CoverJpegQuality) } -func (a *emptyIDReader) Reader(ctx context.Context) (io.ReadCloser, string, error) { +func (a *placeholderReader) Reader(ctx context.Context) (io.ReadCloser, string, error) { r, source := extractImage(ctx, a.artID, fromPlaceholder()) return r, source, nil } diff --git a/model/artwork_id.go b/model/artwork_id.go index 28ea8ef2b..cf5c1cdc4 100644 --- a/model/artwork_id.go +++ b/model/artwork_id.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "strings" + + "golang.org/x/exp/slices" ) type Kind struct{ prefix string } @@ -11,8 +13,15 @@ type Kind struct{ prefix string } var ( KindMediaFileArtwork = Kind{"mf"} KindAlbumArtwork = Kind{"al"} + KindPlaylistArtwork = Kind{"pl"} ) +var artworkKindList = []string{ + KindAlbumArtwork.prefix, + KindMediaFileArtwork.prefix, + KindPlaylistArtwork.prefix, +} + type ArtworkID struct { Kind Kind ID string @@ -26,11 +35,11 @@ func (id ArtworkID) String() string { } func ParseArtworkID(id string) (ArtworkID, error) { - parts := strings.Split(id, "-") + parts := strings.SplitN(id, "-", 2) if len(parts) != 2 { return ArtworkID{}, errors.New("invalid artwork id") } - if parts[0] != KindAlbumArtwork.prefix && parts[0] != KindMediaFileArtwork.prefix { + if !slices.Contains(artworkKindList, parts[0]) { return ArtworkID{}, errors.New("invalid artwork kind") } return ArtworkID{ diff --git a/model/artwork_id_test.go b/model/artwork_id_test.go index ed81c90ed..0cbf6474c 100644 --- a/model/artwork_id_test.go +++ b/model/artwork_id_test.go @@ -19,6 +19,12 @@ var _ = Describe("ParseArtworkID()", func() { Expect(id.Kind).To(Equal(model.KindMediaFileArtwork)) Expect(id.ID).To(Equal("a6f8d2b1")) }) + It("parses playlists artwork ids", func() { + id, err := model.ParseArtworkID("pl-18690de0-151b-4d86-81cb-f418a907315a") + Expect(err).ToNot(HaveOccurred()) + Expect(id.Kind).To(Equal(model.KindPlaylistArtwork)) + Expect(id.ID).To(Equal("18690de0-151b-4d86-81cb-f418a907315a")) + }) It("fails to parse malformed ids", func() { _, err := model.ParseArtworkID("a6f8d2b1") Expect(err).To(MatchError("invalid artwork id"))