diff --git a/.gitignore b/.gitignore index 7507013..d59dcd0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ go.work # Build artifacts +audiomuse-navidrome-plugin bin/ dist/ build/ diff --git a/audiomuse_api.go b/audiomuse_api.go index 04cc7f2..1514187 100644 --- a/audiomuse_api.go +++ b/audiomuse_api.go @@ -6,6 +6,7 @@ import ( "net/url" "strconv" + "github.com/navidrome/navidrome/plugins/pdk/go/host" "github.com/navidrome/navidrome/plugins/pdk/go/pdk" ) @@ -36,19 +37,29 @@ func getSimilarArtists(id string, includeComponentMatches bool) ([]SimilarArtist apiURL := fmt.Sprintf("%s/api/similar_artists?%s", apiBaseURL, params.Encode()) pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] Calling GetSimilarArtists API for artist ID %s: %s", id, apiURL)) - req := pdk.NewHTTPRequest(pdk.MethodGet, apiURL) - resp := req.Send() + // Make HTTP GET request to AudioMuse-AI using the host HTTP service. + // This uses host.HTTPSend as recommended by Navidrome upstream (migrated from pdk.NewHTTPRequest). + resp, err := host.HTTPSend(host.HTTPRequest{ + Method: "GET", + URL: apiURL, + Headers: authHeaders(), + }) + if err != nil { + errMsg := fmt.Sprintf("[AudioMuse] ERROR: HTTP request failed: %v", err) + pdk.Log(pdk.LogError, errMsg) + return nil, fmt.Errorf("AudioMuse-AI HTTP request failed: %w", err) + } - pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] API response status: %d", resp.Status())) - if resp.Status() != 200 { - errMsg := fmt.Sprintf("[AudioMuse] ERROR: AudioMuse-AI returned status %d", resp.Status()) + pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] API response status: %d", resp.StatusCode)) + if resp.StatusCode != 200 { + errMsg := fmt.Sprintf("[AudioMuse] ERROR: AudioMuse-AI returned status %d", resp.StatusCode) pdk.Log(pdk.LogError, errMsg) - return nil, fmt.Errorf("AudioMuse-AI returned status %d", resp.Status()) + return nil, fmt.Errorf("AudioMuse-AI returned status %d", resp.StatusCode) } var artists []SimilarArtistsResponse - body := resp.Body() + body := resp.Body if err := json.Unmarshal(body, &artists); err != nil { errMsg := fmt.Sprintf("[AudioMuse] ERROR: Failed to parse artist response: %v", err) pdk.Log(pdk.LogError, errMsg) diff --git a/go.mod b/go.mod index 8a1de5e..5df3acc 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module audiomuse-navidrome-plugin go 1.25 -require github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260128174646-77367548f6a2 +require github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260224192836-652c27690be6 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/go.sum b/go.sum index 15186f5..87e4892 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/extism/go-pdk v1.1.3 h1:hfViMPWrqjN6u67cIYRALZTZLk/enSPpNKa+rZ9X2SQ= github.com/extism/go-pdk v1.1.3/go.mod h1:Gz+LIU/YCKnKXhgge8yo5Yu1F/lbv7KtKFkiCSzW/P4= -github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260128174646-77367548f6a2 h1:5apPLTMuyJFAMVQr1pT3Zo+Y1K7yzz6N+a9yLcfHhMU= -github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260128174646-77367548f6a2/go.mod h1:5aedoevIXlwUFuR7kbd/WkjaiLg87D3XUFRGIwDBroo= +github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260224192836-652c27690be6 h1:nALRtN92GA309if/sS7KG/p3L613ye4CiyQf1kEXmG8= +github.com/navidrome/navidrome/plugins/pdk/go v0.0.0-20260224192836-652c27690be6/go.mod h1:HijQ0Z0OeEa6LIwUJh6H9WqAptye096jHazmKXf+YV4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= diff --git a/main.go b/main.go index af32d50..5db59a4 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "slices" "strconv" + "github.com/navidrome/navidrome/plugins/pdk/go/host" "github.com/navidrome/navidrome/plugins/pdk/go/metadata" "github.com/navidrome/navidrome/plugins/pdk/go/pdk" ) @@ -14,6 +15,7 @@ import ( // Configuration keys (must match manifest.json) const ( configAPIUrl = "apiUrl" + configAPIToken = "apiToken" configEliminateDuplicates = "eliminateDuplicates" configRadiusSimilarity = "radiusSimilarity" ) @@ -75,6 +77,16 @@ func getConfigBool(key string, defaultValue bool) bool { return defaultValue } +// authHeaders returns a headers map with a Bearer token if configured, or nil otherwise. +func authHeaders() map[string]string { + if token := getConfigString(configAPIToken, ""); token != "" { + return map[string]string{ + "Authorization": "Bearer " + token, + } + } + return nil +} + func (p *audioMusePlugin) GetSimilarSongsByTrack(input metadata.SimilarSongsByTrackRequest) (*metadata.SimilarSongsResponse, error) { pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] GetSimilarSongsByTrack called for track ID: %s, Name: %s, Artist: %s", input.ID, input.Name, input.Artist)) @@ -97,21 +109,30 @@ func (p *audioMusePlugin) GetSimilarSongsByTrack(input metadata.SimilarSongsByTr pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] Calling API: %s", apiURL)) - // Make HTTP GET request to AudioMuse-AI using PDK - req := pdk.NewHTTPRequest(pdk.MethodGet, apiURL) - resp := req.Send() + // Make HTTP GET request to AudioMuse-AI using the host HTTP service. + // This uses host.HTTPSend as recommended by Navidrome upstream (migrated from pdk.NewHTTPRequest). + resp, err := host.HTTPSend(host.HTTPRequest{ + Method: "GET", + URL: apiURL, + Headers: authHeaders(), + }) + if err != nil { + errMsg := fmt.Sprintf("[AudioMuse] ERROR: HTTP request failed: %v", err) + pdk.Log(pdk.LogError, errMsg) + return nil, fmt.Errorf("AudioMuse-AI HTTP request failed: %w", err) + } - pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] API response status: %d", resp.Status())) + pdk.Log(pdk.LogInfo, fmt.Sprintf("[AudioMuse] API response status: %d", resp.StatusCode)) - if resp.Status() != 200 { - errMsg := fmt.Sprintf("[AudioMuse] ERROR: AudioMuse-AI returned status %d", resp.Status()) + if resp.StatusCode != 200 { + errMsg := fmt.Sprintf("[AudioMuse] ERROR: AudioMuse-AI returned status %d", resp.StatusCode) pdk.Log(pdk.LogError, errMsg) - return nil, fmt.Errorf("AudioMuse-AI returned status %d", resp.Status()) + return nil, fmt.Errorf("AudioMuse-AI returned status %d", resp.StatusCode) } // Parse JSON response var tracks []audioMuseResponse - body := resp.Body() + body := resp.Body pdk.Log(pdk.LogDebug, fmt.Sprintf("[AudioMuse] Response body length: %d bytes", len(body))) if err := json.Unmarshal(body, &tracks); err != nil { diff --git a/manifest.json b/manifest.json index 51c49af..ed0f29e 100644 --- a/manifest.json +++ b/manifest.json @@ -15,6 +15,11 @@ "description": "Base URL for the AudioMuse-AI server (e.g., http://192.168.3.203:8000).", "default": "http://192.168.3.203:8000" }, + "apiToken": { + "type": "string", + "title": "API Token", + "description": "Optional Bearer token for AudioMuse-AI API authentication. Leave blank if not required." + }, "artistSimilarCount": { "type": "integer", "title": "Number of Similar Artists", @@ -47,6 +52,13 @@ { "type": "Control", "scope": "#/properties/apiUrl" + }, + { + "type": "Control", + "scope": "#/properties/apiToken", + "options": { + "format": "password" + } } ] },