Compare requested languages to OCR engine instead of tesseract directly

Also refactoring to facilitating validation needing the plugin manager.
This commit is contained in:
James R. Barlow
2020-05-16 01:50:37 -07:00
parent 9af94ac9b7
commit 2bd586e093
8 changed files with 38 additions and 21 deletions
+1 -1
View File
@@ -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
+9 -7
View File
@@ -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
View File
@@ -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):
+6 -2
View File
@@ -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
View File
@@ -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)
+4 -2
View File
@@ -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):
+6 -3
View File
@@ -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