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:
+26
-9
@@ -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())
|
||||
|
||||
@@ -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:])
|
||||
|
||||
Reference in New Issue
Block a user