- Refactor codebase into src/ (preprocessing, translation, assembly) - Add pipeline/ scripts for individual stages - Externalize configuration to config/config.yaml - Fix Cover Image preservation - Update documentation and manuals
111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Manifest 错误分析工具
|
|
用于深入分析翻译结果中的占位符问题
|
|
"""
|
|
import sys
|
|
import re
|
|
import json
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, '.')
|
|
from src.manifest_manager import ManifestManager
|
|
|
|
def analyze_item(item):
|
|
"""详细分析单个 Item 的占位符状态"""
|
|
issues = []
|
|
|
|
twp = item.text_with_placeholders or ""
|
|
trans = item.translation_with_placeholders or ""
|
|
pmap = item.placeholder_map or {}
|
|
|
|
ph_regex = r'φ(/?\d+)φ'
|
|
src_phs = set(re.findall(ph_regex, twp))
|
|
trans_phs = set(re.findall(ph_regex, trans))
|
|
map_ids = {k for k in pmap.keys() if not k.startswith('_')}
|
|
|
|
# 模拟 FormatRestorer 的宽松逻辑
|
|
unknowns = trans_phs - map_ids
|
|
real_unknowns = set()
|
|
for pid in unknowns:
|
|
# 如果是 /N,且 N 在 map 中,则认为是安全的冗余闭合
|
|
if pid.startswith('/') and pid[1:] in map_ids:
|
|
continue
|
|
real_unknowns.add(pid)
|
|
|
|
if real_unknowns:
|
|
issues.append(f"未知占位符(幻觉): {real_unknowns}")
|
|
|
|
missing = map_ids - trans_phs
|
|
if missing:
|
|
issues.append(f"丢失占位符: {missing}")
|
|
|
|
# Check Reordering
|
|
src_ph_list = re.findall(ph_regex, twp)
|
|
trans_ph_list = re.findall(ph_regex, trans)
|
|
common = [p for p in src_ph_list if p in trans_ph_list]
|
|
trans_common = [p for p in trans_ph_list if p in src_ph_list]
|
|
if common != trans_common:
|
|
issues.append(f"占位符乱序: 原文{common} -> 译文{trans_common}")
|
|
|
|
return issues
|
|
|
|
def main():
|
|
manifest_dir = Path("cache/manifests")
|
|
files = list(manifest_dir.glob("*_manifest.json"))
|
|
if not files:
|
|
print("未找到 manifest 文件")
|
|
return
|
|
|
|
target = next((f for f in files if "Karen Hao" in f.name), files[0])
|
|
print(f"Loading: {target}")
|
|
|
|
manifest = ManifestManager(str(target))
|
|
if not manifest.load():
|
|
print("加载失败")
|
|
return
|
|
|
|
items = manifest.get_items()
|
|
error_count = 0
|
|
total_analyzed = 0
|
|
|
|
print("\n" + "="*50)
|
|
print(" 异常项目分析报告")
|
|
print("="*50 + "\n")
|
|
|
|
for item in items:
|
|
# 只分析非成功状态或有 warning 的
|
|
if item.status == "completed":
|
|
continue
|
|
|
|
# 即使是 format_error, failed, translated (with issues)
|
|
issues = analyze_item(item)
|
|
has_error = (item.status in ["failed", "format_error"]) or bool(issues)
|
|
|
|
if has_error:
|
|
total_analyzed += 1
|
|
print(f"ID: {item.global_id} (Status: {item.status})")
|
|
if item.error_msg:
|
|
print(f" Error Msg: {item.error_msg}")
|
|
|
|
# 只有当有具体 issue 时才打印详细文本,避免刷屏
|
|
if issues or item.status == "format_error":
|
|
print(f" 原文: {item.text_with_placeholders[:100]}...")
|
|
print(f" 译文: {item.translation_with_placeholders[:100]}..." if item.translation_with_placeholders else " 译文: (None)")
|
|
print(f" Map: {list(item.placeholder_map.keys())}")
|
|
|
|
for issue in issues:
|
|
print(f" -> {issue}")
|
|
|
|
print("-" * 50)
|
|
error_count += 1
|
|
|
|
if error_count > 50:
|
|
print("... (Errors truncated) ...")
|
|
break
|
|
|
|
print(f"\n分析完成。共发现 {total_analyzed} 个异常项目。")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|