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:
@@ -344,7 +344,10 @@ class TestEnsureOCRLanguagesFromSettings:
|
||||
assert result == {"tesseract_missing": [], "easyocr_failed": []}
|
||||
|
||||
def test_runs_easyocr_check_when_provider_active(self):
|
||||
"""Calls ensure_easyocr_models when 'easyocr' is in ocr_providers."""
|
||||
"""Calls ensure_easyocr_models when 'easyocr' is in ocr_providers.
|
||||
|
||||
When ocrmypdf is absent, only easyocr language checks run.
|
||||
"""
|
||||
from app.utils.ocr_language_manager import ensure_ocr_languages_from_settings
|
||||
|
||||
mock_settings = self._mock_settings(providers="easyocr", easyocr_langs="en,de")
|
||||
@@ -352,6 +355,7 @@ class TestEnsureOCRLanguagesFromSettings:
|
||||
patch("app.utils.ocr_language_manager.ensure_tesseract_languages", return_value=[]) as mock_tess,
|
||||
patch("app.utils.ocr_language_manager.ensure_easyocr_models", return_value=[]) as mock_easy,
|
||||
patch("app.config.settings", mock_settings),
|
||||
patch("shutil.which", return_value=None),
|
||||
):
|
||||
result = ensure_ocr_languages_from_settings()
|
||||
|
||||
@@ -359,8 +363,8 @@ class TestEnsureOCRLanguagesFromSettings:
|
||||
mock_easy.assert_called_once_with(["en", "de"])
|
||||
assert result["easyocr_failed"] == []
|
||||
|
||||
def test_skips_both_when_only_azure(self):
|
||||
"""Neither Tesseract nor EasyOCR checks run when only Azure is configured."""
|
||||
def test_skips_both_when_only_azure_and_no_ocrmypdf(self):
|
||||
"""Neither Tesseract nor EasyOCR checks run when only Azure is configured and ocrmypdf is absent."""
|
||||
from app.utils.ocr_language_manager import ensure_ocr_languages_from_settings
|
||||
|
||||
mock_settings = self._mock_settings(providers="azure")
|
||||
@@ -368,6 +372,7 @@ class TestEnsureOCRLanguagesFromSettings:
|
||||
patch("app.utils.ocr_language_manager.ensure_tesseract_languages") as mock_tess,
|
||||
patch("app.utils.ocr_language_manager.ensure_easyocr_models") as mock_easy,
|
||||
patch("app.config.settings", mock_settings),
|
||||
patch("shutil.which", return_value=None),
|
||||
):
|
||||
result = ensure_ocr_languages_from_settings()
|
||||
|
||||
@@ -375,6 +380,27 @@ class TestEnsureOCRLanguagesFromSettings:
|
||||
mock_easy.assert_not_called()
|
||||
assert result == {"tesseract_missing": [], "easyocr_failed": []}
|
||||
|
||||
def test_runs_tesseract_when_ocrmypdf_available_with_non_tesseract_provider(self):
|
||||
"""Tesseract language check runs when ocrmypdf is on PATH even without the tesseract provider.
|
||||
|
||||
embed_text_layer() uses ocrmypdf internally regardless of the active OCR
|
||||
provider. Pre-downloading language data on startup prevents code-3 failures.
|
||||
"""
|
||||
from app.utils.ocr_language_manager import ensure_ocr_languages_from_settings
|
||||
|
||||
mock_settings = self._mock_settings(providers="azure", tesseract_lang="eng+deu+fra")
|
||||
with (
|
||||
patch("app.utils.ocr_language_manager.ensure_tesseract_languages", return_value=[]) as mock_tess,
|
||||
patch("app.utils.ocr_language_manager.ensure_easyocr_models") as mock_easy,
|
||||
patch("app.config.settings", mock_settings),
|
||||
patch("shutil.which", return_value="/usr/local/bin/ocrmypdf"),
|
||||
):
|
||||
result = ensure_ocr_languages_from_settings()
|
||||
|
||||
mock_tess.assert_called_once_with("eng+deu+fra")
|
||||
mock_easy.assert_not_called()
|
||||
assert result == {"tesseract_missing": [], "easyocr_failed": []}
|
||||
|
||||
def test_runs_both_when_both_providers_active(self):
|
||||
"""Both checks run when both 'tesseract' and 'easyocr' are in ocr_providers."""
|
||||
from app.utils.ocr_language_manager import ensure_ocr_languages_from_settings
|
||||
|
||||
Reference in New Issue
Block a user