Fix code, test case: complain when GS fails to produce PDF/A

Modified pipeline to fix regression and return the proper error code if
we did not produce a PDF/A as expected.  The wrapper forces the output
to be PDF 1.3 which is not PDF/A compliant.

The funny thing is that in some cases JHOVE incorrectly states that a
file is PDF/A-1b compliant, well formed and valid, even when it is not
according to Acrobat XI and is missing the PDF/A metadata marker, as
far as I can tell.  JHOVE may not be as beneficial as hoped.
This commit is contained in:
James R. Barlow
2015-08-10 16:05:00 -07:00
parent 8fe54d1a5c
commit 8d848284df
2 changed files with 58 additions and 12 deletions
+26 -9
View File
@@ -758,12 +758,18 @@ def merge_pages(
filter=formatter(),
output=options.output_file,
extras=[_log, _pdfinfo, _pdfinfo_lock])
def validate_pdfa(
def copy_final(
input_file,
output_file,
log,
pdfinfo,
pdfinfo_lock):
shutil.copy(input_file, output_file)
def validate_pdfa(
input_file,
log):
args_jhove = [
'java',
@@ -798,13 +804,7 @@ def validate_pdfa(
re.IGNORECASE | re.MULTILINE):
pdf_is_pdfa = True
if not pdf_is_valid:
log.warning('Output file: The generated PDF/A file is INVALID')
elif pdf_is_valid and not pdf_is_pdfa:
log.warning('Output file: Generated file is a VALID PDF but not PDF/A')
elif pdf_is_valid and pdf_is_pdfa:
log.info('Output file: The generated PDF/A file is VALID')
shutil.copy(input_file, output_file)
return (pdf_is_valid, pdf_is_pdfa)
# @active_if(ocr_required and options.exact_image)
@@ -845,8 +845,25 @@ def available_cpu_count():
def run_pipeline():
if not options.jobs or options.jobs == 1:
options.jobs = available_cpu_count()
cmdline.run(options)
pdf_is_valid, pdf_is_pdfa = validate_pdfa(options.output_file, _log)
returncode = EXIT_OTHER_ERROR # Assume error
if not pdf_is_valid:
_log.warning('Output file: The generated PDF/A file is INVALID')
returncode = EXIT_INVALID_OUTPUT_PDFA
elif pdf_is_valid and not pdf_is_pdfa:
_log.warning('Output file: Generated file is VALID PDF but not PDF/A')
returncode = EXIT_INVALID_OUTPUT_PDFA
elif pdf_is_valid and pdf_is_pdfa:
_log.info('Output file: The generated PDF/A file is VALID')
returncode = 0
return returncode
if __name__ == '__main__':
run_pipeline()
sys.exit(run_pipeline())
+32 -3
View File
@@ -10,7 +10,15 @@ created instead.
It assumes that it is called from a staged system PATH where the first
item on the PATH contains a file named 'gs' which is a symlink to this
file. It will strip out the first item on path to invoke the real
'gs'.
'gs'. That is, it expects this when called
1. tests/output/[...test name...]/bin/gs is a symlink to this file
2. tests/output/bin is the first item on PATH
3. The real executable is on the path
OCRmyPDF also calls "gs --version" and "gs --help". gs answers both
on stdout so, this wrapper prints to stderr.
'''
@@ -21,15 +29,36 @@ def pdfa_param(arg):
return True
if arg.endswith('.ps'):
return True
if 'ColorConversionStrategy' in arg:
return True
if 'ProcessColorModel' in arg:
return True
if 'OutputICCProfile' in arg:
return True
return False
if __name__ == '__main__':
args = [arg for arg in sys.argv[1:]
if not pdfa_param(arg)]
sys_args = sys.argv[1:]
print("Fake Ghostscript wrapper", file=sys.stderr)
if any(pdfa_param(arg) for arg in sys_args):
# We were asked to produce a PDF/A
# Filter out PDF/A arguments
args = [arg for arg in sys.argv[1:]
if not pdfa_param(arg)]
# Tell Ghostscript to create a PDF 1.3 instead so JHOVE won't
# think it's a PDF/A
indexof_pdfwrite = next(n for n, item in enumerate(args)
if 'pdfwrite' in item)
args.insert(indexof_pdfwrite + 1, '-dCompatibilityLevel=1.3')
print("Rewrote arguments", file=sys.stderr)
else:
args = sys_args
print("Keeping arguments", file=sys.stderr)
exec_path = os.environ['PATH'].split(os.pathsep)
env = os.environ.copy()
env['PATH'] = os.pathsep.join(exec_path[1:])