Add optional MusicBrainz/Cover Art Archive metadata enrichment
getArtistInfo/2 and getAlbumInfo/2 now return a real MusicBrainz disambiguation/cover-art lookup for entities that carry a locally tagged MusicBrainz ID, gated behind the new VIBESONIC_ENABLE_EXTERNAL_METADATA flag (default off). Responses are cached in the existing external_metadata_cache table for 30 days to avoid hammering the free MusicBrainz/CAA services. VibeSonic still works completely offline: with the flag off, or when an entity has no tagged MusicBrainz ID, or on any network/lookup failure, the handlers fall back to local-only fields exactly as before — nothing is ever fabricated, and a failed external lookup never fails the request. internal/metadataenrich is a small, independently-testable HTTP client for the two real APIs (base URLs overridable for tests, exercised against httptest servers rather than the live network). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014r98AtcBbevpscWLsfwVvv
This commit is contained in:
@@ -88,44 +88,50 @@ func handleGetVideoInfo(rc *Context) *apiError {
|
||||
return nil
|
||||
}
|
||||
|
||||
// --- Artist/album info: VibeSonic has no external metadata provider
|
||||
// (last.fm etc.) in Phase 2, so these honestly return only what's known
|
||||
// locally — which for biography/images/similar-artists is nothing —
|
||||
// rather than fabricating placeholder content. ---
|
||||
// --- Artist/album info: local data only (title/name, and a
|
||||
// MusicBrainz ID if one was tagged), optionally enriched from
|
||||
// MusicBrainz/Cover Art Archive when VIBESONIC_ENABLE_EXTERNAL_METADATA
|
||||
// is set and the entity has a tagged MusicBrainz ID — see enrich.go.
|
||||
// VibeSonic must work completely offline; enrichment is always
|
||||
// best-effort and never blocks or fails the response. ---
|
||||
|
||||
func handleGetArtistInfo(rc *Context) *apiError {
|
||||
if _, aerr := rc.Params.Required("id"); aerr != nil {
|
||||
id, aerr := rc.Params.Required("id")
|
||||
if aerr != nil {
|
||||
return aerr
|
||||
}
|
||||
rc.Response = newResponse()
|
||||
rc.Response.ArtistInfo = &ArtistInfo{}
|
||||
rc.Response.ArtistInfo = &ArtistInfo{ArtistInfoBase: artistInfoBase(rc, id)}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleGetArtistInfo2(rc *Context) *apiError {
|
||||
if _, aerr := rc.Params.Required("id"); aerr != nil {
|
||||
id, aerr := rc.Params.Required("id")
|
||||
if aerr != nil {
|
||||
return aerr
|
||||
}
|
||||
rc.Response = newResponse()
|
||||
rc.Response.ArtistInfo2 = &ArtistInfo2{}
|
||||
rc.Response.ArtistInfo2 = &ArtistInfo2{ArtistInfoBase: artistInfoBase(rc, id)}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleGetAlbumInfo(rc *Context) *apiError {
|
||||
if _, aerr := rc.Params.Required("id"); aerr != nil {
|
||||
id, aerr := rc.Params.Required("id")
|
||||
if aerr != nil {
|
||||
return aerr
|
||||
}
|
||||
rc.Response = newResponse()
|
||||
rc.Response.AlbumInfo = &AlbumInfo{}
|
||||
rc.Response.AlbumInfo = albumInfo(rc, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleGetAlbumInfo2(rc *Context) *apiError {
|
||||
if _, aerr := rc.Params.Required("id"); aerr != nil {
|
||||
id, aerr := rc.Params.Required("id")
|
||||
if aerr != nil {
|
||||
return aerr
|
||||
}
|
||||
rc.Response = newResponse()
|
||||
rc.Response.AlbumInfo = &AlbumInfo{}
|
||||
rc.Response.AlbumInfo = albumInfo(rc, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user