o
    eRz                     @  s  U d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m	Z	 ddl
mZ ddlmZ ddlmZmZmZmZmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZmZmZ ddlmZ  ddl!m"Z" ej#dk ruddlm$Z$m%Z% nddl&m$Z$m%Z% erddl'm(Z( dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4de)d fe*d!fe+d"fe,d#fe-d$fe.d%fe/d&fe0d'fe1d(fe2d)fe3d*fe4d+fgZ5d,e6d-< e5D ]
\Z7Z8e9e8e7 qd.Z:d/Z;d0Z<d1Z=G d2d3 d3eZ>e?e@ZAG d4d5 d5eBZCG d6d7 d7eDZEe>d8eEeEjFe>d9eGeGjHe>d:eDeDjFgZIeJeKee)d;eKee)d<eKee)d=eKee4d>gZLeMd?ZNeMd@ZOdgdCdDZPdgdEdFZQdgdGdHZRdhdidKdLZSdjdkdSdTZTdldWdXZUdmdYdZZVG d[d\ d\eZWG d]d^ d^eWZXG d_d` d`eWZYG dadb dbeZZdcdd Z[G dedf dfe%Z\dS )nzPDF metadata handling.    )annotationsN)ABCabstractmethod)datetimewraps)BytesIO)TYPE_CHECKINGAnyCallable
NamedTupleSet)warn)etree)QNameXMLSyntaxError   )NameStreamString)__version__)	parse_xml)   	   )IterableMutableMapping)Pdfz http://purl.org/dc/elements/1.1/zhttp://ns.adobe.com/pdf/1.3/zhttp://www.aiim.org/pdfa/ns/id/zhttp://www.npes.org/pdfx/ns/id/z"http://ns.adobe.com/photoshop/1.0/z.http://prismstandard.org/namespaces/basic/1.0/z.http://prismstandard.org/namespaces/basic/2.0/z.http://prismstandard.org/namespaces/basic/3.0/z+http://www.w3.org/1999/02/22-rdf-syntax-ns#zhttp://ns.adobe.com/xap/1.0/zhttp://ns.adobe.com/xap/1.0/mm/z#http://ns.adobe.com/xap/1.0/rights/)zadobe:ns:meta/xZdcpdfZpdfaidZpdfxidZ	photoshopZprismZprism2Zprism3rdfZxmpZxmpMMZ	xmpRightszlist[tuple[str, str]]DEFAULT_NAMESPACESz$http://www.w3.org/XML/1998/namespaces6   <?xpacket begin="﻿" id="W5M0MpCehiHzreSzNTczkc9d"?>
s   <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="pikepdf">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
 </rdf:RDF>
</x:xmpmeta>
s   
<?xpacket end="w"?>
c                   @  s*   e Zd ZU dZded< ded< ded< dS )	XmpContainerz6Map XMP container object to suitable Python container.strrdf_typetypepy_typezCallable[..., None]Z	insert_fnN__name__
__module____qualname____doc____annotations__ r,   r,   GD:\Projects\ConvertPro\env\Lib\site-packages\pikepdf/models/metadata.pyr!   P   s
   
 r!   c                   @     e Zd ZdZdS )
NeverRaisez"An exception that is never raised.Nr'   r(   r)   r*   r,   r,   r,   r-   r/   [       r/   c                   @  r.   )AltListzXMP AltList container.Nr0   r,   r,   r,   r-   r2   _   r1   r2   AltZBagZSeqtitledescriptionZrightsZ
UsageTermszL(?u)[^\x09\x0A\x0D\x20-\U0000D7FF\U0000E000-\U0000FFFD\U00010000-\U0010FFFF]s   [^\x09\x0A\x0D\x20-\xFF]|&#0;xmlbytesc                 C  s   t t| S Nr   r   r6   r,   r,   r-   _parser_basic}   s   r;   c                 C  s   t ttd| S N    )r   r   re_xml_illegal_bytessubr:   r,   r,   r-   _parser_strip_illegal_bytes   s   r@   c                 C  s   t t| ddS )NT)Zrecoverr9   r:   r,   r,   r-   _parser_recovery   s   rA   r=   _xmlc                 C  s   t d ttS )Nz5Error occurred parsing XMP, replacing with empty XMP.)logwarningr;   	XMP_EMPTY)rB   r,   r,   r-   _parser_replace_with_empty_xmp   s   
rF   ; sstr | Iterable[str]joinerr"   returnc                 C  s\   t | ts(t | tr$td|   t | tr|t| } n
|| } ntdt	d| S )a  Ensure an object can safely be inserted in a XML tag body.

    If we still have a non-str object at this point, the best option is to
    join it, because it's apparently calling for a new node in a place that
    isn't allowed in the spec or not supported.
    zMerging elements of z.object must be a string or iterable of strings )

