RSS Reader
ANetBBS ships a built-in RSS / Atom feed reader. Users browse it from
the web (Tools → RSS Reader) or the BBS terminal (Main BBS Menu → R).
Sysops manage feeds at Admin → Subsystems → RSS Feeds.
A default feed (X-News at https://x-bit.org/rss/rss.xml) is seeded
on first run so a fresh install ships with at least one feed populated.
How users see it
Web
- Tools → RSS Reader lists every active feed with per-user unread
counts. - All Feeds (River) is a combined newest-first stream across every
feed. - Click a feed → paginated item list. New items show in bold with
a NEW badge. - Click an item → full content view. Marks as read.
- "Mark all read" button per-feed and global.
Terminal (telnet/SSH)
- Press
Rfrom the Main BBS Menu. - Feed list shows item count and unread count per feed.
A= combined river of all feeds.- Numeric choice = open that feed.
- Inside a feed: numeric = read item,
N/Ppaginate,Qreturns. *marker = unread; reading clears it.
How the poller works
Background daemon thread (anetbbs.rss.poller) wakes on
RSS_POLL_INTERVAL (default 1800s = 30 min) and refreshes every active
feed via Python's feedparser. Items are deduped per-feed by GUID
(falls back to link or title if the feed doesn't supply a GUID).
Failed fetches set feed.last_error so the sysop sees red badges in
the admin list.
To refresh manually, hit the circular-arrow icon next to a feed in
/admin/rss/.
How sysops add a feed
Admin → Subsystems → RSS Feeds → Add Feed:
| Field | Notes |
|---|---|
| Name | Display name shown to users (e.g., X-News) |
| Category | Free text — news, tech, scene, general. Used for grouping in future versions; currently informational. |
| Feed URL | RSS 2.0 / Atom / RSS 1.0 — feedparser handles all of them. |
| Site URL | Optional human-facing homepage of the feed source. |
| Description | One-liner shown on the feed picker. |
| Sort order | Lower = appears first. |
| Active | Disable to hide a feed without deleting its history. |
Saving a new feed triggers an immediate fetch so users see items right
away (no waiting for the next 30-min poll tick).
Deleting a feed cascades — all its items and per-user read state are
removed.
Tunables
RSS_POLL_INTERVALenv var — seconds between polls (default 1800,
minimum 60). Set tighter on a fast-moving feed; relax on stable
feeds to be a polite citizen.
Storage
| Table | What it holds |
|---|---|
rss_feeds |
Sysop-configured feeds (URL, name, category, last fetch state). |
rss_items |
Article/post records, deduped per-feed by GUID. |
rss_read_status |
Per-user read markers (presence = read, absence = unread). |
Auto-created on app startup via the lightweight migration sweep.
No manual SQL needed.
Future / open questions
- Web autorefresh — the user has to reload the page to see new
items between poll ticks. A SocketIO push of "new item arrived"
would be a nice touch. - Feed groupings by category — currently the category field is
stored but not surfaced in the UI. - Per-user feed subscriptions — right now every user sees every
active feed. A future version could let users hide/show specific
feeds.