rssfeed

package
v1.11.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package rssfeed fetches and parses RSS 2.0 and Atom feeds for the dashboard news tray. It uses encoding/xml only: the feeds it reads are small, and the subset of either format the tray renders (title, link, summary, date, id) is narrow enough that a full feed library would be dead weight.

Index

Constants

View Source
const (
	// DefaultTTL is how long a fetched feed is served from cache.
	DefaultTTL = 15 * time.Minute
)
View Source
const (
	// MaxItemsPerFeed caps what one feed contributes to the tray.
	MaxItemsPerFeed = 20
)

Variables

View Source
var ErrFeedTooLarge = errors.New("feed exceeds the 2 MB size limit")

ErrFeedTooLarge is returned when a feed body exceeds maxFeedBytes.

View Source
var ErrNotAFeed = errors.New("document is not an RSS or Atom feed")

ErrNotAFeed is returned when the document parses as XML but is neither an RSS nor an Atom feed (for example an HTML page served at the feed URL).

Functions

This section is empty.

Types

type Item

type Item struct {
	GUID        string    `json:"guid"`
	Title       string    `json:"title"`
	Link        string    `json:"link"`
	Summary     string    `json:"summary,omitempty"`
	PublishedAt time.Time `json:"published_at"`
}

Item is one normalized entry from a feed.

func Parse

func Parse(data []byte) ([]Item, error)

Parse decodes an RSS 2.0, RSS 1.0 or Atom document into at most MaxItemsPerFeed items, newest first. Entries without a title and a link are dropped, since the tray can neither label nor open them.

func ParseHTMLPage

func ParseHTMLPage(data []byte, base *url.URL) ([]Item, error)

ParseHTMLPage extracts entries from a news listing page that publishes no feed (anthropic.com/news is the motivating case). An entry is an <a href> that wraps either a heading, or a <time> plus an element whose class names a title (the compact list rows such pages use). The heading or title element is the title, a <time> inside the card is the date (its datetime attribute, else its text), and the first <p> is the summary. Relative links resolve against base. Links that leave base's host are ignored, as are duplicates.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager fetches feeds through an SSRF-safe client and caches the parsed result per URL. Memory retained is bounded by the number of distinct URLs fetched (at most MaxItemsPerFeed items each); Forget drops a URL's entry when its feed is deleted or repointed.

func NewManager

func NewManager() *Manager

NewManager returns a Manager that refuses private and link-local targets, both at validation time and at dial time (defeating DNS rebinding).

func NewManagerWithClient

func NewManagerWithClient(client *http.Client) *Manager

NewManagerWithClient is the test seam: it uses the given client and skips URL validation, so feeds can be served from an httptest server on loopback.

func (*Manager) Fetch

func (m *Manager) Fetch(ctx context.Context, url string) ([]Item, error)

Fetch downloads and parses url without touching the cache. Used directly to validate a feed before it is saved.

func (*Manager) Forget

func (m *Manager) Forget(url string)

Forget drops the cached entry for url, including the result of a fetch still in flight for it.

func (*Manager) Get

func (m *Manager) Get(ctx context.Context, url string) ([]Item, error)

Get returns the items for url, serving from cache while fresh. Concurrent callers for the same URL share one upstream fetch.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL