
    DjI                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ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  ej        e          Z eh d          ZdZ e
d           G d d                      ZdTdZdUdZdVd Z dWd#Z!dXd%Z"dYd)Z#dZd+Z$d[d-Z%d\d.Z&d]d0Z'dZd1Z(d^d4Z)d_d5Z*d`d8Z+dad;Z,dbd<Z-dcd>Z.ddd@Z/dedBZ0dfdGZ1dgdHZ2dhdJZ3didNZ4djdOZ5dkdRZ6dkdSZ7dS )lz9Local materialization helpers for the Photos sync engine.    )annotationsN)	dataclass)datetime	timedeltatimezone)Path)Any)ElementTree   )decode_encrypted_textrecord_field_value>   .arw.cr2.cr3.crw.dng.nef.nrf.nrw.orf.pef.raf.rw2zpyicloud photos-cloudkitT)slotsc                      e Zd ZU dZded<   dZded<   dZded<   dZded	<   dZded
<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dS )PhotoXmpMetadataz$Metadata exported into XMP sidecars.strtoolkitN
str | Nonetitledescription
int | Noneorientationmakedigital_source_typelist[str] | Nonekeywordsfloat | Nonegps_altitudegps_latitudegps_longitude	gps_speeddatetime | Nonegps_timestampcreate_daterating)__name__
__module____qualname____doc____annotations__r    r!   r#   r$   r%   r'   r)   r*   r+   r,   r.   r/   r0        h/home/thesage/.hermes/venv/lib/python3.11/site-packages/pyicloud/services/photos_cloudkit/materialize.pyr   r   '   s         ..LLLE"K"""""K""""D&*****!%H%%%%!%L%%%%!%L%%%%"&M&&&&"I""""%)M))))#'K''''Fr7   r   resourcer	   returnboolc                    t          | dd          pd                                }d|v rdS t          t          | dd                    j                                        }|t          v S )z7Return ``True`` when a resource looks like a RAW image.typeN rawTfilename)getattrlowerr   suffixRAW_EXTENSIONS)r9   resource_typerC   s      r8   resource_is_rawrF   ;   si     Xvt44:AACCMt'(J3344;AACCF^##r7   	resourcesdict[str, Any]policyr   c                &   t          |           }|dk    r|S |                    d          }|                    d          }|||S t          |          }t          |          }|dk    r|r|s||c|d<   |d<   n|dk    r|r|s||c|d<   |d<   |S )zEReturn a resource mapping with RAW+JPEG original/alternative aligned.zas-isoriginalalternative)dictgetrF   )rG   rI   alignedrK   rL   original_is_rawalternative_is_raws          r8   apply_align_raw_policyrR   E   s     9ooG{{:&&H++m,,K;.%h//O(55 2?6A83
W]33	=	 	 _	 =O	 6A83
W]3Nr7   pathr   taken_atr   Nonec                   | j                                         dvrdS 	 |                                 }n,# t          $ r t                              d|            Y dS w xY wt          |          rdS t          ||                    d                    }|t                              d|            dS 	 | 	                    |           dS # t          $ r t                              d|            Y dS w xY w)zBWrite EXIF created timestamps for JPEGs that do not have them yet.>   .jpg.jpegNz!Failed to read %s for EXIF updatez%Y:%m:%d %H:%M:%S)
jpeg_bytes	timestampz$Failed to update EXIF datetime on %sz$Failed to write %s after EXIF update)
rC   rB   
read_bytesOSErrorLOGGERdebug_jpeg_has_exif_datetime_insert_exif_datetime_segmentstrftimewrite_bytes)rS   rT   dataupdateds       r8   set_exif_datetime_if_missingre   Z   s.    {"333     8$??? t$$ +##$788  G ;TBBBC!!!!! C C C;TBBBBBBCs!   4 %AA5C %C54C5asset_recorddry_runc                &   t          |          }|dS |                     | j         d          }|                                rt	          |          sdS |rdS |                    t          j        t          |          dd                     dS )zBWrite or refresh a generated XMP sidecar for the given asset file.Nz.xmpzutf-8T)encodingxml_declaration)	build_xmp_metadata	with_namenameexists_can_overwrite_xmp_sidecarrb   r
   tostring_render_xmp_xml)rS   rf   rg   metadatasidecar_paths        r8   write_xmp_sidecarrt   v   s     ",//H>>TY"4"4"455L %?%M%M  H%% 	
 	
 	
    r7   PhotoXmpMetadata | Nonec                *   | dS t          | d          }t          | d          }t          |           }t          |           }t          |           }t	          |           }t          |           }t          | d          }|dk    rdnd}	|dk    rdnd}
