Adventure news: fix posting gates, digest counts, and section gating

- Don't post adventure beats when posting.enabled=false (PostNow ignores the flag)
- Keep the adventure channel out of the round-robin rotation so it can't steal bulletins from the digest
- no_push now retires a fact against the digest, not just the live post
- Default a missing occurred_at to now instead of the Unix epoch
- Keep protocol-relative image URLs on the guarded thumbnailer
- Make digest_hour=0 (midnight UTC) settable
- Quote the true window total in the digest, not the truncated slice
- Hide the Adventure section entirely when it's disabled
This commit is contained in:
prosolis
2026-07-11 08:07:40 -07:00
parent 9bf56cbb4e
commit 8e0d6aff3e
8 changed files with 137 additions and 63 deletions

View File

@@ -34,10 +34,23 @@ type AdventureConfig struct {
// PRIORITY adventure beats post to live. If it isn't a configured Matrix
// channel, adventure runs website-only (stories still appear on /adventure).
Channel string `toml:"channel"`
// DigestHour is the UTC hour [0,23] the daily bulletin digest posts. Default 17.
DigestHour int `toml:"digest_hour"`
// DigestHour is the UTC hour [0,23] the daily bulletin digest posts. Default
// 17. A pointer so digest_hour = 0 (midnight UTC) is distinguishable from
// "unset" and doesn't get silently rewritten to the default.
DigestHour *int `toml:"digest_hour"`
}
// DigestHourOrDefault is the UTC hour the daily digest posts, resolving the
// unset case. Safe on a zero-value AdventureConfig.
func (a AdventureConfig) DigestHourOrDefault() int {
if a.DigestHour == nil {
return defaultDigestHour
}
return *a.DigestHour
}
const defaultDigestHour = 17
// WebConfig controls the read-only HTTP interface (news.parodia.dev style).
type WebConfig struct {
Enabled bool `toml:"enabled"`
@@ -250,7 +263,7 @@ func (c *Config) validate() error {
if c.Adventure.IngestToken == "" {
return fmt.Errorf("adventure.ingest_token is required when adventure is enabled (the bearer secret gogobee presents)")
}
if c.Adventure.DigestHour < 0 || c.Adventure.DigestHour > 23 {
if h := c.Adventure.DigestHourOrDefault(); h < 0 || h > 23 {
return fmt.Errorf("adventure.digest_hour must be 0-23")
}
if c.Adventure.Channel != "" {
@@ -332,9 +345,6 @@ func (c *Config) applyDefaults() {
if c.Web.Push.MinStories == 0 {
c.Web.Push.MinStories = 3
}
if c.Adventure.DigestHour == 0 {
c.Adventure.DigestHour = 17
}
for i := range c.Sources {
if c.Sources[i].PollIntervalMinutes == 0 {
c.Sources[i].PollIntervalMinutes = 20