diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py index 0e0eb462..d11074fa 100644 --- a/src/ocrmypdf/_pipeline.py +++ b/src/ocrmypdf/_pipeline.py @@ -878,19 +878,19 @@ def metadata_fixup( options = context.get_options() input_files = list(f for f in flatten_groups(input_files_groups)) - metadata_file = next( + original_file = next( (ii for ii in input_files if ii.endswith('.repaired.pdf')), None ) layers_file = next( (ii for ii in input_files if ii.endswith('layers.rendered.pdf')), None ) - pdfa = next( + pdfa_file = next( (ii for ii in input_files if ii.endswith('pdfa.pdf')), None ) - metadata = pikepdf.open(metadata_file) - docinfo = get_docinfo(metadata, options) + original = pikepdf.open(original_file) + docinfo = get_docinfo(original, options) - working_file = pdfa if pdfa else layers_file + working_file = pdfa_file if pdfa_file else layers_file pdf = pikepdf.open(working_file) with pdf.open_metadata() as meta: @@ -899,6 +899,20 @@ def metadata_fixup( # match Ghostscript, for consistency if 'xmp:CreateDate' not in meta: meta['xmp:CreateDate'] = meta.get('xmp:ModifyDate', '') + if pdfa_file: + meta_original = original.open_metadata() + not_copied = set(meta_original.keys()) - set(meta.keys()) + if not_copied: + log.warning( + "Some input metadata could not be copied because it is not " + "permitted in PDF/A. You may wish to examine the output " + "PDF's XMP metadata." + ) + log.debug( + "The following metadata fields were not copied: %r", + not_copied + ) + pdf.save(output_file, compress_streams=True, object_stream_mode=pikepdf.ObjectStreamMode.generate) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 8e027fa5..7fe7ab8d 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -21,8 +21,9 @@ import pytest from datetime import timezone from pathlib import Path from shutil import copyfile -from unittest.mock import patch +from unittest.mock import patch, MagicMock import datetime +from shutil import copyfile import pikepdf from pikepdf.models.metadata import decode_pdf_date @@ -278,3 +279,39 @@ def test_kodak_toc(resources, outpdf, spoof_tesseract_noop): if pikepdf.Name.First in p.root.Outlines: assert isinstance(p.root.Outlines.First, pikepdf.Dictionary) + + +def test_metadata_fixup_warning(resources, outdir): + from ocrmypdf._pipeline import metadata_fixup + + input_files = [ + str(outdir / 'graph.repaired.pdf'), + str(outdir / 'layers.rendered.pdf'), + str(outdir / 'pdfa.pdf'), # It is okay that this is not a PDF/A + ] + for f in input_files: + copyfile(resources / 'graph.pdf', f) + + log = MagicMock() + context = MagicMock() + metadata_fixup( + input_files_groups=input_files, + output_file=outdir / 'out.pdf', + log=log, + context=context) + log.warning.assert_not_called() + + # Now add some metadata that will not be copyable + graph = pikepdf.open(outdir / 'graph.repaired.pdf') + with graph.open_metadata() as meta: + meta['prism2:publicationName'] = 'OCRmyPDF Test' + graph.save(outdir / 'graph.repaired.pdf') + + log = MagicMock() + context = MagicMock() + metadata_fixup( + input_files_groups=input_files, + output_file=outdir / 'out.pdf', + log=log, + context=context) + log.warning.assert_called_once()