o
    l>jxV                     @  sN  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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 d
dlmZ d
dlmZ d
dlmZmZmZ e ZeeZ dBddZ!dCddZ"	dDdEddZ#dddFd(d)Z$dddFd*d+Z%dddFd,d-Z&dddFd.d/Z'	dDdGd1d2Z(dHd5d6Z)d7dd8dId>d?Z*G d@dA dAZ+dS )Ju+  
Exporter helpers for Apple Notes → HTML.

These functions are thin, testable wrappers around the existing decoding,
datasource hydration, rendering, and file I/O utilities. They are intentionally
pure (no global state) and perform only the minimal work needed by CLI tools
and higher-level APIs.
    )annotationsN)DictIterableListOptionalTuple)Console)CKRecord   )BodyDecoder)	notes_pb2   )CloudKitNoteDataSource)ExportConfig)NoteRendererrender_note_fragmentrender_note_pagerecordr	   returnOptional[pb.Note]c                 C  s   t | tsdS | jd}|sdS z&t |}|r t|dds#W dS t }|	|j
 tt|ddddW S  tyA   Y dS w )zDecode a Note CKRecord's TextDataEncrypted and return a parsed pb.Note.

    Returns None if body is missing or cannot be parsed.
    NTextDataEncryptedbytesdocumentnote)
isinstancer	   fields	get_valuer   decodegetattrpbNoteStoreProtoParseFromStringr   	Exception)r   rawnbmsg r&   _/home/thesage/.local/lib/python3.10/site-packages/pyicloud/services/notes/rendering/exporter.pydecode_and_parse_note    s   
r(   r   pb.Note	List[str]c                 C  s   g }| j d}|r't|dr't|dg pg D ]}t|dd }|r&|| qg }t|dg p0g D ]}|drI|jdrI|jj}|rI|| q1t }	g }
|| D ]}||	vrc|		| |
| qS|
S )NAttachmentsvalue
recordNameattribute_runattachment_infoattachment_identifier)
r   	get_fieldhasattrr   appendHasFieldr/   r0   setadd)r   r   idsfldrefrnids_from_runsrattraidseenmergedar&   r&   r'   $_attachment_ids_from_record_and_runs5   s2   



rA   note_recordconfigOptional[ExportConfig](Tuple[CloudKitNoteDataSource, List[str]]c              	   C  s  t |d}t||}|r| |}i }tt|dd}t|jD ]F\}	}
|r4td|	  t	|
 t
|
trg||
 z|
jd}|rMt|ddnd}t|dd}|r\|
j||< W q! tyf   Y q!w q!|rz| t| }tt|ddrztd	 t	| td
| W n	 ty   Y nw |jD ]}t
|tsqd}z,tt|dd D ]}|j|}t|dd}t|dd}t
|tr|r|} nqW n ty   d}Y nw |rl||j}|rlz||pd }W n ty   d}Y nw |pt }||}d|v p d|v p d|v p d|v }t|ddo,|p,|}d}z||}W n
 ty@   Y nw |rG|rlz||}W n tyZ   d}Y nw |rf|rl||krl||| qW ||fS  ty~   Y ||fS w ||fS )zBuild a CloudKit-backed Note datasource for a single note.

    Returns (datasource, attachment_ids) where attachment_ids is the merged list
    of attachment record names to which the datasource has been hydrated.
    )_configdebugFzrec_idx Mediar,   Nr-   zmedia lookup responsezattachment media resp:
%sr   r&   downloadURL audiovideomoviempegprefer_media_for_imagesT)r   rA   lookupboolr   	enumeraterecordsconsoleruleprintr   r	   add_attachment_recordr   r1   r-   r"   listkeysLOGGERinfostrgetget_attachment_utilowerr   is_image_utiget_primary_asset_urlget_thumbnail_urlset_primary_asset_url)	ck_clientrB   r   rC   dsatt_idsresp	media_maprG   rec_idxrecr8   r9   r:   mrespmrecurlkvaluparent
parent_uticonfis_imageis_avis_media_upgradecur_primary	cur_thumbr&   r&   r'   build_datasourceP   s   













