Files
FacereDataset/OSHWHUB_INGEST_SPEC.md
2026-04-23 23:42:21 +08:00

275 lines
10 KiB
Markdown
Raw 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.
# 立创开源平台抓取 → Forge 接入 spec
**Date**: 2026-04-23
**给**: 同学爬 oshwhub.com / 立创开源广场
**目的**: 爬回来的数据按这份 spec 整理,我们直接批量接入 Forge 的 BoardReference corpus。
---
## 1. TL;DR — 你交付的目标形态
每个项目一个目录,**三件套**
```
<project_id>/
├── schematic.kicad_sch # ← 我们主要吃这个KiCad 7+ S-expression 格式
├── manifest.json # ← 项目元数据(见 §4
└── source/ # ← 可选:原 EasyEDA 文件归档(.json / .epro 等)
```
**命名**: `project_id` = `oshwhub_<oshwhub数字ID>_<slug>`,纯小写下划线。
例:`oshwhub_1234567_esp32_bluepill_clone`
**交付**: tar.gz 或 git repo 都行。放在我们能访问的路径;我们自己跑批量 migrate。
---
## 2. 硬性前置条件 —— 任何一条不满足就跳过这个项目
### 2.1 License 白名单(关键!)
**仅抓这些许可的项目**
- MIT / BSD-2-Clause / BSD-3-Clause / Apache-2.0
- CC0-1.0 / CC-BY-4.0 / CC-BY-3.0
- CERN-OHL-P-2.0permissive 变体)
- Unlicense / public domain
**必须拒掉的**
- **CC-BY-SA**share-alike会污染我们 corpus——大比例立创项目是这个务必过滤
- GPL / LGPL / AGPL 全家
- "未声明 license" / "All rights reserved"
- CC-BY-NC禁商用
立创项目页面上会显示许可名。你的爬虫要**先读许可、后抓文件**——许可不合格直接跳过,节省带宽。
### 2.2 文件格式
**必须有 KiCad 7+ 格式的 `.kicad_sch`**
- 文件首 20 字节包含 `(kicad_sch`
- version 声明 ≥ 20210621早于这个版本 KiCad 10 加载会 warning 一大堆)
**如果项目只有 EasyEDA 原文件**
- 用 [`easyeda2kicad`](https://github.com/uPesy/easyeda2kicad.py) 工具转(`pip install easyeda2kicad`
- 或者立创 EDA Professional 的"导出 KiCad"功能
- 转完后**必须验证能被 kicad-cli 加载**(见 §6 自测)——转不出来就跳过、不要硬塞
### 2.3 基本质量
- 至少 5 个元件(太简单的 breadboard prototype 没参考价值)
- 不超过 300 元件(太大的我们暂时不处理)
- 不是纯 footprint 测试板(没电气连接)
---
## 3. `schematic.kicad_sch` 的要求
**原样保留**,不改、不格式化、不重新生成。我们的 corpus 依赖**字节级完整保留**才能做零漂移 byte-copy render。
**如果你用 easyeda2kicad 转换**
- 转一次、存盘、不要后续再处理
- 多 sheet 项目:把主 sheet 存为 `schematic.kicad_sch`,其它 sheet 存为 `sheets/<name>.kicad_sch`
(我们暂时只消费根 sheet但不要删其它——留着我们以后升级
---
## 4. `manifest.json` 格式
必填字段:
```json
{
"project_id": "oshwhub_1234567_esp32_bluepill_clone",
"source_platform": "oshwhub",
"source_url": "https://oshwhub.com/username/esp32-bluepill-clone",
"source_author": "username",
"title": "ESP32 Blue Pill 克隆",
"description": "一行到三行描述。可以直接从项目页面抓。双语都抓最好en + zh至少一个。",
"description_zh": "中文描述 (如果有)",
"license": "MIT",
"license_source": "https://oshwhub.com/username/esp32-bluepill-clone/license",
"license_verified": true,
"components_used": ["ESP32-WROOM-32", "AMS1117-3.3", "USB_B_Micro", "C", "R", "LED"],
"file_checksum_sha256": "abc123...",
"file_size_bytes": 178825,
"kicad_sch_version": "20230121",
"crawl_timestamp": "2026-04-23T10:00:00Z",
"converted_from": "easyeda",
"conversion_tool": "easyeda2kicad 0.8.2",
"tags_raw": ["esp32", "dev_board", "usb"]
}
```
字段说明:
- **`source_url`**:立创开源那个 project 的页面 URL。我们保存做 provenance。
- **`license`**:必须是 §2.1 白名单里的字符串之一。**抓不准就跳过**,宁缺毋滥。
- **`license_source`**license 是从哪读到的页面、LICENSE 文件、README。方便我们事后验。
- **`components_used`**:从 sch 里或从 EasyEDA 原 BOM 抓。用于后续 tag 派生——越全越好。
- **`file_checksum_sha256`**sha256 of `schematic.kicad_sch`。dedupe 用。
- **`converted_from` / `conversion_tool`**:原生 KiCad 的项目写 `"converted_from": "native"`EasyEDA 转来的写具体工具和版本。
- **`tags_raw`**:立创页面上那个项目自带的标签/分类。原样塞。我们这边有一个 enrich 管线会基于 `components_used` + `description` 再派生更细的 taghas_mcu / chip_tp4056 / use_portable...),你不用管这一步。
可选但有用:
- `source_easyeda_json_path`: 原 EasyEDA 文件的路径(如果你归档到 `source/` 下的话)
- `commit_sha` / `version`: 如果立创项目有版本号
- `star_count` / `fork_count`: 作为后续 quality 排序参考
---
## 5. 目录结构示例
```
batch_20260423/ # 你一次交付的批次目录
├── README.md # 批次元数据(数量、时间、任何 caveat
├── BATCH_MANIFEST.json # 机器可读的批次清单(见 §5.1
├── oshwhub_1234567_esp32_bluepill/
│ ├── schematic.kicad_sch
│ ├── manifest.json
│ └── source/
│ └── schematic.json # 原 EasyEDA
├── oshwhub_2234568_tp4056_charger_v2/
│ ├── schematic.kicad_sch
│ ├── manifest.json
│ └── source/
│ ├── schematic.json
│ └── pcb.json
├── oshwhub_3234569_audio_preamp/
│ ├── schematic.kicad_sch # 原生 KiCad无 source/
│ └── manifest.json
└── ... (N 个项目)
```
### 5.1 BATCH_MANIFEST.json
让我们能一键扫批次:
```json
{
"batch_id": "batch_20260423",
"created_at": "2026-04-23T12:00:00Z",
"total_projects": 153,
"by_license": {
"MIT": 87,
"CC-BY-4.0": 34,
"Apache-2.0": 20,
"CC0-1.0": 12
},
"projects": [
"oshwhub_1234567_esp32_bluepill",
"oshwhub_2234568_tp4056_charger_v2",
...
]
}
```
---
## 6. 自测 checklist你交付前跑一遍
对每个 `<project_id>/` 跑这 4 个检查,任一失败就把这个项目踢出批次:
```bash
# 1. .kicad_sch 首字节对头
head -c 20 <project_id>/schematic.kicad_sch | grep -q "(kicad_sch" || echo FAIL_1
# 2. 版本 ≥ 20210621
grep -oE "version \d{8}" <project_id>/schematic.kicad_sch | head -1
# expect 20210621 或更大
# 3. 能被 kicad-cli 加载这一步最关键catch 掉所有转换失败)
kicad-cli sch export netlist <project_id>/schematic.kicad_sch \
-o /tmp/test.net 2>&1 | grep -qi "error\|失败" && echo FAIL_3
# 4. manifest.json 合法且必填字段齐
python3 -c "
import json, sys
m = json.load(open('<project_id>/manifest.json'))
required = ['project_id', 'source_url', 'license', 'components_used', 'file_checksum_sha256']
missing = [k for k in required if k not in m or not m[k]]
if missing:
print('FAIL_4 missing:', missing)
sys.exit(1)
"
```
把每个项目的检查结果写进 BATCH_MANIFEST 或单独一个 `failed/` 子目录归档。**交付前所有 4 个检查都要过**。
---
## 7. 已知坑 & 建议
### 7.1 立创开源的 license 现实
经验数据(不保证准确):
- 立创项目里**可能 50%+ 是 "CC-BY-SA 4.0"**,这是默认选项 → 我们直接拒
- 大概 20-30% 是 "未声明 license" → 拒
- 10-15% 是 MIT / Apache / CC0 → 要!
- 少量 GPL → 拒
**预期 hit rate**: 你抓 1000 个项目可能只有 150-250 能通过 license 关卡。这是正常的,不要为了数量降低许可标准。
### 7.2 EasyEDA → KiCad 转换质量
`easyeda2kicad.py` 对大部分项目能用,但:
- 自定义 symbol立创 SZLCSC 专有库)可能转不过来 → 转完 kicad-cli 加载会 fail → 被 §6 check 3 过滤掉
- 多 sheet hierarchy 偶尔乱 → 只保根 sheet 也能用
- footprint 转换常有问题——我们暂时不在乎 footprintcorpus 主要消费 schematic转不过就空着
### 7.3 描述文字
立创项目标题和描述常常**中英混杂 + markdown 标记 + emoji**。原样保留没关系,我们的 enrich 管线会 strip markdown。但**别主动翻译或改写** —— 原文有最多信息。
### 7.4 同项目多版本
立创有的项目带版本v1 / v2 / Rev.B。**不同版本视作不同项目**,分别抓、分别起 project_id。不要合并。
### 7.5 电气图多页
立创项目经常一个 sch 项目分多页root + mcu_sheet + power_sheet 等)。你遇到时:
- 如果 easyeda2kicad 能转出层级结构 → 主 sheet 存 `schematic.kicad_sch`,子 sheet 存 `sheets/<name>.kicad_sch`
- 如果只导出根 sheet → 根 sheet 存 `schematic.kicad_sch`,在 `manifest.json``"has_unsaved_subsheets": true` 标记
- 转不出来 → 跳
---
## 8. 交付后我们会做什么(你不用担心这部分)
参考、别去实现:
1. `batch_migrate_oshwhub.py` 扫整个批次,逐个 `board_ingest_from_file` 入 corpus
2. License 白名单再 double-check 一遍(防你漏过)
3. sha256 dedupe跨批次
4. `enrich_tags.py` 跑一遍基于 `components_used` + `description` 生成 chip_* / has_* / use_* tag 家族
5. 用 kicad-cli 跑 ERC 取 `source_erc_status`,脏的标记一下但仍入库(用户能看到警告)
---
## 9. 测试批次建议
**第一次交付先给小批 5-10 个项目**,覆盖:
- 3-5 个 MIT/Apache 原生 KiCad
- 2-3 个 CC0/CC-BY-4.0 从 EasyEDA 转的
- 1-2 个你不确定的 edge case多 sheet、异常元件等
我们跑一遍 ingest给你反馈"格式上还要改啥" / "这块数据不够",再开始量产爬。
---
## 10. 联系点
- 这份文档的源头:`hardware_agent_docs/OSHWHUB_INGEST_SPEC.md`
- 我们的 BoardReference schema 定义:`src/facere/references/schema.py`
- 已有的 ingest 入口:`src/facere/references/board_ingest.py`
- 批量 migrate 脚本参考:`benchmarks/corpus_build/migrate_raw_to_board_refs.py`
有问题直接问我(张大佬)—— 格式细节比速度重要,不清楚的**先对一下再做**。