refactor: 拆 generate_report 为 _collect/_select/_render 三段
所有选择逻辑(9 处 board_select + featured_pick + _localize + pad) 全归 _select,_render 纯拼装写盘,薄壳 generate_report 仅编排。 结构化 bundle 传参;副作用(record_pushed_links/_save_snapshot/ save_json)保持原时序在 _render 末尾。行为不变,89 测试绿(T2)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -489,7 +489,11 @@ def _format_skill_section(items: list[dict[str, Any]], *, hot: bool = False) ->
|
|||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def generate_report() -> tuple[str, str, Path, Path]:
|
def _collect(date_str: str) -> dict[str, Any]:
|
||||||
|
"""抓取 skills/github/news 数据并归一化,计算 wecom 限额与周去重 recent keys。
|
||||||
|
|
||||||
|
无副作用(不写快照/不记已推)。返回供 _select/_render 消费的 bundle。
|
||||||
|
"""
|
||||||
# Hot/Trending 前排同 source 极密,需更深抓取才能凑够展示用的唯一 source
|
# Hot/Trending 前排同 source 极密,需更深抓取才能凑够展示用的唯一 source
|
||||||
trending_n = env_int("DAILY_TRENDING_LIMIT", 400)
|
trending_n = env_int("DAILY_TRENDING_LIMIT", 400)
|
||||||
hot_n = max(env_int("DAILY_HOT_LIMIT", 400), compare_depth())
|
hot_n = max(env_int("DAILY_HOT_LIMIT", 400), compare_depth())
|
||||||
@@ -570,11 +574,79 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
| recent_shown["github_emerging"]
|
| recent_shown["github_emerging"]
|
||||||
| recent_shown["github_topic"]
|
| recent_shown["github_topic"]
|
||||||
)
|
)
|
||||||
|
return {
|
||||||
|
"trending_n": trending_n,
|
||||||
|
"hot_n": hot_n,
|
||||||
|
"github_limit": github_limit,
|
||||||
|
"emerging_limit": emerging_limit,
|
||||||
|
"topic_limit": topic_limit,
|
||||||
|
"wecom_trending": wecom_trending,
|
||||||
|
"wecom_hot": wecom_hot,
|
||||||
|
"wecom_github": wecom_github,
|
||||||
|
"wecom_emerging": wecom_emerging,
|
||||||
|
"wecom_topic": wecom_topic,
|
||||||
|
"wecom_limits": wecom_limits,
|
||||||
|
"pool": pool,
|
||||||
|
"pad_pool": pad_pool,
|
||||||
|
"feed": feed,
|
||||||
|
"prev_ids": prev_ids,
|
||||||
|
"now": now,
|
||||||
|
"date_str": date_str,
|
||||||
|
"time_str": time_str,
|
||||||
|
"updated": updated,
|
||||||
|
"trending": trending,
|
||||||
|
"hot": hot,
|
||||||
|
"github_trending": github_trending,
|
||||||
|
"github_emerging": github_emerging,
|
||||||
|
"github_topic": github_topic,
|
||||||
|
"topic_name": topic_name,
|
||||||
|
"news_merged": news_merged,
|
||||||
|
"ai_news": ai_news,
|
||||||
|
"cn_ai_news": cn_ai_news,
|
||||||
|
"ai_news_research": ai_news_research,
|
||||||
|
"wecom_news": wecom_news,
|
||||||
|
"wecom_tech_news": wecom_tech_news,
|
||||||
|
"recent_shown": recent_shown,
|
||||||
|
"skill_recent": skill_recent,
|
||||||
|
"github_recent": github_recent,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _select(c: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
"""全部「选择 + 数据突变」:9 处 board_select + featured_pick + LLM 步骤 + pad。
|
||||||
|
|
||||||
|
时序约束内聚本段:featured pick 依赖 deep-pool;_localize 在 featured 后、
|
||||||
|
pad 前执行;写回 shown keys/llm_input 也在此。_render 不再做任何选择。
|
||||||
|
副作用: apply_featured_pick 写回 shown keys(保持原时序)。
|
||||||
|
"""
|
||||||
|
date_str = c["date_str"]
|
||||||
|
feed = c["feed"]
|
||||||
|
prev_ids = c["prev_ids"]
|
||||||
|
updated = c["updated"]
|
||||||
|
time_str = c["time_str"]
|
||||||
|
trending = c["trending"]
|
||||||
|
hot = c["hot"]
|
||||||
|
github_trending = c["github_trending"]
|
||||||
|
github_emerging = c["github_emerging"]
|
||||||
|
github_topic = c["github_topic"]
|
||||||
|
topic_name = c["topic_name"]
|
||||||
|
news_merged = c["news_merged"]
|
||||||
|
ai_news = c["ai_news"]
|
||||||
|
cn_ai_news = c["cn_ai_news"]
|
||||||
|
wecom_news = c["wecom_news"]
|
||||||
|
wecom_tech_news = c["wecom_tech_news"]
|
||||||
|
wecom_limits = c["wecom_limits"]
|
||||||
|
pool = c["pool"]
|
||||||
|
pad_pool = c["pad_pool"]
|
||||||
|
recent_shown = c["recent_shown"]
|
||||||
|
skill_recent = c["skill_recent"]
|
||||||
|
github_recent = c["github_recent"]
|
||||||
|
|
||||||
selected_trending = board_select(
|
selected_trending = board_select(
|
||||||
board="skills_trending",
|
board="skills_trending",
|
||||||
items=trending,
|
items=trending,
|
||||||
recent_keys=skill_recent,
|
recent_keys=skill_recent,
|
||||||
limit=wecom_trending,
|
limit=c["wecom_trending"],
|
||||||
pool_size=pool,
|
pool_size=pool,
|
||||||
kind="skill",
|
kind="skill",
|
||||||
)
|
)
|
||||||
@@ -582,7 +654,7 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
board="skills_hot",
|
board="skills_hot",
|
||||||
items=hot,
|
items=hot,
|
||||||
recent_keys=skill_recent,
|
recent_keys=skill_recent,
|
||||||
limit=wecom_hot,
|
limit=c["wecom_hot"],
|
||||||
pool_size=pool,
|
pool_size=pool,
|
||||||
kind="skill",
|
kind="skill",
|
||||||
)
|
)
|
||||||
@@ -590,7 +662,7 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
board="github_trending",
|
board="github_trending",
|
||||||
items=github_trending,
|
items=github_trending,
|
||||||
recent_keys=github_recent,
|
recent_keys=github_recent,
|
||||||
limit=wecom_github,
|
limit=c["wecom_github"],
|
||||||
pool_size=pool,
|
pool_size=pool,
|
||||||
kind="github",
|
kind="github",
|
||||||
)
|
)
|
||||||
@@ -599,7 +671,7 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
board="github_emerging",
|
board="github_emerging",
|
||||||
items=github_emerging,
|
items=github_emerging,
|
||||||
recent_keys=github_recent,
|
recent_keys=github_recent,
|
||||||
limit=wecom_emerging,
|
limit=c["wecom_emerging"],
|
||||||
pool_size=pool,
|
pool_size=pool,
|
||||||
kind="github",
|
kind="github",
|
||||||
)
|
)
|
||||||
@@ -608,7 +680,7 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
board="github_topic",
|
board="github_topic",
|
||||||
items=github_topic,
|
items=github_topic,
|
||||||
recent_keys=github_recent,
|
recent_keys=github_recent,
|
||||||
limit=wecom_topic,
|
limit=c["wecom_topic"],
|
||||||
pool_size=pool,
|
pool_size=pool,
|
||||||
kind="github",
|
kind="github",
|
||||||
)
|
)
|
||||||
@@ -741,6 +813,178 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
|
|
||||||
themes = theme_clusters(feed, theme_rules=THEME_RULES, skill_id_fn=_skill_id)
|
themes = theme_clusters(feed, theme_rules=THEME_RULES, skill_id_fn=_skill_id)
|
||||||
|
|
||||||
|
pick_src = trending[0].get("source", "") if trending else ""
|
||||||
|
pick_name = trending[0].get("title", "") if trending else ""
|
||||||
|
pick_command = pick_command_from_featured(featured) or (
|
||||||
|
f"npx skills add {pick_src}/{pick_name}"
|
||||||
|
if pick_src and pick_name
|
||||||
|
else "npx skills add vercel-labs/skills/find-skills"
|
||||||
|
)
|
||||||
|
pick_why = pick_why_from_featured(featured) or ""
|
||||||
|
pick_title = str((featured or {}).get("title") or pick_name or "").strip()
|
||||||
|
pick_url = str((featured or {}).get("url") or "").strip()
|
||||||
|
|
||||||
|
gt = selected_trending
|
||||||
|
gh = selected_hot
|
||||||
|
gt_pad = board_select(
|
||||||
|
board="skills_trending",
|
||||||
|
items=trending,
|
||||||
|
recent_keys=skill_recent,
|
||||||
|
limit=pad_pool,
|
||||||
|
pool_size=pool,
|
||||||
|
kind="skill",
|
||||||
|
)
|
||||||
|
gh_pad = board_select(
|
||||||
|
board="skills_hot",
|
||||||
|
items=hot,
|
||||||
|
recent_keys=skill_recent,
|
||||||
|
limit=pad_pool,
|
||||||
|
pool_size=pool,
|
||||||
|
kind="skill",
|
||||||
|
)
|
||||||
|
wecom_github_items = [_prepare_github_item(item) for item in selected_github]
|
||||||
|
wecom_emerging_items = [_prepare_github_item(item) for item in selected_emerging]
|
||||||
|
wecom_topic_items = [_prepare_github_item(item) for item in selected_topic]
|
||||||
|
github_pad_recent = (
|
||||||
|
recent_shown["github_trending"]
|
||||||
|
| recent_shown["github_emerging"]
|
||||||
|
| recent_shown["github_topic"]
|
||||||
|
)
|
||||||
|
wecom_github_pad = [
|
||||||
|
_prepare_github_item(item)
|
||||||
|
for item in board_select(
|
||||||
|
board="github_trending",
|
||||||
|
items=github_trending,
|
||||||
|
recent_keys=github_pad_recent,
|
||||||
|
limit=pad_pool,
|
||||||
|
pool_size=pool,
|
||||||
|
kind="github",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
wecom_emerging_pad = [
|
||||||
|
_prepare_github_item(item)
|
||||||
|
for item in board_select(
|
||||||
|
board="github_emerging",
|
||||||
|
items=github_emerging,
|
||||||
|
recent_keys=github_pad_recent,
|
||||||
|
limit=pad_pool,
|
||||||
|
pool_size=pool,
|
||||||
|
kind="github",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
wecom_topic_pad = [
|
||||||
|
_prepare_github_item(item)
|
||||||
|
for item in board_select(
|
||||||
|
board="github_topic",
|
||||||
|
items=github_topic,
|
||||||
|
recent_keys=github_pad_recent,
|
||||||
|
limit=pad_pool,
|
||||||
|
pool_size=pool,
|
||||||
|
kind="github",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
delta_pad = eff_mode == "delta" and wecom_delta_pad()
|
||||||
|
board_kwargs = {
|
||||||
|
"mode": eff_mode,
|
||||||
|
"movement": movement,
|
||||||
|
"trending": gt,
|
||||||
|
"hot": gh,
|
||||||
|
"topic_name": topic_name,
|
||||||
|
"github_trending": wecom_github_items,
|
||||||
|
"github_emerging": wecom_emerging_items,
|
||||||
|
"github_topic": wecom_topic_items,
|
||||||
|
"wecom_trending": c["wecom_trending"],
|
||||||
|
"wecom_hot": c["wecom_hot"],
|
||||||
|
"wecom_github": c["wecom_github"],
|
||||||
|
"wecom_emerging": c["wecom_emerging"],
|
||||||
|
"wecom_topic": c["wecom_topic"],
|
||||||
|
"pad": delta_pad,
|
||||||
|
"date_str": date_str,
|
||||||
|
"trending_pad": gt_pad,
|
||||||
|
"hot_pad": gh_pad,
|
||||||
|
"github_trending_pad": wecom_github_pad,
|
||||||
|
"github_emerging_pad": wecom_emerging_pad,
|
||||||
|
"github_topic_pad": wecom_topic_pad,
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"selected_trending": selected_trending,
|
||||||
|
"selected_hot": selected_hot,
|
||||||
|
"boards_for_wecom": boards_for_wecom,
|
||||||
|
"llm_input": llm_input,
|
||||||
|
"featured": featured,
|
||||||
|
"movement": movement,
|
||||||
|
"eff_mode": eff_mode,
|
||||||
|
"push_gate": push_gate,
|
||||||
|
"wecom_ai": wecom_ai,
|
||||||
|
"wecom_cn": wecom_cn,
|
||||||
|
"agent_wecom": agent_wecom,
|
||||||
|
"editorial_theme": editorial_theme,
|
||||||
|
"editorial_highlights": editorial_highlights,
|
||||||
|
"themes": themes,
|
||||||
|
"pick_command": pick_command,
|
||||||
|
"pick_why": pick_why,
|
||||||
|
"pick_title": pick_title,
|
||||||
|
"pick_url": pick_url,
|
||||||
|
"board_kwargs": board_kwargs,
|
||||||
|
"prev_ids": prev_ids,
|
||||||
|
"gt": gt,
|
||||||
|
"gh": gh,
|
||||||
|
"wecom_github_items": wecom_github_items,
|
||||||
|
"wecom_emerging_items": wecom_emerging_items,
|
||||||
|
"wecom_topic_items": wecom_topic_items,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _render(c: dict[str, Any], s: dict[str, Any]) -> tuple[str, str, Path, Path]:
|
||||||
|
"""纯拼装: 拼完整版 markdown + 企微 wecom_md + 写盘。
|
||||||
|
|
||||||
|
零选择逻辑。副作用: record_pushed_links + _save_snapshot + save_json + 写文件,
|
||||||
|
全部保持原时序(在拼装完成后执行)。
|
||||||
|
"""
|
||||||
|
feed = c["feed"]
|
||||||
|
now = c["now"]
|
||||||
|
date_str = c["date_str"]
|
||||||
|
time_str = c["time_str"]
|
||||||
|
updated = c["updated"]
|
||||||
|
trending = c["trending"]
|
||||||
|
hot = c["hot"]
|
||||||
|
github_trending = c["github_trending"]
|
||||||
|
github_emerging = c["github_emerging"]
|
||||||
|
github_topic = c["github_topic"]
|
||||||
|
topic_name = c["topic_name"]
|
||||||
|
news_merged = c["news_merged"]
|
||||||
|
ai_news = c["ai_news"]
|
||||||
|
cn_ai_news = c["cn_ai_news"]
|
||||||
|
ai_news_research = c["ai_news_research"]
|
||||||
|
wecom_news = c["wecom_news"]
|
||||||
|
wecom_tech_news = c["wecom_tech_news"]
|
||||||
|
trending_n = c["trending_n"]
|
||||||
|
hot_n = c["hot_n"]
|
||||||
|
github_limit = c["github_limit"]
|
||||||
|
emerging_limit = c["emerging_limit"]
|
||||||
|
topic_limit = c["topic_limit"]
|
||||||
|
prev_ids = s["prev_ids"]
|
||||||
|
llm_input = s["llm_input"]
|
||||||
|
featured = s["featured"]
|
||||||
|
eff_mode = s["eff_mode"]
|
||||||
|
push_gate = s["push_gate"]
|
||||||
|
wecom_ai = s["wecom_ai"]
|
||||||
|
wecom_cn = s["wecom_cn"]
|
||||||
|
agent_wecom = s["agent_wecom"]
|
||||||
|
editorial_theme = s["editorial_theme"]
|
||||||
|
editorial_highlights = s["editorial_highlights"]
|
||||||
|
themes = s["themes"]
|
||||||
|
pick_command = s["pick_command"]
|
||||||
|
pick_why = s["pick_why"]
|
||||||
|
pick_title = s["pick_title"]
|
||||||
|
pick_url = s["pick_url"]
|
||||||
|
board_kwargs = s["board_kwargs"]
|
||||||
|
gt = s["gt"]
|
||||||
|
gh = s["gh"]
|
||||||
|
wecom_github_items = s["wecom_github_items"]
|
||||||
|
wecom_emerging_items = s["wecom_emerging_items"]
|
||||||
|
wecom_topic_items = s["wecom_topic_items"]
|
||||||
|
|
||||||
lines = [
|
lines = [
|
||||||
f"# 早报 · {date_str}",
|
f"# 早报 · {date_str}",
|
||||||
"",
|
"",
|
||||||
@@ -814,17 +1058,6 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
lines.append(f"- {ex}")
|
lines.append(f"- {ex}")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
pick_src = trending[0].get("source", "") if trending else ""
|
|
||||||
pick_name = trending[0].get("title", "") if trending else ""
|
|
||||||
pick_command = pick_command_from_featured(featured) or (
|
|
||||||
f"npx skills add {pick_src}/{pick_name}"
|
|
||||||
if pick_src and pick_name
|
|
||||||
else "npx skills add vercel-labs/skills/find-skills"
|
|
||||||
)
|
|
||||||
pick_why = pick_why_from_featured(featured) or ""
|
|
||||||
pick_title = str((featured or {}).get("title") or pick_name or "").strip()
|
|
||||||
pick_url = str((featured or {}).get("url") or "").strip()
|
|
||||||
|
|
||||||
lines.extend(["---", "", "## 安装示例", "", "```bash"])
|
lines.extend(["---", "", "## 安装示例", "", "```bash"])
|
||||||
for item in trending[:4]:
|
for item in trending[:4]:
|
||||||
src, name = item.get("source", ""), item.get("title", "")
|
src, name = item.get("source", ""), item.get("title", "")
|
||||||
@@ -833,88 +1066,7 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
lines.extend(["```", "", f"*企微短版见 `output/{date_str}.wecom.md`*"])
|
lines.extend(["```", "", f"*企微短版见 `output/{date_str}.wecom.md`*"])
|
||||||
|
|
||||||
markdown = "\n".join(lines)
|
markdown = "\n".join(lines)
|
||||||
gt = selected_trending
|
|
||||||
gh = selected_hot
|
|
||||||
gt_pad = board_select(
|
|
||||||
board="skills_trending",
|
|
||||||
items=trending,
|
|
||||||
recent_keys=skill_recent,
|
|
||||||
limit=pad_pool,
|
|
||||||
pool_size=pool,
|
|
||||||
kind="skill",
|
|
||||||
)
|
|
||||||
gh_pad = board_select(
|
|
||||||
board="skills_hot",
|
|
||||||
items=hot,
|
|
||||||
recent_keys=skill_recent,
|
|
||||||
limit=pad_pool,
|
|
||||||
pool_size=pool,
|
|
||||||
kind="skill",
|
|
||||||
)
|
|
||||||
wecom_github_items = [_prepare_github_item(item) for item in selected_github]
|
|
||||||
wecom_emerging_items = [_prepare_github_item(item) for item in selected_emerging]
|
|
||||||
wecom_topic_items = [_prepare_github_item(item) for item in selected_topic]
|
|
||||||
github_pad_recent = (
|
|
||||||
recent_shown["github_trending"]
|
|
||||||
| recent_shown["github_emerging"]
|
|
||||||
| recent_shown["github_topic"]
|
|
||||||
)
|
|
||||||
wecom_github_pad = [
|
|
||||||
_prepare_github_item(item)
|
|
||||||
for item in board_select(
|
|
||||||
board="github_trending",
|
|
||||||
items=github_trending,
|
|
||||||
recent_keys=github_pad_recent,
|
|
||||||
limit=pad_pool,
|
|
||||||
pool_size=pool,
|
|
||||||
kind="github",
|
|
||||||
)
|
|
||||||
]
|
|
||||||
wecom_emerging_pad = [
|
|
||||||
_prepare_github_item(item)
|
|
||||||
for item in board_select(
|
|
||||||
board="github_emerging",
|
|
||||||
items=github_emerging,
|
|
||||||
recent_keys=github_pad_recent,
|
|
||||||
limit=pad_pool,
|
|
||||||
pool_size=pool,
|
|
||||||
kind="github",
|
|
||||||
)
|
|
||||||
]
|
|
||||||
wecom_topic_pad = [
|
|
||||||
_prepare_github_item(item)
|
|
||||||
for item in board_select(
|
|
||||||
board="github_topic",
|
|
||||||
items=github_topic,
|
|
||||||
recent_keys=github_pad_recent,
|
|
||||||
limit=pad_pool,
|
|
||||||
pool_size=pool,
|
|
||||||
kind="github",
|
|
||||||
)
|
|
||||||
]
|
|
||||||
delta_pad = eff_mode == "delta" and wecom_delta_pad()
|
|
||||||
board_kwargs = {
|
|
||||||
"mode": eff_mode,
|
|
||||||
"movement": movement,
|
|
||||||
"trending": gt,
|
|
||||||
"hot": gh,
|
|
||||||
"topic_name": topic_name,
|
|
||||||
"github_trending": wecom_github_items,
|
|
||||||
"github_emerging": wecom_emerging_items,
|
|
||||||
"github_topic": wecom_topic_items,
|
|
||||||
"wecom_trending": wecom_trending,
|
|
||||||
"wecom_hot": wecom_hot,
|
|
||||||
"wecom_github": wecom_github,
|
|
||||||
"wecom_emerging": wecom_emerging,
|
|
||||||
"wecom_topic": wecom_topic,
|
|
||||||
"pad": delta_pad,
|
|
||||||
"date_str": date_str,
|
|
||||||
"trending_pad": gt_pad,
|
|
||||||
"hot_pad": gh_pad,
|
|
||||||
"github_trending_pad": wecom_github_pad,
|
|
||||||
"github_emerging_pad": wecom_emerging_pad,
|
|
||||||
"github_topic_pad": wecom_topic_pad,
|
|
||||||
}
|
|
||||||
if agent_wecom:
|
if agent_wecom:
|
||||||
wecom_md = replace_wecom_skill_sections(agent_wecom, **board_kwargs)
|
wecom_md = replace_wecom_skill_sections(agent_wecom, **board_kwargs)
|
||||||
else:
|
else:
|
||||||
@@ -1000,6 +1152,13 @@ def generate_report() -> tuple[str, str, Path, Path]:
|
|||||||
return markdown, wecom_md, out_md, out_wecom
|
return markdown, wecom_md, out_md, out_wecom
|
||||||
|
|
||||||
|
|
||||||
|
def generate_report() -> tuple[str, str, Path, Path]:
|
||||||
|
"""编排三段: 抓取(_collect) → 选择(_select) → 拼装(_render)。"""
|
||||||
|
collected = _collect(_now_cst().strftime("%Y-%m-%d"))
|
||||||
|
selected = _select(collected)
|
||||||
|
return _render(collected, selected)
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
log_file = LOG_DIR / f"{_now_cst():%Y-%m-%d}.log"
|
log_file = LOG_DIR / f"{_now_cst():%Y-%m-%d}.log"
|
||||||
|
|||||||
Reference in New Issue
Block a user