Files
rsser/rss/parse.go
T
2026-08-05 12:06:46 +05:00

103 lines
2.1 KiB
Go

package rss
import (
"context"
"log/slog"
"net/url"
"time"
"github.com/mmcdole/gofeed"
"github.com/prodigeris/html2text"
"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
}
description, err := html2text.FromString(item.Description, html2text.Options{
PrettyTables: true,
})
if err != nil {
description = item.Description
}
title, fixedDescription := fixers.Fix(feedURL.Host, item.Title, description)
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
}
}
}
}