From 1d78371e13c19488d472257ab614e0be17bfa85e Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 1 Feb 2026 10:05:13 +0900 Subject: refactor: extract feed fetch and sync logic into shared feed package Consolidate duplicated feed fetching and article syncing code from AddFeed resolver and fetchOneFeed into reusable feed.Fetch and feed.Sync functions. This unifies behavior (10s timeout, article updates) across both call sites. Co-Authored-By: Claude Opus 4.5 --- backend/feed/feed.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 backend/feed/feed.go (limited to 'backend/feed') diff --git a/backend/feed/feed.go b/backend/feed/feed.go new file mode 100644 index 0000000..4349d1e --- /dev/null +++ b/backend/feed/feed.go @@ -0,0 +1,75 @@ +package feed + +import ( + "context" + "fmt" + "time" + + "github.com/mmcdole/gofeed" + + "undef.ninja/x/feedaka/db" +) + +func Fetch(ctx context.Context, url string) (*gofeed.Feed, error) { + fp := gofeed.NewParser() + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + feed, err := fp.ParseURLWithContext(url, ctx) + if err != nil { + return nil, fmt.Errorf("failed to fetch %s: %w", url, err) + } + return feed, nil +} + +func Sync(ctx context.Context, queries *db.Queries, feedID int64, f *gofeed.Feed) error { + err := queries.UpdateFeedMetadata(ctx, db.UpdateFeedMetadataParams{ + Title: f.Title, + FetchedAt: time.Now().UTC().Format(time.RFC3339), + ID: feedID, + }) + if err != nil { + return err + } + + guids, err := queries.GetArticleGUIDsByFeed(ctx, feedID) + if err != nil { + return err + } + existingFeedGUIDs := make(map[string]bool, len(guids)) + for _, guid := range guids { + existingFeedGUIDs[guid] = true + } + + for _, item := range f.Items { + if existingFeedGUIDs[item.GUID] { + err := queries.UpdateArticle(ctx, db.UpdateArticleParams{ + Title: item.Title, + Url: item.Link, + FeedID: feedID, + Guid: item.GUID, + }) + if err != nil { + return err + } + } else { + exists, err := queries.CheckArticleExistsByGUID(ctx, item.GUID) + if err != nil { + return err + } + if exists == 1 { + continue + } + _, err = queries.CreateArticle(ctx, db.CreateArticleParams{ + FeedID: feedID, + Guid: item.GUID, + Title: item.Title, + Url: item.Link, + IsRead: 0, + }) + if err != nil { + return err + } + } + } + return nil +} -- cgit v1.3-1-g0d28