o
    vhG                  	   @   s  d dl Z d dlmZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZ d dlZd dlmZ d dlmZmZ ddlmZ dd	lmZmZ d
dlmZ dejdefddZe dZdede
ej fddZdejde
ej fddZ dejdeeejef  fddZ!dejdej"fddZ#dejdeej"ej$ej%ef fddZ&dejdej'fd d!Z(d"ej"dej)fd#d$Z*d%e	ej" d&efd'd(Z+G d)d* d*ej,Z-ej./ej0e'd+fZ1	,d`d-ej2de
ej' fd.d/Z3d0eejej'f d1ejd-ej2fd2d3Z4d0eejej'f d1ejd-ej2fd4d5Z5d0eejej'f d1ejd6eeedf de6fd7d8Z7	9dad:ej8d%eej" fd;d<Z9d:ej8d0eejej'f de	ej" fd=d>Z:d?ej'fd@dAZ;dBej'dej2fdCdDZ<d%e	ej" fdEdFZ=e dGZ>dHdI dJD Z?G dKdL dLe@ZAdejde
e fdMdNZBdejdOe
e dej"fdPdQZCdejdOe
e dej$fdRdSZDdejdOe
e dej.fdTdUZEdejdOe
e fdVdWZFe dXZGdejdOe
e dej'fdYdZZHd[ede	ej" fd\d]ZId^d_ ZJeJ  dS )b    N)datetime)BytesIO)BinaryIODictIterableIteratorListOptionalTupleUnion)etree)genericmisc   )SecurityHandler)get_and_applyisoparse   )modelnamereturnc                 C   s   d| j | jf S )Nz{%s}%sns
local_name)r    r   `/var/www/html/hyperkenya/venv/lib/python3.10/site-packages/pyhanko/pdf_utils/metadata/xmp_xml.py_tag   s   r   z\{(.*)}(.*)tagc                 C   s0   t | }|d urtj|d|ddS d S )Nr   r   r   )TAG_REmatchr   ExpandedNamegroup)r   mr   r   r   _untag   s   
r#   elemc                 C   s   | j }t|trt|S d S N)r   
isinstancestrr#   )r$   r   r   r   r   _name&   s   
r(   c                 c   sL    | j  D ]\}}t|tsJ t|tsJ t|}|r#||fV  qd S r%   )attribitemsr&   r'   r#   )r$   	attr_namevaluer   r   r   r   
iter_attrs.   s   
r-   descriptionr,   c                 C   sN   |D ]"\}}t |jtr|js| t||j qtt| t|| qd S r%   )	r&   r,   r'   
qualifierssetr   add_xmp_valuer   
SubElement)r.   r,   kvr   r   r   _xmp_struct_to_xml:   s
   r5   	containerc                 C   s   t |tr
|| _d S t |tjr| ttjt| d S t |tjr3t	
| ttj}t|| d S t |tjrXt	
| t|j }|jD ]}tt	
|ttj| qGd S ttt|r%   )r&   r'   textr   XmpUrir0   r   RDF_RESOURCEXmpStructurer   r2   RDF_DESCRIPTIONr5   XmpArray
array_typeas_rdfentriesr1   RDF_LINotImplementedErrortype)r6   r,   r.   arrr4   r   r   r   _add_inner_valueD   s,   


rD   c                 C   s   |j }|jr3t| ttj}|jddD ]\}}tt|t|| qt	t|ttj
|j nt	| |j |jd urJ| ttj|j d S d S )NF)	with_lang)r/   has_non_lang_qualsr   r2   r   r   r;   
iter_qualsr1   rD   	RDF_VALUEr,   langr0   XML_LANG)r6   r,   qualsr.   r3   r4   r   r   r   r1   `   s    
r1   rootc                 C   s6   t ttj}t||  |ttjd t |S )N )	r   Elementr   r   r;   r5   r0   	RDF_ABOUTElementTree)rL   r.   r   r   r   _xmp_root_as_xml_treeu   s   

rQ   rootsoutc                 C   s   | dd | dtjd  dtj dd | dtjd  dd | D ]}t|}|j |d	dd
 q,| d | d | d d S )Nu6   <?xpacket begin="﻿" id="W5M0MpCehiHzreSzNTczkc9d"?>
utf-8z<x:xmpmeta xmlns:x="xz" x:xmptk="z">
z<rdf:RDF xmlns:rdf="rdfF)xml_declarationencodings   
</rdf:RDF>s   
</x:xmpmeta>s   
<?xpacket end="r"?>)writeencoder   NSVENDORrQ   )rR   rS   rL   xmp_datar   r   r   serialise_xmp}   s"   	

r^   c                
       s   e Zd Z				ddee dee dee dee f fddZede	e