isinstancer"   r   r   r   joinsorted	TypeErrorre_xml_illegal_charsr?   )rH   rJ   r,   r,   r-   _clean   s   


rR   dr   c                 C  sj   d| j d}|| d7 }| d}|r3|d |dd |dd }}}|| | d	| d	7 }|S )
a  Encode Python datetime object as PDF date string.

    From Adobe pdfmark manual:
    (D:YYYYMMDDHHmmSSOHH'mm')
    D: is an optional prefix. YYYY is the year. All fields after the year are
    optional. MM is the month (01-12), DD is the day (01-31), HH is the
    hour (00-23), mm are the minutes (00-59), and SS are the seconds
    (00-59). The remainder of the string defines the relation of local
    time to GMT. O is either + for a positive difference (local time is
    later than GMT) or - (minus) for a negative difference. HH' is the
    absolute value of the offset from GMT in hours, and mm' is the
    absolute value of the offset in minutes. If no GMT information is
    specified, the relation between the specified time and GMT is
    considered unknown. Regardless of whether or not GMT
    information is specified, the remainder of the string should specify
    the local time.

    'D:' is required in PDF/A, so we always add it.
    D:Z04dz
%m%d%H%M%Sz%zr      r      ')yearstrftime)rS   rH   tzsignZtz_hoursZtz_minsr,   r,   r-   encode_pdf_date   s   
$r\   c                 C  s   t | tr	t| } | dr| dd } | dr | dd} n| dr+| dd} | dd} zt| d	W S  tyG   t| d
 Y S w )zDecode a pdfmark date to a Python datetime object.

    A pdfmark date is a string in a paritcular format. See the pdfmark
    Reference for the specification.
    rT   r   NzZ00'00'z+0000ZrW   rL   z%Y%m%d%H%M%S%zz%Y%m%d%H%M%S)	rM   r   r"   
startswithendswithreplacer   strptime
ValueError)rH   r,   r,   r-   decode_pdf_date   s   



rc   c                   @  s4   e Zd ZdZeedddZeedd	d
ZdS )	ConverterzXMP <-> DocumentInfo converter.docinfo_val
str | NonerK   r
   c                 C     dS )z/Derive XMP metadata from a DocumentInfo string.Nr,   re   r,   r,   r-   xmp_from_docinfo       zConverter.xmp_from_docinfoxmp_valc                 C  rg   )z9Derive a DocumentInfo value from equivalent XMP metadata.Nr,   rk   r,   r,   r-   docinfo_from_xmp   rj   zConverter.docinfo_from_xmpNre   rf   rK   r
   )rk   r
   rK   rf   )r'   r(   r)   r*   staticmethodr   ri   rm   r,   r,   r,   r-   rd      s    rd   c                   @  s*   e Zd ZdZedddZedd	 Zd
S )AuthorConverterz-Convert XMP document authors to DocumentInfo.re   rf   rK   r
   c                 C  s   | gS )z*Derive XMP authors info from DocumentInfo.r,   rh   r,   r,   r-   ri      s   z AuthorConverter.xmp_from_docinfoc                 C  s.   t | tr| S | du s| dgkrdS d| S )zDerive DocumentInfo authors from XMP.

        XMP supports multiple author values, while DocumentInfo has a string,
        so we return the values separated by semi-colons.
        NrG   )rM   r"   rN   rl   r,   r,   r-   rm      s
   

