Documentation
¶
Overview ¶
Package api handles external service integrations
Package api provides clients for external APIs ¶
Package api provides clients for external API ¶
Package api provides clients for external API ¶
Package api provides clients for external API
Index ¶
- Variables
- func AlbumNamesMatch(a, b string) bool
- func FindCurrentLine(syncedLyrics []SyncedLyric, position float64) string
- func LastFMDoAuth() (string, error)
- func NormalizeAlbumName(s string) string
- func OpenBrowser(url string)
- func SaveNotifyArt(imageData []byte)
- func SendDesktopNotification(song *models.Song, stationName string, cfg *config.Config, withImage bool)
- func SetDiscogsLogger(l *log.Logger)
- type ArtistInfo
- type BlockResponse
- type ChannelInfo
- type Comment
- type CommentsResponse
- type ConnErrorType
- type DiscogsArtist
- type DiscogsClient
- type FavsCount
- type FavsCountResponse
- type LRCLibClient
- func (l *LRCLibClient) GetLyrics(ctx context.Context, artist, track string) (*LyricsResponse, error)
- func (l *LRCLibClient) GetLyricsByDuration(ctx context.Context, artist, track, album string, duration float64) (*LyricsResponse, error)
- func (l *LRCLibClient) SearchLyrics(ctx context.Context, query string) ([]LyricsResponse, error)
- type LastFMClient
- type LidarrAlbumStatus
- type LidarrArtistStatus
- type LidarrClient
- func (lc *LidarrClient) GetArtistAlbums(ctx context.Context, artistID int, mbAlbumTitles []string) (map[string]*LidarrAlbumStatus, error)
- func (lc *LidarrClient) GetArtistByMBID(ctx context.Context, mbid string) (*LidarrArtistStatus, error)
- func (lc *LidarrClient) IsConfigured() bool
- func (lc *LidarrClient) OpenArtistURL(mbid string) string
- func (lc *LidarrClient) OpenSearchByMBID(mbid string) string
- func (lc *LidarrClient) OpenSearchURL(searchTerm string) string
- type ListChannelsResponse
- type ListenBrainzClient
- func (c *ListenBrainzClient) Enabled() bool
- func (c *ListenBrainzClient) Name() string
- func (c *ListenBrainzClient) Scrobble(ctx context.Context, song models.Song, startTime time.Time) error
- func (c *ListenBrainzClient) SendNowPlaying(ctx context.Context, song models.Song) error
- func (c *ListenBrainzClient) ShortName() string
- type LyricsResponse
- type MBAlbum
- type MusicBrainzClient
- type NowPlayingResponse
- type ParseResponse
- type PlaylistResponse
- type ProfileFavoritesResponse
- type RPAuthClient
- func (a *RPAuthClient) Chan99Cutoff() int
- func (a *RPAuthClient) CookieString() string
- func (a *RPAuthClient) HasAuth() bool
- func (a *RPAuthClient) LoadState(path string) error
- func (a *RPAuthClient) Login(username, password string) error
- func (a *RPAuthClient) Reauth() error
- func (a *RPAuthClient) SaveState(path string) error
- func (a *RPAuthClient) SetChan99Cutoff(cutoff int)
- func (a *RPAuthClient) SetCredentials(username, password string)
- func (a *RPAuthClient) UserID() string
- func (a *RPAuthClient) Username() string
- type RPAuthResponse
- type RPAuthState
- type RPCommentsClient
- type RPRatingsClient
- func (c *RPRatingsClient) GetAllProfileFavorites(userID, mode string, lowerLimit, upperLimit int) ([]RatedSong, error)
- func (c *RPRatingsClient) GetFavsCount() (*FavsCountResponse, error)
- func (c *RPRatingsClient) GetProfileFavorites(userID, mode string, lowerLimit, upperLimit, offset int) (*ProfileFavoritesResponse, error)
- func (c *RPRatingsClient) SubmitRating(songID int64, rating int) (*RatingResponse, error)
- type RadioParadiseAPI
- func (r *RadioParadiseAPI) GetBitrate() int
- func (r *RadioParadiseAPI) GetBlock(ctx context.Context) (*BlockResponse, error)
- func (r *RadioParadiseAPI) GetChannel() int
- func (r *RadioParadiseAPI) GetFileExtension() string
- func (r *RadioParadiseAPI) GetNowPlaying(ctx context.Context) (*NowPlayingResponse, error)
- func (r *RadioParadiseAPI) GetPlaylist(ctx context.Context) (*PlaylistResponse, error)
- func (r *RadioParadiseAPI) IsAuthenticated() bool
- func (r *RadioParadiseAPI) ListChannels(ctx context.Context) (ListChannelsResponse, error)
- func (r *RadioParadiseAPI) ParseBlockSongs(blockData *BlockResponse) ([]*models.Song, string)
- func (r *RadioParadiseAPI) SetBitrate(bitrate int)
- func (r *RadioParadiseAPI) SetChannel(channel int)
- func (r *RadioParadiseAPI) WithAuth(authClient *RPAuthClient) *RadioParadiseAPI
- type RatedSong
- type RatingResponse
- type ScrobbleCache
- type ScrobbleClient
- type ScrobbleEntry
- type ScrobbleResult
- type Scrobbler
- func (s *Scrobbler) Enabled() bool
- func (s *Scrobbler) Scrobble(ctx context.Context, song models.Song, startTime time.Time)
- func (s *Scrobbler) ScrobbleWithResult(ctx context.Context, song models.Song, startTime time.Time) []ScrobbleResult
- func (s *Scrobbler) SendNowPlaying(ctx context.Context, song models.Song)
- func (s *Scrobbler) ServiceNames() []string
- type SearchResponse
- type SummaryResponse
- type SyncedLyric
- type TADBAlbumInfo
- type TADBArtist
- type TheAudioDBClient
- type WikipediaClient
Constants ¶
This section is empty.
Variables ¶
var LastFMAPIKey = ""
LastFMAPIKey and LastFMSharedSecret are injected at build time via -ldflags. For development, register your own Last.fm API app and set these.
Functions ¶
func AlbumNamesMatch ¶
AlbumNamesMatch checks if two album names refer to the same album using fuzzy comparison.
func FindCurrentLine ¶
func FindCurrentLine(syncedLyrics []SyncedLyric, position float64) string
FindCurrentLine finds the current lyric line based on playback position
func LastFMDoAuth ¶
LastFMDoAuth runs the one-time Last.fm authorization flow. It opens the browser for the user to grant access, then fetches the session key. Returns the session key or an error.
func NormalizeAlbumName ¶
NormalizeAlbumName normalizes an album name for fuzzy comparison. Strips remaster/reissue suffixes, accents, and punctuation.
func OpenBrowser ¶ added in v1.2.0
func OpenBrowser(url string)
OpenBrowser opens a URL in the default browser (fire-and-forget).
func SaveNotifyArt ¶
func SaveNotifyArt(imageData []byte)
SaveNotifyArt saves album art data to the notification art path
func SendDesktopNotification ¶
func SendDesktopNotification(song *models.Song, stationName string, cfg *config.Config, withImage bool)
SendDesktopNotification shows a desktop notification with song info
func SetDiscogsLogger ¶
Types ¶
type ArtistInfo ¶
type ArtistInfo struct {
Summary string
PageTitle string
PageURL string
ThumbnailURL string
Discography string // Studio albums list
}
ArtistInfo represents Wikipedia artist information
type BlockResponse ¶
type BlockResponse struct {
Song map[string]map[string]any `json:"song"`
ImageBase string `json:"image_base"`
Bitrate string `json:"bitrate"`
Channel ChannelInfo `json:"channel"`
Event string `json:"event"`
Elapsed int `json:"elapsed"`
BlockID string `json:"block_id"`
SliceNum string `json:"slice_num"`
SchedTime int64 `json:"sched_time_millis"`
}
BlockResponse represents the /play API response
type ChannelInfo ¶
type ChannelInfo struct {
Chan string `json:"chan"`
Title string `json:"title"`
StreamName string `json:"stream_name"`
IsER bool `json:"isER"`
}
ChannelInfo represents channel information from the API
type Comment ¶
type Comment struct {
Username string
PostedTime string
Message string
QuotedText string
Upvotes int
Downvotes int
Location string
}
Comment represents a single comment from RP
type CommentsResponse ¶
type CommentsResponse struct {
Comments []Comment
TotalComments int
MoreComments bool
MoreOffset int
}
CommentsResponse represents the comments::list API response
type ConnErrorType ¶
type ConnErrorType int
ConnErrorType classifies connection errors for display
const ( ConnErrorNetwork ConnErrorType = iota // No internet, DNS failure, etc. ConnErrorTimeout // Request timed out ConnErrorServer // RP server error (5xx) ConnErrorOther // Unknown error )
func ClassifyConnError ¶
func ClassifyConnError(err error) ConnErrorType
ClassifyConnError determines the type of connection error for user-facing messages
type DiscogsArtist ¶
DiscogsArtist holds artist data fetched from Discogs
type DiscogsClient ¶
type DiscogsClient struct {
// contains filtered or unexported fields
}
DiscogsClient provides access to the Discogs API. Supports three auth methods (none required, all optional):
- Personal access token (simplest — one value from discogs.com/settings/developers)
- Consumer key + secret (developer app credentials)
- Environment variables: DISCOGS_TOKEN, or DISCOGS_KEY + DISCOGS_SECRET
Without auth: low rate limit (25/min), no image URLs. With any auth: high rate limit (60/min), image URLs included.
func NewDiscogsClient ¶
func NewDiscogsClient(token, key, secret string) *DiscogsClient
NewDiscogsClient creates a new Discogs API client. Config values take priority over environment variables. Auth is optional — the client works without it (limited rate, no images).
func (*DiscogsClient) HasAuth ¶
func (d *DiscogsClient) HasAuth() bool
HasAuth returns true if any authentication is configured
func (*DiscogsClient) SearchArtist ¶
func (d *DiscogsClient) SearchArtist(ctx context.Context, artistName, albumName string) (*DiscogsArtist, error)
SearchArtist searches for an artist and fetches their details. If albumName is provided, it will be used to disambiguate when multiple artists match by checking if the artist has a release matching that album.
type FavsCount ¶
type FavsCount struct {
R5 string `json:"r5"`
R6 string `json:"r6"`
R7 string `json:"r7"`
R8 string `json:"r8"`
R9 string `json:"r9"`
R10 string `json:"r10"`
}
FavsCount represents the user's rating distribution
type FavsCountResponse ¶
type FavsCountResponse struct {
FavsCount FavsCount `json:"favsCount"`
Chan99Cutoff int `json:"chan_99_cutoff"`
}
FavsCountResponse represents the list_chan_favscount API response
type LRCLibClient ¶
type LRCLibClient struct {
// contains filtered or unexported fields
}
LRCLibClient provides access to the LRCLib lyrics API
func NewLRCLibClient ¶
func NewLRCLibClient() *LRCLibClient
NewLRCLibClient creates a new LRCLib API client
func (*LRCLibClient) GetLyrics ¶
func (l *LRCLibClient) GetLyrics(ctx context.Context, artist, track string) (*LyricsResponse, error)
GetLyrics fetches lyrics by artist and track name
func (*LRCLibClient) GetLyricsByDuration ¶
func (l *LRCLibClient) GetLyricsByDuration(ctx context.Context, artist, track, album string, duration float64) (*LyricsResponse, error)
GetLyricsByDuration fetches lyrics with duration filter for better matching Uses progressive fallback: original → cleaned → no album → looser matching
func (*LRCLibClient) SearchLyrics ¶
func (l *LRCLibClient) SearchLyrics(ctx context.Context, query string) ([]LyricsResponse, error)
SearchLyrics searches for lyrics by query
type LastFMClient ¶
type LastFMClient struct {
// contains filtered or unexported fields
}
LastFMClient implements ScrobbleClient for Last.fm.
func NewLastFMClient ¶
func NewLastFMClient(apiKey, sharedSecret, sessionKey string) *LastFMClient
NewLastFMClient creates a new Last.fm scrobble client.
func (*LastFMClient) Enabled ¶
func (c *LastFMClient) Enabled() bool
func (*LastFMClient) Name ¶
func (c *LastFMClient) Name() string
func (*LastFMClient) SendNowPlaying ¶
func (*LastFMClient) ShortName ¶
func (c *LastFMClient) ShortName() string
type LidarrAlbumStatus ¶ added in v1.2.0
type LidarrAlbumStatus struct {
InLidarr bool // true if album exists in Lidarr
Monitored bool // true if album is monitored
HasFiles bool // true if any track files exist on disk
PercentOfTracks float64 // percentage of tracks downloaded (0–100)
}
LidarrAlbumStatus represents an album's status in Lidarr
type LidarrArtistStatus ¶ added in v1.2.0
type LidarrArtistStatus struct {
InLidarr bool // true if artist exists in Lidarr
Monitored bool // true if artist is monitored
ArtistID int // Lidarr's internal artist ID
ArtistName string // Lidarr's matched artist name
Error string // error message if lookup failed
}
LidarrArtistStatus represents an artist's status in Lidarr
type LidarrClient ¶ added in v1.2.0
type LidarrClient struct {
// contains filtered or unexported fields
}
LidarrClient provides access to the Lidarr API. Requires base URL and API key from config.
func NewLidarrClient ¶ added in v1.2.0
func NewLidarrClient(baseURL, apiKey string, enabled bool) *LidarrClient
NewLidarrClient creates a new Lidarr API client. baseURL should be something like "http://localhost:8686" apiKey is the Lidarr API key from Settings > General
func (*LidarrClient) GetArtistAlbums ¶ added in v1.2.0
func (lc *LidarrClient) GetArtistAlbums(ctx context.Context, artistID int, mbAlbumTitles []string) (map[string]*LidarrAlbumStatus, error)
GetArtistAlbums returns a map of album titles to their Lidarr status. Album titles are matched against MusicBrainz release group titles.
func (*LidarrClient) GetArtistByMBID ¶ added in v1.2.0
func (lc *LidarrClient) GetArtistByMBID(ctx context.Context, mbid string) (*LidarrArtistStatus, error)
GetArtistByMBID looks up an artist in Lidarr by MusicBrainz ID. Returns artist status with ID and monitored flag.
func (*LidarrClient) IsConfigured ¶ added in v1.2.0
func (lc *LidarrClient) IsConfigured() bool
IsConfigured returns true if the client is enabled and has URL and API key set
func (*LidarrClient) OpenArtistURL ¶ added in v1.2.0
func (lc *LidarrClient) OpenArtistURL(mbid string) string
OpenArtistURL returns the URL to open an artist page in Lidarr's web UI. Lidarr v3+ uses the MusicBrainz ID (foreignArtistId) in web UI routes, not the internal numeric database ID.
func (*LidarrClient) OpenSearchByMBID ¶ added in v1.2.0
func (lc *LidarrClient) OpenSearchByMBID(mbid string) string
OpenSearchByMBID returns the URL to open Lidarr's add/search page with MBID prefix
func (*LidarrClient) OpenSearchURL ¶ added in v1.2.0
func (lc *LidarrClient) OpenSearchURL(searchTerm string) string
OpenSearchURL returns the URL to open Lidarr's add/search page
type ListChannelsResponse ¶
type ListChannelsResponse []struct {
Chan string `json:"chan"`
Title string `json:"title"`
StreamName string `json:"stream_name"`
Downloadable bool `json:"downloadable"`
}
ListChannelsResponse represents the /list_chan API response
type ListenBrainzClient ¶
type ListenBrainzClient struct {
// contains filtered or unexported fields
}
ListenBrainzClient implements ScrobbleClient for ListenBrainz.
func NewListenBrainzClient ¶
func NewListenBrainzClient(token string) *ListenBrainzClient
NewListenBrainzClient creates a new ListenBrainz scrobble client.
func (*ListenBrainzClient) Enabled ¶
func (c *ListenBrainzClient) Enabled() bool
func (*ListenBrainzClient) Name ¶
func (c *ListenBrainzClient) Name() string
func (*ListenBrainzClient) SendNowPlaying ¶
func (*ListenBrainzClient) ShortName ¶
func (c *ListenBrainzClient) ShortName() string
type LyricsResponse ¶
type LyricsResponse struct {
ID int64 `json:"id"`
Name string `json:"name"`
TrackName string `json:"trackName"`
ArtistName string `json:"artistName"`
AlbumName string `json:"albumName"`
Duration float64 `json:"duration"`
Instrumental bool `json:"instrumental"`
PlainLyrics string `json:"plainLyrics"`
SyncedLyrics string `json:"syncedLyrics"`
Lang string `json:"lang"`
IsRC bool `json:"isRc"`
SpotifyID string `json:"spotifyId"`
}
LyricsResponse represents the LRCLib API response
type MusicBrainzClient ¶
type MusicBrainzClient struct {
// contains filtered or unexported fields
}
MusicBrainzClient provides access to the MusicBrainz API
func NewMusicBrainzClient ¶
func NewMusicBrainzClient() *MusicBrainzClient
NewMusicBrainzClient creates a new MusicBrainz API client
func (*MusicBrainzClient) GetDiscography ¶
func (mb *MusicBrainzClient) GetDiscography(ctx context.Context, artistName string, rpAlbum string) (string, []MBAlbum, error)
GetDiscography searches for an artist and returns their official studio albums. rpAlbum is the current song's album name from Radio Paradise, used to validate that the matched MB artist actually has this album (catches false positives). Returns the artist's MusicBrainz ID, albums, and error. Returns nil albums if the artist is not found or the match cannot be validated.
func (*MusicBrainzClient) SearchArtist ¶ added in v1.2.0
type NowPlayingResponse ¶
type NowPlayingResponse struct {
Song map[string]any `json:"song"`
ImageBase string `json:"image_base"`
Bitrate string `json:"bitrate"`
Channel string `json:"channel"`
PlayTime string `json:"play_time"`
Elapsed int `json:"elapsed"`
TrackTotal int `json:"track_total"`
TrackNumber int `json:"track_number"`
}
NowPlayingResponse represents the /now_playing API response
type ParseResponse ¶
type ParseResponse struct {
Parse struct {
Sections []struct {
Line string `json:"line"`
Index string `json:"index"`
} `json:"sections"`
Text struct {
Content string `json:"*"`
} `json:"text"`
} `json:"parse"`
}
ParseResponse represents Wikipedia parse API response
type PlaylistResponse ¶
type PlaylistResponse struct {
Songs []map[string]any `json:"song"`
ImageBase string `json:"image_base"`
Bitrate string `json:"bitrate"`
Channel string `json:"channel"`
}
PlaylistResponse represents the /nowplaying_list_v2022 API response
type ProfileFavoritesResponse ¶
ProfileFavoritesResponse represents the account::profile-favorites API response
type RPAuthClient ¶
type RPAuthClient struct {
// contains filtered or unexported fields
}
RPAuthClient handles Radio Paradise authentication
func NewRPAuthClient ¶
func NewRPAuthClient() *RPAuthClient
NewRPAuthClient creates a new auth client (unauthenticated until Login or LoadState)
func (*RPAuthClient) Chan99Cutoff ¶
func (a *RPAuthClient) Chan99Cutoff() int
Chan99Cutoff returns the RP favorites rating threshold (default 7 if not set)
func (*RPAuthClient) CookieString ¶
func (a *RPAuthClient) CookieString() string
CookieString returns the cookie header value for authenticated requests
func (*RPAuthClient) HasAuth ¶
func (a *RPAuthClient) HasAuth() bool
HasAuth returns true if valid session tokens are loaded
func (*RPAuthClient) LoadState ¶
func (a *RPAuthClient) LoadState(path string) error
LoadState restores session tokens from disk
func (*RPAuthClient) Login ¶
func (a *RPAuthClient) Login(username, password string) error
Login authenticates with RP using username/password and stores session tokens
func (*RPAuthClient) Reauth ¶
func (a *RPAuthClient) Reauth() error
Reauth attempts to re-authenticate using stored credentials
func (*RPAuthClient) SaveState ¶
func (a *RPAuthClient) SaveState(path string) error
SaveState persists session tokens to disk
func (*RPAuthClient) SetChan99Cutoff ¶
func (a *RPAuthClient) SetChan99Cutoff(cutoff int)
SetChan99Cutoff stores the RP favorites rating threshold
func (*RPAuthClient) SetCredentials ¶
func (a *RPAuthClient) SetCredentials(username, password string)
SetCredentials sets credentials for later Login call
func (*RPAuthClient) UserID ¶
func (a *RPAuthClient) UserID() string
UserID returns the authenticated user ID
func (*RPAuthClient) Username ¶
func (a *RPAuthClient) Username() string
Username returns the authenticated username
type RPAuthResponse ¶
type RPAuthResponse struct {
Status string `json:"status"`
UserID string `json:"user_id"`
Username string `json:"username"`
Passwd string `json:"passwd"`
Level string `json:"level"`
CountryCode string `json:"country_code"`
}
RPAuthResponse represents the /api/auth JSON response
type RPAuthState ¶
type RPAuthState struct {
CPasswd string `toml:"c_passwd"`
UserID string `toml:"c_user_id"`
CValidated string `toml:"c_validated"`
Chan99Cutoff int `toml:"chan_99_cutoff"`
}
RPAuthState represents persisted session tokens
type RPCommentsClient ¶
type RPCommentsClient struct {
// contains filtered or unexported fields
}
RPCommentsClient handles RP comments API interactions
func NewRPCommentsClient ¶
func NewRPCommentsClient(authClient *RPAuthClient) *RPCommentsClient
NewRPCommentsClient creates a new comments API client
func (*RPCommentsClient) GetComments ¶
func (c *RPCommentsClient) GetComments(songID int64, numComments int, order string) (*CommentsResponse, error)
GetComments fetches comments for a song
func (*RPCommentsClient) GetCommentsWithOffset ¶
func (c *RPCommentsClient) GetCommentsWithOffset(songID int64, numComments int, order string, offset int) (*CommentsResponse, error)
GetCommentsWithOffset fetches comments starting from a given offset (for pagination)
type RPRatingsClient ¶
type RPRatingsClient struct {
// contains filtered or unexported fields
}
RPRatingsClient handles RP ratings and favorites API interactions
func NewRPRatingsClient ¶
func NewRPRatingsClient(authClient *RPAuthClient) *RPRatingsClient
NewRPRatingsClient creates a new ratings/favorites API client
func (*RPRatingsClient) GetAllProfileFavorites ¶
func (c *RPRatingsClient) GetAllProfileFavorites(userID, mode string, lowerLimit, upperLimit int) ([]RatedSong, error)
GetAllProfileFavorites fetches all user-rated songs across all pages
func (*RPRatingsClient) GetFavsCount ¶
func (c *RPRatingsClient) GetFavsCount() (*FavsCountResponse, error)
GetFavsCount fetches the user's rating distribution and channel 99 cutoff
func (*RPRatingsClient) GetProfileFavorites ¶
func (c *RPRatingsClient) GetProfileFavorites(userID, mode string, lowerLimit, upperLimit, offset int) (*ProfileFavoritesResponse, error)
GetProfileFavorites fetches the user's rated songs (paginated) mode: "High" for ratings >= lowerLimit, "Low" for ratings <= upperLimit lowerLimit/upperLimit: rating range filter (1-10) offset: pagination offset (returns 20 songs per page)
func (*RPRatingsClient) SubmitRating ¶
func (c *RPRatingsClient) SubmitRating(songID int64, rating int) (*RatingResponse, error)
SubmitRating submits a rating (1-10) for a song
type RadioParadiseAPI ¶
type RadioParadiseAPI struct {
// contains filtered or unexported fields
}
RadioParadiseAPI handles all Radio Paradise API interactions
func NewRadioParadiseAPI ¶
func NewRadioParadiseAPI(channel, bitrate int) *RadioParadiseAPI
NewRadioParadiseAPI creates a new Radio Paradise API client
func (*RadioParadiseAPI) GetBitrate ¶
func (r *RadioParadiseAPI) GetBitrate() int
GetBitrate returns the current bitrate
func (*RadioParadiseAPI) GetBlock ¶
func (r *RadioParadiseAPI) GetBlock(ctx context.Context) (*BlockResponse, error)
GetBlock fetches audio block with playback URLs
func (*RadioParadiseAPI) GetChannel ¶
func (r *RadioParadiseAPI) GetChannel() int
GetChannel returns the current channel
func (*RadioParadiseAPI) GetFileExtension ¶
func (r *RadioParadiseAPI) GetFileExtension() string
GetFileExtension returns file extension based on bitrate setting
func (*RadioParadiseAPI) GetNowPlaying ¶
func (r *RadioParadiseAPI) GetNowPlaying(ctx context.Context) (*NowPlayingResponse, error)
GetNowPlaying fetches current song info
func (*RadioParadiseAPI) GetPlaylist ¶
func (r *RadioParadiseAPI) GetPlaylist(ctx context.Context) (*PlaylistResponse, error)
GetPlaylist fetches extended playlist with timing
func (*RadioParadiseAPI) IsAuthenticated ¶
func (r *RadioParadiseAPI) IsAuthenticated() bool
IsAuthenticated returns true if an auth client is attached and has valid tokens
func (*RadioParadiseAPI) ListChannels ¶
func (r *RadioParadiseAPI) ListChannels(ctx context.Context) (ListChannelsResponse, error)
ListChannels fetches all available channels from RP
func (*RadioParadiseAPI) ParseBlockSongs ¶
func (r *RadioParadiseAPI) ParseBlockSongs(blockData *BlockResponse) ([]*models.Song, string)
ParseBlockSongs parses block data to extract songs with gapless URLs and timing Returns songs in play order (songs[0] = currently playing/next song)
func (*RadioParadiseAPI) SetBitrate ¶
func (r *RadioParadiseAPI) SetBitrate(bitrate int)
SetBitrate sets the bitrate
func (*RadioParadiseAPI) SetChannel ¶
func (r *RadioParadiseAPI) SetChannel(channel int)
SetChannel sets the channel (station)
func (*RadioParadiseAPI) WithAuth ¶
func (r *RadioParadiseAPI) WithAuth(authClient *RPAuthClient) *RadioParadiseAPI
WithAuth attaches an RP authentication client to the API client. When auth is available, all requests will include session cookies.
type RatedSong ¶
type RatedSong struct {
SongID string `json:"song_id"`
Title string `json:"title"`
Artist string `json:"artist"`
Album string `json:"album"`
AlbumID string `json:"album_id"`
ASIN string `json:"asin"`
Year string `json:"year"`
Cover string `json:"cover"`
Rating string `json:"rating"`
ListenerRating float64 `json:"listener_rating"`
ListenerRatingRounded int `json:"listener_rating_rounded"`
RatingsNum string `json:"ratings_num"`
}
RatedSong represents a song from the user's profile favorites/ratings
type RatingResponse ¶
type RatingResponse struct {
Status string `json:"status"`
SongID int64 `json:"song_id"`
UserID string `json:"user_id"`
Rating int `json:"rating"`
}
RatingResponse represents the /api/rating API response
type ScrobbleCache ¶
type ScrobbleCache struct {
// contains filtered or unexported fields
}
ScrobbleCache manages a disk-backed queue of failed scrobbles.
func NewScrobbleCache ¶
func NewScrobbleCache(dir string) *ScrobbleCache
NewScrobbleCache creates a cache backed by the given directory.
func (*ScrobbleCache) Add ¶
func (c *ScrobbleCache) Add(entry ScrobbleEntry) error
Add appends a scrobble entry to the disk cache.
func (*ScrobbleCache) Load ¶
func (c *ScrobbleCache) Load() []ScrobbleEntry
Load reads all cached scrobbles from disk. Returns empty slice if none.
func (*ScrobbleCache) Replace ¶
func (c *ScrobbleCache) Replace(entries []ScrobbleEntry) error
Replace overwrites the cache with the given entries.
type ScrobbleClient ¶
type ScrobbleClient interface {
// SendNowPlaying notifies the service that a track has started playing.
SendNowPlaying(ctx context.Context, song models.Song) error
// Scrobble submits a completed listen to the service.
Scrobble(ctx context.Context, song models.Song, startTime time.Time) error
// Enabled returns true if this client is configured and ready.
Enabled() bool
// Name returns the display name of this service (e.g. "last.fm", "listenbrainz").
Name() string
// ShortName returns a short display name (e.g. "fm", "lb").
ShortName() string
}
ScrobbleClient defines the interface for scrobble service clients.
type ScrobbleEntry ¶
type ScrobbleEntry struct {
Artist string `json:"artist"`
Track string `json:"track"`
Album string `json:"album,omitempty"`
DurationSecs int `json:"duration_secs"`
Timestamp int64 `json:"timestamp"`
Service string `json:"service"` // "fm" or "lb"
}
ScrobbleEntry represents a failed scrobble to be retried later.
type ScrobbleResult ¶
ScrobbleResult holds the outcome of a scrobble attempt for UI display.
type Scrobbler ¶
type Scrobbler struct {
// contains filtered or unexported fields
}
Scrobbler manages all configured scrobble clients.
func NewScrobbler ¶
NewScrobbler creates a new Scrobbler from the given config.
func (*Scrobbler) Scrobble ¶
Scrobble submits a listen to all enabled clients. Failed submissions are cached.
func (*Scrobbler) ScrobbleWithResult ¶
func (s *Scrobbler) ScrobbleWithResult(ctx context.Context, song models.Song, startTime time.Time) []ScrobbleResult
ScrobbleWithResult is like Scrobble but returns results for each service.
func (*Scrobbler) SendNowPlaying ¶
SendNowPlaying sends now-playing notification to all enabled clients.
func (*Scrobbler) ServiceNames ¶
ServiceNames returns display names of all enabled services.
type SearchResponse ¶
type SearchResponse struct {
Query struct {
Search []struct {
Title string `json:"title"`
Snippet string `json:"snippet"`
} `json:"search"`
} `json:"query"`
}
SearchResponse represents Wikipedia search API response
type SummaryResponse ¶
type SummaryResponse struct {
Title string `json:"title"`
Description string `json:"description"`
Extract string `json:"extract"`
Thumbnail struct {
Source string `json:"source"`
} `json:"thumbnail"`
ContentUrls struct {
Desktop struct {
Page string `json:"page"`
} `json:"desktop"`
} `json:"content_urls"`
}
SummaryResponse represents Wikipedia summary API response
type SyncedLyric ¶
SyncedLyric represents a single line of synced lyrics
func ParseSyncedLyrics ¶
func ParseSyncedLyrics(syncedLyrics string) []SyncedLyric
ParseSyncedLyrics parses LRC format synced lyrics
type TADBAlbumInfo ¶
type TADBAlbumInfo struct {
Description string // Album description/blurb
}
TADBAlbumInfo holds album info from album search
type TADBArtist ¶
type TADBArtist struct {
Name string
Bio string
Thumb string
FanArts []string
AlbumInfo *TADBAlbumInfo // Album info for disambiguation
}
TADBArtist holds artist data fetched from TheAudioDB
type TheAudioDBClient ¶
type TheAudioDBClient struct {
// contains filtered or unexported fields
}
TheAudioDBClient provides access to TheAudioDB API
func NewTheAudioDBClient ¶
func NewTheAudioDBClient() *TheAudioDBClient
NewTheAudioDBClient creates a new TheAudioDB API client
func (*TheAudioDBClient) SearchArtist ¶
func (t *TheAudioDBClient) SearchArtist(ctx context.Context, artistName, albumName string) (*TADBArtist, error)
SearchArtist searches for an artist on TheAudioDB. If albumName is provided, it uses album search to disambiguate when multiple artists match. Returns nil if the artist is not found.
type WikipediaClient ¶
type WikipediaClient struct {
// contains filtered or unexported fields
}
WikipediaClient provides access to Wikipedia API
func NewWikipediaClient ¶
func NewWikipediaClient() *WikipediaClient
NewWikipediaClient creates a new Wikipedia API client
func (*WikipediaClient) FindArtist ¶
func (w *WikipediaClient) FindArtist(ctx context.Context, artistName string) (*ArtistInfo, error)
FindArtist finds Wikipedia article for an artist