j d	d fd
dZed	e	e
j fddZde
jfddZd	efddZ  ZS )MetadataStreamN	dict_datastream_dataencoded_datahandlerc                    s:   d | _ t j||||d td| d< td| d< d S )N)r`   ra   rb   rc   z	/Metadataz/Typez/XMLz/Subtype)_xmpsuper__init__r   pdf_name)selfr`   ra   rb   rc   	__class__r   r   rf      s   zMetadataStream.__init__xmpr   c                 C   s   |  }||_ |  |S r%   )rd   _reserialise)clsrk   stmr   r   r   from_xmp   s   zMetadataStream.from_xmpc                 C   s    | j d u rtt| j| _ | j S r%   )rd   	parse_xmpr   data)rh   r   r   r   rk      s   
zMetadataStream.xmpmetac                 C   s"   t || jd| _|   d | _d S )N)rR   )update_xmp_with_metark   rd   rl   _encoded_data)rh   rr   r   r   r   rs      s   
z#MetadataStream.update_xmp_with_metac                 C   s2   t  }| jd us
J t| j| |  | _}|S r%   )r   rd   r^   getvalue_data)rh   rn   rq   r   r   r   rl      s
   zMetadataStream._reserialise)NNNN)__name__
__module____qualname__r	   dictbytesr   rf   classmethodr   r   r:   ro   propertyrk   DocumentMetadatars   rl   __classcell__r   r   ri   r   r_      s(    r_   	x-defaultFmeta_strc                 C   s   t | tjr7| jdkr|rtntj }n| jrd| j nd}tjtj	t
| j | f}t
| j|S t | trK|r@tntj }t
| |S d S )NDEFAULT-rM   )r&   r   StringWithLanguage	lang_codeLANG_X_DEFAULTr   
Qualifiersofcountry_coderJ   XmpValuer,   r'   )r   lang_xdefaultrK   ccr   r   r   _meta_string_as_value   s   

r   fieldskeyc                 C   s$   t |dd}|d ur|| |< d S d S )NFr   )r   r   r   r   valr   r   r   _write_meta_string   s   r   c                 C   s4   t |dd}|d urttj|g| |< d S d S )NTr   )r   r   r   r<   alternativer   r   r   r   _write_lang_alternative   s   r   	meta_datec                 C   sL   t |tr|}n|dkrtjt d}ndS t|jdd | |< dS )Nnow)tzFr   )microsecondT)	r&   r   r   tzlocalget_localzoner   r   replace	isoformat)r   r   r   r,   r   r   r   _write_meta_date   s   
r   r   rr   c                 C   s   dd |D }t | |S )Nc                 S       i | ]}|D ]\}}||qqS r   r   .0rL   r3   r4   r   r   r   
<dictcomp>  
    
z(update_xmp_with_meta.<locals>.<dictcomp>)_populate_xmp_with_meta)rr   rR   r   r   r   r   rs      s   
rs   c                 C   s   t |tj| j t|tjtj | jrt|g| j	S t |tj
| j t|tj| j t| jdd}|d urDttj|g|tj< t|tj| j t|tj| j | jrbt|tjd| j t|g| j	S )NFr   ,)r   r   XMP_MODDATElast_modifiedr   PDF_PRODUCERr\   xmp_unmanagedr:   	xmp_extraXMP_CREATEDATEcreatedr   DC_TITLEtitler   authorr   r<   ordered
DC_CREATORDC_DESCRIPTIONsubjectXMP_CREATORTOOLcreatorkeywordsPDF_KEYWORDSjoin)rr   r   r   r   r   r   r   	  s    
r   xmp_valc                 C   sJ   t | jtr
| j}ntdzt|}W |S  ty$   td|dw )NzWrong type for XMP datezFailed to parse z
 as a date)r&   r,   r'   XmpXmlProcessingErrorr   
ValueError)r   dt_strdtr   r   r   	_parse_dt"  s   
r   r   c                 C   s   d }| }t | jtjrt| jjdkr| jjd }t |jtrU|j}|j}|j}|s.|}|S |dkr;tj	|dd}|S |
dd}tj	||d t|dkrQ|d nd d}|S )Nr   r   r   )r   r   r   )r   r   )r&   r,   r   r<   lenr?   r'   r/   rI   r   split)r   resultfocusval_strrK   rI   
componentsr   r   r   _simplify_meta_str.  s*   
r   c           
      C   s  dd | D }i }| tjd }|d urt||d< | tjd }|d ur+t||d< t|tjt}|d ur:||d< t|tjt}|d urI||d< t|tj	t}|d urX||d< | tj
d }|d urqt|jtrq|jd|d	< | tjd }	|	d urt|	jtr|	j|d
< tjdi |S )Nc                 S   r   r   r   r   r   r   r   r   J  r   z!meta_from_xmp.<locals>.<dictcomp>r   r   r   r   r   r   r   r   r   )getr   r   r   r   r   r   r   r   r   r   r&   r,   r'   r   r   r~   )
rR   
all_fieldskwargsmod_datecreate_dater   r   r   r   r   r   r   r   meta_from_xmpI  s8   
r   sC   \s*<\?\s?xpacket begin="(...?)" id="W5M0MpCehiHzreSzNTczkc9d"\s?\?>c                 C   s   i | ]}d  ||qS )u   ﻿)rZ   )r   encr   r   r   r   r  s    
r   )rT   zutf-16bezutf-16leutf32c                   @   s   e Zd ZdS )r   N)rw   rx   ry   r   r   r   r   r   x  s    r   c                 C   s   |  ttjd S r%   )r   r   r   rJ   )r$   r   r   r   _check_lang|  s   r   rI   c                 C   s   i }| D ]}t |}|d ur"||v rtd| dt||d||< qt| D ]\}}|tjkrDt|r;t|}n|}t	|||< q't
|S )NzDuplicate field z in XMP structure valuerI   )r(   r   _proc_xmp_valuer-   r   rJ   HTTP_URI_REr   r8   r   r:   )r$   rI   r   childr   
attr_valuer,   r   r   r   _proc_xmp_struct  s$   



