From a0f9ca3a30d3de8b3b4f555985f2fd5decee0d7f Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Mon, 25 May 2020 01:31:46 -0700 Subject: [PATCH] Move Tesseract options validation into plugin --- src/ocrmypdf/_sync.py | 2 - src/ocrmypdf/_validation.py | 31 +------------- src/ocrmypdf/builtin_plugins/tesseract_ocr.py | 41 ++++++++++++++++++- src/ocrmypdf/pluginspec.py | 2 +- tests/test_validation.py | 19 ++++++--- 5 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/ocrmypdf/_sync.py b/src/ocrmypdf/_sync.py index c25bf8e8..87302438 100644 --- a/src/ocrmypdf/_sync.py +++ b/src/ocrmypdf/_sync.py @@ -323,8 +323,6 @@ def run_pipeline(options, *, plugin_manager, api=False): original_filename, start_input_file, work_folder / 'origin.pdf', options ) - plugin_manager.hook.prepare(options=options) - # Gather pdfinfo and create context pdfinfo = get_pdfinfo( origin_pdf, diff --git a/src/ocrmypdf/_validation.py b/src/ocrmypdf/_validation.py index bfd52e69..785ca13a 100644 --- a/src/ocrmypdf/_validation.py +++ b/src/ocrmypdf/_validation.py @@ -123,18 +123,6 @@ def check_options_output(options): msg += f"Found Ghostscript {ghostscript.version()}" log.warning(msg) - # Decide on what renderer to use - if options.pdf_renderer == 'auto': - options.pdf_renderer = 'sandwich' - - if options.pdf_renderer == 'sandwich' and not tesseract.has_textonly_pdf( - options.tesseract_env, languages - ): - raise MissingDependencyError( - "You are using an alpha version of Tesseract 4.0 that does not support " - "the textonly_pdf parameter. We don't support versions this old." - ) - if options.output_type == 'pdfa': options.output_type = 'pdfa-2' @@ -277,18 +265,6 @@ def check_options_advanced(options): "--pdfa-image-compression argument has no effect when " "--output-type is not 'pdfa', 'pdfa-1', or 'pdfa-2'" ) - if not tesseract.has_user_words(options.tesseract_env) and ( - options.user_words or options.user_patterns - ): - log.warning( - "Tesseract 4.0 ignores --user-words and --user-patterns, so these " - "arguments have no effect." - ) - if options.tesseract_pagesegmode in (0, 2): - log.warning( - "The --tesseract-pagesegmode argument you select will disable OCR. " - "This may cause processing to fail." - ) def check_options_metadata(options): @@ -322,6 +298,7 @@ def check_options(options, plugin_manager): check_options_advanced(options) check_options_pillow(options) check_dependency_versions(options) + plugin_manager.hook.check_options(options=options) def check_closed_streams(options): # pragma: no cover @@ -464,12 +441,6 @@ def report_output_file_size(options, input_file, output_file): def check_dependency_versions(options): - check_external_program( - program='tesseract', - package={'linux': 'tesseract-ocr'}, - version_checker=tesseract.version, - need_version='4.0.0', # using backport for Travis CI - ) check_external_program( program='gs', package='ghostscript', diff --git a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py index ee97845b..41cc830a 100644 --- a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py +++ b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py @@ -15,11 +15,16 @@ # You should have received a copy of the GNU General Public License # along with OCRmyPDF. If not, see . +import logging + from ocrmypdf import hookimpl from ocrmypdf.cli import numeric -from ocrmypdf.exec import tesseract +from ocrmypdf.exceptions import MissingDependencyError +from ocrmypdf.exec import check_external_program, tesseract from ocrmypdf.pluginspec import OcrEngine +log = logging.getLogger(__name__) + @hookimpl def add_options(parser): @@ -76,6 +81,40 @@ def add_options(parser): ) +@hookimpl +def check_options(options): + check_external_program( + program='tesseract', + package={'linux': 'tesseract-ocr'}, + version_checker=tesseract.version, + need_version='4.0.0', # using backport for Travis CI + ) + + # Decide on what renderer to use + if options.pdf_renderer == 'auto': + options.pdf_renderer = 'sandwich' + + if options.pdf_renderer == 'sandwich' and not tesseract.has_textonly_pdf( + options.tesseract_env, set(options.language) + ): + raise MissingDependencyError( + "You are using an alpha version of Tesseract 4.0 that does not support " + "the textonly_pdf parameter. We don't support versions this old." + ) + if not tesseract.has_user_words(options.tesseract_env) and ( + options.user_words or options.user_patterns + ): + log.warning( + "Tesseract 4.0 ignores --user-words and --user-patterns, so these " + "arguments have no effect." + ) + if options.tesseract_pagesegmode in (0, 2): + log.warning( + "The --tesseract-pagesegmode argument you select will disable OCR. " + "This may cause processing to fail." + ) + + class TesseractOcrEngine(OcrEngine): @staticmethod def version(): diff --git a/src/ocrmypdf/pluginspec.py b/src/ocrmypdf/pluginspec.py index 5e0a4f88..432b1946 100644 --- a/src/ocrmypdf/pluginspec.py +++ b/src/ocrmypdf/pluginspec.py @@ -39,7 +39,7 @@ def add_options(parser: ArgumentParser) -> None: @hookspec -def prepare(options: Namespace) -> None: +def check_options(options: Namespace) -> None: """Called to notify a plugin that a file will be processed. The plugin may modify the *options*. All objects that are in options must diff --git a/tests/test_validation.py b/tests/test_validation.py index 857dbda0..babc301d 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -69,7 +69,8 @@ def test_old_tesseract_error(): with patch('ocrmypdf.exec.tesseract.has_textonly_pdf', return_value=False): with pytest.raises(MissingDependencyError): opts = make_opts(pdf_renderer='sandwich', language='eng') - vd.check_options_output(opts) + plugin_manager = get_plugin_manager(opts.plugins) + vd.check_options(opts, plugin_manager) def test_lossless_redo(): @@ -96,12 +97,17 @@ def test_optimizing(caplog): def test_user_words(caplog): - with patch('ocrmypdf.exec.tesseract.version', return_value='4.0.0'): - vd.check_options_advanced(make_opts(user_words='foo')) + + with patch('ocrmypdf.exec.tesseract.has_user_words', return_value=False): + opts = make_opts(user_words='foo') + plugin_manager = get_plugin_manager(opts.plugins) + vd.check_options(opts, plugin_manager) assert '4.0 ignores --user-words' in caplog.text caplog.clear() - with patch('ocrmypdf.exec.tesseract.version', return_value='4.1.0'): - vd.check_options_advanced(make_opts(user_patterns='foo')) + with patch('ocrmypdf.exec.tesseract.has_user_words', return_value=True): + opts = make_opts(user_patterns='foo') + plugin_manager = get_plugin_manager(opts.plugins) + vd.check_options(opts, plugin_manager) assert '4.0 ignores --user-words' not in caplog.text @@ -223,5 +229,6 @@ def test_version_comparison(): def test_pagesegmode_warning(caplog): opts = make_opts(tesseract_pagesegmode='0') - vd.check_options_advanced(opts) + plugin_manager = get_plugin_manager(opts.plugins) + vd.check_options(opts, plugin_manager) assert 'disable OCR' in caplog.text