mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 11:54:59 -04:00
Paginate briefing cards and add video previews
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
const UserAgent = "box-box/phase-19b-rss-spike"
|
||||
const UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||||
|
||||
// Source describes a feed that can be fetched and normalized.
|
||||
type Source struct {
|
||||
@@ -207,6 +207,12 @@ type rssItem struct {
|
||||
PubDate string `xml:"pubDate"`
|
||||
Description string `xml:"description"`
|
||||
Categories []string `xml:"category"`
|
||||
Thumbnail struct {
|
||||
URL string `xml:"url,attr"`
|
||||
} `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
||||
Content struct {
|
||||
URL string `xml:"url,attr"`
|
||||
} `xml:"http://search.yahoo.com/mrss/ content"`
|
||||
}
|
||||
|
||||
type atomFeed struct {
|
||||
@@ -225,6 +231,12 @@ type atomEntry struct {
|
||||
Term string `xml:"term,attr"`
|
||||
Label string `xml:"label,attr"`
|
||||
} `xml:"category"`
|
||||
MediaGroup struct {
|
||||
Thumbnail struct {
|
||||
URL string `xml:"url,attr"`
|
||||
} `xml:"http://search.yahoo.com/mrss/ thumbnail"`
|
||||
Description string `xml:"http://search.yahoo.com/mrss/ description"`
|
||||
} `xml:"http://search.yahoo.com/mrss/ group"`
|
||||
}
|
||||
|
||||
type atomLink struct {
|
||||
@@ -243,6 +255,10 @@ func normalizeRSS(source Source, raw []rssItem, fetchedAt time.Time) []Item {
|
||||
if !source.SkipSummary {
|
||||
summary = stripHTML(entry.Description)
|
||||
}
|
||||
imgURL := entry.Thumbnail.URL
|
||||
if imgURL == "" {
|
||||
imgURL = entry.Content.URL
|
||||
}
|
||||
items = append(items, Item{
|
||||
Source: source.ID,
|
||||
Title: cleanText(entry.Title),
|
||||
@@ -251,6 +267,7 @@ func normalizeRSS(source Source, raw []rssItem, fetchedAt time.Time) []Item {
|
||||
Summary: summary,
|
||||
Category: firstNonEmpty(entry.Categories, source.Category),
|
||||
FetchedAt: fetchedAt,
|
||||
OGImageURL: imgURL,
|
||||
})
|
||||
}
|
||||
return DeduplicateByURL(items)
|
||||
@@ -265,17 +282,19 @@ func normalizeAtom(source Source, raw []atomEntry, fetchedAt time.Time) []Item {
|
||||
}
|
||||
summary := ""
|
||||
if !source.SkipSummary {
|
||||
raw := firstNonEmpty([]string{entry.Summary, entry.Content}, "")
|
||||
raw := firstNonEmpty([]string{entry.Summary, entry.Content, entry.MediaGroup.Description}, "")
|
||||
summary = stripHTML(raw)
|
||||
}
|
||||
items = append(items, Item{
|
||||
Source: source.ID,
|
||||
Title: cleanText(entry.Title),
|
||||
URL: atomEntryURL(entry),
|
||||
PublishedAt: parseFeedTime(firstNonEmpty([]string{entry.Published, entry.Updated}, "")),
|
||||
Summary: summary,
|
||||
Category: category,
|
||||
FetchedAt: fetchedAt,
|
||||
Source: source.ID,
|
||||
Title: cleanText(entry.Title),
|
||||
URL: atomEntryURL(entry),
|
||||
PublishedAt: parseFeedTime(firstNonEmpty([]string{entry.Published, entry.Updated}, "")),
|
||||
Summary: summary,
|
||||
Category: category,
|
||||
FetchedAt: fetchedAt,
|
||||
OGImageURL: entry.MediaGroup.Thumbnail.URL,
|
||||
OGDescription: stripHTML(entry.MediaGroup.Description),
|
||||
})
|
||||
}
|
||||
return DeduplicateByURL(items)
|
||||
|
||||
@@ -166,6 +166,9 @@ func enrichOG(ctx context.Context, client *http.Client, items []Item, parallel i
|
||||
}
|
||||
|
||||
for i := range items {
|
||||
if items[i].OGImageURL != "" {
|
||||
continue // Already has preview from feed, skip OG head fetch
|
||||
}
|
||||
wg.Add(1)
|
||||
go func(idx int) {
|
||||
defer wg.Done()
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
func TestCoverageCRUD(t *testing.T) {
|
||||
s := openTestStore(t)
|
||||
|
||||
// Verify schema migration version is 4 (since we added 004_coverage.sql)
|
||||
// Verify schema migration version is 5 (since we added 005_news_enriched.sql)
|
||||
version, err := s.SchemaVersion()
|
||||
if err != nil {
|
||||
t.Fatalf("SchemaVersion() error = %v", err)
|
||||
}
|
||||
if version != 4 {
|
||||
t.Fatalf("SchemaVersion() = %d, want 4", version)
|
||||
if version != 5 {
|
||||
t.Fatalf("SchemaVersion() = %d, want 5", version)
|
||||
}
|
||||
|
||||
// Verify session_coverage table exists
|
||||
|
||||
@@ -28,8 +28,8 @@ func TestOpenAppliesMigrations(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("SchemaVersion() error = %v", err)
|
||||
}
|
||||
if version != 4 {
|
||||
t.Fatalf("SchemaVersion() = %d, want 4", version)
|
||||
if version != 5 {
|
||||
t.Fatalf("SchemaVersion() = %d, want 5", version)
|
||||
}
|
||||
|
||||
tables := []string{
|
||||
@@ -99,6 +99,12 @@ func TestMigrationsAreIdempotent(t *testing.T) {
|
||||
if count != 1 {
|
||||
t.Fatalf("schema_migrations v4 count = %d, want 1", count)
|
||||
}
|
||||
if err := s.db.QueryRow(`SELECT COUNT(*) FROM schema_migrations WHERE version = 5`).Scan(&count); err != nil {
|
||||
t.Fatalf("count schema_migrations v5: %v", err)
|
||||
}
|
||||
if count != 1 {
|
||||
t.Fatalf("schema_migrations v5 count = %d, want 1", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawPayloadInsertAndRead(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user