feat(subsonic): add getAlbumInfo with cache

Release-As: 0.16.1
This commit is contained in:
sentriz
2023-11-07 23:43:11 +00:00
parent 3f5cf56c88
commit cc1a99f033
14 changed files with 268 additions and 48 deletions

View File

@@ -11,9 +11,10 @@ import (
"log"
"net/http"
"go.senan.xyz/gonic/artistinfocache"
"go.senan.xyz/gonic/db"
"go.senan.xyz/gonic/handlerutil"
"go.senan.xyz/gonic/infocache/albuminfocache"
"go.senan.xyz/gonic/infocache/artistinfocache"
"go.senan.xyz/gonic/jukebox"
"go.senan.xyz/gonic/lastfm"
"go.senan.xyz/gonic/playlist"
@@ -63,10 +64,11 @@ type Controller struct {
transcoder transcode.Transcoder
lastFMClient *lastfm.Client
artistInfoCache *artistinfocache.ArtistInfoCache
albumInfoCache *albuminfocache.AlbumInfoCache
resolveProxyPath ProxyPathResolver
}
func New(dbc *db.DB, scannr *scanner.Scanner, musicPaths []MusicPath, podcastsPath string, cacheAudioPath string, cacheCoverPath string, jukebox *jukebox.Jukebox, playlistStore *playlist.Store, scrobblers []scrobble.Scrobbler, podcasts *podcast.Podcasts, transcoder transcode.Transcoder, lastFMClient *lastfm.Client, artistInfoCache *artistinfocache.ArtistInfoCache, resolveProxyPath ProxyPathResolver) (*Controller, error) {
func New(dbc *db.DB, scannr *scanner.Scanner, musicPaths []MusicPath, podcastsPath string, cacheAudioPath string, cacheCoverPath string, jukebox *jukebox.Jukebox, playlistStore *playlist.Store, scrobblers []scrobble.Scrobbler, podcasts *podcast.Podcasts, transcoder transcode.Transcoder, lastFMClient *lastfm.Client, artistInfoCache *artistinfocache.ArtistInfoCache, albumInfoCache *albuminfocache.AlbumInfoCache, resolveProxyPath ProxyPathResolver) (*Controller, error) {
c := Controller{
ServeMux: http.NewServeMux(),
@@ -83,6 +85,7 @@ func New(dbc *db.DB, scannr *scanner.Scanner, musicPaths []MusicPath, podcastsPa
transcoder: transcoder,
lastFMClient: lastFMClient,
artistInfoCache: artistInfoCache,
albumInfoCache: albumInfoCache,
resolveProxyPath: resolveProxyPath,
}
@@ -132,8 +135,9 @@ func New(dbc *db.DB, scannr *scanner.Scanner, musicPaths []MusicPath, podcastsPa
c.Handle("/getArtist", chain(resp(c.ServeGetArtist)))
c.Handle("/getArtists", chain(resp(c.ServeGetArtists)))
c.Handle("/search3", chain(resp(c.ServeSearchThree)))
c.Handle("/getArtistInfo2", chain(resp(c.ServeGetArtistInfoTwo)))
c.Handle("/getStarred2", chain(resp(c.ServeGetStarredTwo)))
c.Handle("/getArtistInfo2", chain(resp(c.ServeGetArtistInfoTwo)))
c.Handle("/getAlbumInfo2", chain(resp(c.ServeGetAlbumInfoTwo)))
// browse by folder
c.Handle("/getIndexes", chain(resp(c.ServeGetIndexes)))

View File

@@ -380,6 +380,38 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response {
return sub
}
func (c *Controller) ServeGetAlbumInfoTwo(r *http.Request) *spec.Response {
params := r.Context().Value(CtxParams).(params.Params)
id, err := params.GetID("id")
if err != nil {
return spec.NewError(10, "please provide an `id` parameter")
}
var album db.Album
err = c.dbc.
Where("id=?", id.Value).
Find(&album).
Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return spec.NewError(70, "album with id %q not found", id)
}
sub := spec.NewResponse()
sub.AlbumInfo = &spec.AlbumInfo{}
info, err := c.albumInfoCache.GetOrLookup(r.Context(), album.ID)
if err != nil {
log.Printf("error fetching album info from lastfm: %v", err)
return sub
}
sub.AlbumInfo.Notes = info.Notes
sub.AlbumInfo.MusicBrainzID = info.MusicBrainzID
sub.AlbumInfo.LastFMURL = info.LastFMURL
return sub
}
func (c *Controller) ServeGetGenres(_ *http.Request) *spec.Response {
var genres []*db.Genre
c.dbc.

View File

@@ -15,8 +15,8 @@ import (
"github.com/disintegration/imaging"
"github.com/jinzhu/gorm"
"go.senan.xyz/gonic/artistinfocache"
"go.senan.xyz/gonic/db"
"go.senan.xyz/gonic/infocache/artistinfocache"
"go.senan.xyz/gonic/server/ctrlsubsonic/params"
"go.senan.xyz/gonic/server/ctrlsubsonic/spec"
"go.senan.xyz/gonic/server/ctrlsubsonic/specid"

View File

@@ -45,27 +45,28 @@ type Response struct {
MusicFolders *MusicFolders `xml:"musicFolders" json:"musicFolders,omitempty"`
ScanStatus *ScanStatus `xml:"scanStatus" json:"scanStatus,omitempty"`
Licence *Licence `xml:"license" json:"license,omitempty"`
SearchResultTwo *SearchResultTwo `xml:"searchResult2" json:"searchResult2,omitempty"`
SearchResultThree *SearchResultThree `xml:"searchResult3" json:"searchResult3,omitempty"`
User *User `xml:"user" json:"user,omitempty"`
Playlists *Playlists `xml:"playlists" json:"playlists,omitempty"`
Playlist *Playlist `xml:"playlist" json:"playlist,omitempty"`
ArtistInfo *ArtistInfo `xml:"artistInfo" json:"artistInfo,omitempty"`
ArtistInfoTwo *ArtistInfo `xml:"artistInfo2" json:"artistInfo2,omitempty"`
Genres *Genres `xml:"genres" json:"genres,omitempty"`
PlayQueue *PlayQueue `xml:"playQueue" json:"playQueue,omitempty"`
JukeboxStatus *JukeboxStatus `xml:"jukeboxStatus" json:"jukeboxStatus,omitempty"`
JukeboxPlaylist *JukeboxPlaylist `xml:"jukeboxPlaylist" json:"jukeboxPlaylist,omitempty"`
Podcasts *Podcasts `xml:"podcasts" json:"podcasts,omitempty"`
NewestPodcasts *NewestPodcasts `xml:"newestPodcasts" json:"newestPodcasts,omitempty"`
Bookmarks *Bookmarks `xml:"bookmarks" json:"bookmarks,omitempty"`
Starred *Starred `xml:"starred" json:"starred,omitempty"`
StarredTwo *StarredTwo `xml:"starred2" json:"starred2,omitempty"`
TopSongs *TopSongs `xml:"topSongs" json:"topSongs,omitempty"`
SimilarSongs *SimilarSongs `xml:"similarSongs" json:"similarSongs,omitempty"`
SimilarSongsTwo *SimilarSongsTwo `xml:"similarSongs2" json:"similarSongs2,omitempty"`
InternetRadioStations *InternetRadioStations `xml:"internetRadioStations" json:"internetRadioStations,omitempty"`
Lyrics *Lyrics `xml:"lyrics" json:"lyrics,omitempty"`
SearchResultTwo *SearchResultTwo `xml:"searchResult2" json:"searchResult2,omitempty"`
SearchResultThree *SearchResultThree `xml:"searchResult3" json:"searchResult3,omitempty"`
User *User `xml:"user" json:"user,omitempty"`
Playlists *Playlists `xml:"playlists" json:"playlists,omitempty"`
Playlist *Playlist `xml:"playlist" json:"playlist,omitempty"`
ArtistInfo *ArtistInfo `xml:"artistInfo" json:"artistInfo,omitempty"`
ArtistInfoTwo *ArtistInfo `xml:"artistInfo2" json:"artistInfo2,omitempty"`
AlbumInfo *AlbumInfo `xml:"albumInfo" json:"albumInfo,omitempty"`
Genres *Genres `xml:"genres" json:"genres,omitempty"`
PlayQueue *PlayQueue `xml:"playQueue" json:"playQueue,omitempty"`
JukeboxStatus *JukeboxStatus `xml:"jukeboxStatus" json:"jukeboxStatus,omitempty"`
JukeboxPlaylist *JukeboxPlaylist `xml:"jukeboxPlaylist" json:"jukeboxPlaylist,omitempty"`
Podcasts *Podcasts `xml:"podcasts" json:"podcasts,omitempty"`
NewestPodcasts *NewestPodcasts `xml:"newestPodcasts" json:"newestPodcasts,omitempty"`
Bookmarks *Bookmarks `xml:"bookmarks" json:"bookmarks,omitempty"`
Starred *Starred `xml:"starred" json:"starred,omitempty"`
StarredTwo *StarredTwo `xml:"starred2" json:"starred2,omitempty"`
TopSongs *TopSongs `xml:"topSongs" json:"topSongs,omitempty"`
SimilarSongs *SimilarSongs `xml:"similarSongs" json:"similarSongs,omitempty"`
SimilarSongsTwo *SimilarSongsTwo `xml:"similarSongs2" json:"similarSongs2,omitempty"`
InternetRadioStations *InternetRadioStations `xml:"internetRadioStations" json:"internetRadioStations,omitempty"`
Lyrics *Lyrics `xml:"lyrics" json:"lyrics,omitempty"`
}
func NewResponse() *Response {
@@ -305,6 +306,12 @@ type ArtistInfo struct {
Similar []*Artist `xml:"similarArtist,omitempty" json:"similarArtist,omitempty"`
}
type AlbumInfo struct {
Notes string `xml:"notes" json:"notes"`
MusicBrainzID string `xml:"musicBrainzId" json:"musicBrainzId"`
LastFMURL string `xml:"lastFmUrl" json:"lastFmUrl"`
}
type Genres struct {
List []*Genre `xml:"genre" json:"genre"`
}