t          t          ||||	|
||	                    d          |	                    d	          |	                    d
          |	                    d          |	                    d          ||          S )z;Build an XMP metadata payload from a CloudKit asset record.N
captionEncextendedDescEncassetSubtypeV2   
ScreenshotscreenCapturealtitudelatitude	longitudespeedrZ   )r   r    r!   r#   r$   r%   r'   r)   r*   r+   r,   r.   r/   r0   )
r   _extract_orientation_extract_keywords_extract_location_extract_create_date_extract_ratingr   r   PYICLOUD_XMP_TOOLKITrN   )rf   r    r!   r#   r'   locationr/   r0   asset_subtyper$   r%   s              r8   rk   rk      s#    t!,==E'6GHHK&|44K ..H ..H&|44K\**F&|5EFFM(A--<<4D-:a-?-?//T$/\\*--\\*--ll;//,,w''ll;//   r7   record
field_namebytes | Nonec                   t          | |          }|d S t          |t                    r|}n-t          |t                    r|                    d          }nd S 	 t          j        |          S # t          $ r |cY S w xY w)Nascii)r   
isinstancebytesr   encodebase64	b64decode	Exception)r   r   valuer?   s       r8   _decode_field_bytesr      s    vz22E}t% 	E3		 ll7##t$$$   


s   A/ /A>=A>r"   c                   t          | d          }|r|                    d          rd S 	 t          j        t	          j        |t          j                             }n# t          $ r Y d S w xY w|                    d          }t          |t                    sd S |                    d          }t          |t                    r|nd S )NadjustmentSimpleDataEnc)s   crdts   bplist00rr   r#   )r   
startswithjsonloadszlib
decompress	MAX_WBITSr   rN   r   rM   int)rf   r?   adjustmentsrr   r#   s        r8   r   r      s    
l,E
F
FC #..!788 tjt~o!F!FGG   ttz**Hh%% t,,}--K$[#66@;;D@s   2A 
A,+A,r&   c                    t          | d          }|sd S 	 t          j        |          }n# t          $ r Y d S w xY wt	          |t
                    sd S d |D             S )NkeywordsEncc                ,    g | ]}t          |          S r6   )r   ).0items     r8   
<listcomp>z%_extract_keywords.<locals>.<listcomp>   s    ((($CII(((r7   )r   plistlibr   r   r   list)rf   r?   r   s      r8   r   r      s    
lM
:
:C ts##   tteT"" t((%((((s   + 
99c                   t          | d          }|si S 	 t          j        |          }n# t          $ r i cY S w xY wt	          |t
                    si S |                    d          }|t	          |t                    sd }t          |                    d                    t          |                    d                    t          |                    d                    t          |                    d                    |dS )NlocationEncrZ   altlatlonr   )r}   r~   r   r   rZ   )	r   r   r   r   r   rM   rN   r   _maybe_float)rf   r?   r   rZ   s       r8   r   r      s   