Cry   rC   re   r   rf   Iterable[str]
assets_dirr\   out_dirDict[str, str]c             	   C  sd  t j|dd i }ddd}t j|}|D ]}	||	pd	 }
||
s&q||	}|r7|d
s8|ds8qzn| ||}|}zBt	|d}|
d}W d   n1 sWw   Y  |dr| ds|d }z
t || |}W n ty   |}Y nw W n ty   |}Y nw t jj|t j|d}||	| |||	< W q ty   Y qw |S )u  Download PDFs for attachments and rewrite datasource URLs to local paths.

    Returns a mapping of attachment id → relative path used in HTML.
    Only applies to PDF UTIs. Files are renamed with `.pdf` extension when the
    magic header is present.
    Texist_oksOptional[str]r   rQ   c                 S  s   t | o|  dv S )N)zcom.adobe.pdfz
public.pdfzcom.apple.paper.doc.pdf)rQ   r_   r   r&   r&   r'   _is_pdf_uti   s   
z(download_pdf_assets.<locals>._is_pdf_utirJ   http://https://rb   Ns   %PDF-z.pdfstart)r   r   r   rQ   osmakedirspathabspathr^   r_   ra   
startswithdownload_asset_toopenreadendswithreplacer"   relpathrc   )rd   re   rf   r|   r}   rC   updatedr   note_subdirr=   utirm   
saved_pathresolvedfhheadnew_pathrelr&   r&   r'   download_pdf_assets   sN   

r   c             	   C  s  t j|dd i }|pt }ddd}t j|}	|D ]}
||
p#d	 }||s,q||
}|sFz|	|
}W n t
yE   d
}Y nw |rR|dsS|dsSqzo| ||	}|}zCt|d}|d}W d
   n1 srw   Y  ||}|r| |s|| }z
t || |}W n t
y   |}Y nw W n t
y   |}Y nw t jj|t j|d}||
| |||
< W q t
y   Y qw |S )u   Download image attachments and rewrite datasource URLs to local paths.

    Returns a mapping of attachment id → relative path used in HTML.
    Applies to common image UTIs (jpeg/png/heic/webp/gif/bmp/tiff...).
    Tr   r   r   r   r   c                 S  s   z`|  dr	W dS |  drW dS |  ds|  drW dS |  dr.| d	d
 dkr.W dS t| d
krI| dd	 dkrI| d	d
 }|dv rIW dS |  drQW dS |  ds[|  dr^W dS W d S  tyj   Y d S w )Ns   z.jpgs   PNG

z.pngs   GIF87as   GIF89az.gif   RIFF      s   WEBPz.webp      ftyp)s   heics   heifs   mif1s   msf1s   hevcz.heics   BMz.bmps   II* s   MM *z.tiff)r   lenr"   r   brandr&   r&   r'   _infer_image_ext  s.   


z/download_image_assets.<locals>._infer_image_extrJ   Nr   r   r      r   r   r   r   r   )r   r   r   r   r   r^   r_   r`   ra   rb   r"   r   r   r   r   r   r   r   rc   )rd   re   rf   r|   r}   rC   r   rs   r   r   r=   r   rm   r   r   r   r   extr   r   r&   r&   r'   download_image_assets   sZ   



r   c             	   C  s  t j|dd i }ddd}t j|}|D ]}	||	pd	 }
d
|
v p4d|
v p4d|
v p4d|
v p4d|
v }|s8q||	}|rI|dsJ|dsJqz~| ||}|}zRt	|d}|
d}W d   n1 siw   Y  ||}|sd|
v r{d}nd|
v rd}|r| |s|| }z
t || |}W n ty   |}Y nw W n ty   |}Y nw t jj|t j|d}||	| |||	< W q ty   Y qw |S )u   Download audio/video attachments and rewrite datasource URLs to local paths.

    Returns a mapping of attachment id → relative path used in HTML.
    Tr   r   r   r   r   c                 S  s  zvt | dkr&| dd dkr&| dd }|dv rW dS |dv r#W dS W d	S t | dkr7| dd d
