This commit is contained in:
2026-10-25 10:30:22 +08:00
parent 38894ba80c
commit ae84347912
11 changed files with 287 additions and 12 deletions

View File

@@ -6,7 +6,7 @@ import logging
import threading
from dataclasses import dataclass
from .ai_tutor import AITutor, AITutorError
from .ai_tutor import AITutor, AITutorError, translation_needs_repair
from .models import (
AdminSubtitleTranslationResponse,
SentenceBoundaryDocument,
@@ -133,6 +133,23 @@ class SubtitleTranslationService:
video_hash,
)
def repair_missing(self, video_hash: str) -> AdminSubtitleTranslationResponse:
"""Re-translate missing or still-English sentences, keeping good Chinese."""
if self.repository.get_video(video_hash) is None:
raise KeyError(video_hash)
document = self.repository.get_document(video_hash)
if document is None:
raise KeyError(video_hash)
missing = missing_translation_indexes(document)
if missing:
self.invalidate(video_hash)
self.repository.clear_sentence_translations(video_hash, missing)
snapshot = self.ensure(video_hash)
else:
snapshot = self.snapshot(document)
result = self._with_terms(snapshot)
return result.model_copy(update={"attempted_count": len(missing)})
def admin_snapshot(self, video_hash: str) -> AdminSubtitleTranslationResponse | None:
current = self.current(video_hash)
if current is None:
@@ -157,8 +174,12 @@ class SubtitleTranslationService:
TranslationTerm(source=source, zh=zh)
for source, zh in self.repository.get_translation_glossary(snapshot.video_hash)
]
document = self.repository.get_document(snapshot.video_hash)
missing_count = 0 if document is None else len(missing_translation_indexes(document))
payload = snapshot.model_dump()
payload["terms"] = terms
payload["missing_count"] = missing_count
payload["attempted_count"] = 0
return AdminSubtitleTranslationResponse(**payload)
def ensure_from_local(self, document: SentenceBoundaryDocument) -> SubtitleTranslationResponse:
@@ -275,3 +296,11 @@ class SubtitleTranslationService:
with job.lock:
job.running = False
job.done.set()
def missing_translation_indexes(document: SentenceBoundaryDocument) -> list[int]:
return [
sentence.index
for sentence in document.sentences
if translation_needs_repair(sentence.text, sentence.zh_text)
]