feat: implement feed agg and browse

This commit is contained in:
Stevan Freeborn
2026-08-03 07:14:33 -05:00
parent f51b1b941a
commit 667f5f112b
12 changed files with 444 additions and 40 deletions
+68 -1
View File
@@ -2,9 +2,16 @@ package rss
import (
"context"
"database/sql"
"encoding/xml"
"fmt"
"html"
"net/http"
"time"
"github.com/StevanFreeborn/gator/internal/database"
"github.com/StevanFreeborn/gator/internal/state"
"github.com/google/uuid"
)
type RSSItem struct {
@@ -25,7 +32,7 @@ type RSSFeed struct {
Channel RSSChannel `xml:"channel"`
}
func FetchFeed(ctx context.Context, feedURL string) (*RSSFeed, error) {
func fetchFeed(ctx context.Context, feedURL string) (*RSSFeed, error) {
var rssFeed RSSFeed
req, err := http.NewRequestWithContext(ctx, http.MethodGet, feedURL, nil)
@@ -59,3 +66,63 @@ func FetchFeed(ctx context.Context, feedURL string) (*RSSFeed, error) {
return &rssFeed, nil
}
func ScrapeNextFeed(ctx context.Context, s *state.State) {
nextFeed, err := s.Database.GetNextFeedToFetch(ctx)
if err != nil {
fmt.Print("Failed to lookup next feed to fetch\r\n")
return
}
fmt.Printf("Fetching feed '%s'\r\n", nextFeed.Name)
fetchedFeed, err := fetchFeed(ctx, nextFeed.Url)
if err != nil {
fmt.Printf("Failed to fetch feed '%s'\r\n", nextFeed.Name)
return
}
markFeedParams := database.MarkFeedAsFetchedParams{
ID: nextFeed.ID,
LastFetchedAt: sql.NullTime{
Time: time.Now(),
Valid: true,
},
}
err = s.Database.MarkFeedAsFetched(ctx, markFeedParams)
for _, item := range fetchedFeed.Channel.Item {
publishedAt, err := time.Parse(time.RFC3339, item.PubDate)
publishedAtValue := sql.NullTime{
Time: publishedAt,
Valid: err == nil,
}
createPostParams := database.CreatePostParams{
ID: uuid.New(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Title: item.Title,
Url: item.Link,
Description: item.Description,
PublishedAt: publishedAtValue,
FeedID: nextFeed.ID,
}
_, err = s.Database.CreatePost(ctx, createPostParams)
if err != nil {
fmt.Printf(" Skipping saving post '%s'\r\n", item.Title)
continue
}
fmt.Printf(" Saved post '%s'\r\n", item.Title)
}
if err != nil {
fmt.Printf("Failed to mark feed as fetched.\r\n")
}
}