diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-01 10:05:13 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-01 10:05:13 +0900 |
| commit | 1d78371e13c19488d472257ab614e0be17bfa85e (patch) | |
| tree | 6c14cf068faac9a9a411d1cf6c436ae23ba235c2 /backend/feed/feed.go | |
| parent | 65d6ebca318fecb48b32c0ecdba3ae01304b55de (diff) | |
| download | feedaka-1d78371e13c19488d472257ab614e0be17bfa85e.tar.gz feedaka-1d78371e13c19488d472257ab614e0be17bfa85e.tar.zst feedaka-1d78371e13c19488d472257ab614e0be17bfa85e.zip | |
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 <noreply@anthropic.com>
Diffstat (limited to 'backend/feed/feed.go')
| -rw-r--r-- | backend/feed/feed.go | 75 |
1 files changed, 75 insertions, 0 deletions
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 +} |
