Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
5.8 KiB
5.8 KiB
③auto_dishu.py · 主流水线程序 · 2026-05-21
HLDP://juzi/tools/auto_dishu/2026-05-21
├── 作用: 自动从知识库取书·调用晨星拆书·保存结果
├── 操作: 整段复制粘贴到终端,回车
└── 看到「✅ auto_dishu.py 创建完成」就成功了
复制这整段到终端,回车
cat > ~/chenxing-aircraft/tools/auto_dishu.py << 'ENDOFFILE'
#!/usr/bin/env python3
"""
自动拆书流水线 · auto_dishu.py
桔子×晨星 · 2026-05-21
用法:
python3 tools/auto_dishu.py --book 折春漪 --end_chapter 400
python3 tools/auto_dishu.py --book 折春漪 --start_chapter 301 --end_chapter 400
"""
import argparse
import asyncio
import os
import sqlite3
import sys
from pathlib import Path
try:
from openai import AsyncOpenAI
except ImportError:
print("请先安装依赖: pip install openai")
sys.exit(1)
BASE_DIR = Path(__file__).parent.parent
DB_PATH = BASE_DIR / "chenxing.db"
DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY", "")
NOTION_API_KEY = os.environ.get("NOTION_API_KEY", "")
NOTION_DISHU_PAGE_ID = os.environ.get("NOTION_DISHU_PAGE_ID", "")
DISHU_SYSTEM = "你是晨星,桔子妈妈的拆书宝宝。请用场景颗粒拆书法v2.0认真分析,格式严格按三模块输出,缺一不可。"
DISHU_PROMPT = """请用「场景颗粒拆书法v2.0」分析以下章节内容。
拆书格式(三模块·缺一不可):
【模块一·逐章场景表格】
| 场景序号 | 场景边界 | 人物动作/对话 | 情绪质地 | 读者感受 |
(每个场景一行)
【模块二·章末规律锁定】
- 本章节奏类型:
- 情绪弧线:(开头→过程→结尾)
- 卡点设计:
- 可复用规律:(至少2条)
【模块三·期待点库存】
- 新增期待点:
- 消解期待点:
- 遗留悬念:
待分析内容:
{content}"""
def db_get_chunks(book_name: str) -> list:
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
try:
rows = conn.execute(
"SELECT id, title, content FROM knowledge WHERE tags LIKE ? AND category='book' ORDER BY id",
(f"%{book_name}%",)
).fetchall()
if not rows:
rows = conn.execute(
"SELECT id, title, content FROM knowledge WHERE title LIKE ? ORDER BY id",
(f"%{book_name}%",)
).fetchall()
return [{"id": r["id"], "title": r["title"], "content": r["content"]} for r in rows]
finally:
conn.close()
def save_local(book_name: str, title: str, content: str):
out = BASE_DIR / "output" / book_name
out.mkdir(parents=True, exist_ok=True)
safe_title = title[:80].replace("/", "_").replace("\\", "_")
(out / f"{safe_title}.md").write_text(f"# {title}\n\n{content}", encoding="utf-8")
async def analyze(content: str) -> str:
if not DEEPSEEK_API_KEY:
raise ValueError("未配置 DEEPSEEK_API_KEY 环境变量")
client = AsyncOpenAI(api_key=DEEPSEEK_API_KEY, base_url="https://api.deepseek.com")
resp = await client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": DISHU_SYSTEM},
{"role": "user", "content": DISHU_PROMPT.format(content=content[:8000])}
],
max_tokens=4096,
temperature=0.7
)
return resp.choices[0].message.content
async def run(book_name: str, start_chapter: int, end_chapter: int):
print(f"\n{'='*50}")
print(f"🚀 自动拆书流水线")
print(f"📚 《{book_name}》")
print(f"{'='*50}\n")
chunks = db_get_chunks(book_name)
if not chunks:
print(f"❌ 知识库中未找到《{book_name}》")
print("请先运行: python3 tools/book_splitter.py --file 书名.txt --book 书名")
return
print(f"✅ 找到 {len(chunks)} 个知识库块")
total = len(chunks)
analyzed = 0
for i, chunk in enumerate(chunks):
label = chunk["title"]
print(f"\n[{i+1}/{total}] 分析中:{label}")
print(f" 字数:{len(chunk['content']):,}")
try:
result = await analyze(chunk["content"])
notion_title = f"《{book_name}》{label}·场景颗粒拆书"
written = False
if NOTION_DISHU_PAGE_ID and NOTION_API_KEY:
sys.path.insert(0, str(BASE_DIR))
from tools.notion_writer import create_notion_page
written = create_notion_page(notion_title, result, NOTION_DISHU_PAGE_ID)
if written:
print(f" ✅ 写入Notion:{notion_title}")
save_local(book_name, notion_title, result)
if not written:
print(f" 📁 已保存本地:output/{book_name}/")
analyzed += 1
print(f" ⏱ 等待3秒...")
await asyncio.sleep(3)
except Exception as e:
print(f" ❌ 出错:{e}")
await asyncio.sleep(5)
print(f"\n{'='*50}")
print(f"🎉 全部完成!共分析 {analyzed} 块")
if NOTION_DISHU_PAGE_ID:
print(f"📝 结果已写入 Notion")
print(f"📁 本地备份:output/{book_name}/")
print(f"{'='*50}\n")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--book", required=True, help="书名(不含《》)")
parser.add_argument("--start_chapter", type=int, default=1)
parser.add_argument("--end_chapter", type=int, required=True)
args = parser.parse_args()
asyncio.run(run(args.book, args.start_chapter, args.end_chapter))
ENDOFFILE
echo "✅ auto_dishu.py 创建完成"
三个脚本全部创建后,验证一下
ls -la ~/chenxing-aircraft/tools/
应该看到四个文件:__init__.py + book_splitter.py + notion_writer.py + auto_dishu.py
🌟 三个脚本都装好之后,告诉宝宝!下一步是测试运行 💜