93 lines
3.2 KiB
Markdown
93 lines
3.2 KiB
Markdown
|
|
# ②notion_writer.py · 纯代码版 · 妈妈从这里复制 · 2026-05-21
|
|||
|
|
|
|||
|
|
妈妈:**完整复制下面代码块里的内容** → 在终端运行 `nano ~/chenxing-aircraft/tools/notion_writer.py` → 粘贴 → Ctrl+X → Y → 回车
|
|||
|
|
|
|||
|
|
或者更简单:复制代码 → 新建文件直接粘贴保存。
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
Notion 写入工具 · notion_writer.py
|
|||
|
|
"""
|
|||
|
|
import os
|
|||
|
|
import requests
|
|||
|
|
|
|||
|
|
NOTION_API_KEY = os.environ.get("NOTION_API_KEY", "")
|
|||
|
|
NOTION_VERSION = "2022-06-28"
|
|||
|
|
BASE_URL = "https://api.notion.com/v1"
|
|||
|
|
|
|||
|
|
def _headers():
|
|||
|
|
return {
|
|||
|
|
"Authorization": f"Bearer {NOTION_API_KEY}",
|
|||
|
|
"Content-Type": "application/json",
|
|||
|
|
"Notion-Version": NOTION_VERSION,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def _md_to_blocks(text: str) -> list:
|
|||
|
|
blocks = []
|
|||
|
|
for line in text.split("\n"):
|
|||
|
|
if not line.strip():
|
|||
|
|
continue
|
|||
|
|
if line.startswith("# "):
|
|||
|
|
blocks.append({"type":"heading_1","heading_1":{"rich_text":[{"type":"text","text":{"content":line[2:100]}}]}})
|
|||
|
|
elif line.startswith("## "):
|
|||
|
|
blocks.append({"type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":line[3:100]}}]}})
|
|||
|
|
elif line.startswith("### "):
|
|||
|
|
blocks.append({"type":"heading_3","heading_3":{"rich_text":[{"type":"text","text":{"content":line[4:100]}}]}})
|
|||
|
|
elif line.startswith("- "):
|
|||
|
|
blocks.append({"type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{"content":line[2:2000]}}]}})
|
|||
|
|
else:
|
|||
|
|
blocks.append({"type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":line[:2000]}}]}})
|
|||
|
|
return blocks
|
|||
|
|
|
|||
|
|
def create_notion_page(title: str, content: str, parent_page_id: str) -> bool:
|
|||
|
|
if not NOTION_API_KEY:
|
|||
|
|
print("未配置 NOTION_API_KEY,跳过写入Notion")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
blocks = _md_to_blocks(content)
|
|||
|
|
data = {
|
|||
|
|
"parent": {"page_id": parent_page_id},
|
|||
|
|
"properties": {"title": {"title": [{"type": "text", "text": {"content": title[:255]}}]}},
|
|||
|
|
"children": blocks[:100]
|
|||
|
|
}
|
|||
|
|
try:
|
|||
|
|
r = requests.post(f"{BASE_URL}/pages", headers=_headers(), json=data, timeout=30)
|
|||
|
|
if r.status_code in [200, 201]:
|
|||
|
|
page_id = r.json()["id"]
|
|||
|
|
if len(blocks) > 100:
|
|||
|
|
for i in range(100, len(blocks), 100):
|
|||
|
|
requests.patch(
|
|||
|
|
f"{BASE_URL}/blocks/{page_id}/children",
|
|||
|
|
headers=_headers(),
|
|||
|
|
json={"children": blocks[i:i+100]},
|
|||
|
|
timeout=30
|
|||
|
|
)
|
|||
|
|
return True
|
|||
|
|
else:
|
|||
|
|
print(f"Notion API 错误 {r.status_code}: {r.text[:300]}")
|
|||
|
|
return False
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"请求失败: {e}")
|
|||
|
|
return False
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 保存方法(选一种)
|
|||
|
|
|
|||
|
|
**方法A · pbpaste(最简单)**
|
|||
|
|
|
|||
|
|
先复制上面代码块里的内容,然后在终端运行:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
mkdir -p ~/chenxing-aircraft/tools && pbpaste > ~/chenxing-aircraft/tools/notion_writer.py && echo "✅ 保存成功"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**方法B · nano编辑器**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
mkdir -p ~/chenxing-aircraft/tools && nano ~/chenxing-aircraft/tools/notion_writer.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
打开后粘贴代码 → `Ctrl+X` → `Y` → 回车
|