Remove plugins (for now)
It's holding up too many other useful, releaseable changes.
This commit is contained in:
@@ -23,7 +23,6 @@ PDF is the best format for storing and exchanging scanned documents. Unfortunat
|
||||
docker
|
||||
advanced
|
||||
api
|
||||
plugins
|
||||
batch
|
||||
security
|
||||
errors
|
||||
|
||||
@@ -27,8 +27,6 @@ next
|
||||
- Added a high level API for applications that want to integrate OCRmyPDF.
|
||||
Special thanks to Martin Wind (@mawi1988) whose made significant contributions
|
||||
to this effort.
|
||||
- Added a simple plugin interface that makes certain steps of the pipeline
|
||||
configurable.
|
||||
- Added progress bars for long-running steps. As such, the behavior of output
|
||||
messages is different.
|
||||
- Dropped the ``ocrmypdf-polyglot`` and ``ocrmypdf-webservice`` images.
|
||||
|
||||
@@ -28,8 +28,6 @@ import pikepdf
|
||||
from pikepdf.models.metadata import encode_pdf_date
|
||||
|
||||
from . import PROGRAM_NAME, VERSION, leptonica
|
||||
|
||||
from ._plugins import load_plugin
|
||||
from .exceptions import (
|
||||
DpiError,
|
||||
EncryptedPdfError,
|
||||
@@ -160,12 +158,6 @@ def validate_pdfinfo_options(context):
|
||||
pdfinfo = context.pdfinfo
|
||||
options = context.options
|
||||
|
||||
if options.plugin_validation:
|
||||
validate = load_plugin(options.plugin_validation)
|
||||
result = validate(context)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
if pdfinfo.needs_rendering:
|
||||
log.error(
|
||||
"This PDF contains dynamic XFA forms created by Adobe LiveCycle "
|
||||
@@ -536,10 +528,6 @@ def create_ocr_image(image, page_context):
|
||||
pix = pix.masked_threshold_on_background_norm()
|
||||
im = pix.topil()
|
||||
|
||||
if options.filter_ocr_image:
|
||||
filt = load_plugin(options.filter_ocr_image)
|
||||
im = filt(im)
|
||||
|
||||
del draw
|
||||
# Pillow requires integer DPI
|
||||
dpi = round(xres), round(yres)
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# © 2019 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This file is part of OCRmyPDF.
|
||||
#
|
||||
# OCRmyPDF is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# OCRmyPDF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OCRmyPDF. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _load_object_from_module(location):
|
||||
"""Load a object given a module location
|
||||
|
||||
For location=a.b.c, will effectively run "from a.b import c"
|
||||
|
||||
Example:
|
||||
_load_object_from_module("a.b.c")
|
||||
|
||||
"""
|
||||
module_parts = location.split('.')
|
||||
module_name = '.'.join(module_parts[:-1])
|
||||
object_name = module_parts[-1]
|
||||
module = importlib.import_module(module_name)
|
||||
obj = getattr(module, object_name)
|
||||
log.debug(f"Loaded object: from {module_name} import {object_name}")
|
||||
return obj
|
||||
|
||||
|
||||
def _load_object_from_pyfile(location):
|
||||
"""Load a object from a file
|
||||
|
||||
Example:
|
||||
_load_object_from_pyfile("test.py::blur_filter")
|
||||
"""
|
||||
filename, object_name = location.split('::', maxsplit=1)
|
||||
log.debug(f"Loading object {object_name} from {filename}")
|
||||
|
||||
module_name = Path(filename).stem
|
||||
spec = importlib.util.spec_from_file_location(module_name, filename)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
obj = getattr(module, object_name)
|
||||
return obj
|
||||
|
||||
|
||||
def load_plugin(plugin):
|
||||
if callable(plugin):
|
||||
return plugin
|
||||
|
||||
if not isinstance(plugin, str):
|
||||
raise TypeError()
|
||||
|
||||
if '::' not in plugin:
|
||||
plugin = _load_object_from_module(plugin)
|
||||
else:
|
||||
plugin = _load_object_from_pyfile(plugin)
|
||||
|
||||
return plugin
|
||||
|
||||
|
||||
def check_plugin_loadable(plugin):
|
||||
load_plugin(plugin)
|
||||
return plugin
|
||||
+1
-8
@@ -122,12 +122,7 @@ def create_options(*, input_file, output_file, **kwargs):
|
||||
for arg, val in kwargs.items():
|
||||
if val is None:
|
||||
continue
|
||||
if (arg.startswith('plugin') or arg.startswith('filter')) and (
|
||||
callable(val) or isinstance(val, str)
|
||||
):
|
||||
deferred.append((arg, val))
|
||||
continue
|
||||
elif arg == 'tesseract_env':
|
||||
if arg == 'tesseract_env':
|
||||
deferred.append((arg, val))
|
||||
continue
|
||||
cmd_style_arg = arg.replace('_', '-')
|
||||
@@ -203,8 +198,6 @@ def ocr( # pylint: disable=unused-argument
|
||||
user_patterns=None,
|
||||
keep_temporary_files=None,
|
||||
progress_bar=None,
|
||||
filter_ocr_image=None,
|
||||
plugin_validation=None,
|
||||
tesseract_env=None,
|
||||
):
|
||||
"""Run OCRmyPDF on one PDF or image.
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
import argparse
|
||||
|
||||
from . import PROGRAM_NAME, VERSION
|
||||
from ._plugins import check_plugin_loadable
|
||||
|
||||
|
||||
def numeric(basetype, min_=None, max_=None):
|
||||
@@ -467,14 +466,6 @@ advanced.add_argument(
|
||||
help="Specify the location of the Tesseract user patterns file.",
|
||||
)
|
||||
|
||||
plugins = parser.add_argument_group("Filters and Plugins", argparse.SUPPRESS)
|
||||
plugins.add_argument(
|
||||
'--filter-ocr-image', help=argparse.SUPPRESS, type=check_plugin_loadable
|
||||
)
|
||||
plugins.add_argument(
|
||||
'--plugin-validation', help=argparse.SUPPRESS, type=check_plugin_loadable
|
||||
)
|
||||
|
||||
debugging = parser.add_argument_group(
|
||||
"Debugging", "Arguments to help with troubleshooting and debugging"
|
||||
)
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
# © 2019 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This file is part of OCRmyPDF.
|
||||
#
|
||||
# OCRmyPDF is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# OCRmyPDF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OCRmyPDF. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
|
||||
from PIL import Image
|
||||
import pytest
|
||||
|
||||
|
||||
import ocrmypdf
|
||||
from ocrmypdf.filters import invert, whiteout
|
||||
from ocrmypdf._plugins import load_plugin
|
||||
|
||||
|
||||
check_ocrmypdf = pytest.helpers.check_ocrmypdf
|
||||
|
||||
|
||||
def filter_42():
|
||||
return 42
|
||||
|
||||
|
||||
def test_pyfile():
|
||||
obj = load_plugin(f'{__file__}::filter_42')
|
||||
assert obj() == 42
|
||||
|
||||
|
||||
def test_pyfile_notexist():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
load_plugin('thisfile.doesnot.exist.py::filter_42')
|
||||
|
||||
|
||||
def test_pyfile_noobject():
|
||||
with pytest.raises(AttributeError):
|
||||
load_plugin(f'{__file__}::no_function_with_this_name')
|
||||
|
||||
|
||||
def test_module():
|
||||
obj = load_plugin(f'os.getuid')
|
||||
assert obj() == os.getuid()
|
||||
|
||||
|
||||
def test_module_notexist():
|
||||
with pytest.raises(ModuleNotFoundError):
|
||||
load_plugin('thismodule.doesnot.exist')
|
||||
|
||||
|
||||
def test_filter_from_cmdline(resources, outdir):
|
||||
(outdir / 'temp.py').write_text(
|
||||
"from PIL import Image\n"
|
||||
"def whiteout(im):\n"
|
||||
" return Image.new(im.mode, im.size)\n"
|
||||
)
|
||||
|
||||
check_ocrmypdf(
|
||||
resources / 'crom.png',
|
||||
outdir / 'out.pdf',
|
||||
'--image-dpi',
|
||||
'100',
|
||||
'--sidecar',
|
||||
outdir / 'sidecar.txt',
|
||||
'--filter-ocr-image',
|
||||
f"{outdir / 'temp.py'}::whiteout",
|
||||
)
|
||||
|
||||
assert (outdir / 'sidecar.txt').read_text().strip() == ''
|
||||
|
||||
|
||||
def test_filter_from_api(resources, outdir):
|
||||
ocrmypdf.ocr(
|
||||
resources / 'crom.png',
|
||||
outdir / 'out.pdf',
|
||||
image_dpi=100,
|
||||
sidecar=outdir / 'sidecar.txt',
|
||||
filter_ocr_image=whiteout,
|
||||
)
|
||||
assert (outdir / 'sidecar.txt').read_text().strip() == ''
|
||||
Reference in New Issue
Block a user