z AuthorConverter.docinfo_from_xmpNrn   r'   r(   r)   r*   ro   ri   rm   r,   r,   r,   r-   rp      s    rp   c                   @  s(   e Zd ZdZedd Zedd ZdS )DateConverterz"Convert XMP dates to DocumentInfo.c                 C  s   | dkrdS t |  S )z"Derive XMP date from DocumentInfo.rL   )rc   	isoformatrh   r,   r,   r-   ri      s   zDateConverter.xmp_from_docinfoc                 C  sP   |  dr| dd d } z
t| }W t|S  ty'   td|  ddw )zDerive DocumentInfo from XMP.r]   Nz+00:00zInvalid isoformat string: 'rW   )r_   r   fromisoformat
IndexErrorrb   r\   )rk   Zdateobjr,   r,   r-   rm     s   
zDateConverter.docinfo_from_xmpNrq   r,   r,   r,   r-   rr      s    
rr   c                   @  s2   e Zd ZU dZded< ded< ded< ded< d	S )
DocinfoMappingzEMap DocumentInfo keys to their XMP equivalents, along with converter.r"   nskeyr   nameztype[Converter] | None	converterNr&   r,   r,   r,   r-   rw     s   
 rw   c                   s   t   fdd}|S )z|Ensure the XMP has been loaded and parsed.

    TODO: Can this be removed? Why allow the uninit'ed state to even exist?
    c                   s$   | j s|    | g|R i |S r8   )_xmp_load)selfargskwargsfnr,   r-   wrapper#  s   zensure_loaded.<locals>.wrapperr   )r   r   r,   r   r-   ensure_loaded  s   r   c                   @  s  e Zd ZU dZeedejeeedej	deedej
deedejdeedejdeedejeeed	ejdeed
ejegZded< dd eD Zded< eeZded< eeeegZded< egZded< 			didjddZ	dkdld#d$Z dmd%d&Z!dnd)d*Z"e#d+d, Z$d-d. Z%d/d0 Z&dod1d2Z'd3d4 Z(e)dpd8d9Z*d:d; Z+d<d= Z,d>d? Z-dqdrdBdCZ.dqdDdEZ/e#dsdGdHZ0e#dsdIdJZ1e#dKdL Z2e#dMdN Z3	dtdudRdSZ4dvdUdVZ5dwdYdZZ6d[d\ Z7d]d^ Z8e#dxd_d`Z9e#dsdadbZ:e;dydcddZ<e;dydedfZ=e#dgdh Z>dS )zPdfMetadataa>  Read and edit the metadata associated with a PDF.

    The PDF specification contain two types of metadata, the newer XMP
    (Extensible Metadata Platform, XML-based) and older DocumentInformation
    dictionary. The PDF 2.0 specification removes the DocumentInformation
    dictionary.

    This primarily works with XMP metadata, but includes methods to generate
    XMP from DocumentInformation and will also coordinate updates to
    DocumentInformation so that the two are kept consistent.

    XMP metadata fields may be accessed using the full XML namespace URI or
    the short name. For example ``metadata['dc:description']``
    and ``metadata['{http://purl.org/dc/elements/1.1/}description']``
    both refer to the same field. Several common XML namespaces are registered
    automatically.

    See the XMP specification for details of allowable fields.

    To update metadata, use a with block.

    Example:

        >>> with pdf.open_metadata() as records:
                records['dc:title'] = 'New Title'

    See Also:
        :meth:`pikepdf.Pdf.open_metadata`
    Zcreatorr5   Nr4   KeywordsProducerZ
