feat: 所有新闻/政策/研究摘要加入 pub_time 发布时间字段\n\n- summarize_news.py: AI摘要后用原始RSS时间按标题匹配回填pub_time\n- summarize_policy.py: 同上\n- summarize_research.py: 同上\n- 时间格式: 当天显示HH:MM, 非当天显示MM-DD HH:MM\n- 前端brief.html: 新闻卡片badge行右侧显示pub_time\n- 已用backfill脚本为现有数据补填pub_time(96/102, 8/15, 33/37)
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
"""Use DeepSeek to summarize AI/quant research RSS into categorized briefs."""
|
||||
"""Use DeepSeek to summarize AI/quant research RSS into categorized briefs.
|
||||
v2: back-fills pub_time from raw RSS data after AI summarization.
|
||||
"""
|
||||
import json, os, requests, re
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from dateutil import parser as dtparser
|
||||
|
||||
API_KEY = "sk-bbca4a0380d549389f0d27cdea0b5228"
|
||||
API_URL = "https://api.deepseek.com/v1/chat/completions"
|
||||
@ -19,6 +22,46 @@ def load_raw():
|
||||
return data.get("items", [])
|
||||
|
||||
|
||||
def build_time_lookup(raw_items):
|
||||
"""Build lookup: title -> pub_time (Beijing time string)."""
|
||||
lookup = {}
|
||||
for item in raw_items:
|
||||
title = item.get("title", "").strip()
|
||||
published = item.get("published", "").strip()
|
||||
if not title or not published:
|
||||
continue
|
||||
try:
|
||||
dt = dtparser.parse(published)
|
||||
if dt.tzinfo:
|
||||
dt = dt.astimezone(tz)
|
||||
else:
|
||||
dt = dt.replace(tzinfo=tz)
|
||||
now = datetime.now(tz)
|
||||
if dt.date() == now.date():
|
||||
time_str = dt.strftime("%H:%M")
|
||||
else:
|
||||
time_str = dt.strftime("%m-%d %H:%M")
|
||||
lookup[title] = time_str
|
||||
except Exception:
|
||||
continue
|
||||
return lookup
|
||||
|
||||
|
||||
def match_pub_time(items, lookup):
|
||||
for item in items:
|
||||
if "pub_time" in item:
|
||||
continue
|
||||
title = item.get("title", "").strip()
|
||||
if title in lookup:
|
||||
item["pub_time"] = lookup[title]
|
||||
else:
|
||||
for raw_title, time_val in lookup.items():
|
||||
short = min(len(raw_title), len(title))
|
||||
if short > 10 and (raw_title[:short] in title or title[:short] in raw_title):
|
||||
item["pub_time"] = time_val
|
||||
break
|
||||
|
||||
|
||||
def summarize(items):
|
||||
news_text = ""
|
||||
for i, item in enumerate(items[:100], 1):
|
||||
@ -41,7 +84,7 @@ def summarize(items):
|
||||
- 行业动态(AI 公司、产品发布、监管动态)
|
||||
|
||||
## 输出格式
|
||||
每条:rank, subtitle(15-30字), title, source, link, summary(200-400字,说清楚这篇讲了什么、有什么用)
|
||||
每条:rank, subtitle(15-30字), title(必须与原始标题完全一致,这是时间匹配的关键), source, link, summary(200-400字,说清楚这篇讲了什么、有什么用)
|
||||
|
||||
## 原始内容
|
||||
{news_text}
|
||||
@ -72,9 +115,8 @@ JSON格式: {{"categories": [{{"name":"分类名","items":[{{"rank":1,"subtitle"
|
||||
try:
|
||||
result = json.loads(content)
|
||||
except:
|
||||
import re as re_
|
||||
content = re_.sub(r',\s*}', '}', content)
|
||||
content = re_.sub(r',\s*]', ']', content)
|
||||
content = re.sub(r',\s*}', '}', content)
|
||||
content = re.sub(r',\s*]', ']', content)
|
||||
try:
|
||||
result = json.loads(content)
|
||||
except:
|
||||
@ -86,18 +128,26 @@ JSON格式: {{"categories": [{{"name":"分类名","items":[{{"rank":1,"subtitle"
|
||||
|
||||
def run():
|
||||
now = datetime.now(tz).strftime("%Y-%m-%d %H:%M")
|
||||
items = load_raw()
|
||||
if not items:
|
||||
raw_items = load_raw()
|
||||
if not raw_items:
|
||||
print("No research data")
|
||||
exit(0)
|
||||
|
||||
print(f"Loaded {len(items)} research items. AI summarizing...")
|
||||
data = summarize(items)
|
||||
print(f"Loaded {len(raw_items)} research items. AI summarizing...")
|
||||
data = summarize(raw_items)
|
||||
|
||||
if not data:
|
||||
print("Summarization failed")
|
||||
exit(1)
|
||||
|
||||
# Back-fill pub_time
|
||||
time_lookup = build_time_lookup(raw_items)
|
||||
matched = 0
|
||||
for cat in data.get("categories", []):
|
||||
match_pub_time(cat["items"], time_lookup)
|
||||
matched += sum(1 for item in cat["items"] if "pub_time" in item)
|
||||
print(f"Matched pub_time for {matched} articles")
|
||||
|
||||
result = {
|
||||
"updated_at": now,
|
||||
"categories": data.get("categories", []),
|
||||
|
||||
Reference in New Issue
Block a user