mirror of
https://github.com/navidrome/navidrome.git
synced 2026-03-04 06:35:52 +00:00
fix(plugins): update return types in metadata interfaces to use pointers
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
d6b412acde
commit
e6b0af63ce
@ -191,11 +191,11 @@ Agents = "lastfm,spotify,my-plugin"
|
||||
|
||||
Integrates with external scrobbling services. Export one or more of these functions:
|
||||
|
||||
| Function | Input | Output | Description |
|
||||
|------------------------------|-----------------------|-------------------------|-----------------------------|
|
||||
| `nd_scrobbler_is_authorized` | `{userId, username}` | `{authorized}` | Check if user is authorized |
|
||||
| `nd_scrobbler_now_playing` | See below | `{error?, errorType?}` | Send now playing |
|
||||
| `nd_scrobbler_scrobble` | See below | `{error?, errorType?}` | Submit a scrobble |
|
||||
| Function | Input | Output | Description |
|
||||
|------------------------------|-----------------------|----------------|-----------------------------||
|
||||
| `nd_scrobbler_is_authorized` | `{userId, username}` | `{authorized}` | Check if user is authorized |
|
||||
| `nd_scrobbler_now_playing` | See below | (none) | Send now playing |
|
||||
| `nd_scrobbler_scrobble` | See below | (none) | Submit a scrobble |
|
||||
|
||||
**NowPlaying/Scrobble Input:**
|
||||
|
||||
@ -220,21 +220,23 @@ Integrates with external scrobbling services. Export one or more of these functi
|
||||
}
|
||||
```
|
||||
|
||||
**Error Output (on failure):**
|
||||
**Error Handling:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "error message",
|
||||
"errorType": "notAuthorized|retryLater|unrecoverable"
|
||||
}
|
||||
On success, return `0`. On failure, use `pdk.SetError()` with one of these error types:
|
||||
|
||||
- `scrobbler(not_authorized)` – User needs to re-authorize
|
||||
- `scrobbler(retry_later)` – Temporary failure, Navidrome will retry
|
||||
- `scrobbler(unrecoverable)` – Permanent failure, scrobble discarded
|
||||
|
||||
```go
|
||||
import "github.com/navidrome/navidrome/plugins/pdk/go/scrobbler"
|
||||
|
||||
// Return error using predefined constants
|
||||
return scrobbler.ScrobblerErrorNotAuthorized
|
||||
return scrobbler.ScrobblerErrorRetryLater
|
||||
return scrobbler.ScrobblerErrorUnrecoverable
|
||||
```
|
||||
|
||||
- `notAuthorized` – User needs to re-authorize
|
||||
- `retryLater` – Temporary failure, Navidrome will retry
|
||||
- `unrecoverable` – Permanent failure, scrobble discarded
|
||||
|
||||
On success, return empty JSON `{}` or omit output entirely.
|
||||
|
||||
### Lifecycle
|
||||
|
||||
Optional initialization callback. Export this function to run code when your plugin loads:
|
||||
@ -718,8 +720,8 @@ import (
|
||||
|
||||
type myPlugin struct{}
|
||||
|
||||
func (p *myPlugin) GetArtistBiography(input metadata.ArtistBiographyInput) metadata.ArtistBiographyOutput {
|
||||
return metadata.ArtistBiographyOutput{Biography: "Biography text..."}
|
||||
func (p *myPlugin) GetArtistBiography(input metadata.ArtistRequest) (*metadata.ArtistBiographyResponse, error) {
|
||||
return &metadata.ArtistBiographyResponse{Biography: "Biography text..."}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
// //nd:capability name=metadata
|
||||
// type MetadataAgent interface {
|
||||
// //nd:export name=nd_get_artist_biography
|
||||
// GetArtistBiography(ArtistInput) (ArtistBiographyOutput, error)
|
||||
// GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
// }
|
||||
//
|
||||
// Annotation Reference:
|
||||
@ -35,7 +35,7 @@
|
||||
//
|
||||
// // Optional provider interfaces
|
||||
// type ArtistBiographyProvider interface {
|
||||
// GetArtistBiography(ArtistInput) (ArtistBiographyOutput, error)
|
||||
// GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
// }
|
||||
//
|
||||
// // Registration function
|
||||
@ -47,9 +47,9 @@
|
||||
//
|
||||
// // Scrobbler requires all methods
|
||||
// type Scrobbler interface {
|
||||
// IsAuthorized(AuthInput) (AuthOutput, error)
|
||||
// NowPlaying(NowPlayingInput) (ScrobblerOutput, error)
|
||||
// Scrobble(ScrobbleInput) (ScrobblerOutput, error)
|
||||
// IsAuthorized(IsAuthorizedRequest) (*IsAuthorizedResponse, error)
|
||||
// NowPlaying(NowPlayingRequest) error
|
||||
// Scrobble(ScrobbleRequest) error
|
||||
// }
|
||||
//
|
||||
// func Register(impl Scrobbler) { ... }
|
||||
|
||||
@ -11,35 +11,35 @@ package capabilities
|
||||
type MetadataAgent interface {
|
||||
// GetArtistMBID retrieves the MusicBrainz ID for an artist.
|
||||
//nd:export name=nd_get_artist_mbid
|
||||
GetArtistMBID(ArtistMBIDRequest) (ArtistMBIDResponse, error)
|
||||
GetArtistMBID(ArtistMBIDRequest) (*ArtistMBIDResponse, error)
|
||||
|
||||
// GetArtistURL retrieves the external URL for an artist.
|
||||
//nd:export name=nd_get_artist_url
|
||||
GetArtistURL(ArtistRequest) (ArtistURLResponse, error)
|
||||
GetArtistURL(ArtistRequest) (*ArtistURLResponse, error)
|
||||
|
||||
// GetArtistBiography retrieves the biography for an artist.
|
||||
//nd:export name=nd_get_artist_biography
|
||||
GetArtistBiography(ArtistRequest) (ArtistBiographyResponse, error)
|
||||
GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
|
||||
// GetSimilarArtists retrieves similar artists for a given artist.
|
||||
//nd:export name=nd_get_similar_artists
|
||||
GetSimilarArtists(SimilarArtistsRequest) (SimilarArtistsResponse, error)
|
||||
GetSimilarArtists(SimilarArtistsRequest) (*SimilarArtistsResponse, error)
|
||||
|
||||
// GetArtistImages retrieves images for an artist.
|
||||
//nd:export name=nd_get_artist_images
|
||||
GetArtistImages(ArtistRequest) (ArtistImagesResponse, error)
|
||||
GetArtistImages(ArtistRequest) (*ArtistImagesResponse, error)
|
||||
|
||||
// GetArtistTopSongs retrieves top songs for an artist.
|
||||
//nd:export name=nd_get_artist_top_songs
|
||||
GetArtistTopSongs(TopSongsRequest) (TopSongsResponse, error)
|
||||
GetArtistTopSongs(TopSongsRequest) (*TopSongsResponse, error)
|
||||
|
||||
// GetAlbumInfo retrieves album information.
|
||||
//nd:export name=nd_get_album_info
|
||||
GetAlbumInfo(AlbumRequest) (AlbumInfoResponse, error)
|
||||
GetAlbumInfo(AlbumRequest) (*AlbumInfoResponse, error)
|
||||
|
||||
// GetAlbumImages retrieves images for an album.
|
||||
//nd:export name=nd_get_album_images
|
||||
GetAlbumImages(AlbumRequest) (AlbumImagesResponse, error)
|
||||
GetAlbumImages(AlbumRequest) (*AlbumImagesResponse, error)
|
||||
}
|
||||
|
||||
// ArtistMBIDRequest is the request for GetArtistMBID.
|
||||
|
||||
@ -55,12 +55,12 @@ func (a *MetadataAgent) AgentName() string {
|
||||
// GetArtistMBID retrieves the MusicBrainz ID for an artist
|
||||
func (a *MetadataAgent) GetArtistMBID(ctx context.Context, id string, name string) (string, error) {
|
||||
input := capabilities.ArtistMBIDRequest{ID: id, Name: name}
|
||||
result, err := callPluginFunction[capabilities.ArtistMBIDRequest, capabilities.ArtistMBIDResponse](ctx, a.plugin, FuncGetArtistMBID, input)
|
||||
result, err := callPluginFunction[capabilities.ArtistMBIDRequest, *capabilities.ArtistMBIDResponse](ctx, a.plugin, FuncGetArtistMBID, input)
|
||||
if err != nil {
|
||||
return "", errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if result.MBID == "" {
|
||||
if result == nil || result.MBID == "" {
|
||||
return "", agents.ErrNotFound
|
||||
}
|
||||
|
||||
@ -70,11 +70,11 @@ func (a *MetadataAgent) GetArtistMBID(ctx context.Context, id string, name strin
|
||||
// GetArtistURL retrieves the external URL for an artist
|
||||
func (a *MetadataAgent) GetArtistURL(ctx context.Context, id, name, mbid string) (string, error) {
|
||||
input := capabilities.ArtistRequest{ID: id, Name: name, MBID: mbid}
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, capabilities.ArtistURLResponse](ctx, a.plugin, FuncGetArtistURL, input)
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, *capabilities.ArtistURLResponse](ctx, a.plugin, FuncGetArtistURL, input)
|
||||
if err != nil {
|
||||
return "", errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
if result.URL == "" {
|
||||
if result == nil || result.URL == "" {
|
||||
return "", agents.ErrNotFound
|
||||
}
|
||||
return result.URL, nil
|
||||
@ -83,12 +83,12 @@ func (a *MetadataAgent) GetArtistURL(ctx context.Context, id, name, mbid string)
|
||||
// GetArtistBiography retrieves the biography for an artist
|
||||
func (a *MetadataAgent) GetArtistBiography(ctx context.Context, id, name, mbid string) (string, error) {
|
||||
input := capabilities.ArtistRequest{ID: id, Name: name, MBID: mbid}
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, capabilities.ArtistBiographyResponse](ctx, a.plugin, FuncGetArtistBiography, input)
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, *capabilities.ArtistBiographyResponse](ctx, a.plugin, FuncGetArtistBiography, input)
|
||||
if err != nil {
|
||||
return "", errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if result.Biography == "" {
|
||||
if result == nil || result.Biography == "" {
|
||||
return "", agents.ErrNotFound
|
||||
}
|
||||
|
||||
@ -98,12 +98,12 @@ func (a *MetadataAgent) GetArtistBiography(ctx context.Context, id, name, mbid s
|
||||
// GetSimilarArtists retrieves similar artists
|
||||
func (a *MetadataAgent) GetSimilarArtists(ctx context.Context, id, name, mbid string, limit int) ([]agents.Artist, error) {
|
||||
input := capabilities.SimilarArtistsRequest{ID: id, Name: name, MBID: mbid, Limit: int32(limit)}
|
||||
result, err := callPluginFunction[capabilities.SimilarArtistsRequest, capabilities.SimilarArtistsResponse](ctx, a.plugin, FuncGetSimilarArtists, input)
|
||||
result, err := callPluginFunction[capabilities.SimilarArtistsRequest, *capabilities.SimilarArtistsResponse](ctx, a.plugin, FuncGetSimilarArtists, input)
|
||||
if err != nil {
|
||||
return nil, errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if len(result.Artists) == 0 {
|
||||
if result == nil || len(result.Artists) == 0 {
|
||||
return nil, agents.ErrNotFound
|
||||
}
|
||||
|
||||
@ -118,12 +118,12 @@ func (a *MetadataAgent) GetSimilarArtists(ctx context.Context, id, name, mbid st
|
||||
// GetArtistImages retrieves images for an artist
|
||||
func (a *MetadataAgent) GetArtistImages(ctx context.Context, id, name, mbid string) ([]agents.ExternalImage, error) {
|
||||
input := capabilities.ArtistRequest{ID: id, Name: name, MBID: mbid}
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, capabilities.ArtistImagesResponse](ctx, a.plugin, FuncGetArtistImages, input)
|
||||
result, err := callPluginFunction[capabilities.ArtistRequest, *capabilities.ArtistImagesResponse](ctx, a.plugin, FuncGetArtistImages, input)
|
||||
if err != nil {
|
||||
return nil, errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if len(result.Images) == 0 {
|
||||
if result == nil || len(result.Images) == 0 {
|
||||
return nil, agents.ErrNotFound
|
||||
}
|
||||
|
||||
@ -138,12 +138,12 @@ func (a *MetadataAgent) GetArtistImages(ctx context.Context, id, name, mbid stri
|
||||
// GetArtistTopSongs retrieves top songs for an artist
|
||||
func (a *MetadataAgent) GetArtistTopSongs(ctx context.Context, id, artistName, mbid string, count int) ([]agents.Song, error) {
|
||||
input := capabilities.TopSongsRequest{ID: id, Name: artistName, MBID: mbid, Count: int32(count)}
|
||||
result, err := callPluginFunction[capabilities.TopSongsRequest, capabilities.TopSongsResponse](ctx, a.plugin, FuncGetArtistTopSongs, input)
|
||||
result, err := callPluginFunction[capabilities.TopSongsRequest, *capabilities.TopSongsResponse](ctx, a.plugin, FuncGetArtistTopSongs, input)
|
||||
if err != nil {
|
||||
return nil, errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if len(result.Songs) == 0 {
|
||||
if result == nil || len(result.Songs) == 0 {
|
||||
return nil, agents.ErrNotFound
|
||||
}
|
||||
|
||||
@ -158,11 +158,15 @@ func (a *MetadataAgent) GetArtistTopSongs(ctx context.Context, id, artistName, m
|
||||
// GetAlbumInfo retrieves album information
|
||||
func (a *MetadataAgent) GetAlbumInfo(ctx context.Context, name, artist, mbid string) (*agents.AlbumInfo, error) {
|
||||
input := capabilities.AlbumRequest{Name: name, Artist: artist, MBID: mbid}
|
||||
result, err := callPluginFunction[capabilities.AlbumRequest, capabilities.AlbumInfoResponse](ctx, a.plugin, FuncGetAlbumInfo, input)
|
||||
result, err := callPluginFunction[capabilities.AlbumRequest, *capabilities.AlbumInfoResponse](ctx, a.plugin, FuncGetAlbumInfo, input)
|
||||
if err != nil {
|
||||
return nil, errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
return nil, agents.ErrNotFound
|
||||
}
|
||||
|
||||
return &agents.AlbumInfo{
|
||||
Name: result.Name,
|
||||
MBID: result.MBID,
|
||||
@ -174,12 +178,12 @@ func (a *MetadataAgent) GetAlbumInfo(ctx context.Context, name, artist, mbid str
|
||||
// GetAlbumImages retrieves images for an album
|
||||
func (a *MetadataAgent) GetAlbumImages(ctx context.Context, name, artist, mbid string) ([]agents.ExternalImage, error) {
|
||||
input := capabilities.AlbumRequest{Name: name, Artist: artist, MBID: mbid}
|
||||
result, err := callPluginFunction[capabilities.AlbumRequest, capabilities.AlbumImagesResponse](ctx, a.plugin, FuncGetAlbumImages, input)
|
||||
result, err := callPluginFunction[capabilities.AlbumRequest, *capabilities.AlbumImagesResponse](ctx, a.plugin, FuncGetAlbumImages, input)
|
||||
if err != nil {
|
||||
return nil, errors.Join(agents.ErrNotFound, err)
|
||||
}
|
||||
|
||||
if len(result.Images) == 0 {
|
||||
if result == nil || len(result.Images) == 0 {
|
||||
return nil, agents.ErrNotFound
|
||||
}
|
||||
|
||||
|
||||
@ -153,52 +153,52 @@ type Metadata interface{}
|
||||
|
||||
// ArtistMBIDProvider provides the GetArtistMBID function.
|
||||
type ArtistMBIDProvider interface {
|
||||
GetArtistMBID(ArtistMBIDRequest) (ArtistMBIDResponse, error)
|
||||
GetArtistMBID(ArtistMBIDRequest) (*ArtistMBIDResponse, error)
|
||||
}
|
||||
|
||||
// ArtistURLProvider provides the GetArtistURL function.
|
||||
type ArtistURLProvider interface {
|
||||
GetArtistURL(ArtistRequest) (ArtistURLResponse, error)
|
||||
GetArtistURL(ArtistRequest) (*ArtistURLResponse, error)
|
||||
}
|
||||
|
||||
// ArtistBiographyProvider provides the GetArtistBiography function.
|
||||
type ArtistBiographyProvider interface {
|
||||
GetArtistBiography(ArtistRequest) (ArtistBiographyResponse, error)
|
||||
GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
}
|
||||
|
||||
// SimilarArtistsProvider provides the GetSimilarArtists function.
|
||||
type SimilarArtistsProvider interface {
|
||||
GetSimilarArtists(SimilarArtistsRequest) (SimilarArtistsResponse, error)
|
||||
GetSimilarArtists(SimilarArtistsRequest) (*SimilarArtistsResponse, error)
|
||||
}
|
||||
|
||||
// ArtistImagesProvider provides the GetArtistImages function.
|
||||
type ArtistImagesProvider interface {
|
||||
GetArtistImages(ArtistRequest) (ArtistImagesResponse, error)
|
||||
GetArtistImages(ArtistRequest) (*ArtistImagesResponse, error)
|
||||
}
|
||||
|
||||
// ArtistTopSongsProvider provides the GetArtistTopSongs function.
|
||||
type ArtistTopSongsProvider interface {
|
||||
GetArtistTopSongs(TopSongsRequest) (TopSongsResponse, error)
|
||||
GetArtistTopSongs(TopSongsRequest) (*TopSongsResponse, error)
|
||||
}
|
||||
|
||||
// AlbumInfoProvider provides the GetAlbumInfo function.
|
||||
type AlbumInfoProvider interface {
|
||||
GetAlbumInfo(AlbumRequest) (AlbumInfoResponse, error)
|
||||
GetAlbumInfo(AlbumRequest) (*AlbumInfoResponse, error)
|
||||
}
|
||||
|
||||
// AlbumImagesProvider provides the GetAlbumImages function.
|
||||
type AlbumImagesProvider interface {
|
||||
GetAlbumImages(AlbumRequest) (AlbumImagesResponse, error)
|
||||
GetAlbumImages(AlbumRequest) (*AlbumImagesResponse, error)
|
||||
} // Internal implementation holders
|
||||
var (
|
||||
artistMBIDImpl func(ArtistMBIDRequest) (ArtistMBIDResponse, error)
|
||||
artistURLImpl func(ArtistRequest) (ArtistURLResponse, error)
|
||||
artistBiographyImpl func(ArtistRequest) (ArtistBiographyResponse, error)
|
||||
similarArtistsImpl func(SimilarArtistsRequest) (SimilarArtistsResponse, error)
|
||||
artistImagesImpl func(ArtistRequest) (ArtistImagesResponse, error)
|
||||
artistTopSongsImpl func(TopSongsRequest) (TopSongsResponse, error)
|
||||
albumInfoImpl func(AlbumRequest) (AlbumInfoResponse, error)
|
||||
albumImagesImpl func(AlbumRequest) (AlbumImagesResponse, error)
|
||||
artistMBIDImpl func(ArtistMBIDRequest) (*ArtistMBIDResponse, error)
|
||||
artistURLImpl func(ArtistRequest) (*ArtistURLResponse, error)
|
||||
artistBiographyImpl func(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
similarArtistsImpl func(SimilarArtistsRequest) (*SimilarArtistsResponse, error)
|
||||
artistImagesImpl func(ArtistRequest) (*ArtistImagesResponse, error)
|
||||
artistTopSongsImpl func(TopSongsRequest) (*TopSongsResponse, error)
|
||||
albumInfoImpl func(AlbumRequest) (*AlbumInfoResponse, error)
|
||||
albumImagesImpl func(AlbumRequest) (*AlbumImagesResponse, error)
|
||||
)
|
||||
|
||||
// Register registers a metadata implementation.
|
||||
|
||||
@ -150,42 +150,42 @@ type Metadata interface{}
|
||||
|
||||
// ArtistMBIDProvider provides the GetArtistMBID function.
|
||||
type ArtistMBIDProvider interface {
|
||||
GetArtistMBID(ArtistMBIDRequest) (ArtistMBIDResponse, error)
|
||||
GetArtistMBID(ArtistMBIDRequest) (*ArtistMBIDResponse, error)
|
||||
}
|
||||
|
||||
// ArtistURLProvider provides the GetArtistURL function.
|
||||
type ArtistURLProvider interface {
|
||||
GetArtistURL(ArtistRequest) (ArtistURLResponse, error)
|
||||
GetArtistURL(ArtistRequest) (*ArtistURLResponse, error)
|
||||
}
|
||||
|
||||
// ArtistBiographyProvider provides the GetArtistBiography function.
|
||||
type ArtistBiographyProvider interface {
|
||||
GetArtistBiography(ArtistRequest) (ArtistBiographyResponse, error)
|
||||
GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
||||
}
|
||||
|
||||
// SimilarArtistsProvider provides the GetSimilarArtists function.
|
||||
type SimilarArtistsProvider interface {
|
||||
GetSimilarArtists(SimilarArtistsRequest) (SimilarArtistsResponse, error)
|
||||
GetSimilarArtists(SimilarArtistsRequest) (*SimilarArtistsResponse, error)
|
||||
}
|
||||
|
||||
// ArtistImagesProvider provides the GetArtistImages function.
|
||||
type ArtistImagesProvider interface {
|
||||
GetArtistImages(ArtistRequest) (ArtistImagesResponse, error)
|
||||
GetArtistImages(ArtistRequest) (*ArtistImagesResponse, error)
|
||||
}
|
||||
|
||||
// ArtistTopSongsProvider provides the GetArtistTopSongs function.
|
||||
type ArtistTopSongsProvider interface {
|
||||
GetArtistTopSongs(TopSongsRequest) (TopSongsResponse, error)
|
||||
GetArtistTopSongs(TopSongsRequest) (*TopSongsResponse, error)
|
||||
}
|
||||
|
||||
// AlbumInfoProvider provides the GetAlbumInfo function.
|
||||
type AlbumInfoProvider interface {
|
||||
GetAlbumInfo(AlbumRequest) (AlbumInfoResponse, error)
|
||||
GetAlbumInfo(AlbumRequest) (*AlbumInfoResponse, error)
|
||||
}
|
||||
|
||||
// AlbumImagesProvider provides the GetAlbumImages function.
|
||||
type AlbumImagesProvider interface {
|
||||
GetAlbumImages(AlbumRequest) (AlbumImagesResponse, error)
|
||||
GetAlbumImages(AlbumRequest) (*AlbumImagesResponse, error)
|
||||
}
|
||||
|
||||
// NotImplementedCode is the standard return code for unimplemented functions.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user