CreateDateZCreatorToolZ
ModifyDatezlist[DocinfoMapping]DOCINFO_MAPPINGc                 C  s   i | ]\}}||qS r,   r,   ).0uriprefixr,   r,   r-   
<dictcomp>V  s    zPdfMetadata.<dictcomp>zdict[str, str]NS
REVERSE_NSz Iterable[Callable[[bytes], Any]]_PARSERS_OVERWRITE_INVALID_XML_PARSERS_STANDARDTr   r   pikepdf_markboolsync_docinfooverwrite_invalid_xmlc                 C  s(   || _ d | _|| _|| _d| _|| _d S NF)_pdfr|   markr   	_updatingr   )r~   r   r   r   r   r,   r,   r-   __init__a  s   
zPdfMetadata.__init__Fdelete_missingraise_failurerK   Nonec                   s  d fdd	}| j D ]V\}}}}t||}	|t|}
|
du r*|r)|	| v r)| |	= q
zt|
}
|r6||
}
|
s:W q
| |	|
d W q
 tttfy` } z|d| d| W Y d}~q
d}~ww dd | j D }d	d |	 D | }|D ]}|d| d
t
|| d qvdS )a1  Populate the XMP metadata object with DocumentInfo.

        Arguments:
            docinfo: a DocumentInfo, e.g pdf.docinfo
            delete_missing: if the entry is not DocumentInfo, delete the equivalent
                from XMP
            raise_failure: if True, raise any failure to convert docinfo;
                otherwise warn and continue

        A few entries in the deprecated DocumentInfo dictionary are considered
        approximately equivalent to certain XMP records. This method copies
        those entries into the XMP metadata.
        Nc                   s    rt | |t|  d S r8   )rb   r   )msger   r,   r-   warn_or_raise  s   
z4PdfMetadata.load_from_docinfo.<locals>.warn_or_raiseTzThe metadata field z could not be copied to XMPc                 S  s   h | ]
\}}}}t |qS r,   r"   )r   _docinfo_namer,   r,   r-   	<setcomp>  s    z0PdfMetadata.load_from_docinfo.<locals>.<setcomp>c                 S  s   h | ]}t |qS r,   r   )r   kr,   r,   r-   r     s    z with value 'z,' has no XMP equivalent, so it was discardedr8   )r   r   getr"   ri   _setitemrb   AttributeErrorNotImplementedErrorkeysrepr)r~   docinfor   r   r   r   Zshortkeyr   r{   qnamevalr   Zvalid_docinfo_namesZextra_docinfo_namesextrar,   r   r-   load_from_docinfoo  s<   

zPdfMetadata.load_from_docinfoc                 C  s8   z	| j jj }W n ty   d}Y nw | | d S r<   )r   RootMetadata
read_bytesr   
_load_from)r~   datar,   r,   r-   r}     s   zPdfMetadata._loadr   r7   c                 C  s8  |  dkrt}| jr| jn| j}|D ]:}z||| _W n0 | jr#tntyL } zt|	ds7t|	drBt
 | _W Y d }~ nW Y d }~qd }~ww  | jd urz| jd}|D ]
}t| j|j q\|   W d S  | jrttnty } ztjd|d t
 | _W Y d }~d S d }~ww td t
 | _d S )Nr=   z!Start tag expected, '<' not foundzDocument is emptyz/processing-instruction()zError occurred parsing XMP)exc_info)striprE   r   r   r   r|   r   r/   r"   r^   rF   xpathr   Z
strip_tagstag_get_rdf_root	ExceptionrC   rD   )r~   r   parsersparserr   Zpispir,   r,   r-   r     sT   



zPdfMetadata._load_fromc                 C  s
   d| _ | S )NT)r   r~   r,   r,   r-   	__enter__  s   zPdfMetadata.__enter__c                 C  s2   z|d urW d| _ d S |   W d| _ d S d| _ w r   )r   _apply_changes)r~   exc_typeexc_valexc_tbr,   r,   r-   __exit__  s   

zPdfMetadata.__exit__c                 C  s(  | j j | jD ]\}}}}t||}z| | }W n ty,   || j jv r*| j j|= Y qw |rcz||}W n, tyI   td| d d}Y n tyb } ztd| d| d| |d}~ww |du rs|| j jv rr| j j|= qt	|}z|
d| j j|< W q ty   || j j|< Y qw dS )zUpdate the PDF's DocumentInfo dictionary to match XMP metadata.

        The standard mapping is described here:
            https://www.pdfa.org/pdfa-metadata-xmp-rdf-dublin-core/
        zThe DocumentInfo field z could not be updated from XMPNz4An error occurred while updating DocumentInfo field z
 from XMP z with value ascii)r   r   r   r   KeyErrorrm   rb   r   r   rR   encodeUnicodeEncodeError)r~   r   elementr   r{   r   valuer   r,   r,   r-   _update_docinfo  sV   



zPdfMetadata._update_docinfoc                 C  sJ   t  }|r
|t | jj|ddd |r|t |d | }|S )Nutf-8T)encodingZpretty_printr   )r   writeXPACKET_BEGINr|   XPACKET_ENDseekread)r~   xpacketr   Z	xml_bytesr,   r,   r-   _get_xml_bytes  s   


zPdfMetadata._get_xml_bytesc                 C  s   | j r%| jttdtt  j	 dd | jtt
ddt dd |  }t| j|| jj_tj| jjjtj< tj| jjjtj< | jrM|   dS dS )zSerialize our changes back to the PDF in memory.

        Depending how we are initialized, leave our metadata mark and producer.
        ZMetadataDateT)applying_markr   zpikepdf N)r   r   r   
XMP_NS_XMPr   nowutcnow
astimezonetzinfors   
XMP_NS_PDFpikepdf_versionr   r   r   r   r   r   TypeXMLZSubtyper   r   )r~   r6   r,   r,   r-   r     s$   zPdfMetadata._apply_changesrz   QName | strr"   c                 C  s   t |tr	t|S t |tst| d|dkr|S |dr"|S z|jddd\}}W n ty;   d|}}Y nw | j| }tt||S )zkConvert name to an XML QName.

        e.g. pdf:Producer -> {http://ns.adobe.com/pdf/1.3/}Producer
        z must be strrL   {:rU   maxsplitr   )rM   r   r"   rP   r^   splitrb   r   )clsrz   r   r   r   r,   r,   r-   _qname/  s   



zPdfMetadata._qnamec                 C  s0   |j ddd\}}|dd}| j| d | S )z~Given a fully qualified XML name, find a prefix.

        e.g. {http://ns.adobe.com/pdf/1.3/}Producer -> pdf:Producer
        }rU   r   r   rL   r   )r   r`   r   )r~   ZurinameZuripartr   r   r,   r,   r-   _prefix_from_uriH  s   zPdfMetadata._prefix_from_uric                 C  s   | d| j}|durz|d jW S  ty   Y dS w tD ]%\}}}| d| | j}|du r2q| }|D ]}|||j q7|  S dS )zGather the sub-elements attached to a node.

        Gather rdf:Bag and and rdf:Seq into set and list respectively. For
        alternate languages values, take the first language only for
        simplicity.
        zrdf:AltNr   rL   zrdf:)findr   textrv   XMP_CONTAINERS)r~   nodeitemsZxmlcontainer	containerZinsertfnresultitemr,   r,   r-   _get_subelementsQ  s    zPdfMetadata._get_subelementsc                 C  s8   | j d| j}|d u r| j  }|jdkstd|S )Nz
