Remove plugins (for now)

It's holding up too many other useful,
releaseable changes.
This commit is contained in:
James R. Barlow
2019-07-27 01:41:14 -07:00
parent 6189910c74
commit f83de20c37
7 changed files with 1 additions and 201 deletions
-1
View File
@@ -23,7 +23,6 @@ PDF is the best format for storing and exchanging scanned documents. Unfortunat
docker
advanced
api
plugins
batch
security
errors
-2
View File
@@ -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.
-12
View File
@@ -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)
-79
View File
@@ -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
View File
@@ -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.
-9
View File
@@ -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"
)
-90
View File
@@ -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() == ''