deisign/open-source-signal
GitHub: deisign/open-source-signal
一套专为乌克兰问责工作设计的双语 OSINT 静态发布工具包,提供从期刊编辑到网站部署和 Telegram 分发的完整工作流。
Stars: 1 | Forks: 0
# 开源 Signal
**Open Source Signal / Сигнал відкритих джерел** 是一个静态发布工具包,专为专注于乌克兰问责工作的双语 OSINT 期刊而设计。
它由一名乌克兰士兵在战时的基辅构建。对乌克兰而言,OSINT 不是一种爱好或小众的技术手艺。它是社会记录战争、抵制虚假信息、保留证据、了解袭击情况并在压力下维持公众问责的方式之一。
该项目将 OSINT 视为一项公民技能:如何阅读信息源、验证声明、处理证据、解释局限性,以及如何在不造成不必要伤害的情况下进行发布。其编辑重点是具有国际视野的乌克兰问责 OSINT:战争罪行验证、公共利益调查、俄罗斯 KIA/POW/MIA/失踪/受伤 OSINT、平台研究、地理定位、监控基础设施以及研究人员安全。
其可见成果是一个双语摘要。而更大的目标是可复用的开源基础设施:具备来源意识的发布、编辑工作流、道德准则、验证记录、主题归档、每周期刊,以及面向乌克兰和国际读者的实用 OSINT 素养。
## 文档
项目规则和操作说明位于:
```
docs/EDITORIAL_POLICY.md
docs/SOURCE_POLICY.md
ROADMAP.md
SECURITY.md
```
这些文档涵盖了编辑范围、信息源角色、Telegram 线索处理、高风险的归属表述、发布边界、路线图和安全报告。
## 路线图
该项目旨在超越日常摘要,发展成为可复用的公共利益 OSINT 基础设施:包括周刊、证据与来源风险元数据、主题页面、归档过滤器、链接检查以及谨慎的 Telegram 线索收集。
参见:
```
ROADMAP.md
```
## 功能说明
该项目目前支持八种工作模式。
### 0. 为下一期创建安全草稿
`create_issue.py` 会在 `drafts/` 目录中创建一个未完成的期刊草稿,因此不会破坏已发布的网站。
```
python create_issue.py --date 2026-05-14 --issue 001
```
当草稿填写完毕后,验证并将其发布到 `issues/` 目录中:
```
python create_issue.py --publish drafts/2026-05-14.json
```
完整说明位于:
```
docs/ADD_ISSUE.md
```
### 1. 渲染单期内容
`render_issue.py` 接收一个期刊的 JSON 文件,并使用 `templates/issue.html.j2` 将其渲染为独立的 HTML 期刊。
```
python render_issue.py issues/2026-05-13.json --out dist
```
### 2. 构建 Web 首页和归档
`build_site.py` 从 `issues/` 目录中提取所有 JSON 文件,将期刊页面渲染到 `dist/issues/` 目录中,并构建:
```
dist/index.html
dist/archive.html
dist/issues/open-source-signal-2026-05-13.html
```
运行:
```
python build_site.py --issues issues --templates templates --out dist --config site.json
```
### 3. 生成 Telegram 公告
`telegram_digest.py` 接收相同的期刊 JSON 数据,并渲染一条简短的英文或乌克兰文 Telegram 公告。
```
python telegram_digest.py issues/2026-05-13.json \
--lang uk \
--url https://osintsignal.org/issues/open-source-signal-2026-05-13.html \
--out dist
```
### 4. 在本地发送 Telegram 公告
`send_telegram.py` 将准备好的公告发送到 Telegram 频道或聊天中。默认的解析模式为 Telegram HTML,因此生成的公告会保留粗体标题、斜体引语以及带有链接的完整期刊 URL。
```
export TELEGRAM_BOT_TOKEN="123456:ABC..."
export TELEGRAM_CHAT_ID="@your_channel_name"
python send_telegram.py \
--text-file dist/telegram-open-source-signal-2026-05-13.uk.txt \
--disable-preview
```
空运行:
```
python send_telegram.py \
--text-file dist/telegram-open-source-signal-2026-05-13.uk.txt \
--chat-id @your_channel_name \
--dry-run
```
### 5. 通过 GitHub Pages 构建和部署
项目包含了适配仓库的 GitHub Actions 工作流:
```
.github/workflows/pages.yml
```
每次推送到 `main` 分支时,它会自动安装依赖项、运行测试、构建 `dist/` 目录、上传 Pages 产物并进行部署。你也可以在 Actions 标签页中手动触发运行。
设置说明位于:
```
docs/GITHUB_PAGES_SETUP.md
```
### 6. 通过 GitHub Actions 发布 Telegram 公告
包含一个手动的 Telegram 工作流:
```
.github/workflows/telegram.yml
```
添加仓库密钥:
```
TELEGRAM_BOT_TOKEN
TELEGRAM_CHAT_ID
```
然后运行:
```
Actions → Publish Telegram announcement → Run workflow
```
该工作流被有意设置为手动触发,因此常规的重建提交不会刷屏频道。
设置说明位于:
```
docs/TELEGRAM_SETUP.md
```
### 7. 将 Daily Signal 文本导入期刊 JSON
`import_daily_signal.py` 可将结构化的 Daily Signal markdown/text 文件转换为完整的 `issues/YYYY-MM-DD.json` 文件。
```
python import_daily_signal.py drafts/daily_signal_2026-05-15.md \
--date 2026-05-15 \
--issue 002 \
--out issues
```
此外还包含一个手动的 GitHub Actions 工作流:
```
.github/workflows/import_daily_signal.yml
```
在以下位置使用它:
```
Actions → Import Daily Signal → Run workflow
```
完整说明位于:
```
docs/IMPORT_DAILY_SIGNAL.md
```
### 8. 通过一次 GitHub Actions 运行发布每日期刊
包含了组合发布工作流:
```
.github/workflows/publish_daily_issue.yml
```
在以下位置使用它:
```
Actions → Publish Daily Issue → Run workflow
```
它会导入粘贴的 Daily Signal 内容、运行测试、构建网站、提交期刊内容、渲染 Telegram 公告、检查重复发送保护机制、如果启用则发送 Telegram 消息,并记录发送日志。
完整说明位于:
```
docs/PUBLISH_DAILY_ISSUE.md
```
## 编辑与信息源政策
该项目现在将编辑规则和信息源登记表保存在仓库中:
```
docs/EDITORIAL_POLICY.md
docs/SOURCE_POLICY.md
data/sources_web.yaml
data/sources_telegram.yaml
```
语言处理:
- 将英文 OSINT 材料改编为乌克兰文。
- 将仅包含乌克兰文的材料改编回英文,以供国际读者阅读。
- 两个版本都必须读起来像是经过编辑的出版文本,而不是字面意义上的机器翻译。
新的乌克兰问责专栏:
```
Ukraine Lens / Українська оптика
War Crimes Verification / Верифікація воєнних злочинів
Losses, Captivity & Missing / Втрати, полон, зниклі
Telegram Radar / Telegram-радар
```
Evocation.info 被作为信息源指引包含在内,而不是作为独立的证据。
## 安装说明
```
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
## 测试
```
python -m pytest -q
```
## 数据模型
主要的可编辑期刊文件位于:
```
issues/
```
每个条目都包含英语和乌克兰语的改编文本:
- 专栏 / emoji / 主题
- 信息源名称、日期和 URL
- 事件概述
- 重要性分析
- 使用指南
- 局限性说明
- 标签
内部编辑备注存储在期刊 JSON 的 `internal_notes` 字段中,但它们**不会**在公开的期刊页面上渲染。
## 网站 URL
公开的基础 URL 配置在:
```
site.json
```
默认值:
```
https://osintsignal.org
```
当手动的 `issue_url` 输入为空时,Telegram 工作流会使用此 `base_url`。
## 排版
HTML 模板使用以下字体:
- Fraunces 用于拉丁文报头。
- Source Serif 4 用于乌克兰语展示排版。
- Inter 用于正文内容。
- Arimo 用于专栏标签和字段标签,例如 `What happened`、`Why it matters`、`Що сталося`、`Чому це важливо`。
- JetBrains Mono 用于技术/元数据元素。
## Telegram 重复发送保护
手动的 Telegram 工作流会将成功的发送记录在 `data/telegram_sent.json` 中。为同一期/语言重新运行该工作流不会再次发送,除非将 `force` 输入设置为 `true`。
标签:事实核查, 信息验证, 内容管理系统, 新闻发布工作流, 逆向工具, 静态网站生成器