mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-30 15:07:56 +01:00
fix(podcast): address CodeRabbit review feedback
- Remove total HTTP client timeout from episode downloads (use transport phase timeouts instead) and delete partial files on failure - Keep SSE progress listener subscribed while the show view is mounted - Return podcastEpisode (with streamId) from getNewestPodcasts - Clean up dependent rows and MediaFiles in DeleteChannel within a tx - Limit RSS feed body size to 32 MiB - Block additional reserved IP ranges in the SSRF guard - Fall back to enclosure URL when an item has no <guid> - Handle clipboard write failure in the podcast list
This commit is contained in:
parent
19385dc28b
commit
4bebfad0ed
10 changed files with 126 additions and 52 deletions
|
|
@ -225,25 +225,7 @@ func (api *Router) GetNewestPodcasts(r *http.Request) (*responses.Subsonic, erro
|
|||
resp := newResponse()
|
||||
resp.NewestPodcasts = &responses.NewestPodcasts{}
|
||||
for _, ep := range eps {
|
||||
child := responses.Child{
|
||||
Id: ep.ID,
|
||||
Title: ep.Title,
|
||||
IsDir: false,
|
||||
Parent: ep.ChannelID,
|
||||
Duration: int32(ep.Duration),
|
||||
Size: ep.Size,
|
||||
BitRate: int32(ep.BitRate),
|
||||
Suffix: ep.Suffix,
|
||||
ContentType: ep.ContentType,
|
||||
Type: "podcast",
|
||||
ChannelId: ep.ChannelID,
|
||||
Description: ep.Description,
|
||||
Status: string(ep.Status),
|
||||
}
|
||||
if !ep.PublishDate.IsZero() {
|
||||
child.PublishDate = ep.PublishDate.UTC().Format(time.RFC3339)
|
||||
}
|
||||
resp.NewestPodcasts.Episode = append(resp.NewestPodcasts.Episode, child)
|
||||
resp.NewestPodcasts.Episode = append(resp.NewestPodcasts.Episode, buildPodcastEpisode(ep))
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,12 +118,12 @@ var _ = Describe("Podcasts", func() {
|
|||
BeforeEach(func() {
|
||||
now := time.Now()
|
||||
episodeRepo.Data = map[string]*model.PodcastEpisode{
|
||||
"ep-1": {ID: "ep-1", Title: "Ep1", ChannelID: "ch-1", PublishDate: now.Add(-time.Hour), Status: model.PodcastStatusCompleted},
|
||||
"ep-2": {ID: "ep-2", Title: "Ep2", ChannelID: "ch-1", PublishDate: now, Status: model.PodcastStatusNew},
|
||||
"ep-1": {ID: "ep-1", Title: "Ep1", ChannelID: "ch-1", StreamID: "stream-ep-1", PublishDate: now.Add(-time.Hour), Status: model.PodcastStatusCompleted},
|
||||
"ep-2": {ID: "ep-2", Title: "Ep2", ChannelID: "ch-1", StreamID: "stream-ep-2", PublishDate: now, Status: model.PodcastStatusNew},
|
||||
}
|
||||
})
|
||||
|
||||
It("returns episodes in Child format", func() {
|
||||
It("returns episodes in podcastEpisode format", func() {
|
||||
r := httptest.NewRequest("GET", "/rest/getNewestPodcasts", nil)
|
||||
r = r.WithContext(userCtx)
|
||||
|
||||
|
|
@ -132,14 +132,14 @@ var _ = Describe("Podcasts", func() {
|
|||
Expect(resp.NewestPodcasts.Episode).To(HaveLen(2))
|
||||
})
|
||||
|
||||
It("sets type to podcast", func() {
|
||||
It("includes streamId so clients can play the episode", func() {
|
||||
r := httptest.NewRequest("GET", "/rest/getNewestPodcasts", nil)
|
||||
r = r.WithContext(userCtx)
|
||||
|
||||
resp, err := api.GetNewestPodcasts(r)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
for _, ep := range resp.NewestPodcasts.Episode {
|
||||
Expect(ep.Type).To(Equal("podcast"))
|
||||
Expect(ep.StreamId).To(Equal("stream-" + ep.ID))
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -169,12 +169,7 @@ type Child struct {
|
|||
SongCount int32 `xml:"songCount,attr,omitempty" json:"songCount,omitempty"`
|
||||
IsVideo bool `xml:"isVideo,attr,omitempty" json:"isVideo,omitempty"`
|
||||
BookmarkPosition int64 `xml:"bookmarkPosition,attr,omitempty" json:"bookmarkPosition,omitempty"`
|
||||
// Podcast-specific fields (used in getNewestPodcasts)
|
||||
ChannelId string `xml:"channelId,attr,omitempty" json:"channelId,omitempty"`
|
||||
Description string `xml:"description,attr,omitempty" json:"description,omitempty"`
|
||||
Status string `xml:"status,attr,omitempty" json:"status,omitempty"`
|
||||
PublishDate string `xml:"publishDate,attr,omitempty" json:"publishDate,omitempty"`
|
||||
*OpenSubsonicChild `xml:",omitempty" json:",omitempty"`
|
||||
*OpenSubsonicChild `xml:",omitempty" json:",omitempty"`
|
||||
}
|
||||
|
||||
type OpenSubsonicChild struct {
|
||||
|
|
@ -706,7 +701,7 @@ type Podcasts struct {
|
|||
}
|
||||
|
||||
type NewestPodcasts struct {
|
||||
Episode []Child `xml:"episode,omitempty" json:"episode,omitempty"`
|
||||
Episode []PodcastEpisode `xml:"episode,omitempty" json:"episode,omitempty"`
|
||||
}
|
||||
|
||||
type PodcastFundingResp struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue