Merge branch 'main' of github.com:ocrmypdf/OCRmyPDF
This commit is contained in:
@@ -852,24 +852,43 @@ def metadata_fixup(working_file: Path, context: PdfContext) -> Path:
|
||||
|
||||
with pikepdf.open(context.origin) as original, pikepdf.open(working_file) as pdf:
|
||||
docinfo = get_docinfo(original, context)
|
||||
with pdf.open_metadata() as meta:
|
||||
meta.load_from_docinfo(docinfo, delete_missing=False, raise_failure=False)
|
||||
with pdf.open_metadata() as meta_pdf:
|
||||
meta_pdf.load_from_docinfo(docinfo, delete_missing=False, raise_failure=False)
|
||||
# If xmp:CreateDate is missing, set it to the modify date to
|
||||
# match Ghostscript, for consistency
|
||||
if 'xmp:CreateDate' not in meta:
|
||||
meta['xmp:CreateDate'] = meta.get('xmp:ModifyDate', '')
|
||||
# ensure consistency with Ghostscript.
|
||||
if 'xmp:CreateDate' not in meta_pdf:
|
||||
meta_pdf['xmp:CreateDate'] = meta_pdf.get('xmp:ModifyDate', '')
|
||||
|
||||
with original.open_metadata(
|
||||
set_pikepdf_as_editor=False, update_docinfo=False, strict=False
|
||||
) as meta_original:
|
||||
if meta.get('dc:title') == 'Untitled':
|
||||
if meta_pdf.get('dc:title') == 'Untitled':
|
||||
# Ghostscript likes to set title to Untitled if omitted from input.
|
||||
# Reverse this, because PDF/A TechNote 0003:Metadata in PDF/A-1
|
||||
# and the XMP Spec do not make this recommendation.
|
||||
if 'dc:title' not in meta_original:
|
||||
del meta['dc:title']
|
||||
missing = set(meta_original.keys()) - set(meta.keys())
|
||||
report_on_metadata(missing)
|
||||
del meta_pdf['dc:title']
|
||||
# If the user explicitly specified an empty string for any of the
|
||||
# following, they should be unset and not reported as missing in
|
||||
# the output pdf. Note that some metadata fields use differing names
|
||||
# between PDF-A and PDF.
|
||||
for meta in [meta_pdf, meta_original]:
|
||||
if options.title == '' and 'dc:title' in meta:
|
||||
del meta['dc:title'] # PDF-A and PDF
|
||||
if options.author == '':
|
||||
if 'dc:creator' in meta:
|
||||
del meta['dc:creator'] # PDF-A (Not xmp:CreatorTool)
|
||||
if 'pdf:Author' in meta:
|
||||
del meta['pdf:Author'] # PDF
|
||||
if options.subject == '':
|
||||
if 'dc:description' in meta:
|
||||
del meta['dc:description'] # PDF-A
|
||||
if 'dc:subject' in meta:
|
||||
del meta['dc:subject'] # PDF
|
||||
if options.keywords == '' and 'pdf:Keywords' in meta:
|
||||
del meta['pdf:Keywords'] # PDF-A and PDF
|
||||
meta_missing = set(meta_original.keys()) - set(meta_pdf.keys())
|
||||
report_on_metadata(meta_missing)
|
||||
|
||||
optimizing = context.plugin_manager.hook.is_optimization_enabled(
|
||||
context=context
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
%PDF-1.3
|
||||
%¿÷¢þ
|
||||
1 0 obj
|
||||
<< /Pages 2 0 R /Type /Catalog >>
|
||||
endobj
|
||||
2 0 obj
|
||||
<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
|
||||
endobj
|
||||
3 0 obj
|
||||
<< /MediaBox [ 0 0 720 720 ] /Parent 2 0 R /Resources << >> /Type /Page >>
|
||||
endobj
|
||||
xref
|
||||
0 4
|
||||
0000000000 65535 f
|
||||
0000000015 00000 n
|
||||
0000000064 00000 n
|
||||
0000000123 00000 n
|
||||
trailer << /Root 1 0 R /Size 4 /ID [<52bba3c78160d0c6e851b59110e5d076><52bba3c78160d0c6e851b59110e5d076>] >>
|
||||
startxref
|
||||
213
|
||||
%%EOF
|
||||
%BeginExifToolUpdate
|
||||
1 0 obj
|
||||
<<
|
||||
/Pages 2 0 R
|
||||
/Type /Catalog
|
||||
/Metadata 5 0 R
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<<
|
||||
/Author (yXaryipxyRk9dVjWjSSaVaNCKeLRgEVzPRMp)
|
||||
/Keywords (s9EeALwUg7urA7fnnhm5EtUyC54sW2WPUzqh)
|
||||
/Subject (t49vimctvnuH7ZeAjAkv52ACvWFjcnm5MPJr)
|
||||
/Title (NFY5f7Ft2DWMkxLhXwxvFf7eWR2KeK3vEDcd)
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/Type /Metadata
|
||||
/Subtype /XML
|
||||
/Length 3232
|
||||
>>
|
||||
stream
|
||||
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 12.60'>
|
||||
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
||||
|
||||
<rdf:Description rdf:about=''
|
||||
xmlns:dc='http://purl.org/dc/elements/1.1/'>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>t49vimctvnuH7ZeAjAkv52ACvWFjcnm5MPJr</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:title>
|
||||
<rdf:Alt>
|
||||
<rdf:li xml:lang='x-default'>NFY5f7Ft2DWMkxLhXwxvFf7eWR2KeK3vEDcd</rdf:li>
|
||||
</rdf:Alt>
|
||||
</dc:title>
|
||||
</rdf:Description>
|
||||
|
||||
<rdf:Description rdf:about=''
|
||||
xmlns:pdf='http://ns.adobe.com/pdf/1.3/'>
|
||||
<pdf:Author>yXaryipxyRk9dVjWjSSaVaNCKeLRgEVzPRMp</pdf:Author>
|
||||
<pdf:Keywords>s9EeALwUg7urA7fnnhm5EtUyC54sW2WPUzqh</pdf:Keywords>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end='w'?>
|
||||
endstream
|
||||
endobj
|
||||
xref
|
||||
0 2
|
||||
0000000000 65535 f
|
||||
0000000452 00000 n
|
||||
4 2
|
||||
0000000517 00000 n
|
||||
0000000728 00000 n
|
||||
trailer
|
||||
<<
|
||||
/Root 1 0 R
|
||||
/Size 6
|
||||
/ID [ <52bba3c78160d0c6e851b59110e5d076> <54bba3c78160d0c6e851b59110e5d076> ]
|
||||
/Info 4 0 R
|
||||
/Prev 213
|
||||
>>
|
||||
%EndExifToolUpdate 431
|
||||
startxref
|
||||
4043
|
||||
%%EOF
|
||||
@@ -76,6 +76,50 @@ def test_override_metadata(output_type, resources, outpdf):
|
||||
assert pdfa_info['output'] == output_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize('output_type', ['pdfa', 'pdf', 'pdfa-1', 'pdfa-2', 'pdfa-3'])
|
||||
@pytest.mark.parametrize('field', ['title', 'author', 'subject', 'keywords'])
|
||||
def test_unset_metadata(output_type, field, resources, outpdf):
|
||||
input_file = resources / 'meta.pdf'
|
||||
|
||||
# magic strings contained in the input pdf metadata
|
||||
meta = {
|
||||
'title': b'NFY5f7Ft2DWMkxLhXwxvFf7eWR2KeK3vEDcd',
|
||||
'author': b'yXaryipxyRk9dVjWjSSaVaNCKeLRgEVzPRMp',
|
||||
'subject': b't49vimctvnuH7ZeAjAkv52ACvWFjcnm5MPJr',
|
||||
'keywords': b's9EeALwUg7urA7fnnhm5EtUyC54sW2WPUzqh'}
|
||||
|
||||
p = run_ocrmypdf(
|
||||
input_file,
|
||||
outpdf,
|
||||
f'--{field}',
|
||||
'',
|
||||
'--output-type',
|
||||
output_type,
|
||||
'--plugin',
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
|
||||
assert p.returncode == ExitCode.ok, p.stderr
|
||||
|
||||
# We mainly want to ensure that when '' is passed, the corresponding
|
||||
# metadata is unset in the output pdf. Since metedata is not compressed,
|
||||
# the best way to gaurentee the metadata of interest didn't carry
|
||||
# forward is to just check to ensure the corresponding magic string
|
||||
# isn't contained anywhere in the output pdf. We'll also check to ensure
|
||||
# it's in the input pdf and that any values not unset are still in the
|
||||
# output pdf.
|
||||
with open(input_file, 'rb') as before, open(outpdf, 'rb') as after:
|
||||
before_data = before.read()
|
||||
after_data = after.read()
|
||||
|
||||
for k, v in meta.items():
|
||||
assert v in before_data
|
||||
if k == field:
|
||||
assert v not in after_data
|
||||
else:
|
||||
assert v in after_data
|
||||
|
||||
|
||||
def test_high_unicode(resources, no_outpdf):
|
||||
# Ghostscript doesn't support high Unicode, so neither do we, to be
|
||||
# safe
|
||||
|
||||
Reference in New Issue
Block a user