Files
inspiration-collector/scripts/summarize_policy.py

153 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Summarize policy news using DeepSeek AI.
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"
MODEL = "deepseek-v4-flash"
RAW_FILE = "/var/www/nav/data/policy.json"
OUTPUT = "/var/www/nav/data/policy_summary.json"
tz = timezone(timedelta(hours=8))
def load_raw():
if not os.path.exists(RAW_FILE):
return []
with open(RAW_FILE) as f:
data = json.load(f)
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[:150], 1):
title = item.get("title", "")
summary = item.get("summary", "")[:200].replace("<", "").replace(">", "")
source = item.get("source", "")
link = item.get("link", "")
news_text += f"{i}. [{source}] {title}\n {summary}\n url: {link}\n\n"
prompt = f"""你是一个资深的政策新闻编辑助手。精选当下最重要的中国政策新闻。
## 选稿标准
- 国务院常务会议、中央政治局会议等高层决策
- 重要法律法规的颁布或修订
- 部委级重大政策发布(发改委、财政部、央行、工信部等)
- 经济政策调整(货币政策、财政政策、产业政策)
- 民生政策(教育、医疗、住房、养老、就业)
- 外交政策重大声明
## 输出格式
每条包含:
- subtitle15-30字完整标题中文
- title原标题必须与原始新闻标题完全一致这是时间匹配的关键
- source来源
- link原文链接
- summary300-500字政策解读摘要关键信息用**加粗**标出
精选 **10-20 条** 最重要政策新闻。
JSON格式: {{"categories": [{{"name":"政策速递","items":[{{"rank":1,"subtitle":"小标题","title":"原标题","source":"来源","link":"https://...","summary":"正文..."}}]}}]}}"""
resp = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={"model": MODEL, "messages": [{"role": "user", "content": prompt}],
"temperature": 0.3, "max_tokens": 20000},
timeout=180,
)
if resp.status_code != 200:
print(f"API error: {resp.status_code}")
return None
content = resp.json()["choices"][0]["message"]["content"].strip()
if content.startswith("```"):
lines = content.split("\n")
content = "\n".join(lines[1:-1]) if lines[-1].strip() == "```" else "\n".join(lines[1:])
try:
return json.loads(content)
except:
content = re.sub(r',\s*}', '}', content)
content = re.sub(r',\s*]', ']', content)
try:
return json.loads(content)
except:
print(f"JSON parse failed")
return None
if __name__ == "__main__":
now = datetime.now(tz).strftime("%Y-%m-%d %H:%M")
raw_items = load_raw()
if not raw_items:
print("No raw policy data")
exit(0)
print(f"Loaded {len(raw_items)} raw items. Summarizing...")
data = summarize(raw_items)
if not data:
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", [])}
total = sum(len(c["items"]) for c in result["categories"])
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
with open(OUTPUT, "w", encoding="utf-8") as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f"Written {total} articles -> {OUTPUT}")