api

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: MIT Imports: 25 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
var LastFMAPIKey = ""

LastFMAPIKey and LastFMSharedSecret are injected at build time via -ldflags. For development, register your own Last.fm API app and set these.

View Source
var LastFMSharedSecret = ""

Functions

func AlbumNamesMatch

func AlbumNamesMatch(a, b string) bool

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

func LastFMDoAuth() (string, error)

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

func NormalizeAlbumName(s string) string

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

func SetDiscogsLogger(l *log.Logger)

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

type DiscogsArtist struct {
	Name         string
	Profile      string
	PrimaryImage string
	GalleryURLs  []string
}

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) Scrobble

func (c *LastFMClient) Scrobble(ctx context.Context, song models.Song, startTime time.Time) error

func (*LastFMClient) SendNowPlaying

func (c *LastFMClient) SendNowPlaying(ctx context.Context, song models.Song) error

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) Scrobble

func (c *ListenBrainzClient) Scrobble(ctx context.Context, song models.Song, startTime time.Time) error

func (*ListenBrainzClient) SendNowPlaying

func (c *ListenBrainzClient) SendNowPlaying(ctx context.Context, song models.Song) error

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 MBAlbum

type MBAlbum struct {
	Title string
	Year  string
}

MBAlbum represents a studio album from MusicBrainz

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

func (mb *MusicBrainzClient) SearchArtist(ctx context.Context, artistName string) (mbid string, matchedName string, err error)

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

type ProfileFavoritesResponse struct {
	Songs    []RatedSong
	NumSongs int
}

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

type ScrobbleResult struct {
	Service string
	Success bool
}

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

func NewScrobbler(cfg *config.Config) *Scrobbler

NewScrobbler creates a new Scrobbler from the given config.

func (*Scrobbler) Enabled

func (s *Scrobbler) Enabled() bool

Enabled returns true if any scrobble client is configured.

func (*Scrobbler) Scrobble

func (s *Scrobbler) Scrobble(ctx context.Context, song models.Song, startTime time.Time)

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

func (s *Scrobbler) SendNowPlaying(ctx context.Context, song models.Song)

SendNowPlaying sends now-playing notification to all enabled clients.

func (*Scrobbler) ServiceNames

func (s *Scrobbler) ServiceNames() []string

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

type SyncedLyric struct {
	Time    float64 // Time in seconds
	Content string  // Lyric text
}

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL