Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71f0e7f545 | ||
|
|
895fddd85e | ||
|
|
5a59e4d543 | ||
|
|
b51abf2249 | ||
|
|
6d3f9ff15a | ||
|
|
5d1d1a712b | ||
|
|
6d5f8133e0 | ||
|
|
13018d3d5c |
@@ -22,6 +22,8 @@ stages:
|
|||||||
python.version: "3.7"
|
python.version: "3.7"
|
||||||
Python38:
|
Python38:
|
||||||
python.version: "3.8"
|
python.version: "3.8"
|
||||||
|
Python39:
|
||||||
|
python.version: "3.9"
|
||||||
steps:
|
steps:
|
||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
inputs:
|
inputs:
|
||||||
@@ -59,6 +61,8 @@ stages:
|
|||||||
python.version: "3.7"
|
python.version: "3.7"
|
||||||
Python38:
|
Python38:
|
||||||
python.version: "3.8"
|
python.version: "3.8"
|
||||||
|
Python39:
|
||||||
|
python.version: "3.9"
|
||||||
steps:
|
steps:
|
||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
inputs:
|
inputs:
|
||||||
|
|||||||
+11
-10
@@ -20,7 +20,8 @@ and largely have the same functions.
|
|||||||
|
|
||||||
import ocrmypdf
|
import ocrmypdf
|
||||||
|
|
||||||
ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True)
|
if __name__ == '__main__': # To ensure correct behavior on Windows
|
||||||
|
ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True)
|
||||||
|
|
||||||
With a few exceptions, all of the command line arguments are available
|
With a few exceptions, all of the command line arguments are available
|
||||||
and may be passed as equivalent keywords.
|
and may be passed as equivalent keywords.
|
||||||
@@ -35,8 +36,9 @@ The :func:`ocrmypdf.ocr` function runs OCRmyPDF similar to command line
|
|||||||
execution. To do this, it will:
|
execution. To do this, it will:
|
||||||
|
|
||||||
- create a monitoring thread
|
- create a monitoring thread
|
||||||
- create worker processes (forking itself)
|
- create worker processes (on Linux, forking itself; on Windows and macOS, by
|
||||||
- manage the signal flags of worker processes
|
spawning)
|
||||||
|
- manage the signal flags of its worker processes
|
||||||
- execute other subprocesses (forking and executing other programs)
|
- execute other subprocesses (forking and executing other programs)
|
||||||
|
|
||||||
The Python process that calls ``ocrmypdf.ocr()`` must be sufficiently
|
The Python process that calls ``ocrmypdf.ocr()`` must be sufficiently
|
||||||
@@ -47,9 +49,9 @@ There is no currently no option to manage how jobs are scheduled other
|
|||||||
than the argument ``jobs=`` which will limit the number of worker
|
than the argument ``jobs=`` which will limit the number of worker
|
||||||
processes.
|
processes.
|
||||||
|
|
||||||
Forking a child process to call ``ocrmypdf.ocr()`` is suggested. That
|
Creating a child process to call ``ocrmypdf.ocr()`` is suggested. That
|
||||||
way your application will survive and remain interactive even if
|
way your application will survive and remain interactive even if
|
||||||
OCRmyPDF does not.
|
OCRmyPDF fails for any reason.
|
||||||
|
|
||||||
Programs that call ``ocrmypdf.ocr()`` should also install a SIGBUS signal
|
Programs that call ``ocrmypdf.ocr()`` should also install a SIGBUS signal
|
||||||
handler (except on Windows), to raise an exception if access to a memory
|
handler (except on Windows), to raise an exception if access to a memory
|
||||||
@@ -57,11 +59,10 @@ mapped file fails. OCRmyPDF may use memory mapping.
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
On Windows, the script that calls ``ocrmypdf.ocr()`` must be protected
|
On Windows and macOS, the script that calls ``ocrmypdf.ocr()`` must be
|
||||||
by an "ifmain" guard (``if __name__ == '__main__'``) or you must use
|
protected by an "ifmain" guard (``if __name__ == '__main__'``). If you do
|
||||||
``ocrmypdf.ocr(...use_threads=True)``. If you do not take at least one
|
not take at least one of these steps, process semantics will prevent
|
||||||
of these steps, Windows process semantics will prevent OCRmyPDF from working
|
OCRmyPDF from working correctly.
|
||||||
correctly.
|
|
||||||
|
|
||||||
Logging
|
Logging
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ may be unreliable. Use the API to depend on precise behavior.
|
|||||||
The public API may be useful in scripts that launch OCRmyPDF processes or that
|
The public API may be useful in scripts that launch OCRmyPDF processes or that
|
||||||
wish to use some of its features for working with PDFs.
|
wish to use some of its features for working with PDFs.
|
||||||
|
|
||||||
|
v11.3.3
|
||||||
|
=======
|
||||||
|
|
||||||
|
- If unpaper outputs non-UTF-8 data, quietly fix this rather than choke on the
|
||||||
|
conversion. (Possibly addresses #671.)
|
||||||
|
|
||||||
v11.3.2
|
v11.3.2
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
@@ -99,9 +99,7 @@ def get_languages():
|
|||||||
|
|
||||||
args_tess = ['tesseract', '--list-langs']
|
args_tess = ['tesseract', '--list-langs']
|
||||||
try:
|
try:
|
||||||
proc = run(
|
proc = run(args_tess, text=True, stdout=PIPE, stderr=STDOUT, check=True)
|
||||||
args_tess, universal_newlines=True, stdout=PIPE, stderr=STDOUT, check=True
|
|
||||||
)
|
|
||||||
output = proc.stdout
|
output = proc.stdout
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
raise MissingDependencyError(lang_error(e.output)) from e
|
raise MissingDependencyError(lang_error(e.output)) from e
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ def run(input_file, output_file, dpi, mode_args):
|
|||||||
args_unpaper,
|
args_unpaper,
|
||||||
close_fds=True,
|
close_fds=True,
|
||||||
check=True,
|
check=True,
|
||||||
universal_newlines=True,
|
|
||||||
stderr=STDOUT, # unpaper writes logging output to stdout and stderr
|
stderr=STDOUT, # unpaper writes logging output to stdout and stderr
|
||||||
stdout=PIPE, # and cannot send file output to stdout
|
stdout=PIPE, # and cannot send file output to stdout
|
||||||
cwd=tmpdir,
|
cwd=tmpdir,
|
||||||
|
|||||||
+9
-9
@@ -299,18 +299,18 @@ def ocr( # pylint: disable=unused-argument
|
|||||||
else:
|
else:
|
||||||
plugins = list(plugins)
|
plugins = list(plugins)
|
||||||
|
|
||||||
parser = get_parser()
|
# No new variable names should be assigned until these two steps are run
|
||||||
_plugin_manager = get_plugin_manager(plugins)
|
create_options_kwargs = {k: v for k, v in locals().items() if k != 'kwargs'}
|
||||||
_plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member
|
|
||||||
|
|
||||||
create_options_kwargs = {
|
|
||||||
k: v for k, v in locals().items() if not k.startswith('_') and k != 'kwargs'
|
|
||||||
}
|
|
||||||
create_options_kwargs.update(kwargs)
|
create_options_kwargs.update(kwargs)
|
||||||
|
|
||||||
|
parser = get_parser()
|
||||||
|
create_options_kwargs['parser'] = parser
|
||||||
|
plugin_manager = get_plugin_manager(plugins)
|
||||||
|
plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member
|
||||||
|
|
||||||
if 'verbose' in kwargs:
|
if 'verbose' in kwargs:
|
||||||
warn("ocrmypdf.ocr(verbose=) is ignored. Use ocrmypdf.configure_logging().")
|
warn("ocrmypdf.ocr(verbose=) is ignored. Use ocrmypdf.configure_logging().")
|
||||||
|
|
||||||
options = create_options(**create_options_kwargs)
|
options = create_options(**create_options_kwargs)
|
||||||
check_options(options, _plugin_manager)
|
check_options(options, plugin_manager)
|
||||||
return run_pipeline(options=options, plugin_manager=_plugin_manager, api=True)
|
return run_pipeline(options=options, plugin_manager=plugin_manager, api=True)
|
||||||
|
|||||||
@@ -52,10 +52,15 @@ def run(args, *, env=None, logs_errors_to_stdout=False, **kwargs):
|
|||||||
|
|
||||||
log.debug("Running: %s", args)
|
log.debug("Running: %s", args)
|
||||||
process_log = log.getChild(os.path.basename(program))
|
process_log = log.getChild(os.path.basename(program))
|
||||||
if sys.version_info < (3, 7) and os.name == 'nt':
|
if sys.version_info < (3, 7):
|
||||||
# Can't use close_fds=True on Windows with Python 3.6 or older
|
if os.name == 'nt':
|
||||||
# https://bugs.python.org/issue19575, etc.
|
# Can't use close_fds=True on Windows with Python 3.6 or older
|
||||||
kwargs['close_fds'] = False
|
# https://bugs.python.org/issue19575, etc.
|
||||||
|
kwargs['close_fds'] = False
|
||||||
|
if 'text' in kwargs:
|
||||||
|
# Convert run(...text=) to run(...universal_newlines=) for Python 3.6
|
||||||
|
kwargs['universal_newlines'] = kwargs['text']
|
||||||
|
del kwargs['text']
|
||||||
|
|
||||||
stderr = None
|
stderr = None
|
||||||
stderr_name = 'stderr' if not logs_errors_to_stdout else 'stdout'
|
stderr_name = 'stderr' if not logs_errors_to_stdout else 'stdout'
|
||||||
@@ -119,7 +124,7 @@ def get_version(
|
|||||||
proc = run(
|
proc = run(
|
||||||
args_prog,
|
args_prog,
|
||||||
close_fds=True,
|
close_fds=True,
|
||||||
universal_newlines=True,
|
text=True,
|
||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
stderr=STDOUT,
|
stderr=STDOUT,
|
||||||
check=True,
|
check=True,
|
||||||
|
|||||||
+2
-2
@@ -128,7 +128,7 @@ def run_ocrmypdf_api(input_file, output_file, *args):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.helpers.register
|
@pytest.helpers.register
|
||||||
def run_ocrmypdf(input_file, output_file, *args, universal_newlines=True):
|
def run_ocrmypdf(input_file, output_file, *args, text=True):
|
||||||
"Run ocrmypdf and let caller deal with results"
|
"Run ocrmypdf and let caller deal with results"
|
||||||
|
|
||||||
p_args = (
|
p_args = (
|
||||||
@@ -151,7 +151,7 @@ def run_ocrmypdf(input_file, output_file, *args, universal_newlines=True):
|
|||||||
p_args,
|
p_args,
|
||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
stderr=PIPE,
|
stderr=PIPE,
|
||||||
universal_newlines=universal_newlines,
|
universal_newlines=text, # When dropping support for Python 3.6 change to text=
|
||||||
env=env,
|
env=env,
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -598,7 +598,7 @@ def test_compression_preserved(ocrmypdf_exec, resources, image, outpdf):
|
|||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
stderr=PIPE,
|
stderr=PIPE,
|
||||||
stdin=input_stream,
|
stdin=input_stream,
|
||||||
universal_newlines=True,
|
universal_newlines=True, # When dropping support for Python 3.6 change to text=
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -659,7 +659,7 @@ def test_compression_changed(ocrmypdf_exec, resources, image, compression, outpd
|
|||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
stderr=PIPE,
|
stderr=PIPE,
|
||||||
stdin=input_stream,
|
stdin=input_stream,
|
||||||
universal_newlines=True,
|
universal_newlines=True, # When dropping support for Python 3.6 change to text=
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
assert p.returncode == ExitCode.ok, p.stderr
|
assert p.returncode == ExitCode.ok, p.stderr
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir):
|
|||||||
'--rotate-pages',
|
'--rotate-pages',
|
||||||
'--rotate-pages-threshold',
|
'--rotate-pages-threshold',
|
||||||
'0.001',
|
'0.001',
|
||||||
universal_newlines=False,
|
text=False,
|
||||||
)
|
)
|
||||||
err = err.decode('utf-8', errors='replace')
|
err = err.decode('utf-8', errors='replace')
|
||||||
assert p.returncode == 0, err
|
assert p.returncode == 0, err
|
||||||
|
|||||||
Reference in New Issue
Block a user