From c9959e7335130a67a5fb2452449e67725cbb4247 Mon Sep 17 00:00:00 2001 From: Akhil Gupta Date: Sun, 20 Jun 2021 17:57:30 +0530 Subject: [PATCH] Now get rss feeds for tags and all podcasts --- Readme.md | 2 +- client/episodes_new.html | 2 +- client/settings.html | 5 ++- client/tags.html | 7 ++++ controllers/podcast.go | 81 ++++++++++++++++++++++++++++++++++++++++ main.go | 2 + model/rssModels.go | 62 ++++++++++++++++++++++++++++++ 7 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 model/rssModels.go diff --git a/Readme.md b/Readme.md index c569ccf..5ff40a8 100644 --- a/Readme.md +++ b/Readme.md @@ -14,7 +14,7 @@ -->

Podgrab

-

Current Version - 2021.06.02

+

Current Version - 2021.06.20

A self-hosted podcast manager to download episodes as soon as they become live diff --git a/client/episodes_new.html b/client/episodes_new.html index 8635a9c..770ad6c 100644 --- a/client/episodes_new.html +++ b/client/episodes_new.html @@ -440,7 +440,7 @@ var app = new Vue({ changeBookmarkStatus(item){ isBookmarked= this.isBookmarked(item); - let self=this; + var self=this; changeBookmarkStatus(item.ID,!isBookmarked,function(){ if(isBookmarked){ item.BookmarkDate=self.nildate diff --git a/client/settings.html b/client/settings.html index 497fff1..f5c838d 100644 --- a/client/settings.html +++ b/client/settings.html @@ -39,6 +39,9 @@

Export OPML
+
+ Rss Feed +

@@ -121,7 +124,7 @@ - + diff --git a/client/tags.html b/client/tags.html index cd9df02..6f8ccd5 100644 --- a/client/tags.html +++ b/client/tags.html @@ -100,6 +100,13 @@ title="Add Episode to existing player playlist" > +
diff --git a/controllers/podcast.go b/controllers/podcast.go index a71ab81..a356f77 100644 --- a/controllers/podcast.go +++ b/controllers/podcast.go @@ -10,6 +10,7 @@ import ( "github.com/akhilrex/podgrab/model" "github.com/akhilrex/podgrab/service" + "github.com/gin-contrib/location" "github.com/akhilrex/podgrab/db" "github.com/gin-gonic/gin" @@ -399,6 +400,86 @@ func GetTagById(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) } } + +func createRss(items []db.PodcastItem, title, description string, c *gin.Context) model.RssPodcastData { + var rssItems []model.RssItem + url := location.Get(c) + for _, item := range items { + rssItem := model.RssItem{ + Title: item.Title, + Description: item.Summary, + Summary: item.Summary, + Image: model.RssItemImage{ + Text: item.Title, + Href: fmt.Sprintf("%s://%s/podcastitems/%s/image", url.Scheme, url.Host, item.ID), + }, + EpisodeType: item.EpisodeType, + Enclosure: model.RssItemEnclosure{ + URL: fmt.Sprintf("%s://%s/podcastitems/%s/file", url.Scheme, url.Host, item.ID), + Length: fmt.Sprint(item.FileSize), + }, + PubDate: item.PubDate.Format("Mon, 02 Jan 2006 15:04:05 -0700"), + Guid: model.RssItemGuid{ + IsPermaLink: "false", + Text: item.ID, + }, + Link: fmt.Sprintf("%s://%s/allTags", url.Scheme, url.Host), + Text: item.Title, + Duration: fmt.Sprint(item.Duration), + } + rssItems = append(rssItems, rssItem) + } + return model.RssPodcastData{ + Itunes: "http://www.itunes.com/dtds/podcast-1.0.dtd", + Media: "http://search.yahoo.com/mrss/", + Version: "2.0", + Atom: "http://www.w3.org/2005/Atom", + Psc: "https://podlove.org/simple-chapters/", + Content: "http://purl.org/rss/1.0/modules/content/", + Channel: model.RssChannel{ + Item: rssItems, + Title: title, + Description: description, + Summary: description, + Link: fmt.Sprintf("%s://%s/allTags", url.Scheme, url.Host), + }, + } +} + +func GetRssForTagById(c *gin.Context) { + var searchByIdQuery SearchByIdQuery + if c.ShouldBindUri(&searchByIdQuery) == nil { + tag, err := db.GetTagById(searchByIdQuery.Id) + var podIds []string + for _, pod := range tag.Podcasts { + podIds = append(podIds, pod.ID) + } + items := *service.GetAllPodcastItemsByPodcastIds(podIds) + + description := fmt.Sprintf("Playing episodes with tag : %s", tag.Label) + title := fmt.Sprintf(" %s | Podgrab", tag.Label) + + if err == nil { + c.XML(200, createRss(items, title, description, c)) + } + } else { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) + } +} +func GetRss(c *gin.Context) { + var items []db.PodcastItem + + if err := db.GetAllPodcastItems(&items); err != nil { + fmt.Println(err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) + } + + title := "Podgrab" + description := "Pograb playlist" + + c.XML(200, createRss(items, title, description, c)) + +} func DeleteTagById(c *gin.Context) { var searchByIdQuery SearchByIdQuery if c.ShouldBindUri(&searchByIdQuery) == nil { diff --git a/main.go b/main.go index 554cffe..af627b6 100644 --- a/main.go +++ b/main.go @@ -168,6 +168,7 @@ func main() { router.GET("/tags", controllers.GetAllTags) router.GET("/tags/:id", controllers.GetTagById) + router.GET("/tags/:id/rss", controllers.GetRssForTagById) router.DELETE("/tags/:id", controllers.DeleteTagById) router.POST("/tags", controllers.AddTag) router.POST("/podcasts/:id/tags/:tagId", controllers.AddTagToPodcast) @@ -185,6 +186,7 @@ func main() { router.POST("/opml", controllers.UploadOpml) router.GET("/opml", controllers.GetOmpl) router.GET("/player", controllers.PlayerPage) + router.GET("/rss", controllers.GetRss) r.GET("/ws", func(c *gin.Context) { controllers.Wshandler(c.Writer, c.Request) diff --git a/model/rssModels.go b/model/rssModels.go new file mode 100644 index 0000000..3796b50 --- /dev/null +++ b/model/rssModels.go @@ -0,0 +1,62 @@ +package model + +import "encoding/xml" + +//PodcastData is +type RssPodcastData struct { + XMLName xml.Name `xml:"rss"` + Text string `xml:",chardata"` + Itunes string `xml:"itunes,attr"` + Atom string `xml:"atom,attr"` + Media string `xml:"media,attr"` + Psc string `xml:"psc,attr"` + Omny string `xml:"omny,attr"` + Content string `xml:"content,attr"` + Googleplay string `xml:"googleplay,attr"` + Acast string `xml:"acast,attr"` + Version string `xml:"version,attr"` + Channel RssChannel `xml:"channel"` +} +type RssChannel struct { + Text string `xml:",chardata"` + Language string `xml:"language"` + Link string `xml:"link"` + Title string `xml:"title"` + Description string `xml:"description"` + Type string `xml:"type"` + Summary string `xml:"summary"` + Item []RssItem `xml:"item"` +} +type RssItem struct { + Text string `xml:",chardata"` + Title string `xml:"title"` + Description string `xml:"description"` + Encoded string `xml:"encoded"` + Summary string `xml:"summary"` + EpisodeType string `xml:"episodeType"` + Author string `xml:"author"` + Image RssItemImage `xml:"image"` + Guid RssItemGuid `xml:"guid"` + ClipId string `xml:"clipId"` + PubDate string `xml:"pubDate"` + Duration string `xml:"duration"` + Enclosure RssItemEnclosure `xml:"enclosure"` + Link string `xml:"link"` + Episode string `xml:"episode"` +} + +type RssItemEnclosure struct { + Text string `xml:",chardata"` + URL string `xml:"url,attr"` + Length string `xml:"length,attr"` + Type string `xml:"type,attr"` +} +type RssItemImage struct { + Text string `xml:",chardata"` + Href string `xml:"href,attr"` +} + +type RssItemGuid struct { + Text string `xml:",chardata"` + IsPermaLink string `xml:"isPermaLink,attr"` +}
Current Version2021.06.02 2021.06.20
Website