Add kids news channel; document per-source language filter
- New kids channel (/kids) with theme color, surfaced in the web UI and routed to by BBC Newsround, DOGO News, Science News Explores, and NASA for Students in the example config. - README and config.example.toml now mention the optional per-source `language` filter added in the previous commit.
This commit is contained in:
@@ -29,6 +29,7 @@ A Matrix news bot that ingests RSS feeds from curated sources and routes each st
|
|||||||
| `music` | Records, scenes, artists |
|
| `music` | Records, scenes, artists |
|
||||||
| `anime` | Series, studios, manga |
|
| `anime` | Series, studios, manga |
|
||||||
| `foss` | Kernel, distros, free/open source |
|
| `foss` | Kernel, distros, free/open source |
|
||||||
|
| `kids` | World news written for younger readers (web-only) |
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -66,14 +67,14 @@ See `config.example.toml` for the full structure. Key sections:
|
|||||||
- `matrix` — homeserver, credentials, channel room IDs, optional admin room
|
- `matrix` — homeserver, credentials, channel room IDs, optional admin room
|
||||||
- `posting` — rate limiting (min interval, burst cap, daily cap), optional `round_robin` block
|
- `posting` — rate limiting (min interval, burst cap, daily cap), optional `round_robin` block
|
||||||
- `storage` — database path, retention windows
|
- `storage` — database path, retention windows
|
||||||
- `sources` — RSS feeds with tier, polling interval, and **required** `direct_route` (must match a key in `matrix.channels`)
|
- `sources` — RSS feeds with tier, polling interval, and **required** `direct_route` (must match a key in `matrix.channels`). Optional `language = "en"` drops items whose per-item `<language>` tag doesn't prefix-match — handy for multilingual feeds like Politico Europe
|
||||||
- `web` — read-only HTTP UI (enabled toggle, listen address, site title, public base URL)
|
- `web` — read-only HTTP UI (enabled toggle, listen address, site title, public base URL)
|
||||||
|
|
||||||
Environment variables can be referenced with `${VAR}` syntax in the TOML.
|
Environment variables can be referenced with `${VAR}` syntax in the TOML.
|
||||||
|
|
||||||
### Web UI
|
### Web UI
|
||||||
|
|
||||||
Set `web.enabled: true` (default port `:8080`) to expose Pete's classified-story archive over HTTP. A landing page at `/` plus one section per channel (`/gaming`, `/tech`, `/politics`, `/eu`, `/music`, `/anime`, `/foss`), all pulling from the `stories` table. A `/weather` page demos the seasonal canvas overlay in isolation. Adding a section is two lines in `internal/web/server.go` (the `channels` slice) plus a matching theme color in `internal/web/static/css/input.css`.
|
Set `web.enabled: true` (default port `:8080`) to expose Pete's classified-story archive over HTTP. A landing page at `/` plus one section per channel (`/gaming`, `/tech`, `/politics`, `/eu`, `/music`, `/anime`, `/foss`, `/kids`), all pulling from the `stories` table. A `/weather` page demos the seasonal canvas overlay in isolation. Adding a section is two lines in `internal/web/server.go` (the `channels` slice) plus a matching theme color in `internal/web/static/css/input.css`.
|
||||||
|
|
||||||
The frontend uses a small Tailwind build:
|
The frontend uses a small Tailwind build:
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ base_url = "https://news.parodia.dev"
|
|||||||
|
|
||||||
# Every enabled source MUST set direct_route to a key from [matrix.channels] above.
|
# Every enabled source MUST set direct_route to a key from [matrix.channels] above.
|
||||||
# There is no automatic classification — Pete posts each story to its configured channel.
|
# There is no automatic classification — Pete posts each story to its configured channel.
|
||||||
|
# Optional: language = "en" drops feed items whose per-item <language> tag is
|
||||||
|
# set and doesn't match (prefix). Useful for multilingual feeds like Politico
|
||||||
|
# Europe that publish the same story in en / fr / de side-by-side. Items with
|
||||||
|
# no language tag pass through unchanged.
|
||||||
[[sources]]
|
[[sources]]
|
||||||
name = "The Guardian — World"
|
name = "The Guardian — World"
|
||||||
feed_url = "https://www.theguardian.com/world/rss"
|
feed_url = "https://www.theguardian.com/world/rss"
|
||||||
@@ -114,6 +118,38 @@ poll_interval_minutes = 60
|
|||||||
direct_route = "music"
|
direct_route = "music"
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
[[sources]]
|
||||||
|
name = "BBC Newsround"
|
||||||
|
feed_url = "http://feeds.bbci.co.uk/newsround/rss.xml"
|
||||||
|
tier = 1
|
||||||
|
poll_interval_minutes = 30
|
||||||
|
direct_route = "kids"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[sources]]
|
||||||
|
name = "DOGO News"
|
||||||
|
feed_url = "https://www.dogonews.com/articles.rss"
|
||||||
|
tier = 1
|
||||||
|
poll_interval_minutes = 60
|
||||||
|
direct_route = "kids"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[sources]]
|
||||||
|
name = "Science News Explores"
|
||||||
|
feed_url = "https://www.snexplores.org/feed"
|
||||||
|
tier = 1
|
||||||
|
poll_interval_minutes = 60
|
||||||
|
direct_route = "kids"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[[sources]]
|
||||||
|
name = "NASA for Students"
|
||||||
|
feed_url = "https://www.nasa.gov/rss/dyn/educationnews.rss"
|
||||||
|
tier = 1
|
||||||
|
poll_interval_minutes = 60
|
||||||
|
direct_route = "kids"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
[[sources]]
|
[[sources]]
|
||||||
name = "Post-Punk.com"
|
name = "Post-Punk.com"
|
||||||
feed_url = "https://post-punk.com/feed/"
|
feed_url = "https://post-punk.com/feed/"
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ var channels = []Channel{
|
|||||||
{Slug: "music", Title: "Music", Theme: "music", Emoji: "🎵", Blurb: "Records, scenes, and the artists shaping the sound."},
|
{Slug: "music", Title: "Music", Theme: "music", Emoji: "🎵", Blurb: "Records, scenes, and the artists shaping the sound."},
|
||||||
{Slug: "anime", Title: "Anime", Theme: "anime", Emoji: "🌸", Blurb: "Series, studios, and the wider world of anime and manga."},
|
{Slug: "anime", Title: "Anime", Theme: "anime", Emoji: "🌸", Blurb: "Series, studios, and the wider world of anime and manga."},
|
||||||
{Slug: "foss", Title: "FOSS", Theme: "foss", Emoji: "🐧", Blurb: "Kernel, distros, and the wider free and open source software world."},
|
{Slug: "foss", Title: "FOSS", Theme: "foss", Emoji: "🐧", Blurb: "Kernel, distros, and the wider free and open source software world."},
|
||||||
|
{Slug: "kids", Title: "Kids", Theme: "kids", Emoji: "🧒", Blurb: "World news written for younger readers — short, clear, and curious."},
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceInfo is the trimmed view of a configured feed for the settings panel.
|
// SourceInfo is the trimmed view of a configured feed for the settings panel.
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ html[data-phase="night"] {
|
|||||||
.bg-theme-music { background-color: #b079d6; }
|
.bg-theme-music { background-color: #b079d6; }
|
||||||
.bg-theme-anime { background-color: #ec5e8a; }
|
.bg-theme-anime { background-color: #ec5e8a; }
|
||||||
.bg-theme-foss { background-color: #d97706; }
|
.bg-theme-foss { background-color: #d97706; }
|
||||||
|
.bg-theme-kids { background-color: #14b8a6; }
|
||||||
|
|
||||||
.text-theme-gaming { color: #2d8a5a; }
|
.text-theme-gaming { color: #2d8a5a; }
|
||||||
.text-theme-tech { color: #2f7fb8; }
|
.text-theme-tech { color: #2f7fb8; }
|
||||||
@@ -84,6 +85,7 @@ html[data-phase="night"] {
|
|||||||
.text-theme-music { color: #8a4fb8; }
|
.text-theme-music { color: #8a4fb8; }
|
||||||
.text-theme-anime { color: #c33a6a; }
|
.text-theme-anime { color: #c33a6a; }
|
||||||
.text-theme-foss { color: #b8530a; }
|
.text-theme-foss { color: #b8530a; }
|
||||||
|
.text-theme-kids { color: #0f766e; }
|
||||||
|
|
||||||
.decoration-theme-gaming { text-decoration-color: #4caf7d; }
|
.decoration-theme-gaming { text-decoration-color: #4caf7d; }
|
||||||
.decoration-theme-tech { text-decoration-color: #5aa9e6; }
|
.decoration-theme-tech { text-decoration-color: #5aa9e6; }
|
||||||
@@ -92,6 +94,7 @@ html[data-phase="night"] {
|
|||||||
.decoration-theme-music { text-decoration-color: #b079d6; }
|
.decoration-theme-music { text-decoration-color: #b079d6; }
|
||||||
.decoration-theme-anime { text-decoration-color: #ec5e8a; }
|
.decoration-theme-anime { text-decoration-color: #ec5e8a; }
|
||||||
.decoration-theme-foss { text-decoration-color: #d97706; }
|
.decoration-theme-foss { text-decoration-color: #d97706; }
|
||||||
|
.decoration-theme-kids { text-decoration-color: #14b8a6; }
|
||||||
|
|
||||||
.border-theme-gaming { border-color: #4caf7d; }
|
.border-theme-gaming { border-color: #4caf7d; }
|
||||||
.border-theme-tech { border-color: #5aa9e6; }
|
.border-theme-tech { border-color: #5aa9e6; }
|
||||||
@@ -100,6 +103,7 @@ html[data-phase="night"] {
|
|||||||
.border-theme-music { border-color: #b079d6; }
|
.border-theme-music { border-color: #b079d6; }
|
||||||
.border-theme-anime { border-color: #ec5e8a; }
|
.border-theme-anime { border-color: #ec5e8a; }
|
||||||
.border-theme-foss { border-color: #d97706; }
|
.border-theme-foss { border-color: #d97706; }
|
||||||
|
.border-theme-kids { border-color: #14b8a6; }
|
||||||
|
|
||||||
/* "Posted to Matrix" glow — soft pulsing aura in the channel's theme color. */
|
/* "Posted to Matrix" glow — soft pulsing aura in the channel's theme color. */
|
||||||
.glow-theme-gaming { box-shadow: 0 0 0 2px rgba(76,175,125,0.35), 0 0 24px 4px rgba(76,175,125,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
.glow-theme-gaming { box-shadow: 0 0 0 2px rgba(76,175,125,0.35), 0 0 24px 4px rgba(76,175,125,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
||||||
@@ -109,6 +113,7 @@ html[data-phase="night"] {
|
|||||||
.glow-theme-music { box-shadow: 0 0 0 2px rgba(176,121,214,0.35), 0 0 24px 4px rgba(176,121,214,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
.glow-theme-music { box-shadow: 0 0 0 2px rgba(176,121,214,0.35), 0 0 24px 4px rgba(176,121,214,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
||||||
.glow-theme-anime { box-shadow: 0 0 0 2px rgba(236,94,138,0.35), 0 0 24px 4px rgba(236,94,138,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
.glow-theme-anime { box-shadow: 0 0 0 2px rgba(236,94,138,0.35), 0 0 24px 4px rgba(236,94,138,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
||||||
.glow-theme-foss { box-shadow: 0 0 0 2px rgba(217,119,6,0.35), 0 0 24px 4px rgba(217,119,6,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
.glow-theme-foss { box-shadow: 0 0 0 2px rgba(217,119,6,0.35), 0 0 24px 4px rgba(217,119,6,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
||||||
|
.glow-theme-kids { box-shadow: 0 0 0 2px rgba(20,184,166,0.35), 0 0 24px 4px rgba(20,184,166,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; }
|
||||||
|
|
||||||
@keyframes pete-glow-pulse {
|
@keyframes pete-glow-pulse {
|
||||||
0%, 100% { filter: brightness(1); }
|
0%, 100% { filter: brightness(1); }
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user