From 16d9d004086e22d871c6a6766470abefdb4da0ef Mon Sep 17 00:00:00 2001 From: Duncan Overbruck Date: Mon, 2 Mar 2020 17:23:22 +0100 Subject: [PATCH] ctrlsubsonic: add getSongsByGenre view --- server/ctrlsubsonic/handlers_by_tags.go | 29 +++++++++++++++++++++++++ server/ctrlsubsonic/spec/spec.go | 5 +++++ server/server.go | 1 + 3 files changed, 35 insertions(+) diff --git a/server/ctrlsubsonic/handlers_by_tags.go b/server/ctrlsubsonic/handlers_by_tags.go index f04f09f..c15cc7c 100644 --- a/server/ctrlsubsonic/handlers_by_tags.go +++ b/server/ctrlsubsonic/handlers_by_tags.go @@ -296,3 +296,32 @@ func (c *Controller) ServeGetGenres(r *http.Request) *spec.Response { } return sub } + +func (c *Controller) ServeGetSongsByGenre(r *http.Request) *spec.Response { + params := r.Context().Value(CtxParams).(params.Params) + genre := params.Get("genre") + if genre == "" { + return spec.NewError(10, "please provide an `genre` parameter") + } + + // TODO: add musicFolderId parameter: + // (Since 1.12.0) Only return albums in the music folder with the given ID. + + var tracks []*db.Track + c.DB. + Joins("JOIN albums ON tracks.album_id=albums.id"). + Joins("JOIN genres ON tracks.tag_genre_id=genres.id AND genres.name=?", genre). + Preload("Album"). + Offset(params.GetIntOr("offset", 0)). + Limit(params.GetIntOr("count", 10)). + Find(&tracks) + + sub := spec.NewResponse() + sub.TracksByGenre = &spec.TracksByGenre{ + List: make([]*spec.TrackChild, len(tracks)), + } + for i, track := range tracks { + sub.TracksByGenre.List[i] = spec.NewTrackByTags(track, track.Album) + } + return sub +} diff --git a/server/ctrlsubsonic/spec/spec.go b/server/ctrlsubsonic/spec/spec.go index 99e761c..5a78f40 100644 --- a/server/ctrlsubsonic/spec/spec.go +++ b/server/ctrlsubsonic/spec/spec.go @@ -28,6 +28,7 @@ type Response struct { Artist *Artist `xml:"artist" json:"artist,omitempty"` Directory *Directory `xml:"directory" json:"directory,omitempty"` RandomTracks *RandomTracks `xml:"randomSongs" json:"randomSongs,omitempty"` + TracksByGenre *TracksByGenre `xml:"songsByGenre" json:"songsByGenre,omitempty"` MusicFolders *MusicFolders `xml:"musicFolders" json:"musicFolders,omitempty"` ScanStatus *ScanStatus `xml:"scanStatus" json:"scanStatus,omitempty"` Licence *Licence `xml:"license" json:"license,omitempty"` @@ -109,6 +110,10 @@ type RandomTracks struct { List []*TrackChild `xml:"song" json:"song"` } +type TracksByGenre struct { + List []*TrackChild `xml:"song" json:"song"` +} + type TrackChild struct { Album string `xml:"album,attr,omitempty" json:"album,omitempty"` AlbumID int `xml:"albumId,attr,omitempty" json:"albumId,omitempty,string"` diff --git a/server/server.go b/server/server.go index 80aae98..4245193 100644 --- a/server/server.go +++ b/server/server.go @@ -145,6 +145,7 @@ func setupSubsonic(r *mux.Router, ctrl *ctrlsubsonic.Controller) { r.Handle("/getPlayQueue{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetPlayQueue)) r.Handle("/getSong{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetSong)) r.Handle("/getRandomSongs{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetRandomSongs)) + r.Handle("/getSongsByGenre{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetSongsByGenre)) // ** begin raw r.Handle("/download{_:(?:\\.view)?}", ctrl.HR(ctrl.ServeStream)) r.Handle("/getCoverArt{_:(?:\\.view)?}", ctrl.HR(ctrl.ServeGetCoverArt))