Use Cover Art Archive for albums with MusicBrainz IDs #12

Closed
sproutsberry wants to merge 11 commits from cover-art-archive into main
2 changed files with 35 additions and 9 deletions
Showing only changes of commit 4a6db5a123 - Show all commits
+20 -9
View File
@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/navidrome/navidrome/plugins/pdk/go/host" "github.com/navidrome/navidrome/plugins/pdk/go/host"
"github.com/navidrome/navidrome/plugins/pdk/go/pdk" "github.com/navidrome/navidrome/plugins/pdk/go/pdk"
11
@@ -110,6 +111,8 @@ func uploadToUguu(imageData []byte, contentType string) (string, error) {
// Cover Art Archive // Cover Art Archive
// ============================================================================ // ============================================================================
const CAA_TIMEOUT = 5 * time.Second
// caaResponse only includes relevant parameters; see API for full response // caaResponse only includes relevant parameters; see API for full response
// https://musicbrainz.org/doc/Cover_Art_Archive/API // https://musicbrainz.org/doc/Cover_Art_Archive/API
type caaResponse struct { type caaResponse struct {
@@ -127,18 +130,26 @@ type caaResponse struct {
func getThumbnailForMBZAlbumID(mbzAlbumID string) (string, error) { func getThumbnailForMBZAlbumID(mbzAlbumID string) (string, error) {
req := pdk.NewHTTPRequest(pdk.MethodGet, fmt.Sprintf("https://coverartarchive.org/release/%s", mbzAlbumID)) req := pdk.NewHTTPRequest(pdk.MethodGet, fmt.Sprintf("https://coverartarchive.org/release/%s", mbzAlbumID))
resp := req.Send()
if status := resp.Status(); status == 404 { respChan := make(chan pdk.HTTPResponse, 1)
pdk.Log(pdk.LogDebug, fmt.Sprintf("No cover art for MusicBrainz Album ID: %s", mbzAlbumID)) go func() { respChan <- req.Send() }()
return "", nil
} else if status >= 400 {
return "", fmt.Errorf("HTTP %d", resp.Status())
}
var result caaResponse var result caaResponse
if err := json.Unmarshal(resp.Body(), &result); err != nil {
return "", fmt.Errorf("failed to parse: %w", err) select {
case resp := <-respChan:
if status := resp.Status(); status == 404 {
pdk.Log(pdk.LogDebug, fmt.Sprintf("No cover art for MusicBrainz Album ID: %s", mbzAlbumID))
return "", nil
} else if status >= 400 {
return "", fmt.Errorf("HTTP %d", resp.Status())
}
if err := json.Unmarshal(resp.Body(), &result); err != nil {
return "", fmt.Errorf("failed to parse: %w", err)
}
case <-time.After(CAA_TIMEOUT):
return "", fmt.Errorf("Timed out")
} }
for _, image := range result.Images { for _, image := range result.Images {
+15
View File
@@ -2,6 +2,7 @@ package main
import ( import (
"errors" "errors"
"time"
"github.com/navidrome/navidrome/plugins/pdk/go/host" "github.com/navidrome/navidrome/plugins/pdk/go/host"
"github.com/navidrome/navidrome/plugins/pdk/go/pdk" "github.com/navidrome/navidrome/plugins/pdk/go/pdk"
@@ -165,5 +166,19 @@ var _ = Describe("getImageURL", func() {
Expect(url).To(Equal("https://example.com/art.jpg")) Expect(url).To(Equal("https://example.com/art.jpg"))
host.CacheMock.AssertCalled(GinkgoT(), "SetString", "caa.artwork.test", "", int64(86400)) host.CacheMock.AssertCalled(GinkgoT(), "SetString", "caa.artwork.test", "", int64(86400))
}) })
It("returns artwork directly after 5 second timeout", func() {
host.CacheMock.On("GetString", "caa.artwork.test").Return("", false, nil)
host.ArtworkMock.On("GetTrackUrl", "track1", int32(300)).Return("https://example.com/art.jpg", nil)
// Mock coverartarchive.org HTTP get
caaReq := &pdk.HTTPRequest{}
pdk.PDKMock.On("NewHTTPRequest", pdk.MethodGet, "https://coverartarchive.org/release/test").Return(caaReq)
pdk.PDKMock.On("Send", caaReq).WaitUntil(time.After(7 * time.Second)).Return(pdk.NewStubHTTPResponse(200, nil,
[]byte(`{"images":[{"front":false,"thumbnails":{"250":"https://coverartarchive.org/release/test/0-250.jpg"}}]}`)))
url := getImageURL("testuser", scrobbler.TrackInfo{ID: "track1", MBZAlbumID: "test"})
Expect(url).To(Equal("https://example.com/art.jpg"))
})
}) })
}) })