216 lines
8.4 KiB
Python
216 lines
8.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
调试和测试脚本
|
|
用于诊断 EPUB 解析问题
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# 添加 src 目录到路径
|
|
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
|
|
|
from src.epub_parser import EPUBParser
|
|
from src.text_processor import TextProcessor
|
|
from src.utils import load_config
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
from rich.panel import Panel
|
|
from bs4 import BeautifulSoup
|
|
import ebooklib
|
|
|
|
|
|
def debug_epub_structure(epub_path: str):
|
|
"""调试 EPUB 结构"""
|
|
console = Console()
|
|
|
|
try:
|
|
# 加载配置
|
|
config = load_config('config/config.json')
|
|
|
|
# 初始化解析器
|
|
parser = EPUBParser(epub_path)
|
|
text_processor = TextProcessor(config)
|
|
|
|
console.print(f"[bold blue]调试 EPUB 文件: {epub_path}[/bold blue]\n")
|
|
|
|
# 显示基本信息
|
|
book_info = parser.get_book_info()
|
|
info_table = Table(title="书籍信息")
|
|
info_table.add_column("属性", style="cyan")
|
|
info_table.add_column("值", style="white")
|
|
|
|
for key, value in book_info.items():
|
|
info_table.add_row(key, str(value))
|
|
|
|
console.print(info_table)
|
|
|
|
# 显示目录结构
|
|
console.print("\n[bold green]目录结构分析:[/bold green]")
|
|
|
|
toc_table = Table(title="目录结构")
|
|
toc_table.add_column("类型", style="cyan")
|
|
toc_table.add_column("标题", style="white")
|
|
toc_table.add_column("状态", style="green")
|
|
|
|
# 检查各种内容类型
|
|
content_types = ['preface', 'introduction', 'prologue', 'abstract', 'epilogue', 'acknowledgments']
|
|
|
|
for content_type in content_types:
|
|
item = parser.toc_structure.get(content_type)
|
|
if item:
|
|
toc_table.add_row(content_type, item['title'], "✓ 找到")
|
|
else:
|
|
toc_table.add_row(content_type, "-", "✗ 未找到")
|
|
|
|
# 章节信息
|
|
chapters = parser.toc_structure['chapters']
|
|
toc_table.add_row("chapters", f"{len(chapters)} 个章节", "✓ 找到" if chapters else "✗ 未找到")
|
|
|
|
console.print(toc_table)
|
|
|
|
# 显示章节列表
|
|
if chapters:
|
|
console.print("\n[bold yellow]章节列表:[/bold yellow]")
|
|
chapter_table = Table()
|
|
chapter_table.add_column("序号", style="cyan")
|
|
chapter_table.add_column("标题", style="white")
|
|
chapter_table.add_column("内容长度", style="green")
|
|
|
|
for i, chapter in enumerate(chapters[:10], 1): # 只显示前10个
|
|
content = parser._extract_item_content(chapter)
|
|
content_length = len(content) if content else 0
|
|
chapter_table.add_row(str(i), chapter['title'], f"{content_length:,} 字符")
|
|
|
|
if len(chapters) > 10:
|
|
chapter_table.add_row("...", f"还有 {len(chapters) - 10} 个章节", "...")
|
|
|
|
console.print(chapter_table)
|
|
|
|
# 测试段落提取
|
|
console.print("\n[bold magenta]段落提取测试:[/bold magenta]")
|
|
|
|
# 选择第一个有内容的项目进行测试
|
|
test_content = None
|
|
test_title = ""
|
|
|
|
# 优先测试序言类内容
|
|
for content_type in ['prologue', 'preface', 'introduction', 'abstract']:
|
|
item = parser.toc_structure.get(content_type)
|
|
if item:
|
|
test_content = parser._extract_item_content(item)
|
|
test_title = f"{content_type}: {item['title']}"
|
|
break
|
|
|
|
# 如果没有序言,测试第一个章节
|
|
if not test_content and chapters:
|
|
test_content = parser._extract_item_content(chapters[0])
|
|
test_title = f"章节: {chapters[0]['title']}"
|
|
|
|
if test_content:
|
|
paragraphs = text_processor.extract_paragraphs(test_content)
|
|
|
|
console.print(f"测试内容: {test_title}")
|
|
console.print(f"原始内容长度: {len(test_content):,} 字符")
|
|
console.print(f"提取段落数: {len(paragraphs)}")
|
|
|
|
if paragraphs:
|
|
# 显示前几个段落
|
|
para_table = Table(title="段落示例")
|
|
para_table.add_column("序号", style="cyan")
|
|
para_table.add_column("类型", style="yellow")
|
|
para_table.add_column("内容预览", style="white")
|
|
para_table.add_column("长度", style="green")
|
|
|
|
for i, para in enumerate(paragraphs[:5], 1):
|
|
preview = para['text'][:100] + "..." if len(para['text']) > 100 else para['text']
|
|
para_table.add_row(
|
|
str(i),
|
|
para.get('type', 'unknown'),
|
|
preview,
|
|
str(len(para['text']))
|
|
)
|
|
|
|
console.print(para_table)
|
|
|
|
# 测试翻译块创建
|
|
chunks = text_processor.create_chunks(paragraphs, 3)
|
|
console.print(f"\n[cyan]翻译块信息:[/cyan] 创建了 {len(chunks)} 个翻译块")
|
|
|
|
if chunks:
|
|
chunk_table = Table(title="翻译块示例")
|
|
chunk_table.add_column("块号", style="cyan")
|
|
chunk_table.add_column("段落数", style="yellow")
|
|
chunk_table.add_column("总字符数", style="green")
|
|
|
|
for i, chunk in enumerate(chunks[:3], 1): # 显示前3个块
|
|
total_chars = sum(len(p['text']) for p in chunk)
|
|
chunk_table.add_row(str(i), str(len(chunk)), f"{total_chars:,}")
|
|
|
|
console.print(chunk_table)
|
|
|
|
else:
|
|
console.print("[red]未能提取到段落![/red]")
|
|
|
|
# 显示原始内容的一部分用于调试
|
|
soup = BeautifulSoup(test_content, 'html.parser')
|
|
text_content = soup.get_text()[:500]
|
|
|
|
console.print(Panel(
|
|
text_content,
|
|
title="原始文本内容(前500字符)",
|
|
border_style="red"
|
|
))
|
|
else:
|
|
console.print("[red]未找到可测试的内容![/red]")
|
|
|
|
# 显示所有 HTML 文件
|
|
console.print("\n[bold cyan]所有 HTML 文件:[/bold cyan]")
|
|
|
|
try:
|
|
html_items = list(parser.book.get_items_of_type(ebooklib.ITEM_DOCUMENT))
|
|
|
|
file_table = Table()
|
|
file_table.add_column("文件名", style="cyan")
|
|
file_table.add_column("大小", style="green")
|
|
file_table.add_column("内容预览", style="white")
|
|
|
|
for item in html_items[:10]: # 只显示前10个
|
|
try:
|
|
content = item.get_content().decode('utf-8', errors='ignore')
|
|
soup = BeautifulSoup(content, 'html.parser')
|
|
text_preview = soup.get_text()[:100].replace('\n', ' ')
|
|
|
|
file_table.add_row(
|
|
item.get_name(),
|
|
f"{len(content):,} 字符",
|
|
text_preview + "..." if len(text_preview) == 100 else text_preview
|
|
)
|
|
except Exception as e:
|
|
file_table.add_row(item.get_name(), "错误", f"读取失败: {e}")
|
|
|
|
if len(html_items) > 10:
|
|
file_table.add_row("...", f"还有 {len(html_items) - 10} 个文件", "...")
|
|
|
|
console.print(file_table)
|
|
|
|
except Exception as e:
|
|
console.print(f"[yellow]无法列出 HTML 文件: {e}[/yellow]")
|
|
|
|
# 总结
|
|
console.print(f"\n[bold green]✓ 调试完成[/bold green]")
|
|
console.print(f"[green]结论: EPUB 文件结构正常,可以进行翻译[/green]")
|
|
|
|
except Exception as e:
|
|
console.print(f"[red]调试失败: {e}[/red]")
|
|
import traceback
|
|
console.print(traceback.format_exc())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 2:
|
|
print("使用方法: python debug.py <epub_file>")
|
|
sys.exit(1)
|
|
|
|
epub_file = sys.argv[1]
|
|
debug_epub_structure(epub_file) |