lM
:
:C 	>#&&   			h%% 	[))IZ	8%D%D	 e!4!455 e!4!455!(,,u"5"566hll73344  s   + ::r-   c                n   t          | d          }t          |t                    r|S t          |t          t          f          sd S t          | d          }t          |t          t          f          rt          |          nd}t          j        |dz  t          t          |                              S )N	assetDatetimeZoneOffsetr   g     @@)seconds)tz)r   r   r   r   floatfromtimestampr   r   )rf   
asset_dateoffsetoffset_secondss       r8   r   r      s    #L+>>J*h'' j3,// t.>??F$.vU|$D$DKS[[[!N!VIn55566   r7   c                    t          | d          dk    rdS t          | d          dk    rdS t          | d          dk    rdS d S )NisHiddenr   	isDeleted
isFavorite   )r   )rf   s    r8   r   r     sU    ,
33q88r,4499r,55::q4r7   r   r(   c                \    t          | t          t          f          rt          |           S d S N)r   r   r   )r   s    r8   r   r     s)    %#u&& U||4r7   c                D   	 t          j        |                                           }n# t           j        $ r Y dS w xY w|j                            d          p|j                            d          }t          |t                    o|                    t                    S )NFz{adobe:ns:meta/}xmptkx:xmptk)
r
   parsegetroot
ParseErrorattribrN   r   r   r   r   )rS   rootr   s      r8   ro   ro     s     &&..00!   uukoo566T$+//):T:TGgs##P(:(:;O(P(PPs   &) <<rr   ElementTree.Elementc                j   t          j        dd| j        d          }t          j        |dddi          }t          j        ddd	d
          }t          j        dddd          }t          j        dddd          }t          j        dddd          }t          j        dddd          }t          j        dddd          }| j        r| j        t          j        |d          _        | j        r| j        t          j        |d          _        | j        rNt          j        |d          }	t          j        |	d          }
| j        D ]}|t          j        |
d          _        | j        ,t          | j                  t          j        |d          _        | j
        r| j
        t          j        |d          _        | j        r| j        t          j        |d          _        | j        ,t          | j                  t          j        |d          _        | j        ,t          | j                  t          j        |d          _        | j        ,t          | j                  t          j        |d          _        | j        ,t          | j                  t          j        |d           _        | j        2| j                            d!          t          j        |d"          _        | j        N| j                            d!          }|t          j        |d#          _        |t          j        |d$          _        | j        ,t          | j                  t          j        |d%          _        ||||||fD ]7}t)          t+          |                    d&k    r|                    |           8|S )'Nz	x:xmpmetazadobe:ns:meta/)zxmlns:xr   zrdf:RDFz	xmlns:rdfz+http://www.w3.org/1999/02/22-rdf-syntax-ns#zrdf:Descriptionr>   z http://purl.org/dc/elements/1.1/)	rdf:aboutzxmlns:dczhttp://ns.adobe.com/exif/1.0/)r   z
xmlns:exifz+http://iptc.org/std/Iptc4xmpExt/2008-02-29/)r   zxmlns:Iptc4xmpExtz"http://ns.adobe.com/photoshop/1.0/)r   zxmlns:photoshopzhttp://ns.adobe.com/tiff/1.0/)r   z
xmlns:tiffzhttp://ns.adobe.com/xap/1.0/)r   z	xmlns:xmpzdc:titlezdc:descriptionz
dc:subjectzrdf:Seqzrdf:liztiff:Orientationz	tiff:MakezIptc4xmpExt:DigitalSourceTypezexif:GPSAltitudezexif:GPSLatitudezexif:GPSLongitudezexif:GPSSpeedz%Y-%m-%dT%H:%M:%S%zzexif:GPSTimeStampzxmp:CreateDatezphotoshop:DateCreatedz
xmp:Ratingr   )r
   Elementr   
SubElementr    textr!   r'   r#   r   r$   r%   r)   r*   r+   r,   r.   ra   r/   r0   lenr   append)rr   xml_docrdfdescription_dcdescription_exifdescription_iptcdescription_photoshopdescription_tiffdescription_xmpsubjectseqkeywordrZ   r!   s                 r8   rq   rq     sU   !$1ABB G 
 	CD C !(:	
 	
 N #*9	
 	
  #*!N	
 	
  (/C	
 	
  #*9	
 	
  ")7	
 	
 O ~ QBJ.~z::? & % 	,	
 	

 A(FF$Wi88( 	A 	AG9@K"31166'LO M
 M
/1CDDI } SEM]/==B# . - 	+	
 	
 (LO!M
 M
/1CDDI (LO!M
 M
/1CDDI )MP"N
 N
/1DEEJ %ILJ
 J
/AAF ) '001FGG 	1	
 	

'(112GHH	IR0@AAF  	!#	
 	
 "EHOF
 F
==B
 	 	$ 	$ tK  !!A%%JJ{###Nr7   rY   r   c                x  	
 t          |           

dS t          
          }|dS t          
d|          }|dS t          
|          }|dS |\  }}dD ]}t	          
||          }|r dS t          
|d          }|dS t          
|          }|dS |\  }	t          	
fddD                       S )NF   )2  Ti  c              3  :   K   | ]}t          |          V  d S r   )_read_ascii_tag)r   tagexif_ifdexif_payloads     r8   	<genexpr>z*_jpeg_has_exif_datetime.<locals>.<genexpr>  s/      XX|Xs;;XXXXXXr7   )    )_extract_exif_payload_tiff_byte_order_read_uint32_parse_tiff_ifdr   _read_long_tagany)rY   
byte_orderifd0_offsetparsed_ifd0r   r   exif_ifd_offsetr   r   s            @@r8   r_   r_     s   (44Lu!,//Ju|Q
;;Ku\;77F~uGAt  dC88 	44	 %\4@@Ou\?;;F~uKAxXXXXXGWXXXXXXr7   c                   t          |           dk     s| d d         dk    rd S d}|dz   t          |           k    r| |         dk    rd S | |dz            }|dv rd S t          j        d| |dz   |dz                      d         }|dk     s|dz   |z   t          |           k    rd S |dz   }|dz   |z   }|d	k    r| ||d
z            dk    r| |d
z   |         S |}|dz   t          |           k    d S )Nr            r   >         >Hr            Exif  )r   structunpack)rY   indexmarkersegment_lengthpayload_startpayload_ends         r8   r   r     s;   
:j!n;;tE
!)s:
&
&e$$4EAI&\!!4tZ	EAI8M-NOOPQRA^!;c*oo!M!M4	ai.0dNN==1+<<=PPma/+=>>! !)s:
&
&" 4r7   r   c                p    t          |           dk     rd S | d d         dk    rdS | d d         dk    rdS d S )Nr      II   <   MM   >)r   )r   s    r8   r   r     sQ    
<1tBQB5  tBQB5  t4r7   rZ   c                &   t          |           dk     s| d d         dk    rd S |                    d          dz   }t          |          }d|z   }dt          j        dt          |          dz             z   |z   }| d d         |z   | dd          z   S )Nr   r   r       r   s   r   )r   r   _build_exif_tiffr   pack)rY   rZ   ascii_timestamptiffpayloadsegments         r8   r`   r`     s    
:j!n;;t&&w//'9OO,,D$GFKc'llQ.>???'IGbqb>G#jn44r7   r  c                   d}|t          j        dd          z   t          j        dd          z   }d}d}||z   }|t          |           z   }d}||z   }|t          |           z   }	t          dt          |           |          t	          d|          g}
t          d	t          |           |          t          d
t          |           |	          g}|t          j        dt          |
                    z   d                    |
          z   t          j        dd          z   | z   t          j        dt          |                    z   d                    |          z   t          j        dd          z   | z   | z   S )Nr  z<H*   <I      r   r   r   r   r7   r   )r   r  r   _pack_ascii_entry_pack_long_entryjoin)r  r   tiff_headerr   	ifd0_sizeifd0_data_offsetr   exif_ifd_sizeexif_data_offsetdigitized_offsetr   r   s               r8   r
  r
    s   Jv{4444v{47K7KKKK I"Y.&_)=)==O$M&6'#o*>*>> 	&#o"6"68HII11D
 	&#o"6"68HII&#o"6"68HIIH 	
+dCII
&
&	'
((4..	 +dA

	 		
 +dCMM
*
*	+ ((8

	 +dA

	 	 		r7   r   r   countr   c                \    t          j        d| d|          t          j        d|          z   S )N<HHIr   r  r   r  )r   r  r   s      r8   r  r  
  s)    ;vsAu--D&0I0IIIr7   c                \    t          j        d| dd          t          j        d|          z   S )Nr   r   r   r  r!  )r   r   s     r8   r  r    s)    ;vsAq))FKe,D,DDDr7   4tuple[bytes, dict[int, tuple[int, int, int]]] | Nonec                \   t          |           dk     s|dz   t          |           k    rd S | d d         }|dk    rd}n|dk    rd}nd S t          | ||          }|d S i }|dz   }t          |          D ]}|dz   t          |           k    r d S t          | ||          }t          | |dz   |          }	t          | |dz   |          }
