package rss import ( "context" "log/slog" "net/url" "time" "github.com/mmcdole/gofeed" "go.dev.pztrn.name/rsser/fixers" ) // Parse parses RSS feeds and produce output in outputs. func (r *RSS) Parse() { for _, feed := range r.cfg.RSS.Feeds { ctx, cancelFunc := context.WithTimeout( context.Background(), time.Second*time.Duration(r.cfg.RSS.HTTPClient.RequestTimeoutSeconds), ) //revive:disable:defer defer cancelFunc() parser := gofeed.NewParser() parsedFeedData, err := parser.ParseURLWithContext(feed.URL, ctx) if err != nil { slog.Error("Failed to parse feed!", "name", feed.Name, "error", err.Error()) return } feedURL, _ := url.Parse(feed.URL) for _, item := range parsedFeedData.Items { slog.Info( "Processing feed item...", "domain", feedURL.Host, "guid", item.GUID, ) itemWasProcessed, err := r.checkItemWasProcessed(feedURL.Host, item.GUID) if err != nil { slog.Error( "Failed to check item processing status!", "domain", feedURL.Host, "guid", item.GUID, "error", err.Error(), ) return } if itemWasProcessed { slog.Info( "Feed item already processed, skipping.", "domain", feedURL.Host, "guid", item.GUID, ) continue } title, fixedDescription := fixers.Fix(feedURL.Host, item) for _, output := range r.outputs { if feed.Output == output.Name() { if err := output.Do(feed.Destination, feed.Name, item.Link, title, fixedDescription); err != nil { slog.Error( "Failed to process feed item with outputter!", "feed", feed.Name, "guid", item.GUID, "error", err.Error(), ) return } break } } if err := r.addProcessedItem(feedURL.Host, item.GUID); err != nil { slog.Error( "Failed to save item processing status!", "domain", feedURL.Host, "guid", item.GUID, "error", err.Error(), ) return } } } }