.//rdf:RDFz0{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDFz$Metadata seems to be XML but not XMP)r|   r   r   Zgetrootr   rb   )r~   r   r,   r,   r-   r   i  s   

zPdfMetadata._get_rdf_rootrL   str | QNamec           
      c  s    |  |}|  }|d| jD ]V}|r&|| v r&|||||fV  n|s:| D ]\}}|r9||||fV  q,|r>|nd}||| jD ]}|jrZ|j rZ|d|j|fV  qG| 	|}	|d|	|fV  qGqdS )a#  Get elements from XMP.

        Core routine to find elements matching name within the XMP and yield
        them.

        For XMP spec 7.9.2.2, rdf:Description with property attributes,
        we yield the node which will have the desired as one of its attributes.
        qname is returned so that the node.attrib can be used to locate the
        source.

        For XMP spec 7.5, simple valued XMP properties, we yield the node,
        None, and the value. For structure or array valued properties we gather
        the elements. We ignore qualifiers.

        Args:
            name: a prefixed name or QName to look for within the
                data section of the XMP; looks for all data keys if omitted

        Yields:
            tuple: (node, qname_attrib, value, parent_node)

        zrdf:Description[@rdf:about=""]*N)
r   r   findallr   r   r   r   r   r   r   )
r~   rz   r   r   rdfdescr   vr   r   valuesr,   r,   r-   _get_elementsq  s(   

zPdfMetadata._get_elementsc                 c  s     dd |  |D E d H  d S )Nc                 s  s    | ]}|d  V  qdS )r   Nr,   )r   r   r,   r,   r-   	<genexpr>  s    z2PdfMetadata._get_element_values.<locals>.<genexpr>)r   )r~   rz   r,   r,   r-   _get_element_values  s   zPdfMetadata._get_element_valuesry   c                 C  s   t | |S r8   )anyr   r~   ry   r,   r,   r-   __contains__     zPdfMetadata.__contains__c                 C  s*   zt | |W S  ty   t|d w r8   )nextr   StopIterationr   r   r,   r,   r-   __getitem__  s
   
