Improve PDF/A validity checking at end
This commit is contained in:
@@ -8,7 +8,7 @@ class ExitCode(IntEnum):
|
||||
bad_args = 1
|
||||
input_file = 2
|
||||
missing_dependency = 3
|
||||
invalid_output_pdfa = 4
|
||||
invalid_output_pdf = 4
|
||||
file_access_error = 5
|
||||
already_done_ocr = 6
|
||||
child_process_error = 7
|
||||
|
||||
+18
-12
@@ -27,7 +27,7 @@ import ruffus.proxy_logger as proxy_logger
|
||||
|
||||
from .hocrtransform import HocrTransform
|
||||
from .pageinfo import pdf_get_all_pageinfo
|
||||
from .pdfa import generate_pdfa_def
|
||||
from .pdfa import generate_pdfa_def, file_claims_pdfa
|
||||
from . import ghostscript
|
||||
from . import tesseract
|
||||
from . import qpdf
|
||||
@@ -127,8 +127,12 @@ parser.add_argument(
|
||||
'--image-dpi', metavar='DPI', type=int,
|
||||
help="for input image instead of PDF, use this DPI instead of file's")
|
||||
parser.add_argument(
|
||||
'--output-type', choices=['pdfa', 'pdf'], default='pdf',
|
||||
help="choose output type")
|
||||
'--output-type', choices=['pdfa', 'pdf'], default='pdfa',
|
||||
help="Choose output type. 'pdfa' creates a PDF/A-2b compliant file for "
|
||||
"long term archiving (default, recommended) but may not suitable "
|
||||
"for users who want their file altered as little as possible. 'pdfa' "
|
||||
"also has problems with full Unicode text. 'pdf' attempts to "
|
||||
"preserve file contents as much as possible.")
|
||||
|
||||
metadata = parser.add_argument_group(
|
||||
"Metadata options",
|
||||
@@ -1220,12 +1224,6 @@ def copy_final(
|
||||
shutil.copy(input_file, output_file)
|
||||
|
||||
|
||||
def validate_pdfa(
|
||||
input_file,
|
||||
log):
|
||||
return qpdf.check(input_file, log)
|
||||
|
||||
|
||||
def available_cpu_count():
|
||||
try:
|
||||
return multiprocessing.cpu_count()
|
||||
@@ -1360,9 +1358,17 @@ def run_pipeline():
|
||||
_log.error(e)
|
||||
return ExitCode.other_error
|
||||
|
||||
if not validate_pdfa(options.output_file, _log):
|
||||
_log.warning('Output file: The generated PDF/A file is INVALID')
|
||||
return ExitCode.invalid_output_pdfa
|
||||
if options.output_type == 'pdfa':
|
||||
pdfa_info = file_claims_pdfa(options.output_file)
|
||||
if pdfa_info['pass']:
|
||||
_log.info(pdfa_info['message'])
|
||||
else:
|
||||
_log.warning(pdfa_info['message'])
|
||||
return ExitCode.invalid_output_pdf
|
||||
|
||||
if not qpdf.check(options.output_file, _log):
|
||||
_log.warning('Output file: The generated PDF is INVALID')
|
||||
return ExitCode.invalid_output_pdf
|
||||
|
||||
with _pdfinfo_lock:
|
||||
_log.debug(_pdfinfo)
|
||||
|
||||
@@ -7,6 +7,7 @@ from __future__ import print_function, absolute_import, division
|
||||
from string import Template
|
||||
import codecs
|
||||
import pkg_resources
|
||||
import PyPDF2 as pypdf
|
||||
|
||||
ICC_PROFILE_RELPATH = 'data/sRGB.icc'
|
||||
|
||||
@@ -108,3 +109,39 @@ def generate_pdfa_def(target_filename, pdfmark, icc='sRGB'):
|
||||
# answer), insist on ascii
|
||||
with open(target_filename, 'w', encoding='ascii') as f:
|
||||
f.write(ps)
|
||||
|
||||
|
||||
def file_claims_pdfa(filename):
|
||||
"""Determines if the file claims to be PDF/A compliant
|
||||
|
||||
Checking if a file is a truly compliant PDF/A is a massive undertaking
|
||||
that no open source tool does properly. Some commercial tools are
|
||||
generally reliable (Acrobat).
|
||||
|
||||
This checks if the XMP metadata contains a PDF/A marker.
|
||||
"""
|
||||
|
||||
pdf = pypdf.PdfFileReader(filename)
|
||||
xmp = pdf.getXmpMetadata()
|
||||
|
||||
pdfa_nodes = xmp.getNodesInNamespace(
|
||||
aboutUri='',
|
||||
namespace='http://www.aiim.org/pdfa/ns/id/')
|
||||
|
||||
pdfa_dict = {attr.localName: attr.value for attr in pdfa_nodes}
|
||||
pdfa_dict['pass'] = False
|
||||
if pdfa_dict:
|
||||
part_conformance = pdfa_dict['part'] + pdfa_dict['conformance']
|
||||
valid_part_conforms = {'1A', '1B', '2A', '2B', '2U', '3A', '3B', '3U'}
|
||||
|
||||
message = 'File claims to be PDF/A-{}'.format(
|
||||
part_conformance)
|
||||
|
||||
if part_conformance in valid_part_conforms:
|
||||
pdfa_dict['pass'] = True
|
||||
pdfa_dict['message'] = message
|
||||
else:
|
||||
pdfa_dict['message'] = 'File is a regular PDF'
|
||||
|
||||
return pdfa_dict
|
||||
|
||||
|
||||
Reference in New Issue
Block a user