1
0
Fork 0
forked from 0x2E/fusion
fusion/service/pull/handle.go
Michael Lynch 235e93b0fd Rename pull.FetchFeeds to FetchFeed
If I understand correctly, the function fetches a single feed, so the name should be FetchFeed to reflect the function's purpose.
2025-02-24 20:57:21 -05:00

97 lines
2.1 KiB
Go

package pull
import (
"context"
"fmt"
"io"
"net/http"
"time"
"github.com/0x2e/fusion/model"
"github.com/0x2e/fusion/pkg/httpx"
"github.com/mmcdole/gofeed"
)
func (p *Puller) do(ctx context.Context, f *model.Feed, force bool) error {
logger := pullLogger.With("feed_id", f.ID, "feed_name", f.Name)
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
if f.IsSuspended() {
logger.Infoln("skip: suspended")
return nil
}
if !force {
if f.IsFailed() {
logger.Infoln("skip: failure exists")
return nil
}
if time.Since(f.UpdatedAt) < interval {
logger.Infoln("skip: new enough")
return nil
}
}
failure := ""
fetched, err := FetchFeed(ctx, f)
if err != nil {
failure = err.Error()
p.feedRepo.Update(f.ID, &model.Feed{Failure: &failure})
return err
}
if fetched == nil {
return nil
}
isLatestBuild := f.LastBuild != nil && fetched.UpdatedParsed != nil &&
fetched.UpdatedParsed.Equal(*f.LastBuild)
if len(fetched.Items) != 0 && !isLatestBuild {
data := make([]*model.Item, 0, len(fetched.Items))
for _, i := range fetched.Items {
unread := true
content := i.Content
if content == "" {
content = i.Description
}
guid := i.GUID
if guid == "" {
guid = i.Link
}
data = append(data, &model.Item{
Title: &i.Title,
GUID: &guid,
Link: &i.Link,
Content: &content,
PubDate: i.PublishedParsed,
Unread: &unread,
FeedID: f.ID,
})
}
if err := p.itemRepo.Creates(data); err != nil {
return err
}
}
logger.Infof("fetched %d items", len(fetched.Items))
return p.feedRepo.Update(f.ID, &model.Feed{
LastBuild: fetched.PublishedParsed,
Failure: &failure,
})
}
func FetchFeed(ctx context.Context, f *model.Feed) (*gofeed.Feed, error) {
resp, err := httpx.FusionRequest(ctx, *f.Link, &f.FeedRequestOptions)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("get status code %d", resp.StatusCode)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return gofeed.NewParser().ParseString(string(data))
}