zPdfMetadata.__getitem__c                 c  s0    |   D ]\}}}}|r|V  q|jV  qd S r8   )r   r   )r~   r   attribZ_val_parentsr,   r,   r-   __iter__  s   
zPdfMetadata.__iter__c                 C  s   t tt| S r8   )lenlistiterr   r,   r,   r-   __len__  s   zPdfMetadata.__len__r   set[str] | list[str] | strr   c                 C  s^   | j std| |}| |||| z
| ||| W d S  ty.   | || Y d S w )N/Metadata not opened for editing, use with block)r   RuntimeErrorr   _setitem_check_args_setitem_updater  _setitem_insertr~   ry   r   r   qkeyr,   r,   r-   r     s   
zPdfMetadata._setitemr  c                 C  sh   | j r|s|| d| dfv rtd| d t|tr0|| dv r2t| d d S d S d S )Nzxmp:MetadataDatezpdf:Producerz
Update to zP will be overwritten because metadata was opened with set_pikepdf_as_editor=True
dc:creatorz# should be set to a list of strings)r   r   rC   rD   rM   r"   errorr  r,   r,   r-   r    s   	
zPdfMetadata._setitem_check_argsr   r   c                   s|   t  fddtD }t|ttt|}d }|dkr%tttddi} D ]}tj|tttd|d}t||_	q'd S )Nc                 3  s"    | ]}t  |jr|jV  qd S r8   )rM   r%   r#   )r   cr   r,   r-   r     s    
z1PdfMetadata._setitem_add_array.<locals>.<genexpr>r3   langz	x-defaultZlir  )
r   r   r   
SubElementr"   r   
XMP_NS_RDF
XMP_NS_XMLrR   r   )r~   r   r   r#   seqZ
tag_attribr   elr,   r  r-   _setitem_add_array  s   zPdfMetadata._setitem_add_arrayc           	      C  s4  t | |\}}}}|r@t|ts6|| dkr'|j|= | |t| d S td| d| dt	| |
|t| d S t|tt
fr\|dD ]}|| qL| || d S t|tr|dD ]}|| qft| |tv r| |tt|g d S t||_d S td| d| dt	| )Nr  Setting  to  with type r   )r   r   rM   r"   r   r  r  rR   rP   r$   setr  r   remove	LANG_ALTSr2   r   )	r~   ry   r   r  r   r  _oldval_parentchildr,   r,   r-   r    s&   

