215 lines
7.1 KiB
Python
215 lines
7.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
全局编号系统验证脚本
|
|
测试重构后的翻译流程和中英文对应关系
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# 添加项目根目录到路径
|
|
project_root = Path(__file__).parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
from src.epub_parser import EPUBParser
|
|
from src.text_processor import TextProcessor
|
|
from src.llm_client import OpenRouterClient
|
|
from src.translator import EPUBTranslator
|
|
from src.utils import load_config
|
|
from loguru import logger
|
|
|
|
|
|
async def test_global_id_system():
|
|
"""测试全局ID系统"""
|
|
|
|
print("🔧 测试全局ID系统")
|
|
print("=" * 60)
|
|
|
|
try:
|
|
config = load_config()
|
|
|
|
# 查找测试EPUB
|
|
test_files = list(Path(".").glob("*.epub"))
|
|
if not test_files:
|
|
print("❌ 未找到测试EPUB文件")
|
|
return
|
|
|
|
test_epub = test_files[0]
|
|
print(f"📚 测试文件: {test_epub}\n")
|
|
|
|
# 测试1: 段落提取和编号
|
|
print("📝 测试1: 段落提取和全局编号")
|
|
print("-" * 60)
|
|
|
|
parser = EPUBParser(str(test_epub))
|
|
content_items = parser.extract_all_content_items()
|
|
|
|
if not content_items:
|
|
print("❌ 未找到内容项目")
|
|
return
|
|
|
|
# 提取段落
|
|
text_processor = TextProcessor(config)
|
|
all_paragraphs = []
|
|
|
|
for item in content_items[:2]: # 只测试前2个文件
|
|
paragraphs = text_processor.extract_paragraphs_with_global_id(
|
|
item['content'],
|
|
item['file_name']
|
|
)
|
|
all_paragraphs.extend(paragraphs)
|
|
|
|
print(f"✅ 提取了 {len(all_paragraphs)} 个段落")
|
|
print(f" ID范围: {all_paragraphs[0]['global_id']} - {all_paragraphs[-1]['global_id']}")
|
|
|
|
# 显示前3个段落
|
|
print(f"\n 前3个段落示例:")
|
|
for para in all_paragraphs[:3]:
|
|
print(f" [{para['global_id']}] {para['text'][:60]}...")
|
|
|
|
# 测试2: 分块
|
|
print(f"\n📦 测试2: 智能分块(不切断段落)")
|
|
print("-" * 60)
|
|
|
|
chunks = text_processor.create_chunks_by_size(all_paragraphs)
|
|
|
|
print(f"✅ 创建了 {len(chunks)} 个chunk")
|
|
print(f" Chunk大小限制: {config['translation']['chunk_size']} 字符")
|
|
|
|
# 显示每个chunk的信息
|
|
for i, chunk in enumerate(chunks, 1):
|
|
chunk_size = sum(p['length'] for p in chunk)
|
|
print(f" Chunk {i}: {len(chunk)} 段落, {chunk_size} 字符, "
|
|
f"ID: {chunk[0]['global_id']}-{chunk[-1]['global_id']}")
|
|
|
|
# 验证chunk不跨越段落
|
|
print(f"\n 验证: 检查chunk是否保持段落完整性...")
|
|
for i, chunk in enumerate(chunks, 1):
|
|
if not chunk:
|
|
print(f" ❌ Chunk {i} 为空")
|
|
continue
|
|
|
|
# 检查每个段落是否完整
|
|
for para in chunk:
|
|
if para['length'] == 0:
|
|
print(f" ❌ 发现空段落: {para['global_id']}")
|
|
else:
|
|
print(f" ✅ Chunk {i} 段落完整")
|
|
break
|
|
|
|
# 测试3: 翻译一个小chunk
|
|
print(f"\n🚀 测试3: 翻译示例chunk(带编号)")
|
|
print("-" * 60)
|
|
|
|
if chunks:
|
|
# 选择第一个chunk的前3个段落
|
|
test_chunk = chunks[0][:3]
|
|
|
|
print(f" 测试 {len(test_chunk)} 个段落:")
|
|
for para in test_chunk:
|
|
print(f" [{para['global_id']}] {para['text'][:50]}...")
|
|
|
|
llm_client = OpenRouterClient(config)
|
|
|
|
print(f"\n 发送翻译请求...")
|
|
translations = await llm_client.translate_chunk_with_ids(
|
|
test_chunk,
|
|
model_type="test"
|
|
)
|
|
|
|
print(f"\n 翻译结果:")
|
|
for para in test_chunk:
|
|
global_id = para['global_id']
|
|
translation = translations.get(global_id, "[未找到翻译]")
|
|
|
|
print(f"\n [{global_id}]")
|
|
print(f" EN: {para['text'][:80]}...")
|
|
print(f" ZH: {translation[:80]}...")
|
|
|
|
# 验证对应关系
|
|
if translation.startswith('[翻译失败') or translation == "[未找到翻译]":
|
|
print(f" ❌ 翻译失败")
|
|
else:
|
|
print(f" ✅ 翻译成功")
|
|
|
|
await llm_client.close()
|
|
|
|
# 测试4: 统计信息
|
|
print(f"\n📊 测试4: 统计信息")
|
|
print("-" * 60)
|
|
|
|
stats = text_processor.get_statistics(all_paragraphs)
|
|
print(f" 总段落数: {stats['total_paragraphs']}")
|
|
print(f" 总字符数: {stats['total_characters']}")
|
|
print(f" 平均长度: {stats['average_length']}")
|
|
print(f" 最短段落: {stats['min_length']} 字符")
|
|
print(f" 最长段落: {stats['max_length']} 字符")
|
|
|
|
print(f"\n🎉 全局ID系统测试完成!")
|
|
|
|
except Exception as e:
|
|
print(f"\n❌ 测试失败: {e}")
|
|
logger.error(f"测试失败: {e}", exc_info=True)
|
|
|
|
|
|
async def test_full_flow():
|
|
"""测试完整翻译流程"""
|
|
|
|
print("\n" + "=" * 60)
|
|
print("🧪 测试完整翻译流程(测试模式)")
|
|
print("=" * 60)
|
|
|
|
try:
|
|
config = load_config()
|
|
|
|
# 查找测试EPUB
|
|
test_files = list(Path(".").glob("*.epub"))
|
|
if not test_files:
|
|
print("❌ 未找到测试EPUB文件")
|
|
return
|
|
|
|
test_epub = test_files[0]
|
|
|
|
# 创建翻译器
|
|
translator = EPUBTranslator(config, use_cache=True)
|
|
|
|
# 运行测试模式
|
|
result = await translator.translate_epub(str(test_epub), test_mode=True)
|
|
|
|
if result.get('status') == 'success':
|
|
print(f"\n✅ 测试模式成功")
|
|
print(f" 测试段落数: {result.get('tested_paragraphs', 0)}")
|
|
else:
|
|
print(f"\n❌ 测试模式失败: {result.get('error', '未知错误')}")
|
|
|
|
except Exception as e:
|
|
print(f"\n❌ 测试失败: {e}")
|
|
logger.error(f"测试失败: {e}", exc_info=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# 配置日志
|
|
logger.remove()
|
|
logger.add(
|
|
sys.stdout,
|
|
level="INFO",
|
|
format="<green>{time:HH:mm:ss}</green> | <level>{level}</level> | {message}"
|
|
)
|
|
|
|
print("\n🔧 EPUB翻译器 - 全局编号系统验证")
|
|
print("=" * 60)
|
|
|
|
# 运行测试
|
|
asyncio.run(test_global_id_system())
|
|
asyncio.run(test_full_flow())
|
|
|
|
print("\n" + "=" * 60)
|
|
print("📋 验证总结:")
|
|
print("1. ✅ 全局唯一ID系统")
|
|
print("2. ✅ 智能分块(不切断段落)")
|
|
print("3. ✅ 带编号的LLM翻译")
|
|
print("4. ✅ 精确的ID到翻译映射")
|
|
print("5. ✅ 统计信息完整")
|
|
print("\n🚀 系统已准备就绪,可以开始正式翻译!")
|