Files

143 lines
5.0 KiB
Markdown
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.
---
name: "morning-digest"
description: "通用「数据采集 + 模板注入」引擎:用一份 YAML 配置声明多路数据源(http_json/command/static),采集后用 Jinja2 模板注入成 markdown 文档。适合日报/周报/聚合摘要,不绑定单台机器。"
metadata:
author: xf
version: "2.0.0"
---
# morning-digest — 通用采集 + 模板注入引擎
把「数据采集 → 模板注入 → 输出文档」抽象成一套**配置驱动**的通用 skill,不绑定任何具体机器/域名/IP。早报只是其一例用法,换一份配置即可复用到日报、周报、榜单、聚合摘要。
核心思路:**采集用脚本,排版用模板注入**,全程确定性,不依赖 LLM 排版。
## 流水线
```
build.py --config config/digest.yaml
┌─────────────────────────────────────────────┐
│ 1. 读配置(YAML/JSON) │
│ 2. ${ENV} 占位符替换(机器相关项从环境变量注入)│
│ 3. 逐 source 采集(http_json / command / static_json)
│ 4. Jinja2 模板注入 → 输出 markdown │
└─────────────────────────────────────────────┘
```
## 快速开始
```bash
# 1. 准备环境变量(不写死进仓库)
set -a; . ./.env; set +a
# 2. 一键采集 + 渲染
python3 scripts/build.py --config config/morning-digest.yaml
# 输出:/tmp/digest_today.md(配置里 render.output 决定)
# 只看数据不写文件
python3 scripts/build.py --config config/morning-digest.yaml --dry-run
# 临时覆盖环境变量
python3 scripts/build.py --config config/morning-digest.yaml --env HOT_API=http://localhost:6688
```
## 配置文件结构(YAML)
```yaml
meta:
name: morning-digest
date_format: "%Y-%m-%d"
sources:
<section名>: # 会成为模板变量
type: http_json | command | static_json
# ...adapter 参数
map: # 原始 item → 输出字段
字段名: 表达式
render:
template: templates/digest.md
output: /tmp/xxx.md
```
## Source 类型与适配器
### `http_json` — 拉一个 JSON 接口取列表
```yaml
news:
type: http_json
url: "https://host/api/{country}" # {param} 由 param_loop 填充
param_loop: { key: country, values: [china, us] } # 可选:循环发多请求
items_path: headlines # 响应里取列表的路径
limit: 5
map:
title: "title|headline|name" # | 表示依次回退取第一个非空
url: "url|link"
source: "sourceLabel|{loop.country}" # {loop.key} = 当前循环值
```
### `command` — 跑 shell 命令,读出 JSON
```yaml
github:
type: command
cmd: "python3 ${GITHUB_TRENDING_SCRIPT} {out}" # {out} = 临时 JSON 文件路径
items_from_file: "{out}" # 从文件读(默认解析 stdout)
map: { name: name, desc: desc, url: url, lang: lang, stars: stars, stars_today: stars_today }
```
### `static_json` — 读本地文件(供 LLM/外部注入)
```yaml
tech:
type: static_json
file: "${TECH_FILE}" # 未设置则跳过(optional: true)
map: { title: title, url: url, summary: summary }
```
## map 取值表达式
- `a|b|c` — 依次尝试,取第一个非空字段
- `{loop.key}` — 当前 param_loop 循环值
- `@index` — 1 起始序号
- 空串/缺失 → 该字段为空
## 模板
`templates/digest.md`(Jinja2)。每个 `source` 的 section 名成为一个模板变量(列表)。改排版只改模板,不动脚本。
早报模板里 GitHub Trending 已渲染成 markdown 超链接:
```
**[org/name](https://github.com/org/name)**(lang):desc
```
## 环境变量(`.env.example`)
机器相关项**一律从环境变量注入**,仓库不写死。
| 变量 | 说明 |
|------|------|
| `HOT_API` | DailyHotApi 基址 |
| `GITHUB_TRENDING_SCRIPT` | GitHub Trending 采集脚本 |
| `RSS_SCRIPT` | RSS 采集脚本 |
| `TECH_FILE` | 科技动态注入 JSON(可选) |
| `FEISHU_CREATE_SCRIPT` | 飞书知识库写入脚本(可选) |
## 失败隔离
每个 source 独立 try/except:失败 → 该 section 为空数组,错误写进输出 JSON 顶部的 `_errors`(不影响其他 source,流程不中断)。
## 依赖
- Python 3.10+(`requests`、`jinja2`、`pyyaml` 可选、`bs4` 视 source)
- source 脚本(`${GITHUB_TRENDING_SCRIPT}`、`${RSS_SCRIPT}` 等)按各自配置
## 已知坑
- **github.com 直连间歇性超时**:GitHub Trending source 依赖直连官方页面,外网抖动时会空(记入 `_errors` 不中断)。
- **海外 RSS DNS 吊死**:ak-rss-digest 用子进程隔离 + feedparser,个别源超时不影响整体。
- **飞书写入幂等**:`create_digest.py` 同标题自动复用节点,不重复建文档。
## 扩展
想加数据源?在 `sources` 里加一个 section(选一种 adapter,配好 `map`)→ 在模板里用它,即可。无需改引擎。