fix(ocr): ensure Tesseract language data for embed_text_layer regardless of active OCR provider
Root cause: ensure_ocr_languages_from_settings() only downloaded tessdata when the 'tesseract' provider was active, but embed_text_layer() uses ocrmypdf (which needs tessdata) as a fallback for ALL OCR providers. - embed_text_layer(): call ensure_tesseract_languages(language) after confirming ocrmypdf is on PATH, so language data is present before ocrmypdf is invoked (prevents exit code 3 for fra/deu/etc.) - ensure_ocr_languages_from_settings(): extend the condition from 'tesseract' in active_providers to also trigger when ocrmypdf is on PATH, enabling proactive pre-download at startup for any config - Tests: mock shutil.which and ensure_tesseract_languages in affected test cases; rename azure-only test and add new test for ocrmypdf case Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -279,6 +279,12 @@ def ensure_ocr_languages_from_settings() -> dict[str, list[str]]:
|
||||
present. Missing Tesseract tessdata files are downloaded automatically;
|
||||
missing EasyOCR models are downloaded via the library's built-in mechanism.
|
||||
|
||||
Tesseract language data is always ensured when ``ocrmypdf`` is available on
|
||||
the system, regardless of which OCR providers are active. This is required
|
||||
because :func:`~app.utils.ocr_provider.embed_text_layer` uses ``ocrmypdf``
|
||||
(and therefore Tesseract) as a post-processing fallback for **all** OCR
|
||||
providers – not only the ``tesseract`` provider.
|
||||
|
||||
This function is idempotent – calling it multiple times is safe.
|
||||
|
||||
Returns:
|
||||
@@ -297,7 +303,12 @@ def ensure_ocr_languages_from_settings() -> dict[str, list[str]]:
|
||||
providers_raw = getattr(settings, "ocr_providers", None) or "azure"
|
||||
active_providers = {p.strip().lower() for p in providers_raw.split(",") if p.strip()}
|
||||
|
||||
if "tesseract" in active_providers:
|
||||
# Always ensure Tesseract language data when ocrmypdf is on the system PATH.
|
||||
# embed_text_layer() calls ocrmypdf as a text-layer post-processor for every
|
||||
# OCR provider that does not natively produce a searchable PDF (azure,
|
||||
# easyocr, mistral, google_docai, aws_textract). If the tessdata files are
|
||||
# absent, ocrmypdf exits with code 3 and the text layer is silently skipped.
|
||||
if "tesseract" in active_providers or shutil.which("ocrmypdf") is not None:
|
||||
lang_str = getattr(settings, "tesseract_language", None) or "eng"
|
||||
logger.info("Ensuring Tesseract language data for configured languages: %s", lang_str)
|
||||
result["tesseract_missing"] = ensure_tesseract_languages(lang_str)
|
||||
|
||||
Reference in New Issue
Block a user