o
    l>j-/                     @  s  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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mZmZ ddlmZmZmZmZmZ dd	l m!Z! e"e#Z$d
Z%G dd de&Z'G dd de'Z(G dd de'Z)G dd de'Z*G dd dZ+dS )a   
Low-level CloudKit client for the Notes container.

This "escape hatch" is also used internally by NotesService to implement
developer-friendly methods. It returns typed Pydantic models from
pyicloud.services.notes_models.cloudkit and hides HTTP details.
    )annotationsN)DictIterableIteratorListNoReturnOptional)ValidationError)

CKFVStringCKLookupResponseCKQueryFilterByCKQueryObjectCKQueryResponseCKZoneChangesZoneCKZoneChangesZoneReqCKZoneIDCKZoneIDReqCloudKitExtraMode)CloudKitApiErrorCloudKitAuthErrorCloudKitContainerClientCloudKitRateLimitedredact_cloudkit_url   )NOTES_ZONE_REQ)g      $@g      N@c                   @     e Zd ZdZdS )
NotesErrorzBase Notes transport error.N__name__
__module____qualname____doc__ r"   r"   S/home/thesage/.local/lib/python3.10/site-packages/pyicloud/services/notes/client.pyr   /       r   c                   @  r   )NotesAuthErrorz!Auth/PCS/cookie issues (401/403).Nr   r"   r"   r"   r#   r%   3   r$   r%   c                      $   e Zd ZdZd	d
 fddZ  ZS )NotesRateLimitedz429 Too Many Requests.Nmessagestrretry_afterOptional[float]c                      t  | || _d S N)super__init__r*   )selfr(   r*   	__class__r"   r#   r/   :      
zNotesRateLimited.__init__r-   )r(   r)   r*   r+   r   r   r    r!   r/   __classcell__r"   r"   r1   r#   r'   7       r'   c                      r&   )NotesApiErrorzCatch-all API error.Nr(   r)   payloadOptional[object]c                   r,   r-   )r.   r/   r8   )r0   r(   r8   r1   r"   r#   r/   B   r3   zNotesApiError.__init__r-   )r(   r)   r8   r9   r4   r"   r"   r1   r#   r7   ?   r6   r7   c                   @  s   e Zd ZdZdeddIddZedJddZdKddZdddddLd$d%Z	dd&dMd*d+Z
dNd/d0Zd1d2dOd7d8ZdPd:d;ZdQd=d>ZedRdBdCZedSdGdHZdS )TCloudKitNotesClientz
    Raw CloudKit service for the Notes container.

    Methods map 1:1 to CloudKit endpoints:
      - /records/query
      - /records/lookup
      - /changes/zone
    N)validation_extratimeoutbase_urlr)   base_paramsDict[str, object]r;   CloudKitExtraMode | Noner<   tuple[float, float]c             
   C  s0   t |||||dd| jd| _|| _td d S )NlowerT)r;   r<   bool_param_styleredact_urls
debug_hookz CloudKitNotesClient initialized.)r   _dump_http_debug_client_validation_extraLOGGERinfo)r0   r=   sessionr>   r;   r<   r"   r"   r#   r/   T   s   	
zCloudKitNotesClient.__init__exc	Exceptionreturnr   c                 C  s`   | j p| }t| trtt| |t| tr tt| | jd|t| tr/t	t| | j
d| )N)r*   )r8   )	__cause__
isinstancer   r%   r)   r   r'   r*   r   r7   r8   )rL   causer"   r"   r#   _raise_notes_errorj   s   



z&CloudKitNotesClient._raise_notes_erroropboolc                 C  s4   t |trt |jtr| ||jpi |j dS dS )NTF)rP   r   rO   r	   _log_validationr8   )r0   rS   rL   r"   r"   r#   _log_cloudkit_validationu   s   z,CloudKitNotesClient._log_cloudkit_validation)desired_keysresults_limitcontinuationqueryr   zone_idr   rW   Optional[List[str]]rX   Optional[int]rY   Optional[str]r   c             
   C  s   t d|j z| jj|||||d}t dt|j |W S  ttt	fyD } z| 
d|r4t d | | W Y d }~d S d }~ww )Nz"Executing query for recordType: %s)rZ   r[   rW   rX   rY   zQuery returned %d records.zrecords.queryz!Query response validation failed.)rI   rJ   
recordTyperG   rZ   lenrecordsr   r   r   rV   errorrR   )r0   rZ   r[   rW   rX   rY   resprL   r"   r"   r#   rZ      s"   	
zCloudKitNotesClient.query)rW   record_namesIterable[str]r   c             
   C  s   t |}tdt| z| jj|t|d}tdt|j |W S  tt	t
fyG } z| d|r7td | | W Y d }~d S d }~ww )Nz Executing lookup for %d records.)r[   rW   zLookup returned %d records.zrecords.lookupz"Lookup response validation failed.)listrI   rJ   r`   rG   lookupr   ra   r   r   r   rV   rb   rR   )r0   rd   rW   record_names_listrc   rL   r"   r"   r#   rg      s    
zCloudKitNotesClient.lookupzone_reqr   Iterator[CKZoneChangesZone]c             
   c  s    t d|jj d}z,| jj|dD ]!}t d|t|j |V  |jr+t 	d nt d |d7 }qW d S  t
ttfy] } z| d|rMt d | | W Y d }~d S d }~ww )	Nz#Start fetching changes for zone: %sr   ri   z$Changes page %d returned %d records.z+More changes to come, advancing sync token.zAll changes fetched.zchanges.zonez#Changes response validation failed.)rI   rJ   zoneIDzoneNamerG   iter_changesr`   ra   
moreComingdebugr   r   r   rV   rb   rR   )r0   ri   page_numzonerL   r"   r"   r#   changes   s,   