zPdfMetadata._setitem_updatec                 C  s   |   }t| |tv rtt|g}t|ttfr@t	j
|tttdtttddid}t	
|| |}| || d S t|tr`t	j
|tttdttdd| |t|id}d S td| d| dt| d )NDescriptionaboutrL   r  r  r  r   )r   r"   r   r#  r2   rR   rM   r  r!  r   r  r   r  r  rP   r$   )r~   ry   r   r   r   r   Z_rdfdescr,   r,   r-   r    s(   


 	zPdfMetadata._setitem_insertc                 C  s   |  ||dS r   )r   )r~   ry   r   r,   r,   r-   __setitem__  r   zPdfMetadata.__setitem__c                 C  s   | j stdz?t| |\}}}}|r?|j|= t|jdkr6t|dkr9ttd|jv r<|| W d S W d S W d S W d S || W d S  t	yR   t
|d w )Nr  rU   r   r(  )r   r  r   r   r  r  r   r  r"  r  r   )r~   ry   r   r  r$  parentr,   r,   r-   __delitem__  s"   
zPdfMetadata.__delitem__c                 C  sJ   | j s|   ttd}ttd}z	| | | |  W S  ty$   Y dS w )a  Return the PDF/A conformance level claimed by this PDF, or False.

        A PDF may claim to PDF/A compliant without this being true. Use an
        independent verifier such as veraPDF to test if a PDF is truly
        conformant.

        Returns:
            The conformance level of the PDF/A, or an empty string if the
            PDF does not claim PDF/A conformance. Possible valid values
            are: 1A, 1B, 2A, 2B, 2U, 3A, 3B, 3U.
        partZconformancerL   )r|   r}   r   XMP_NS_PDFA_IDr   )r~   key_partZkey_conformancer,   r,   r-   pdfa_status2  s   

zPdfMetadata.pdfa_statusc                 C  s8   | j s|   ttd}z| | W S  ty   Y dS w )a  Return the PDF/X conformance level claimed by this PDF, or False.

        A PDF may claim to PDF/X compliant without this being true. Use an
        independent verifier such as veraPDF to test if a PDF is truly
        conformant.

        Returns:
            The conformance level of the PDF/X, or an empty string if the
            PDF does not claim PDF/X conformance.
        ZGTS_PDFXVersionrL   )r|   r}   r   XMP_NS_PDFX_IDr   )r~   Zpdfx_versionr,   r,   r-   pdfx_statusJ  s   

zPdfMetadata.pdfx_statusc                 C  s   | j dddS )NF)r   r   )r   decoder   r,   r,   r-   __str__`  s   zPdfMetadata.__str__)TTT)r   r   r   r   r   r   r   r   )FF)r   r   r   r   rK   r   )rK   r   )r   r7   rK   r   )T)rz   r   rK   r"   )rL   )rz   r   )ry   r   )F)ry   r   r   r
  r   r   )r   r   r  r"   rK   r   )r   r   rK   r   )ry   r   r   r
  )rK   r"   )?r'   r(   r)   r*   rw   	XMP_NS_DCr   Authorrp   SubjectZTitler   r   r   r   ZCreationDaterr   ZCreatorZModDater   r+   r    r   dictr   r;   r@   rA   rF   r   r   r   r   r}   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r  r  r	  r   r  r  r  r  r)  r+  propertyr/  r1  r3  r,   r,   r,   r-   r   ,  s   
 
4
+

*	
(



r   )r6   r7   )r=   )rB   r7   )rG   )rH   rI   rJ   r"   rK   r"   )rS   r   rK   r"   )rH   r"   rK   r   )]r*   
__future__r   loggingresysabcr   r   r   	functoolsr   ior   typingr	   r
   r   r   r   warningsr   Zlxmlr   Z
lxml.etreer   r   rL   r   r   r   r   r   rB   r   version_infor   r   collections.abcZpikepdfr   r4  r   r-  r0  ZXMP_NS_PHOTOSHOPZXMP_NS_PRISMZXMP_NS_PRISM2ZXMP_NS_PRISM3r  r   ZXMP_NS_XMP_MMZXMP_NS_XMP_RIGHTSr    r+   Z_uri_prefixZregister_namespacer  r   rE   r   r!   	getLoggerr'   rC   r   r/   r  r2   appendr!  addr   	frozensetr"   r#  compilerQ   r>   r;   r@   rA   rF   rR   r\   rc   rd   rp   rr   rw   r   r   r,   r,   r,   r-   <module>   s   






 	