feat: 日报多来源入库(news_event.sources 列,JSON 数组,主源居首)

- EventRow 新增 sources 字段;init_schema 幂等 ALTER 补列(MariaDB)
- save_report 写入 sources JSON;_article_sources_full 完整来源列表
- source 字段保持 ≤3 拼接兼容;新增多源完整列表测试
- 已部署 pi5:sources 列写入验证通过(单源数组);完整多源待新数据
This commit is contained in:
2026-08-12 13:06:01 +08:00
parent 32e99aeaf6
commit 951276a313
7 changed files with 84 additions and 16 deletions
+23 -10
View File
@@ -96,21 +96,31 @@ def _url_source_label(url: str, source_id: str = "") -> str:
return domain_map.get(domain, domain)
def _article_source_label(article: dict) -> str | None:
"""文章来源展示:去重合并后多来源时拼接展示名,否则回退单源逻辑。
def _article_sources_full(article: dict) -> list[str]:
"""全部来源展示名列表(主源居首、去重)。
多来源(ProcessedArticle.source_ids 长度 > 1)时展示如 "Reuters, CNBC",
最多取前 3 个来源,截断至 64 字符(news_event.source 为 VARCHAR(64))。
多来源(ProcessedArticle.source_ids)时返回完整列表供 news_event.sources
JSON 数组使用;无合并信息时回退单源逻辑。
"""
src_ids = list(dict.fromkeys(
s for s in (article.get("source_ids") or []) if s and s != "?"
))
if len(src_ids) > 1:
names = list(dict.fromkeys(
(_source_name(s) or s) for s in src_ids[:3]
))
return ", ".join(names)[:64]
return _url_source_label(article.get("url"), article.get("source_id", ""))
return list(dict.fromkeys((_source_name(s) or s) for s in src_ids))
src = _url_source_label(article.get("url"), article.get("source_id", ""))
return [src] if src not in (None, "", "?") else []
def _article_source_label(article: dict) -> str | None:
"""文章来源展示(向后兼容 news_event.source):多来源时拼接前 3 个展示名。
多来源(source_ids 长度 > 1)时展示如 "Reuters, CNBC",最多取前 3 个来源,
截断至 64 字符(source 字段为 VARCHAR(64));完整列表见 _article_sources_full。
"""
names = _article_sources_full(article)
if len(names) > 1:
return ", ".join(names[:3])[:64]
return names[0] if names else None
# 日报覆盖时间窗口(小时)
@@ -603,6 +613,8 @@ def _build_report_data(
url = article.get("url") or None
# 去重合并后的多来源(如 "Reuters, CNBC"),否则回退单源展示
src = _article_source_label(article)
# 全部来源列表(主源居首,JSON 数组,写入 news_event.sources)
source_list = _article_sources_full(article)
# 归一化:"" / "?" 不入库,留 None(DB 仅存 positive/negative/neutral)
sentiment = ev.get("sentiment") or None
if sentiment in ("", "?"):
@@ -619,7 +631,8 @@ def _build_report_data(
title=title or "(无标题)",
summary=ev.get("summary_zh") or None,
sentiment=sentiment,
source=src if src not in (None, "", "?") else None,
source=src,
sources=source_list,
url=url,
)
)