mirror of
https://github.com/navidrome/navidrome.git
synced 2026-11-13 13:48:39 +01:00
A MetadataAgent plugin reports "I have no data for this item" by returning an empty response with a nil error. Any error it returns instead is treated as a plugin fault and retried with backoff. That rule was not documented anywhere, so an author naturally returns an error for a missing item, and Navidrome then retries every item the plugin's source does not cover. This is not hypothetical: the artist-nfo-metadata plugin returned an error for every artist without an artist.nfo, which kept those artists in the artwork retry queue for hours and tripped the artwork circuit breaker for the plugin as a whole. Document the rule on the capability interface, which ndpgen copies into the Go PDK, and in the MetadataAgent section of the plugin README.
599 lines
16 KiB
Go
599 lines
16 KiB
Go
// Code generated by ndpgen. DO NOT EDIT.
|
|
//
|
|
// This file contains export wrappers for the MetadataAgent capability.
|
|
// It is intended for use in Navidrome plugins built with TinyGo.
|
|
//
|
|
//go:build wasip1
|
|
|
|
package metadata
|
|
|
|
import (
|
|
"github.com/navidrome/navidrome/plugins/pdk/go/pdk"
|
|
"github.com/navidrome/navidrome/plugins/pdk/go/types"
|
|
)
|
|
|
|
// Deprecated: use types.ArtistRef.
|
|
type ArtistRef = types.ArtistRef
|
|
|
|
// Deprecated: use types.SongRef.
|
|
type SongRef = types.SongRef
|
|
|
|
// AlbumImagesResponse is the response for GetAlbumImages.
|
|
type AlbumImagesResponse struct {
|
|
// Images is the list of album images.
|
|
Images []ImageInfo `json:"images"`
|
|
}
|
|
|
|
// AlbumInfoResponse is the response for GetAlbumInfo.
|
|
type AlbumInfoResponse struct {
|
|
// Name is the album name.
|
|
Name string `json:"name"`
|
|
// MBID is the MusicBrainz ID for the album.
|
|
MBID string `json:"mbid"`
|
|
// Description is the album description/notes.
|
|
Description string `json:"description"`
|
|
// URL is the external URL for the album.
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
// AlbumRequest is the common request for album-related functions.
|
|
type AlbumRequest struct {
|
|
// Name is the album name.
|
|
Name string `json:"name"`
|
|
// Artist is the album artist name.
|
|
Artist string `json:"artist"`
|
|
// MBID is the MusicBrainz ID for the album (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
}
|
|
|
|
// ArtistBiographyResponse is the response for GetArtistBiography.
|
|
type ArtistBiographyResponse struct {
|
|
// Biography is the artist biography text.
|
|
Biography string `json:"biography"`
|
|
}
|
|
|
|
// ArtistImagesResponse is the response for GetArtistImages.
|
|
type ArtistImagesResponse struct {
|
|
// Images is the list of artist images.
|
|
Images []ImageInfo `json:"images"`
|
|
}
|
|
|
|
// ArtistMBIDRequest is the request for GetArtistMBID.
|
|
type ArtistMBIDRequest struct {
|
|
// ID is the internal Navidrome artist ID.
|
|
ID string `json:"id"`
|
|
// Name is the artist name.
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
// ArtistMBIDResponse is the response for GetArtistMBID.
|
|
type ArtistMBIDResponse struct {
|
|
// MBID is the MusicBrainz ID for the artist.
|
|
MBID string `json:"mbid"`
|
|
}
|
|
|
|
// ArtistRequest is the common request for artist-related functions.
|
|
type ArtistRequest struct {
|
|
// ID is the internal Navidrome artist ID.
|
|
ID string `json:"id"`
|
|
// Name is the artist name.
|
|
Name string `json:"name"`
|
|
// MBID is the MusicBrainz ID for the artist (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
}
|
|
|
|
// ArtistURLResponse is the response for GetArtistURL.
|
|
type ArtistURLResponse struct {
|
|
// URL is the external URL for the artist.
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
// ImageInfo represents an image with URL and size.
|
|
type ImageInfo struct {
|
|
// URL is the URL of the image.
|
|
URL string `json:"url"`
|
|
// Size is the size of the image in pixels (width or height).
|
|
Size int32 `json:"size"`
|
|
}
|
|
|
|
// SimilarArtistsRequest is the request for GetSimilarArtists.
|
|
type SimilarArtistsRequest struct {
|
|
// ID is the internal Navidrome artist ID.
|
|
ID string `json:"id"`
|
|
// Name is the artist name.
|
|
Name string `json:"name"`
|
|
// MBID is the MusicBrainz ID for the artist (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
// Limit is the maximum number of similar artists to return.
|
|
Limit int32 `json:"limit"`
|
|
}
|
|
|
|
// SimilarArtistsResponse is the response for GetSimilarArtists.
|
|
type SimilarArtistsResponse struct {
|
|
// Artists is the list of similar artists.
|
|
Artists []types.ArtistRef `json:"artists"`
|
|
}
|
|
|
|
// SimilarSongsByAlbumRequest is the request for GetSimilarSongsByAlbum.
|
|
type SimilarSongsByAlbumRequest struct {
|
|
// ID is the internal Navidrome album ID.
|
|
ID string `json:"id"`
|
|
// Name is the album name.
|
|
Name string `json:"name"`
|
|
// Artist is the album artist name.
|
|
Artist string `json:"artist"`
|
|
// MBID is the MusicBrainz release ID (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
// Count is the maximum number of similar songs to return.
|
|
Count int32 `json:"count"`
|
|
}
|
|
|
|
// SimilarSongsByArtistRequest is the request for GetSimilarSongsByArtist.
|
|
type SimilarSongsByArtistRequest struct {
|
|
// ID is the internal Navidrome artist ID.
|
|
ID string `json:"id"`
|
|
// Name is the artist name.
|
|
Name string `json:"name"`
|
|
// MBID is the MusicBrainz artist ID (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
// Count is the maximum number of similar songs to return.
|
|
Count int32 `json:"count"`
|
|
}
|
|
|
|
// SimilarSongsByTrackRequest is the request for GetSimilarSongsByTrack.
|
|
type SimilarSongsByTrackRequest struct {
|
|
// ID is the internal Navidrome mediafile ID.
|
|
ID string `json:"id"`
|
|
// Name is the track title.
|
|
Name string `json:"name"`
|
|
// Artist is the artist name.
|
|
Artist string `json:"artist"`
|
|
// MBID is the MusicBrainz recording ID (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
// Count is the maximum number of similar songs to return.
|
|
Count int32 `json:"count"`
|
|
}
|
|
|
|
// SimilarSongsResponse is the response for GetSimilarSongsBy* functions.
|
|
type SimilarSongsResponse struct {
|
|
// Songs is the list of similar songs.
|
|
Songs []types.SongRef `json:"songs"`
|
|
}
|
|
|
|
// TopSongsRequest is the request for GetArtistTopSongs.
|
|
type TopSongsRequest struct {
|
|
// ID is the internal Navidrome artist ID.
|
|
ID string `json:"id"`
|
|
// Name is the artist name.
|
|
Name string `json:"name"`
|
|
// MBID is the MusicBrainz ID for the artist (if known).
|
|
MBID string `json:"mbid,omitempty"`
|
|
// Count is the maximum number of top songs to return.
|
|
Count int32 `json:"count"`
|
|
}
|
|
|
|
// TopSongsResponse is the response for GetArtistTopSongs.
|
|
type TopSongsResponse struct {
|
|
// Songs is the list of top songs.
|
|
Songs []types.SongRef `json:"songs"`
|
|
}
|
|
|
|
// Metadata is the marker interface for metadata plugins.
|
|
// Implement one or more of the provider interfaces below.
|
|
// MetadataAgent provides artist and album metadata retrieval.
|
|
// This capability allows plugins to provide external metadata for artists and albums,
|
|
// such as biographies, images, similar artists, and top songs.
|
|
//
|
|
// Plugins implementing this capability can choose which methods to implement.
|
|
// Each method is optional - plugins only need to provide the functionality they support.
|
|
//
|
|
// To say "no data for this item", return a nil response and a nil error. Return an error only when
|
|
// the plugin itself failed, because Navidrome retries failed calls with backoff.
|
|
type Metadata interface{}
|
|
|
|
// ArtistMBIDProvider provides the GetArtistMBID function.
|
|
type ArtistMBIDProvider interface {
|
|
GetArtistMBID(ArtistMBIDRequest) (*ArtistMBIDResponse, error)
|
|
}
|
|
|
|
// ArtistURLProvider provides the GetArtistURL function.
|
|
type ArtistURLProvider interface {
|
|
GetArtistURL(ArtistRequest) (*ArtistURLResponse, error)
|
|
}
|
|
|
|
// ArtistBiographyProvider provides the GetArtistBiography function.
|
|
type ArtistBiographyProvider interface {
|
|
GetArtistBiography(ArtistRequest) (*ArtistBiographyResponse, error)
|
|
}
|
|
|
|
// SimilarArtistsProvider provides the GetSimilarArtists function.
|
|
type SimilarArtistsProvider interface {
|
|
GetSimilarArtists(SimilarArtistsRequest) (*SimilarArtistsResponse, error)
|
|
}
|
|
|
|
// ArtistImagesProvider provides the GetArtistImages function.
|
|
type ArtistImagesProvider interface {
|
|
GetArtistImages(ArtistRequest) (*ArtistImagesResponse, error)
|
|
}
|
|
|
|
// ArtistTopSongsProvider provides the GetArtistTopSongs function.
|
|
type ArtistTopSongsProvider interface {
|
|
GetArtistTopSongs(TopSongsRequest) (*TopSongsResponse, error)
|
|
}
|
|
|
|
// AlbumInfoProvider provides the GetAlbumInfo function.
|
|
type AlbumInfoProvider interface {
|
|
GetAlbumInfo(AlbumRequest) (*AlbumInfoResponse, error)
|
|
}
|
|
|
|
// AlbumImagesProvider provides the GetAlbumImages function.
|
|
type AlbumImagesProvider interface {
|
|
GetAlbumImages(AlbumRequest) (*AlbumImagesResponse, error)
|
|
}
|
|
|
|
// SimilarSongsByTrackProvider provides the GetSimilarSongsByTrack function.
|
|
type SimilarSongsByTrackProvider interface {
|
|
GetSimilarSongsByTrack(SimilarSongsByTrackRequest) (*SimilarSongsResponse, error)
|
|
}
|
|
|
|
// SimilarSongsByAlbumProvider provides the GetSimilarSongsByAlbum function.
|
|
type SimilarSongsByAlbumProvider interface {
|
|
GetSimilarSongsByAlbum(SimilarSongsByAlbumRequest) (*SimilarSongsResponse, error)
|
|
}
|
|
|
|
// SimilarSongsByArtistProvider provides the GetSimilarSongsByArtist function.
|
|
type SimilarSongsByArtistProvider interface {
|
|
GetSimilarSongsByArtist(SimilarSongsByArtistRequest) (*SimilarSongsResponse, 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)
|
|
similarSongsByTrackImpl func(SimilarSongsByTrackRequest) (*SimilarSongsResponse, error)
|
|
similarSongsByAlbumImpl func(SimilarSongsByAlbumRequest) (*SimilarSongsResponse, error)
|
|
similarSongsByArtistImpl func(SimilarSongsByArtistRequest) (*SimilarSongsResponse, error)
|
|
)
|
|
|
|
// Register registers a metadata implementation.
|
|
// The implementation is checked for optional provider interfaces.
|
|
func Register(impl Metadata) {
|
|
if p, ok := impl.(ArtistMBIDProvider); ok {
|
|
artistMBIDImpl = p.GetArtistMBID
|
|
}
|
|
if p, ok := impl.(ArtistURLProvider); ok {
|
|
artistURLImpl = p.GetArtistURL
|
|
}
|
|
if p, ok := impl.(ArtistBiographyProvider); ok {
|
|
artistBiographyImpl = p.GetArtistBiography
|
|
}
|
|
if p, ok := impl.(SimilarArtistsProvider); ok {
|
|
similarArtistsImpl = p.GetSimilarArtists
|
|
}
|
|
if p, ok := impl.(ArtistImagesProvider); ok {
|
|
artistImagesImpl = p.GetArtistImages
|
|
}
|
|
if p, ok := impl.(ArtistTopSongsProvider); ok {
|
|
artistTopSongsImpl = p.GetArtistTopSongs
|
|
}
|
|
if p, ok := impl.(AlbumInfoProvider); ok {
|
|
albumInfoImpl = p.GetAlbumInfo
|
|
}
|
|
if p, ok := impl.(AlbumImagesProvider); ok {
|
|
albumImagesImpl = p.GetAlbumImages
|
|
}
|
|
if p, ok := impl.(SimilarSongsByTrackProvider); ok {
|
|
similarSongsByTrackImpl = p.GetSimilarSongsByTrack
|
|
}
|
|
if p, ok := impl.(SimilarSongsByAlbumProvider); ok {
|
|
similarSongsByAlbumImpl = p.GetSimilarSongsByAlbum
|
|
}
|
|
if p, ok := impl.(SimilarSongsByArtistProvider); ok {
|
|
similarSongsByArtistImpl = p.GetSimilarSongsByArtist
|
|
}
|
|
}
|
|
|
|
// NotImplementedCode is the standard return code for unimplemented functions.
|
|
// The host recognizes this and skips the plugin gracefully.
|
|
const NotImplementedCode int32 = -2
|
|
|
|
//go:wasmexport nd_get_artist_mbid
|
|
func _NdGetArtistMbid() int32 {
|
|
if artistMBIDImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input ArtistMBIDRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := artistMBIDImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_artist_url
|
|
func _NdGetArtistUrl() int32 {
|
|
if artistURLImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input ArtistRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := artistURLImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_artist_biography
|
|
func _NdGetArtistBiography() int32 {
|
|
if artistBiographyImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input ArtistRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := artistBiographyImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_similar_artists
|
|
func _NdGetSimilarArtists() int32 {
|
|
if similarArtistsImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input SimilarArtistsRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := similarArtistsImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_artist_images
|
|
func _NdGetArtistImages() int32 {
|
|
if artistImagesImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input ArtistRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := artistImagesImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_artist_top_songs
|
|
func _NdGetArtistTopSongs() int32 {
|
|
if artistTopSongsImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input TopSongsRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := artistTopSongsImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_album_info
|
|
func _NdGetAlbumInfo() int32 {
|
|
if albumInfoImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input AlbumRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := albumInfoImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_album_images
|
|
func _NdGetAlbumImages() int32 {
|
|
if albumImagesImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input AlbumRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := albumImagesImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_similar_songs_by_track
|
|
func _NdGetSimilarSongsByTrack() int32 {
|
|
if similarSongsByTrackImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input SimilarSongsByTrackRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := similarSongsByTrackImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_similar_songs_by_album
|
|
func _NdGetSimilarSongsByAlbum() int32 {
|
|
if similarSongsByAlbumImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input SimilarSongsByAlbumRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := similarSongsByAlbumImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
//go:wasmexport nd_get_similar_songs_by_artist
|
|
func _NdGetSimilarSongsByArtist() int32 {
|
|
if similarSongsByArtistImpl == nil {
|
|
// Return standard code - host will skip this plugin gracefully
|
|
return NotImplementedCode
|
|
}
|
|
|
|
var input SimilarSongsByArtistRequest
|
|
if err := pdk.InputJSON(&input); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
output, err := similarSongsByArtistImpl(input)
|
|
if err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
if err := pdk.OutputJSON(output); err != nil {
|
|
pdk.SetError(err)
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|