Improve EPUB restoration, book terminology and Calibre QA workflow
This commit is contained in:
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from src.translation.translator_engine import Translator
|
||||
from src.translation.glossary import prepare_glossary
|
||||
from src.translation.llm_client import LLMClient
|
||||
from src.translation.manifest_manager import ManifestManager
|
||||
from src.preprocessing.profiler import BookProfiler
|
||||
@@ -60,6 +61,7 @@ async def run_translate(args):
|
||||
logger.error("OPENAI_API_KEY not found in env or config.")
|
||||
sys.exit(1)
|
||||
|
||||
llm = None
|
||||
try:
|
||||
# Load Manifest
|
||||
manager = ManifestManager(manifest_path)
|
||||
@@ -74,23 +76,34 @@ async def run_translate(args):
|
||||
requests_per_minute=llm_conf.get("requests_per_minute", 60),
|
||||
|
||||
concurrent_requests=llm_conf.get("concurrent_requests", 5),
|
||||
timeout=llm_conf.get("timeout", 180),
|
||||
max_output_tokens=llm_conf.get("max_output_tokens", 16000),
|
||||
chunk_dir=work["chunks"]
|
||||
)
|
||||
|
||||
# Profile
|
||||
profiler = BookProfiler(llm)
|
||||
profiler = BookProfiler(llm, cache_path=work["root"] / "profile.json")
|
||||
profile = await profiler.analyze(manager.entries)
|
||||
logger.info(f"Book Profile: {profile.title} ({profile.genre})")
|
||||
|
||||
# Translate
|
||||
target_chunk_size = trans_conf.get("chunk_size", 4000)
|
||||
concurrent_reqs = llm_conf.get("concurrent_requests", 5)
|
||||
translator = Translator(llm, chunk_size=target_chunk_size, max_concurrent=concurrent_reqs)
|
||||
glossary = await prepare_glossary(
|
||||
manager.entries, llm, work["root"] / "glossary.json",
|
||||
override=getattr(args, 'glossary', None) or trans_conf.get("glossary_path"),
|
||||
auto=trans_conf.get("auto_glossary", True),
|
||||
chunk_chars=trans_conf.get("glossary_scan_chars", 24000))
|
||||
translator = Translator(llm, chunk_size=target_chunk_size, max_concurrent=concurrent_reqs,
|
||||
glossary=glossary, validation_retries=trans_conf.get("validation_retries", 2),
|
||||
on_chunk_complete=manager.save)
|
||||
await translator.translate(manager.entries, profile)
|
||||
|
||||
# Save final state
|
||||
manager.save()
|
||||
await llm.close()
|
||||
if any(not e.translated_text or e.validation_errors for e in manager.entries):
|
||||
raise ValueError("Translation incomplete; inspect manifest validation_errors and resume")
|
||||
|
||||
|
||||
logger.info("Translation complete.")
|
||||
|
||||
@@ -101,10 +114,15 @@ async def run_translate(args):
|
||||
logger.critical(f"Unexpected error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
finally:
|
||||
if llm:
|
||||
await llm.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Step 2: Translation")
|
||||
parser.add_argument("--input-epub", help="Path to original EPUB (to derive book name)")
|
||||
parser.add_argument("--book-name", help="Book name (folder name in work/)")
|
||||
parser.add_argument("--glossary", help="Per-book JSON terminology file")
|
||||
parser.add_argument("--model", default=None, help="LLM Model (overrides config)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
Reference in New Issue
Block a user