159 lines
5.6 KiB
Python
159 lines
5.6 KiB
Python
"""按完整目录读取当前稿用于回看;疑点交回逐章改稿入口。"""
|
|
|
|
from uuid import NAMESPACE_URL, uuid5
|
|
|
|
from muse.交付连载.文字校对 import 文字疑点
|
|
from muse.交付连载.模型 import 交付错误, 全书修订
|
|
from muse.作品规划.接口 import 读取作品范围
|
|
from muse.正式变更.接口 import 作者动作, 固定哈希, 审阅内容, 提交计划
|
|
from muse.正文写作.接口 import (
|
|
准备派生候选,
|
|
可见文本,
|
|
应用选段,
|
|
批量读取当前正文依据,
|
|
段落哈希,
|
|
段落文本,
|
|
读取正文依据,
|
|
)
|
|
|
|
|
|
def 读取全书数据(连, author, work_id):
|
|
"""同事务批量获取目录与全书当前正文依据。"""
|
|
directory = 读取作品范围(连, author, work_id)
|
|
chapter_ids = [c["chapter_id"] for c in directory["chapters"]]
|
|
body_map = 批量读取当前正文依据(连, author, work_id, chapter_ids)
|
|
return directory, body_map
|
|
|
|
|
|
def 整理全书工作面(work_id, directory, body_map, *, names=None, exceptions=()):
|
|
"""纯内存整理工作面结构、段落偏移与文字疑点,不占用数据库连接。"""
|
|
chapters, problems = [], []
|
|
for chapter in directory["chapters"]:
|
|
body = body_map.get(chapter["chapter_id"])
|
|
if body is None:
|
|
chapters.append({**chapter, "state": "missing", "revision": None})
|
|
problems.append({"chapter_id": chapter["chapter_id"], "kind": "missing_body"})
|
|
continue
|
|
text = 可见文本(body["document"])
|
|
state = "ready" if text.strip() else "empty"
|
|
paragraphs, offset = [], 0
|
|
for p in body["document"].paragraphs:
|
|
value = 段落文本(p)
|
|
paragraphs.append(
|
|
{
|
|
"paragraph_id": p.paragraph_id,
|
|
"paragraph_hash": 段落哈希(p),
|
|
"text": value,
|
|
"start": offset,
|
|
"end": offset + len(value),
|
|
}
|
|
)
|
|
offset += len(value) + 1
|
|
chapters.append(
|
|
{
|
|
**chapter,
|
|
"state": state,
|
|
"branch_id": "main",
|
|
"revision": body["revision"],
|
|
"document_hash": body["document_hash"],
|
|
"text": text,
|
|
"paragraph_locations": paragraphs,
|
|
}
|
|
)
|
|
if state == "empty":
|
|
problems.append({"chapter_id": chapter["chapter_id"], "kind": "empty_body"})
|
|
findings = 文字疑点([c for c in chapters if c["revision"] is not None], names, exceptions)
|
|
return {
|
|
"work_id": work_id,
|
|
"directory_revision": directory["revision"],
|
|
"chapters": chapters,
|
|
"problems": problems,
|
|
"copyedit": findings,
|
|
"can_freeze": bool(chapters) and not problems,
|
|
"literary_status": "not_assessed",
|
|
"review_scope": ["directory", "body_presence", "copyedit"],
|
|
}
|
|
|
|
|
|
def 全书工作面(连, author, work_id, *, names=None, exceptions=()):
|
|
directory, body_map = 读取全书数据(连, author, work_id)
|
|
return 整理全书工作面(work_id, directory, body_map, names=names, exceptions=exceptions)
|
|
|
|
|
|
def 跨章候选身份(author, req, chapter):
|
|
return str(
|
|
uuid5(
|
|
NAMESPACE_URL,
|
|
"muse:B08:book-revision:"
|
|
+ 固定哈希(
|
|
[
|
|
author,
|
|
req.batch_id,
|
|
chapter.chapter_id,
|
|
chapter.branch_id,
|
|
]
|
|
),
|
|
)
|
|
)
|
|
|
|
|
|
def _准备跨章(连, 身份, req):
|
|
读取作品范围(连, 身份.作者, req.work_id)
|
|
dependencies, operations = {}, []
|
|
for selected in req.chapters:
|
|
if not selected.patches:
|
|
raise 交付错误("BOOK_REVISION_INVALID", "每个入选章须点名原文与修改")
|
|
body = 读取正文依据(
|
|
连,
|
|
身份.作者,
|
|
selected.chapter_id,
|
|
selected.revision,
|
|
分支=selected.branch_id,
|
|
)
|
|
if body["work_id"] != req.work_id or body["document_hash"] != selected.document_hash:
|
|
raise 交付错误("SOURCE_STALE", "跨章修改的作品、原文或版本不一致")
|
|
changed = 应用选段(body["document"], selected.patches)
|
|
current, plan = 准备派生候选(
|
|
连,
|
|
身份,
|
|
跨章候选身份(身份.作者, req, selected),
|
|
selected.chapter_id,
|
|
selected.branch_id,
|
|
selected.revision,
|
|
changed,
|
|
)
|
|
for ref in current.依赖:
|
|
dependencies[(ref.种类, ref.对象ID)] = ref
|
|
operations.extend(plan.操作)
|
|
return tuple(dependencies.values()), tuple(operations)
|
|
|
|
|
|
class 跨章修订入口:
|
|
身份 = "B08.book_revision"
|
|
请求类型 = 全书修订
|
|
|
|
def 查看(self, 连, 身份, 命令):
|
|
req = 命令.业务请求
|
|
refs, _ = _准备跨章(连, 身份, req)
|
|
target = 跨章候选身份(身份.作者, req, req.chapters[0])
|
|
digest = 固定哈希(req)
|
|
return 审阅内容(
|
|
target,
|
|
0,
|
|
None,
|
|
None,
|
|
None,
|
|
digest,
|
|
None,
|
|
None,
|
|
digest,
|
|
("candidates",),
|
|
refs,
|
|
)
|
|
|
|
def 准备(self, 连, 身份, 命令, 当前):
|
|
if 命令.动作 is not 作者动作.人工保存:
|
|
raise 交付错误("BOOK_REVISION_INVALID", "跨章修改只生成作者可审候选")
|
|
_, operations = _准备跨章(连, 身份, 命令.业务请求)
|
|
return 提交计划(operations)
|