# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import datetime
import hashlib
+import os
from io import BytesIO
from lxml import etree
info_dict = {
'/Author': pdf_metadata.get('author', ''),
'/CreationDate': pdf_date,
- '/Creator': 'pretix',
+ '/Creator': 'python-drafthorse',
'/Keywords': pdf_metadata.get('keywords', ''),
'/ModDate': pdf_date,
'/Subject': pdf_metadata.get('subject', ''),
desc_xmp = etree.SubElement(rdf, ns_rdf + 'Description', nsmap=nsmap_xmp)
desc_xmp.set(ns_rdf + 'about', '')
creator = etree.SubElement(desc_xmp, ns_xmp + 'CreatorTool')
- creator.text = 'pretix'
+ creator.text = 'python-drafthorse'
timestamp = datetime.datetime.now().isoformat()
etree.SubElement(desc_xmp, ns_xmp + 'CreateDate').text = timestamp
etree.SubElement(desc_xmp, ns_xmp + 'ModifyDate').text = timestamp
- """
- xmp_file = resource_filename(__name__, 'xmp/Factur-X_extension_schema.xmp')
+ xmp_file = os.path.join(os.path.dirname(__file__), 'schema', 'ZUGFeRD1p0_extension_schema.xmp')
# Reason for defining a parser below:
# http://lxml.de/FAQ.html#why-doesn-t-the-pretty-print-option-reformat-my-xml-output
parser = etree.XMLParser(remove_blank_text=True)
facturx_ext_schema_root = etree.parse(open(xmp_file), parser)
# The Factur-X extension schema must be embedded into each PDF document
- facturx_ext_schema_desc_xpath = facturx_ext_schema_root.xpath(
- '//rdf:Description', namespaces=nsmap_rdf)
+ facturx_ext_schema_desc_xpath = facturx_ext_schema_root.xpath('//rdf:Description', namespaces=nsmap_rdf)
rdf.append(facturx_ext_schema_desc_xpath[1])
- """
+
# Now is the ZUGFeRD description tag
zugferd_desc = etree.SubElement(rdf, ns_rdf + 'Description', nsmap=nsmap_zf)
zugferd_desc.set(ns_rdf + 'about', '')
--- /dev/null
+<!--
+PDFlib GmbH 2013-2014
+
+Sample ZUGFeRD XMP with the required PDF/A extension schema description
+for the XMP properties of the ZUGFeRD schema and the actual ZUGFeRD properties.
+
+Schema name: ZUGFeRD Schema
+Preferred schema namespace prefix: zf
+Schema namespace URI: urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#
+
+Notes on the ZUGFeRD schema namespace URI:
+
+- The use of mixed upper/lowercase in "CrossIndustryDocument" conforms to
+ the ZUGFeRD 1.0 specification. The PDF samples distributed with the
+ ZUGFeRD 1.0 info package use all-lowercase spelling "crossindustrydocument"
+ which is not correct since it violates the ZUGFeRD specification.
+
+- The required trailing "#" character is missing in the comment in the
+ ZUGFeRD 1.0 extension schema description which is included in the ZUGFeRD
+ specification, but it is correctly present in the actual XMP.
+
+Based on the ZUGFeRD 1.0 package (published 2014-06 on www.ferd-net.de)
+which is Copyright AWV e.V. 2014.
+
+2014-07-01 (based on ZUGFeRD 1.0)
+Adjustments for ZUGFeRD 1.0:
+- updated header comments
+- switched to new namespace URI
+- adjusted property descriptions in the extension schema descriptions
+
+2013-06-19 (based on ZUGFeRD RC)
+Added a trailing hash character "#" to the "zf" namespace name as required
+by the XMP 2005 specification which is referenced in PDF/A-2 and PDF/A-3.
+Without this change Acrobat XI Preflight validation for PDF/A-3 complains
+"Extension schema present but not valid"
+
+2013-06-19
+Singled out the zf properties into a separate rdf:Description node to work
+around bug #4433 in PDFlib 9.0.0 which has been fixed in PDFlib 9.0.1.
+
+-->
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+
+ <!-- The actual ZUGFeRD properties; adjust if required -->
+ <rdf:Description rdf:about="" xmlns:zf="urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#">
+ <zf:ConformanceLevel>BASIC</zf:ConformanceLevel>
+ <zf:DocumentFileName>ZUGFeRD-invoice.xml</zf:DocumentFileName>
+ <zf:DocumentType>INVOICE</zf:DocumentType>
+ <zf:Version>1.0</zf:Version>
+ </rdf:Description>
+
+ <!-- PDF/A extension schema description for the ZUGFeRD schema.
+ It is crucial for PDF/A-3 conformance. Don't touch! -->
+ <rdf:Description rdf:about=""
+ xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
+ xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
+ xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
+
+ <pdfaExtension:schemas>
+ <rdf:Bag>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaSchema:schema>ZUGFeRD PDFA Extension Schema</pdfaSchema:schema>
+ <pdfaSchema:namespaceURI>urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#</pdfaSchema:namespaceURI>
+ <pdfaSchema:prefix>zf</pdfaSchema:prefix>
+ <pdfaSchema:property>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:name>DocumentFileName</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>name of the embedded XML invoice file</pdfaProperty:description>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:name>DocumentType</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>INVOICE</pdfaProperty:description>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:name>Version</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>The actual version of the ZUGFeRD XML schema</pdfaProperty:description>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:name>ConformanceLevel</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>The conformance level of the embedded ZUGFeRD data</pdfaProperty:description>
+ </rdf:li>
+ </rdf:Seq>
+ </pdfaSchema:property>
+ </rdf:li>
+ </rdf:Bag>
+ </pdfaExtension:schemas>
+ </rdf:Description>
+</rdf:RDF>