From f6687df3f3f0d94a2db661b9d4b276175d951d68 Mon Sep 17 00:00:00 2001 From: brian-doherty <76168809+brian-doherty@users.noreply.github.com> Date: Thu, 21 Apr 2022 14:13:47 -0500 Subject: [PATCH] feat(subsonic): add getNewestPodcasts --- db/model.go | 4 ++++ podcasts/podcasts.go | 13 +++++++++++++ server/ctrlsubsonic/handlers_podcast.go | 15 +++++++++++++++ server/ctrlsubsonic/spec/construct_podcast.go | 8 ++++---- server/ctrlsubsonic/spec/spec.go | 5 +++++ server/server.go | 1 + 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/db/model.go b/db/model.go index 41446d97..a97ba321 100644 --- a/db/model.go +++ b/db/model.go @@ -371,6 +371,10 @@ func (pe *PodcastEpisode) SID() *specid.ID { return &specid.ID{Type: specid.PodcastEpisode, Value: pe.ID} } +func (pe *PodcastEpisode) PodcastSID() *specid.ID { + return &specid.ID{Type: specid.Podcast, Value: pe.PodcastID} +} + func (pe *PodcastEpisode) AudioFilename() string { return pe.Filename } diff --git a/podcasts/podcasts.go b/podcasts/podcasts.go index 523553b7..12b919a3 100644 --- a/podcasts/podcasts.go +++ b/podcasts/podcasts.go @@ -75,6 +75,19 @@ func (p *Podcasts) GetPodcastEpisodes(podcastID int) ([]*db.PodcastEpisode, erro return episodes, nil } +func (p *Podcasts) GetNewestPodcastEpisodes(count int) ([]*db.PodcastEpisode, error) { + episodes := []*db.PodcastEpisode{} + err := p.db. + Order("publish_date DESC"). + Limit(count). + Find(&episodes). + Error + if err != nil { + return nil, fmt.Errorf("find newest podcast episodes: %w", err) + } + return episodes, nil +} + func (p *Podcasts) AddNewPodcast(rssURL string, feed *gofeed.Feed, userID int) (*db.Podcast, error) { podcast := db.Podcast{ diff --git a/server/ctrlsubsonic/handlers_podcast.go b/server/ctrlsubsonic/handlers_podcast.go index aaa9cb76..67cb7e7f 100644 --- a/server/ctrlsubsonic/handlers_podcast.go +++ b/server/ctrlsubsonic/handlers_podcast.go @@ -29,6 +29,21 @@ func (c *Controller) ServeGetPodcasts(r *http.Request) *spec.Response { return sub } +func (c *Controller) ServeGetNewestPodcasts(r *http.Request) *spec.Response { + params := r.Context().Value(CtxParams).(params.Params) + count := params.GetOrInt("count", 10) + episodes, err := c.Podcasts.GetNewestPodcastEpisodes(count) + if err != nil { + return spec.NewError(10, "failed get podcast(s): %s", err) + } + sub := spec.NewResponse() + sub.NewestPodcasts = &spec.NewestPodcasts{} + for _, episode := range episodes { + sub.NewestPodcasts.List = append(sub.NewestPodcasts.List, spec.NewPodcastEpisode(episode)) + } + return sub +} + func (c *Controller) ServeDownloadPodcastEpisode(r *http.Request) *spec.Response { params := r.Context().Value(CtxParams).(params.Params) id, err := params.GetID("id") diff --git a/server/ctrlsubsonic/spec/construct_podcast.go b/server/ctrlsubsonic/spec/construct_podcast.go index a214030a..b944160f 100644 --- a/server/ctrlsubsonic/spec/construct_podcast.go +++ b/server/ctrlsubsonic/spec/construct_podcast.go @@ -13,13 +13,13 @@ func NewPodcastChannel(p *db.Podcast) *PodcastChannel { Status: "skipped", } for _, episode := range p.Episodes { - specEpisode := NewPodcastEpisode(p, episode) + specEpisode := NewPodcastEpisode(episode) ret.Episode = append(ret.Episode, specEpisode) } return ret } -func NewPodcastEpisode(p *db.Podcast, e *db.PodcastEpisode) *PodcastEpisode { +func NewPodcastEpisode(e *db.PodcastEpisode) *PodcastEpisode { if e == nil { return nil } @@ -27,11 +27,11 @@ func NewPodcastEpisode(p *db.Podcast, e *db.PodcastEpisode) *PodcastEpisode { ID: e.SID(), StreamID: e.SID(), ContentType: e.MIME(), - ChannelID: p.SID(), + ChannelID: e.PodcastSID(), Title: e.Title, Description: e.Description, Status: string(e.Status), - CoverArt: p.SID(), + CoverArt: e.PodcastSID(), PublishDate: *e.PublishDate, Genre: "Podcast", Duration: e.Length, diff --git a/server/ctrlsubsonic/spec/spec.go b/server/ctrlsubsonic/spec/spec.go index 3392a29e..8a047377 100644 --- a/server/ctrlsubsonic/spec/spec.go +++ b/server/ctrlsubsonic/spec/spec.go @@ -44,6 +44,7 @@ type Response struct { 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"` @@ -294,6 +295,10 @@ type Podcasts struct { List []*PodcastChannel `xml:"channel" json:"channel"` } +type NewestPodcasts struct { + List []*PodcastEpisode `xml:"episode" json:"episode"` +} + type PodcastChannel struct { ID *specid.ID `xml:"id,attr" json:"id"` URL string `xml:"url,attr" json:"url"` diff --git a/server/server.go b/server/server.go index 59f8d579..fac2ec3d 100644 --- a/server/server.go +++ b/server/server.go @@ -253,6 +253,7 @@ func setupSubsonic(r *mux.Router, ctrl *ctrlsubsonic.Controller) { // podcasts r.Handle("/getPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetPodcasts)) + r.Handle("/getNewestPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetNewestPodcasts)) r.Handle("/downloadPodcastEpisode{_:(?:\\.view)?}", ctrl.H(ctrl.ServeDownloadPodcastEpisode)) r.Handle("/createPodcastChannel{_:(?:\\.view)?}", ctrl.H(ctrl.ServeCreatePodcastChannel)) r.Handle("/refreshPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeRefreshPodcasts))