Change most tests to use ocrmypdf API instead of subprocess

The main benefit of this is code coverage gains can actually follow it.
Also removes most ugly os.environ hacks.
This commit is contained in:
James R. Barlow
2019-06-03 01:45:27 -07:00
parent 98a3fda1f5
commit eb5200d26a
18 changed files with 131 additions and 40 deletions
+2 -1
View File
@@ -28,7 +28,7 @@ from collections.abc import Mapping
log = logging.Logger(__name__)
def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)'):
def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)', env=None):
"Get the version of the specified program"
args_prog = [program, version_arg]
try:
@@ -39,6 +39,7 @@ def get_version(program, *, version_arg='--version', regex=r'(\d+(\.\d+)*)'):
stdout=PIPE,
stderr=STDOUT,
check=True,
env=env,
)
output = proc.stdout
except FileNotFoundError as e:
+54 -18
View File
@@ -60,18 +60,16 @@ HOCR_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
"""
@lru_cache(maxsize=1)
def version():
return get_version('tesseract', regex=r'tesseract\s(.+)')
def version(tesseract_env=None):
return get_version('tesseract', regex=r'tesseract\s(.+)', env=tesseract_env)
def v4():
def v4(tesseract_env=None):
"Is this Tesseract v4.0?"
return version() >= '4'
return version(tesseract_env) >= '4'
@lru_cache(maxsize=1)
def has_textonly_pdf():
def has_textonly_pdf(tesseract_env=None):
"""Does Tesseract have textonly_pdf capability?
Available in v4.00.00alpha since January 2017. Best to
@@ -80,7 +78,15 @@ def has_textonly_pdf():
args_tess = ['tesseract', '--print-parameters', 'pdf']
params = ''
try:
params = check_output(args_tess, universal_newlines=True, stderr=STDOUT)
proc = run(
args_tess,
check=True,
universal_newlines=True,
stdout=PIPE,
stderr=STDOUT,
env=tesseract_env,
)
params = proc.stdout
except CalledProcessError as e:
print("Could not --print-parameters from tesseract", file=sys.stderr)
raise MissingDependencyError from e
@@ -89,8 +95,7 @@ def has_textonly_pdf():
return False
@lru_cache(maxsize=1)
def languages():
def languages(tesseract_env=None):
def lang_error(output):
msg = dedent(
"""Tesseract failed to report available languages.
@@ -104,7 +109,12 @@ def languages():
args_tess = ['tesseract', '--list-langs']
try:
proc = run(
args_tess, universal_newlines=True, stdout=PIPE, stderr=STDOUT, check=True
args_tess,
universal_newlines=True,
stdout=PIPE,
stderr=STDOUT,
check=True,
env=tesseract_env,
)
output = proc.stdout
except CalledProcessError as e:
@@ -127,7 +137,7 @@ def tess_base_args(langs, engine_mode):
return args
def get_orientation(input_file, engine_mode, timeout: float, log):
def get_orientation(input_file, engine_mode, timeout: float, log, tesseract_env=None):
args_tesseract = tess_base_args(['osd'], engine_mode) + [
'--psm',
'0',
@@ -136,7 +146,15 @@ def get_orientation(input_file, engine_mode, timeout: float, log):
]
try:
stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout)
p = run(
args_tesseract,
stdout=PIPE,
stderr=STDOUT,
timeout=timeout,
check=True,
env=tesseract_env,
)
stdout = p.stdout
except TimeoutExpired:
return OrientationConfidence(angle=0, confidence=0.0)
except CalledProcessError as e:
@@ -235,6 +253,7 @@ def generate_hocr(
pagesegmode: int,
user_words,
user_patterns,
tesseract_env,
log,
):
@@ -258,7 +277,15 @@ def generate_hocr(
args_tesseract.extend([input_file, prefix, 'hocr', 'txt'] + tessconfig)
try:
log.debug(args_tesseract)
stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout)
p = run(
args_tesseract,
stdout=PIPE,
stderr=STDOUT,
timeout=timeout,
check=True,
env=tesseract_env,
)
stdout = p.stdout
except TimeoutExpired:
# Generate a HOCR file with no recognized text if tesseract times out
# Temporary workaround to hocrTransform not being able to function if
@@ -310,9 +337,10 @@ def generate_pdf(
pagesegmode: int,
user_words,
user_patterns,
tesseract_env,
log,
):
'''Use Tesseract to render a PDF.
"""Use Tesseract to render a PDF.
input_image -- image to analyze
skip_pdf -- if we time out, use this file as output
@@ -324,14 +352,14 @@ def generate_pdf(
tessconfig -- tesseract configuration
timeout -- timeout (seconds)
log -- logger object
'''
"""
args_tesseract = tess_base_args(language, engine_mode)
if pagesegmode is not None:
args_tesseract.extend(['--psm', str(pagesegmode)])
if text_only and has_textonly_pdf():
if text_only and has_textonly_pdf(tesseract_env):
args_tesseract.extend(['-c', 'textonly_pdf=1'])
if user_words:
@@ -348,7 +376,15 @@ def generate_pdf(
args_tesseract.extend([input_image, prefix, 'pdf', 'txt'] + tessconfig)
try:
log.debug(args_tesseract)
stdout = check_output(args_tesseract, stderr=STDOUT, timeout=timeout)
p = run(
args_tesseract,
stdout=PIPE,
stderr=STDOUT,
timeout=timeout,
check=True,
env=tesseract_env,
)
stdout = p.stdout
if os.path.exists(prefix + '.txt'):
shutil.move(prefix + '.txt', output_text)
except TimeoutExpired: