From d23888c68d95bed686a5b298ac6b67fe52b0ac51 Mon Sep 17 00:00:00 2001 From: knight Date: Fri, 20 Mar 2026 12:14:53 -0400 Subject: [PATCH] Add last_posted date to /api/channel-list from Elasticsearch Queries the latest video date per channel and includes it in the channel-list JSON response. Co-Authored-By: Claude Opus 4.6 --- search_app.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/search_app.py b/search_app.py index 3a07f42..bf31307 100644 --- a/search_app.py +++ b/search_app.py @@ -1277,6 +1277,29 @@ def create_app(config: AppConfig = CONFIG) -> Flask: data.sort(key=lambda item: item["Name"].lower()) return jsonify(data) + def _channel_latest_dates() -> Dict[str, Optional[str]]: + """Return {channel_id: latest_date_str} from Elasticsearch.""" + try: + resp = client.search(index=index, body={ + "size": 0, + "aggs": { + "by_channel": { + "terms": {"field": "channel_id.keyword", "size": 500}, + "aggs": {"latest": {"max": {"field": "date"}}}, + } + }, + }, request_timeout=15) + except Exception as exc: + LOGGER.warning("Failed to fetch latest dates: %s", exc) + return {} + result: Dict[str, Optional[str]] = {} + for bucket in resp.get("aggregations", {}).get("by_channel", {}).get("buckets", []): + cid = bucket.get("key") + val = bucket.get("latest", {}).get("value_as_string") + if cid and val: + result[cid] = val[:10] if len(val) > 10 else val + return result + @app.route("/api/channel-list") def channel_list(): payload = { @@ -1285,13 +1308,20 @@ def create_app(config: AppConfig = CONFIG) -> Flask: "source": str(config.channels_path), } try: - payload["channels"] = load_channel_entries(config.channels_path) + entries = load_channel_entries(config.channels_path) except FileNotFoundError: LOGGER.warning("Channel list not found: %s", config.channels_path) payload["error"] = "channels_not_found" + return jsonify(payload) except Exception as exc: LOGGER.exception("Failed to load channel list: %s", exc) payload["error"] = "channels_load_failed" + return jsonify(payload) + + latest_dates = _channel_latest_dates() + for entry in entries: + entry["last_posted"] = latest_dates.get(entry.get("id")) or None + payload["channels"] = entries return jsonify(payload) @app.route("/channels.txt")