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:
2026-08-23 08:35:40 -05:00
co-authored by Claude Sonnet 5
parent 2a69f6dc33
commit a921f9e2bc
7 changed files with 649 additions and 12 deletions
+9
View File
@@ -26,6 +26,13 @@ type Config struct {
SessionSecret string
CookieSecure bool
// EnableExternalMetadata opts into looking up MusicBrainz/Cover Art
// Archive data for songs/albums that already carry a locally-tagged
// MusicBrainz ID. Off by default: VibeSonic must work completely
// without Internet access, and this is the only feature that talks
// to the outside world.
EnableExternalMetadata bool
ExtAuth ExtAuthConfig
}
@@ -53,6 +60,8 @@ func Load() (Config, error) {
MPVPath: envOr("VIBESONIC_MPV_PATH", "mpv"),
SessionSecret: os.Getenv("VIBESONIC_SESSION_SECRET"),
CookieSecure: envBool("VIBESONIC_COOKIE_SECURE", true),
EnableExternalMetadata: envBool("VIBESONIC_ENABLE_EXTERNAL_METADATA", false),
}
cfg.DBPath = envOr("VIBESONIC_DB", filepath.Join(cfg.DataDir, "vibesonic.db"))