zCloudKitNotesClient.changesi   
chunk_sizeurlru   intIterator[bytes]c             
   c  sV    z| j j||dE d H  W d S  tttfy* } z| | W Y d }~d S d }~ww )Nrt   )rG   download_asset_streamr   r   r   rR   )r0   rv   ru   rL   r"   r"   r#   ry      s   z)CloudKitNotesClient.download_asset_stream	directoryc           	      C  s   dd l }dd l}tdt|| |j|dd d| j }|j	||}t
|d}| |D ]}|| q2W d    n1 sDw   Y  td| |S )Nr   z)Downloading asset from %s to directory %sTexist_okzicloud-asset-wbz Finished downloading asset to %s)osuuidrI   rJ   r   makedirsuuid4hexpathjoinopenry   write)	r0   rv   rz   r~   r   fnamer   fchunkr"   r"   r#   download_asset_to   s"   z%CloudKitNotesClient.download_asset_to	zone_namec          	   
   C  sL  t d| t d tdtddtdddd	gd
}z| jj|t|dd}|r1t d |W S W n t	yJ } zt 
d| W Y d}~nd}~ww t d tt|ddg g dd}z	| jj|d}W n tttfy } z| | W Y d}~nd}~ww |jr|jd nd}|rt|ddrt d t|jS t d| td)aZ  
        Fetch a current sync token cheaply by issuing a zero-limit query that
        requests getCurrentSyncToken=true (already in params) and reading the top-level token.

        Some deployments place the token in CKQueryResponse.syncToken; if absent,
        we fall back to a one-shot changes call (no records) to harvest a token.
        z(Fetching current sync token for zone: %sz-Attempting to get sync token via cheap query.SearchIndexesEQUALS	indexNameSTRINGrecents)typevalue)
comparator	fieldName
fieldValue)r_   filterBy)rm   )rZ   r[   z+Successfully obtained sync token via query.z;Failed to get sync token via query, falling back. Error: %sNz0Falling back to get sync token via changes call.REGULAR_CUSTOM_ZONE)rm   zoneTypeF)rl   desiredRecordTypesdesiredKeysreverserk   r   	syncTokenz2Successfully obtained sync token via changes call.z(Failed to obtain sync token for zone: %szUnable to obtain sync token)rI   rJ   rp   r   r   r
   rG   query_sync_tokenr   rM   warningr   r   rs   r   r   r   rR   zonesgetattrr)   r   rb   r7   )	r0   r   qtokeneri   envrL   zr"   r"   r#   current_sync_token   s\   







z&CloudKitNotesClient.current_sync_tokenr8   r   Nonec              
   C  s  t dsd S tdd}| dd}t jdd}z	t j|dd	 W n
 ty.   Y d S w t j|| d
| d}z%t	|ddd}t
j||d|ddd W d    n1 s[w   Y  W n	 tyj   Y nw t j|| d
| d}	zt|dd }
t|di }d }z|j}W n ty   d }Y nw t	|	dddN}|d|
 d| dt| d |rtt dd}t||kr||d | d  n|| W d    W d S W d    W d S W d    W d S 1 sw   Y  W d S  ty   Y d S w )NPYICLOUD_NOTES_DEBUGtime%Y%m%d-%H%M%S/.	workspacenotes_debugTr{   _z_http_request.jsonwutf-8encoding)rv   r8   F   ensure_asciiindentz_http_response.txtstatus_codeheaderszstatus=z
url=z	
headers=z

PYICLOUD_DEBUG_MAX_BYTES524288z
[truncated]
)r~   getenv
__import__strftimereplacer   r   r   rM   r   jsondumpr   textr   dictrw   r`   )rS   rv   r8   rc   tssafe_opout_dirreq_pathr   res_pathstatusr   	body_text	max_bytesr"   r"   r#   rF   (  s\   

"&z$CloudKitNotesClient._dump_http_debugdataerrr	   c                 C  s   t dsd S tdd}t jdd}z	t j|dd W n
 ty(   Y d S w t j|| d|  d	}z+t|d
dd}t	j
| | |d|ddd W d    W d S 1 sZw   Y  W d S  tyk   Y d S w )Nr   r   r   r   r   Tr{   r   z_validation.jsonr   r   r   )rS   errorsr   Fr   r   )r~   r   r   r   r   r   r   rM   r   r   r   r   )rS   r   r   r   r   r   r   r"   r"   r#   rU   O  s,   
&z#CloudKitNotesClient._log_validation)r=   r)   r>   r?   r;   r@   r<   rA   )rL   rM   rN   r   )rS   r)   rL   rM   rN   rT   )rZ   r   r[   r   rW   r\   rX   r]   rY   r^   rN   r   )rd   re   rW   r\   rN   r   )ri   r   rN   rj   )rv   r)   ru   rw   rN   rx   )rv   r)   rz   r)   rN   r)   )r   r)   rN   r)   )rS   r)   rv   r)   r8   r   rN   r   )rS   r)   r   r   r   r	   rN   r   )r   r   r    r!   DEFAULT_TIMEOUTr/   staticmethodrR   rV   rZ   rg   rs   ry   r   r   rF   rU   r"   r"   r"   r#   r:   J   s.    




:&r:   ),r!   
__future__r   r   loggingr~   typingr   r   r   r   r   r   pydanticr	   pyicloud.common.cloudkitr
   r   r   r   r   r   r   r   r   r   pyicloud.common.cloudkit.clientr   r   r   r   r   
_constantsr   	getLoggerr   rI   r   rM   r   r%   r'   r7   r:   r"   r"   r"   r#   <module>   s"     0