t          | |dz   |          }d ||	|
|hv r d S t	          |	          t	          |
          t	          |          f|t	          |          <   |dz  }||fS )	Nr  r   r  r  r  r     r   )r   _read_uint16ranger   r   )r   r   r   fmtr  entriesentry_offsetr   r   
field_type
item_countvalue_offsets               r8   r   r     su    <1
S->-> > >tbqb!JU	u		tvs33E}t/1GA:L5\\ 
 
"s<000044<s;;!,q0@#FF
!,q0@#FF
#L,2BCHHCZ>>>44 __c*oos<?P?PQC<r7   ifddict[int, tuple[int, int, int]]r   c                H   |                     |          }|d S |\  }}}|dk    s|dk     rd S |dk    rt          j        d|          d |         }n&||z   t          |           k    r| |||z            }nd S |                    d                              dd          pd S )	Nr   r   r   r  r	  r   ignore)errors)rN   r   r  r   rstripdecode)r   r.  r   entryr+  r  r-  r?   s           r8   r   r   2  s     GGCLLE}t&+#J|Q%!))tzzk$--fuf5		\!2!2	2	2<,*>>?t::g%%gh%??G4Gr7   c                `    |                     |          }|d S |\  }}}|dk    s|dk    rd S |S )Nr   r   )rN   )r   r.  r   r5  r+  r  r-  s          r8   r   r   D  sE     GGCLLE}t&+#J|Q%1**tr7   rc   r(  c                    |dz   t          |           k    rd S t          j        |                                 d| ||dz                      d         S )Nr   Hr   r   r   r   r4  rc   r   r(  s      r8   r&  r&  P  R    zCIIt=CJJLL+++T&6A:2E-FGGJJr7   c                    |dz   t          |           k    rd S t          j        |                                 d| ||dz                      d         S )Nr   Ir   r9  r:  s      r8   r   r   V  r;  r7   )r9   r	   r:   r;   )rG   rH   rI   r   r:   rH   )rS   r   rT   r   r:   rU   )rS   r   rf   r	   rg   r;   r:   rU   )rf   r	   r:   ru   )r   r	   r   r   r:   r   )rf   r	   r:   r"   )rf   r	   r:   r&   )rf   r	   r:   rH   )rf   r	   r:   r-   )r   r	   r:   r(   )rS   r   r:   r;   )rr   r   r:   r   )rY   r   r:   r;   )rY   r   r:   r   )r   r   r:   r   )rY   r   rZ   r   r:   r   )r  r   r:   r   )r   r   r  r   r   r   r:   r   )r   r   r   r   r:   r   )r   r   r   r   r:   r#  )r   r   r.  r/  r   r   r:   r   )r   r   r.  r/  r   r   r:   r"   )rc   r   r   r   r(  r   r:   r"   )8r4   
__future__r   r   r   loggingr   r   r   dataclassesr   r   r   r   pathlibr   typingr	   	xml.etreer
   mappersr   r   	getLoggerr1   r]   	frozensetrD   r   r   rF   rR   re   rt   rk   r   r   r   r   r   r   r   ro   rq   r_   r   r   r`   r
  r  r  r   r   r   r&  r   r6   r7   r8   <module>rG     s   ? ? " " " " " "       ! ! ! ! ! ! 2 2 2 2 2 2 2 2 2 2             ! ! ! ! ! ! > > > > > > > >		8	$	$     2         &$ $ $ $   *C C C C8   6       F    A A A A
) 
) 
) 
)   ,         Q Q Q Q{ { { {|Y Y Y Y<   2   5 5 5 5       FJ J J JE E E E   @H H H H$	 	 	 	K K K KK K K K K Kr7   