
    h5j                    x   U d 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mZmZ ddlmZ d%dZd&d	Z G d
 de      Z G d de      Z G d de      Z G d de	      Z eedde       eeddd       eeddd       eeddd       eeddd       eedde       eedd d       eed!d"e      gZd#ed$<   y)'z9Converters for XMP <-> DocumentInfo value transformation.    )annotations)ABCabstractmethod)datetime)Any
NamedTuple)	XMP_NS_DC
XMP_NS_PDF
XMP_NS_XMP)Stringc                    d| j                   d}|| j                  d      z  }| j                  d      }|r|d   |dd |dd }}}|| | d	| z  }|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:04dz
%m%d%H%M%Sz%zr            ')yearstrftime)dstzsigntz_hourstz_minss         Y/var/www/html/qr/venv/lib/python3.12/site-packages/pikepdf/models/metadata/_converters.pyencode_pdf_dater      su    . QVVCLAM	""A	
D	B	"$Q%Aa"Qq'h	vhZq	**H    c                t   t        | t              rt        |       } | }|j                  d      r|dd }g d}|D ]'  }|j	                  |      s|j                  |d      } n |j                  dd      }g d}|D ]  }	 t        j                  ||      c S  t        d	|  d
| d      # t        $ r Y :w xY w)zDecode a pdfmark date to a Python datetime object.

    A pdfmark date is a string in a particular format, as described in
    :func:`encode_pdf_date`.
    r      N)zZ00'00'zZ00'00Zz+0000r    )z%Y%m%d%H%M%S%zz%Y%m%d%H%M%Sz%Y%m%dz-Date string does not match any known format: z
 (read as ))	
isinstancer   str
startswithendswithreplacer   strptime
ValueError)r   tutcsutcdate_formatsdate_formats         r   decode_pdf_dater0   0   s     !VF	A||DabED
  ::c?		#w'A 	
		#rAL
 $ 	$$Q44
 DQCzRSQTTUV
WW  		s    B++	B76B7c                  H    e Zd ZdZeedd              Zeedd              Zy)	ConverterzXMP <-> DocumentInfo converter.c                     y)z/Derive XMP metadata from a DocumentInfo string.N docinfo_vals    r   xmp_from_docinfozConverter.xmp_from_docinfoV       r   c                     y)z9Derive a DocumentInfo value from equivalent XMP metadata.Nr4   xmp_vals    r   docinfo_from_xmpzConverter.docinfo_from_xmp[   r8   r   Nr6   
str | Nonereturnr   )r;   r   r?   r>   )__name__
__module____qualname____doc__staticmethodr   r7   r<   r4   r   r   r2   r2   S   s=    )>  > H  Hr   r2   c                  2    e Zd ZdZedd       Zed        Zy)AuthorConverterz-Convert XMP document authors to DocumentInfo.c                    | gS )z*Derive XMP authors info from DocumentInfo.r4   r5   s    r   r7   z AuthorConverter.xmp_from_docinfod   s     }r   c                h    t        | t              r| S | | dgk(  rydj                  d | 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.
        Nz; c              3  &   K   | ]	  }||  y w)Nr4   ).0authors     r   	<genexpr>z3AuthorConverter.docinfo_from_xmp.<locals>.<genexpr>t   s     LF9KLs   )r$   r%   joinr:   s    r   r<   z AuthorConverter.docinfo_from_xmpi   s9     gs#N?g$/yyLgLLLr   Nr=   r@   rA   rB   rC   rD   r7   r<   r4   r   r   rF   rF   a   s-    7  
M 
Mr   rF   c                  0    e Zd ZdZed        Zed        Zy)DateConverterz"Convert XMP dates to DocumentInfo.c                   t        | t              rt        |       } | dk(  ry| j                  d      r| dd n| }t	        |      dv r-|j                         rt	        |      dk(  r|S |dd  d|dd  S t        |       j                         S )z"Derive XMP date from DocumentInfo.r"   r   r    N)      rR   -)r$   r   r%   r&   lenisdigitr0   	isoformat)r6   vals     r   r7   zDateConverter.xmp_from_docinfoz   s     k6*k*K"!,!7!7!=k!"o;s8v#++-c(a-3CBQy#ab'-CC{+5577r   c                    t        |       dv rd| vrd| j                  dd       S | j                  d      r| dd d	z   } t        t	        j
                  |             S )
zDerive DocumentInfo from XMP.)rR      Tr   rT   r"   r!   Nz+00:00)rU   r(   r'   r   r   fromisoformatr:   s    r   r<   zDateConverter.docinfo_from_xmp   sd     w<6!c&8R0122C crlX-Gx55g>??r   NrN   r4   r   r   rP   rP   w   s-    ,	8 	8 @ @r   rP   c                  :    e Zd ZU dZded<   ded<   ded<   ded<   y)	DocinfoMappinga  Map DocumentInfo keys to their XMP equivalents, along with converter.

    ``name`` is stored as the raw PDF name string (e.g. ``"/Author"``) rather
    than as a ``pikepdf.Name`` instance. This keeps the module-level
    DOCINFO_MAPPING free of persistent ``pikepdf.Object`` references, which
    nanobind reports as shutdown leaks. Consumers can pass the string directly
    to a ``pikepdf.Dictionary`` (which accepts str keys) or wrap it in
    ``pikepdf.Name()`` if a Name instance is specifically required.
    r%   nskeynameztype[Converter] | None	converterN)r@   rA   rB   rC   __annotations__r4   r   r   r_   r_      s     	G	H
I%%r   r_   creatorz/Authordescriptionz/SubjectNtitlez/TitleKeywordsz	/KeywordsProducerz	/Producer
CreateDatez/CreationDateCreatorToolz/Creator
ModifyDatez/ModDatezlist[DocinfoMapping]DOCINFO_MAPPING)r   r   r?   r%   )r   r%   r?   r   )rC   
__future__r   abcr   r   r   typingr   r   "pikepdf.models.metadata._constantsr	   r
   r   pikepdf.objectsr   r   r0   r2   rF   rP   r_   rm   rd   r4   r   r   <module>rs      s    @ " #  " P P "@ XFH HMi M,@I @2&Z &$ 9iOD9mZ>9gx6:z;=:z;=:|_mL:}j$?:|ZG	)% 	r   