Dashboard: content + source-health; per-viewer local dates
* Date fix: introduce GOODNEWS_TZ (goodnews/localtime.py) so the brief's "today" rolls over in a pinned zone (Eastern) instead of UTC — robust to host-clock resets. The home page now formats the brief's date in each VISITOR's local timezone (from its UTC freshness stamp), so nobody ever sees "tomorrow." * Admin "Content served": articles live, fresh (7d), ingested (24h), summaries, active sources, today's brief size — queries.content_stats(). * Admin "Source health": per active source, the failure streak, last error, accepted contribution, and computed next-poll time (so backoff / "resting until" is visible), via queries.source_health() reusing the feeds backoff math. Failing sources sort to the top; times render in the viewer's zone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""The site's canonical local day.
|
||||
|
||||
There is one daily brief, so "today" must resolve to a single timezone — not the
|
||||
host clock (which is UTC on the server and was silently reset on a rebuild).
|
||||
GOODNEWS_TZ pins it explicitly (default UTC) so a rebuild can't reintroduce the
|
||||
"brief shows tomorrow's date in the evening" bug. This governs when the brief
|
||||
rolls over and the canonical date on the server-rendered /today page; each
|
||||
visitor's *displayed* date is formatted in their own browser timezone.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
|
||||
def site_tz() -> ZoneInfo:
|
||||
name = os.environ.get("GOODNEWS_TZ", "UTC")
|
||||
try:
|
||||
return ZoneInfo(name)
|
||||
except (ZoneInfoNotFoundError, ValueError):
|
||||
return ZoneInfo("UTC")
|
||||
|
||||
|
||||
def local_now() -> datetime:
|
||||
return datetime.now(site_tz())
|
||||
|
||||
|
||||
def local_today() -> str:
|
||||
"""The site's current calendar date (ISO yyyy-mm-dd) in GOODNEWS_TZ."""
|
||||
return local_now().date().isoformat()
|
||||
Reference in New Issue
Block a user