Compare requested languages to OCR engine instead of tesseract directly
Also refactoring to facilitating validation needing the plugin manager.
This commit is contained in:
@@ -58,7 +58,7 @@ def run(args=None):
|
||||
)
|
||||
log.debug('ocrmypdf %s', __version__)
|
||||
try:
|
||||
check_options(options)
|
||||
check_options(options, plugin_manager)
|
||||
except ValueError as e:
|
||||
log.error(e)
|
||||
return ExitCode.bad_args
|
||||
|
||||
@@ -27,6 +27,7 @@ from shutil import copyfileobj
|
||||
|
||||
import PIL
|
||||
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf._unicodefun import verify_python3_env
|
||||
from ocrmypdf.exceptions import (
|
||||
BadArgsError,
|
||||
@@ -72,7 +73,7 @@ def check_platform():
|
||||
)
|
||||
|
||||
|
||||
def check_options_languages(options):
|
||||
def check_options_languages(options, plugin_manager):
|
||||
if not options.language:
|
||||
options.language = [DEFAULT_LANGUAGE]
|
||||
system_lang = locale.getlocale()[0]
|
||||
@@ -84,12 +85,13 @@ def check_options_languages(options):
|
||||
options.language = options.language[0].split('+')
|
||||
|
||||
languages = set(options.language)
|
||||
if not languages.issubset(tesseract.get_languages(options.tesseract_env)):
|
||||
ocr_engine = plugin_manager.hook.get_ocr_engine()
|
||||
if not languages.issubset(ocr_engine.languages(options)):
|
||||
msg = (
|
||||
"The installed version of tesseract does not have language "
|
||||
"data for the following requested languages: \n"
|
||||
f"{ocr_engine} does not have language data for the following "
|
||||
"requested languages: \n"
|
||||
)
|
||||
for lang in languages - tesseract.get_languages(options.tesseract_env):
|
||||
for lang in languages - ocr_engine.languages(options):
|
||||
msg += lang + '\n'
|
||||
raise MissingDependencyError(msg)
|
||||
|
||||
@@ -308,9 +310,9 @@ def check_options_pillow(options):
|
||||
PIL.Image.MAX_IMAGE_PIXELS = None
|
||||
|
||||
|
||||
def check_options(options):
|
||||
def check_options(options, plugin_manager):
|
||||
check_platform()
|
||||
check_options_languages(options)
|
||||
check_options_languages(options, plugin_manager)
|
||||
check_options_metadata(options)
|
||||
check_options_output(options)
|
||||
check_options_sidecar(options)
|
||||
|
||||
+1
-1
@@ -279,5 +279,5 @@ def ocr( # pylint: disable=unused-argument
|
||||
options = create_options(
|
||||
**{k: v for k, v in locals().items() if not k.startswith('_')}
|
||||
)
|
||||
check_options(options)
|
||||
check_options(options, _plugin_manager)
|
||||
return run_pipeline(options=options, plugin_manager=_plugin_manager, api=True)
|
||||
|
||||
@@ -30,9 +30,12 @@ class TesseractOcrEngine(OcrEngine):
|
||||
tag = '-PDF' if options.pdf_renderer == 'sandwich' else ''
|
||||
return f"Tesseract OCR{tag} {TesseractOcrEngine.version()}"
|
||||
|
||||
def __str__(self):
|
||||
return f"Tesseract OCR {TesseractOcrEngine.version()}"
|
||||
|
||||
@staticmethod
|
||||
def languages():
|
||||
return tesseract.get_languages()
|
||||
def languages(options):
|
||||
return tesseract.get_languages(options.tesseract_env)
|
||||
|
||||
@staticmethod
|
||||
def get_orientation(input_file, options):
|
||||
|
||||
@@ -100,11 +100,15 @@ class OcrEngine(ABC):
|
||||
"""Returns the version of the OCR engine."""
|
||||
|
||||
@abstractstaticmethod
|
||||
def creator_tag(options) -> str:
|
||||
def creator_tag(options: Namespace) -> str:
|
||||
"""Returns the creator tag to identify this software's role in creating the PDF."""
|
||||
|
||||
@abstractstaticmethod
|
||||
def languages() -> AbstractSet[str]:
|
||||
def __str__(self):
|
||||
"""Returns name of OCR engine and version."""
|
||||
|
||||
@abstractstaticmethod
|
||||
def languages(options: Namespace) -> AbstractSet[str]:
|
||||
"""Returns set of languages that are supported."""
|
||||
|
||||
@abstractstaticmethod
|
||||
|
||||
+6
-3
@@ -25,6 +25,7 @@ from subprocess import PIPE, run
|
||||
import pytest
|
||||
|
||||
from ocrmypdf import api, cli, pdfinfo
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf.exec import unpaper
|
||||
|
||||
pytest_plugins = ['helpers_namespace']
|
||||
@@ -217,11 +218,12 @@ def check_ocrmypdf(input_file, output_file, *args, env=None):
|
||||
[str(input_file), str(output_file)]
|
||||
+ [str(arg) for arg in args if arg is not None]
|
||||
)
|
||||
api.check_options(options)
|
||||
plugin_manager = get_plugin_manager(options.plugins)
|
||||
api.check_options(options, plugin_manager)
|
||||
if env:
|
||||
options.tesseract_env = env
|
||||
options.tesseract_env['_OCRMYPDF_TEST_INFILE'] = os.fspath(input_file)
|
||||
result = api.run_pipeline(options, plugin_manager=None, api=True)
|
||||
result = api.run_pipeline(options, plugin_manager=plugin_manager, api=True)
|
||||
|
||||
assert result == 0
|
||||
assert output_file.exists(), "Output file not created"
|
||||
@@ -251,7 +253,8 @@ def run_ocrmypdf_api(input_file, output_file, *args, env=None):
|
||||
if options.tesseract_env:
|
||||
assert all(isinstance(v, (str, bytes)) for v in options.tesseract_env.values())
|
||||
|
||||
api.check_options(options)
|
||||
plugin_manager = get_plugin_manager(options.plugins)
|
||||
api.check_options(options, plugin_manager)
|
||||
return api.run_pipeline(options, plugin_manager=None, api=False)
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf._validation import check_options
|
||||
from ocrmypdf.cli import get_parser
|
||||
from ocrmypdf.exceptions import ExitCode, MissingDependencyError
|
||||
@@ -43,11 +44,12 @@ def test_no_unpaper(resources, no_outpdf):
|
||||
input_ = fspath(resources / "c02-22.pdf")
|
||||
output = fspath(no_outpdf)
|
||||
options = get_parser().parse_args(args=["--clean", input_, output])
|
||||
|
||||
plugin_manager = get_plugin_manager(options.plugins)
|
||||
with patch("ocrmypdf.exec.unpaper.version") as mock_unpaper_version:
|
||||
mock_unpaper_version.side_effect = FileNotFoundError("unpaper")
|
||||
|
||||
with pytest.raises(MissingDependencyError):
|
||||
check_options(options)
|
||||
check_options(options, plugin_manager)
|
||||
|
||||
|
||||
def test_old_unpaper(spoof_unpaper_oldversion, resources, no_outpdf):
|
||||
|
||||
@@ -22,6 +22,7 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
import ocrmypdf._validation as vd
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf.api import create_options
|
||||
from ocrmypdf.cli import get_parser
|
||||
from ocrmypdf.exceptions import BadArgsError, MissingDependencyError
|
||||
@@ -153,8 +154,9 @@ def test_false_action_store_true():
|
||||
@pytest.mark.parametrize('progress_bar', [True, False])
|
||||
def test_no_progress_bar(progress_bar, resources):
|
||||
opts = make_opts(progress_bar=progress_bar, input_file=(resources / 'trivial.pdf'))
|
||||
plugin_manager = get_plugin_manager(opts.plugins)
|
||||
with patch('ocrmypdf._concurrent.tqdm', autospec=True) as tqdmpatch:
|
||||
vd.check_options(opts)
|
||||
vd.check_options(opts, plugin_manager)
|
||||
pdfinfo = PdfInfo(opts.input_file, progbar=opts.progress_bar)
|
||||
assert pdfinfo is not None
|
||||
assert tqdmpatch.called
|
||||
@@ -164,11 +166,12 @@ def test_no_progress_bar(progress_bar, resources):
|
||||
|
||||
def test_language_warning(caplog):
|
||||
opts = make_opts(language=None)
|
||||
plugin_manager = get_plugin_manager(opts.plugins)
|
||||
caplog.set_level(logging.DEBUG)
|
||||
with patch(
|
||||
'ocrmypdf._validation.locale.getlocale', return_value=('en_US', 'UTF-8')
|
||||
):
|
||||
vd.check_options_languages(opts)
|
||||
vd.check_options_languages(opts, plugin_manager)
|
||||
assert opts.language == ['eng']
|
||||
assert '' in caplog.text
|
||||
|
||||
@@ -176,7 +179,7 @@ def test_language_warning(caplog):
|
||||
with patch(
|
||||
'ocrmypdf._validation.locale.getlocale', return_value=('fr_FR', 'UTF-8')
|
||||
):
|
||||
vd.check_options_languages(opts)
|
||||
vd.check_options_languages(opts, plugin_manager)
|
||||
assert opts.language == ['eng']
|
||||
assert 'assuming --language' in caplog.text
|
||||
|
||||
|
||||
Reference in New Issue
Block a user