From 5a7fac748b9a6ec78a2c7a571d075c2991b937a5 Mon Sep 17 00:00:00 2001 From: Darius Rapalis Date: Tue, 11 Mar 2025 12:41:15 +0200 Subject: [PATCH] #6 - fetch feed --- internal/handlers/fetchFeedHandler.go | 30 ++++++++++++++ internal/rss/rss.go | 57 +++++++++++++++++++++++++++ main.go | 1 + 3 files changed, 88 insertions(+) create mode 100644 internal/handlers/fetchFeedHandler.go create mode 100644 internal/rss/rss.go diff --git a/internal/handlers/fetchFeedHandler.go b/internal/handlers/fetchFeedHandler.go new file mode 100644 index 0000000..048dc5a --- /dev/null +++ b/internal/handlers/fetchFeedHandler.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "context" + "fmt" + "github.com/rdarius/boot-dev-blog-aggregator/internal/config" + "github.com/rdarius/boot-dev-blog-aggregator/internal/rss" + "os" +) + +func FetchFeedHandler(s *config.State, cmd config.Command) error { + var feedUrl string + if len(cmd.Args) < 1 { + feedUrl = "https://www.wagslane.dev/index.xml" + } else { + feedUrl = cmd.Args[0] + } + + ctx := context.Background() + + feed, err := rss.FetchFeed(ctx, feedUrl) + if err != nil { + fmt.Println("Failed to fetch feed") + os.Exit(1) + } + + fmt.Printf("%v", feed) + + return nil +} diff --git a/internal/rss/rss.go b/internal/rss/rss.go new file mode 100644 index 0000000..d2962a7 --- /dev/null +++ b/internal/rss/rss.go @@ -0,0 +1,57 @@ +package rss + +import ( + "context" + "encoding/xml" + "html" + "io" + "net/http" +) + +type Feed struct { + Channel struct { + Title string `xml:"title"` + Link string `xml:"link"` + Description string `xml:"description"` + Item []Item `xml:"item"` + } `xml:"channel"` +} + +type Item struct { + Title string `xml:"title"` + Link string `xml:"link"` + Description string `xml:"description"` + PubDate string `xml:"pubDate"` +} + +func FetchFeed(ctx context.Context, feedURL string) (*Feed, error) { + req, err := http.NewRequestWithContext(ctx, "GET", feedURL, nil) + if err != nil { + return nil, err + } + req.Header.Set("User-Agent", "gator") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + res, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var feed Feed + err = xml.Unmarshal(res, &feed) + if err != nil { + return nil, err + } + feed.Channel.Title = html.UnescapeString(feed.Channel.Title) + feed.Channel.Link = html.UnescapeString(feed.Channel.Link) + feed.Channel.Description = html.UnescapeString(feed.Channel.Description) + for i, _ := range feed.Channel.Item { + feed.Channel.Item[i].Link = html.UnescapeString(feed.Channel.Item[i].Link) + feed.Channel.Item[i].Description = html.UnescapeString(feed.Channel.Item[i].Description) + feed.Channel.Item[i].PubDate = html.UnescapeString(feed.Channel.Item[i].PubDate) + feed.Channel.Item[i].Title = html.UnescapeString(feed.Channel.Item[i].Title) + } + return &feed, nil +} diff --git a/main.go b/main.go index 6a03d95..96a6a04 100644 --- a/main.go +++ b/main.go @@ -35,6 +35,7 @@ func main() { commands.Register("register", handlers.RegisterHandler) commands.Register("reset", handlers.ResetUsersHandler) commands.Register("users", handlers.GetUsersHandler) + commands.Register("agg", handlers.FetchFeedHandler) if len(os.Args) < 2 { log.Fatal("usage: boot-dev-blog-aggregator [args...]")