kr7W dS | dr?W dS | dsN| dsN| drQW dS | dra| dd dkraW dS | drq| dd dkrtW dS W d S W d S  ty   Y d S w )Nr   r   r   r   )s   M4A s   mp42s   isom.m4a)s   qt     moov.movz.mp4r   s   ID3z.mp3s   s   s   r   s   WAVEz.wavs   AVI z.avi)r   r   r"   r   r&   r&   r'   _infer_av_ext`  s>   
z)download_av_assets.<locals>._infer_av_extrJ   rK   rL   rN   rM   	quicktimer   r   r   r   Nzcom.apple.m4a-audior   r   r   r   r   )rd   re   rf   r|   r}   rC   r   r   r   r=   r   ru   rm   r   r   r   r   r   r   r   r&   r&   r'   download_av_assetsP  sh   
$
r   c             	   C  s   t j|dd i }t j|}|D ]l}||pd }	d|	vr!q||}
|
r2|
ds3|
ds3qzA| |
|}|}| 	ds]|d }z
t 
|| |}W n ty\   |}Y nw t jj|t j|d}||| |||< W q ty}   Y qw |S )	u   Download VCard (contact) attachments and rewrite datasource URLs to local paths.

    Returns a mapping of attachment id → relative path used in HTML.
    Tr   rJ   zpublic.vcardr   r   z.vcfr   )r   r   r   r   r^   r_   ra   r   r   r   r   r"   r   rc   )rd   re   rf   r|   r}   rC   r   r   r=   r   rm   r   r   r   r   r&   r&   r'   download_vcard_assets  s8   
r    Optional[CloudKitNoteDataSource]c                 C  s   t | ||dS )Nrz   )r   )r   re   rC   r&   r&   r'   render_fragment  s   r   r   r   c                 C  s8   | sdS t dd|  } t dd| } | d d pdS )Nuntitledz\s+ z	[^\w\- ]+-<   )resubstripr   r&   r&   r'   
_safe_name  s
   r   F	full_pagefilenametitlehtml_fragmentr   rQ   r   c          
      C  s   t j|dd |rt| |n|}|pt|  d}t j|}t jt j||}t j||g|kr8tdt	|ddd}	|	
| W d    |S 1 sPw   Y  |S )NTr   z.htmlz!filename must stay within out_dirwutf-8)encoding)r   r   r   r   r   r   join
commonpath
ValueErrorr   write)
r   r   r}   r   r   pagefnamerootr   fr&   r&   r'   
write_html  s   
r   c                   @  s*   e Zd ZdZddddZ	ddddZdS )NoteExporterz5Orchestrator for exporting notes to HTML with assets.NrC   rD   c                 C  s"   || _ |pt | _t| j| _d S N)clientr   rC   r   renderer)selfrd   rC   r&   r&   r'   __init__  s   zNoteExporter.__init__rB   r	   
output_dirr\   r   r   r   c                 C  sj  t |}|sdS t| j||| j\}}tt| jddpd}|  }|dkrnt| jddp5tj	
|d}tj	
||j}	t| j|||	|| jd t| j|||	|| jd t| j|||	|| jd t| j|||	|| jd | j||}
d}|jd}|rzt|tr|d	}nt|tr|}W n	 ty   Y nw t| jd
d}|du rd}t||
|t||dS )z
        Export a single note record to HTML in the output directory.
        Returns the path to the written HTML file, or None if export failed (e.g. no body).
        Nexport_modearchivalr|   assets)r|   r}   rC   UntitledTitleEncryptedr   r   Tr   )r(   ry   r   rC   r\   r   r   r_   r   r   r   r-   r   r   r   r   r   renderr   r   r   r   r   r"   r   rQ   )r   rB   r   r   r   re   rf   r   assets_rootr|   r   r   	title_encr   r&   r&   r'   export  s   


zNoteExporter.exportr   )rC   rD   )rB   r	   r   r\   r   r   r   r   )__name__
__module____qualname____doc__r   r   r&   r&   r&   r'   r   
  s
    	r   )r   r	   r   r   )r   r	   r   r)   r   r*   r   )rB   r	   r   r)   rC   rD   r   rE   )re   r   rf   r{   r|   r\   r}   r\   rC   rD   r   r~   )r   r)   re   r   rC   rD   r   r\   )r   r   r   r\   )r   r\   r   r\   r}   r\   r   rQ   r   r   r   r\   ),r   
__future__r   loggingr   r   typingr   r   r   r   r   rich.consoler   pyicloud.common.cloudkitr	   decodingr   protobufr   r   ck_datasourcer   optionsr   r   r   r   r   rT   	getLoggerr   rZ   r(   rA   ry   r   r   r   r   r   r   r   r   r&   r&   r&   r'   <module>   sD    	


xB[m3