r   c                    sR   t  }|d u r
ttjjtjjtjjd|j } fdd}t|t	| S )N)SeqBagAltc                  3   s,     D ]} t | tjkrt| dV  qd S Nr   )r(   r   r@   r   )lir$   rI   r   r   _entries  s   z_proc_xmp_arr.<locals>._entries)
r(   r   r   XmpArrayTypeORDERED	UNORDEREDALTERNATIVEr   r<   list)r$   rI   r   arr_typer   r   r   r   _proc_xmp_arr  s   r   c                    s    fdd}t jj|  S )Nc                  3   sH    rt jt fV   D ]} t| }|t jkr!|t| fV  qd S r%   )r   rJ   r   r(   rH   r   )q_xmlq_namer   r   r   _quals  s   
z#_extract_qualifiers.<locals>._quals)r   r   r   )r$   rI   r   r   r   r   _extract_qualifiers  s   r   c                 C   sr   zt dd | D }W n ty   d }Y nw |d ur*t||j}t| |}||fS t| |}tj|}||fS )Nc                 s   "    | ]}t |tjkr|V  qd S r%   )r(   r   rH   r   cr   r   r   	<genexpr>       z#_unwrap_resource.<locals>.<genexpr>)	nextStopIterationr   r,   r   r   r   r   lang_as_qual)r$   rI   	rdf_valueinner_valuerK   r   r   r   _unwrap_resource  s   

r   z
^https?://c           	      C   sh  t | p|}| ttjd }|dkr!t| |d\}}t||S |d ur-td|dt| }|dkrm| ttj	d }|d urJtt
|S | jrXt| jtj|S | jrctt| |S tdtj|S |dkr| d }t|}|tjtjtjfv rt||}tj|}n|tjkrt||\}}ntd| d	t||S td
t |  d)NResourcer   zParse type z is not supportedr   rM   r   zCannot process tag with name z as an XMP value formzTag with name z has more than one child.)r   r   r   r   RDF_PARSE_TYPEr   r   r   r   r9   r8   r7   r   r   r)   r   r(   RDF_SEQRDF_ALTRDF_BAGr   r;   )	r$   rI   
parse_typer   rK   child_counturi_strr   r   r   r   r   r     sH   



r   inpc              
   C   s*  |  d}t|}|sd}d}n|d}t|d}t|d}| | |   |}t	j
ddd}z	t	j||d}W n tyP }	 ztd	|	d }	~	ww td
d |t	jD rbtdt|}
|
tjkrn|}n |
tjkrztdd |D }W n ty   tdw tddd |D S )N   rT   r   r   FT)resolve_entitiesremove_comments)parserzFailed to parse XMP XMLc                 s   s    | ]}d V  qdS )r   Nr   )r   _r   r   r   r     s    zparse_xmp.<locals>.<genexpr>zXML entities not supportedc                 s   r   r%   )r(   r   RDF_RDFr   r   r   r   r   (  r   zNo rdf:RDF node in x:xmpmetaz%XMP root must be rdf:RDF or x:xmpmetac                 S   s&   g | ]}t |tjkrt|d dqS r   )r(   r   r;   r   )r   noder   r   r   
<listcomp>.  s
    
zparse_xmp.<locals>.<listcomp>)readXMP_HEADER_PATTERNr   r!   BOM_REGISTRYr   r   seekdecoder   	XMLParser
fromstring	Exceptionr   anyiterEntityr(   r   r   	X_XMPMETAr   r   )r   headerheader_matchrX   start_offsetbominp_strr   rL   e	root_namerdf_rootr   r   r   rp     s@   






rp   c                  C   s$   t j D ]
\} }t| | qd S r%   )r   r[   r*   r   register_namespace)prefixurir   r   r   register_namespaces5  s   r  )F)r   )Krer   ior   typingr   r   r   r   r   r	   r
   r   r   lxmlr   pyhanko.pdf_utilsr   r   	crypt.apir   r   r   rM   r   r    r'   r   compiler   r#   _Elementr(   r-   r:   r5   r<   r8   rD   r   r1   _ElementTreerQ   r^   StreamObjectr_   r   r   rJ   r   
MetaStringr   r   r   boolr   r~   rs   r   r   r   r   r  r  r   r   r   r   r   r   r   r   r   rp   r  r   r   r   r   <module>   s    (



,








%



1-
