66 lines
2.9 KiB
Python
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.

#!/usr/bin/env python3
"""clean skill:按章对齐切窗(LLM 探测输入面)。窗文件含章题标记行,便于 LLM 报 chapter_order。"""
import json
import pathlib
import re
import sys
import click
import psycopg
DSN = ("postgresql://root:f6710e2d0294eb1c10e26a805a64bc54@100.64.0.8:5433/muse-example"
"?keepalives=1&keepalives_idle=15&keepalives_interval=5&keepalives_count=3")
TENANT = 1
OUT = pathlib.Path("/tmp/muse-clean")
@click.command()
@click.option("--work-id", type=int, required=True)
@click.option("--window", type=int, default=100000, show_default=True, help="每窗目标字符数(章对齐)")
@click.option("--from", "from_", type=int, default=1, help="起始章 order_no")
@click.option("--to", type=int, default=0, help="结束章 order_no(0=到末章)")
def main(work_id, window, from_, to):
with psycopg.connect(DSN) as conn:
title = conn.execute("SELECT title FROM muse_content_work WHERE id=%s", (work_id,)).fetchone()[0]
sql = """SELECT c.order_no, c.title, b.content_text
FROM muse_content_chapter c JOIN muse_content_block b ON b.chapter_id=c.id AND b.deleted=FALSE
WHERE c.tenant_id=%s AND c.work_id=%s AND c.deleted=FALSE AND c.order_no>=%s"""
args = [TENANT, work_id, from_]
if to:
sql += " AND c.order_no<=%s"
args.append(to)
rows = conn.execute(sql + " ORDER BY c.order_no", args).fetchall()
d = OUT / str(work_id)
d.mkdir(parents=True, exist_ok=True)
wins, cur, cur_len, cur_span = [], [], 0, []
for no, ct, text in rows:
# 章题标记行:供 LLM 定位 chapter_order;clean_apply 不会删除标记行本身
cur.append(f"\n【第{no}章 | {ct}】\n{text}")
cur_len += len(text)
cur_span.append(no)
if cur_len >= window:
wins.append((cur_span[0], cur_span[-1], "".join(cur)))
cur, cur_len, cur_span = [], 0, []
if cur:
wins.append((cur_span[0], cur_span[-1], "".join(cur)))
manifest = []
for i, (a, b, text) in enumerate(wins, 1):
f = d / f"win-{i:03d}.txt"
f.write_text(f"《{title}》 第{a}–{b}章 原文窗口(章题标记行格式:【第N章 | 章题】)\n{text}")
manifest.append({"win": i, "file": str(f), "from": a, "to": b, "chars": len(text)})
(d / "manifest.json").write_text(json.dumps(
{"work_id": work_id, "title": title, "windows": manifest}, ensure_ascii=False, indent=1))
click.echo(f"《{title}》切窗完成: {len(wins)} 窗 → {d}/win-*.txt(manifest.json 就绪)")
for m in manifest[:5]:
click.echo(f" win-{m['win']:03d} 第{m['from']}–{m['to']}章 {m['chars']:,}字")
if len(manifest) > 5:
click.echo(f" … 共 {len(manifest)} 窗")
if __name__ == "__main__":
try:
main()
except psycopg.Error as e:
click.echo(f"[db错误] {type(e).__name__}: {e}", err=True)
sys.exit(1)