
    Dj'                    P   d Z ddlmZ ddlZddlmZ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 ddlmZmZmZmZ  ej        e          ZdZ e	d	         Z! G d
 de"          Z# G d de#          Z$ G d de#          Z% G d de#          Z& G d d          Z'dS )u  Low-level CloudKit client for the Invites container.

Invites operates across three CK database scopes, but the public scope's
endpoints (``records/resolve`` / ``records/accept``) are shaped differently
from the records-in-zones model used by ``private`` / ``shared``, so the
composition isn't symmetric:

* ``private`` — owner's own events. Held as a
  :class:`CloudKitContainerClient` sub-client.
* ``shared`` — events accepted as a guest. Held as a separate
  :class:`CloudKitContainerClient` sub-client.
* ``public`` — share resolution. No sub-client; reached through a small
  dedicated ``_post_public`` helper that mirrors the common HTTP wrapper's
  auth/rate-limit/error behavior. ``records/resolve`` and ``records/accept``
  take shortGUIDs, not zoneIDs, so they don't fit the typed query/lookup/
  modify abstraction.

A follow-up PR may promote a ``scope=`` parameter to
:class:`CloudKitContainerClient` and collapse this composition into a single
client; see the Invites design doc.
    )annotationsN)AnyDictIterableListLiteralNoReturnOptional)	urlencode)	CKLookupResponseCKModifyOperationCKModifyResponseCKQueryObjectCKQueryResponseCKZoneChangesResponseCKZoneChangesZoneReqCKZoneIDReqCloudKitExtraMode)CloudKitApiErrorCloudKitAuthErrorCloudKitContainerClientCloudKitRateLimited)g      $@g      N@)privatesharedc                      e Zd ZdZdS )InvitesErrorzBase Invites transport error.N__name__
__module____qualname____doc__     [/home/thesage/.hermes/venv/lib/python3.11/site-packages/pyicloud/services/invites/client.pyr   r   8   s        ''''r#   r   c                      e Zd ZdZdS )InvitesAuthErrorz!Auth/PCS/cookie issues (401/403).Nr   r"   r#   r$   r&   r&   <   s        ++++r#   r&   c                  &     e Zd ZdZd
d fd	Z xZS )InvitesRateLimitedz429 Too Many Requests.Nmessagestrretry_afterOptional[float]returnNonec                X    t                                          |           || _        d S N)super__init__r+   )selfr)   r+   	__class__s      r$   r2   zInvitesRateLimited.__init__C   s)    !!!&r#   r0   )r)   r*   r+   r,   r-   r.   r   r   r    r!   r2   __classcell__r4   s   @r$   r(   r(   @   sH          ' ' ' ' ' ' ' ' ' ' 'r#   r(   c                  &     e Zd ZdZd
d fd	Z xZS )InvitesApiErrorzCatch-all API error.Nr)   r*   payloadOptional[object]r-   r.   c                X    t                                          |           || _        d S r0   )r1   r2   r:   )r3   r)   r:   r4   s      r$   r2   zInvitesApiError.__init__K   s&    !!!r#   r0   )r)   r*   r:   r;   r-   r.   r5   r7   s   @r$   r9   r9   H   sH                  r#   r9   c                      e Zd ZdZdeddHdZdIdZedJd            ZdddddddKd(Z	dd)dLd.Z
dd/dMd5Zdd6dNd:ZdOd>ZdOd?ZdPdBZdQdDZdRdGZdS )SCloudKitInvitesClienta  Raw CloudKit service for the Invites container.

    Two :class:`CloudKitContainerClient` sub-clients are constructed at init
    time (private + shared). Public methods take a ``scope`` argument to
    select between them. ``resolve`` / ``accept`` are dedicated public-scope
    helpers that issue their POST via :meth:`_post_public` rather than a
    third sub-client (the public endpoints don't match the records-in-zones
    shape the common client is built around).
    N)validation_extratimeoutenv_base_urlr*   sessionr   base_paramsDict[str, object]r?   CloudKitExtraMode | Noner@   tuple[float, float]r-   r.   c                   || _         t          |pi           | _        || _        | d| _        ||||ddd}t          | dfi || _        t          | dfi || _        t          	                    d           d S )Nz/publiclowerT)rB   rC   r?   r@   bool_param_styleredact_urlsz/privatez/sharedz"CloudKitInvitesClient initialized.)
_sessiondict_base_params_timeout_public_baser   _private_sharedLOGGERinfo)r3   rA   rB   rC   r?   r@   common_kwargss          r$   r2   zCloudKitInvitesClient.__init__^   s       !233+444 & 0 ')
 )
 0%%%
 
)6
 
 /$$$
 
(5
 
 	899999r#   scopeScopeLiteralr   c                Z    |dk    r| j         S |dk    r| j        S t          d|          )Nr   r   zUnsupported scope: )rP   rQ   
ValueError)r3   rU   s     r$   _client_forz!CloudKitInvitesClient._client_for|   s?    I= H<8u88999r#   exc	Exceptionr	   c                ^   | j         p| }t          | t                    rt          t	          |                     |t          | t
                    r$t          t	          |           | j                  |t          | t                    r$t          t	          |           | j
                  | )Nr+   r:   )	__cause__
isinstancer   r&   r*   r   r(   r+   r   r9   r:   )rZ   causes     r$   _raise_invites_errorz*CloudKitInvitesClient._raise_invites_error   s    $c,-- 	8"3s88,,%7c.// 	W$SXX3?KKKQVVc+,, 	L!#c((CK@@@eKr#   F)zone_iddesired_keysresults_limitcontinuation	zone_widequeryr   rc   Optional[CKZoneIDReq]rd   Optional[List[str]]re   Optional[int]rf   Optional[str]rg   boolr   c                   	 |                      |                              ||||||          S # t          t          t          f$ r }|                     |           Y d }~d S d }~ww xY w)N)rh   rc   rd   re   rf   rg   )rY   rh   r   r   r   rb   )	r3   rU   rh   rc   rd   re   rf   rg   rZ   s	            r$   rh   zCloudKitInvitesClient.query   s    
	+##E**00)+)# 1    !"35HI 	+ 	+ 	+%%c*********	+s   -0 A'A""A')rd   record_namesIterable[str]r   r   c                   	 |                      |                              |||          S # t          t          t          f$ r }|                     |           Y d }~d S d }~ww xY w)N)rc   rd   )rY   lookupr   r   r   rb   )r3   rU   ro   rc   rd   rZ   s         r$   rr   zCloudKitInvitesClient.lookup   s    	+##E**11) 2   
 !"35HI 	+ 	+ 	+%%c*********	+   *- A$AA$)atomic
operationsList[CKModifyOperation]rt   Optional[bool]r   c                   	 |                      |                              |||          S # t          t          t          f$ r }|                     |           Y d }~d S d }~ww xY w)N)ru   rc   rt   )rY   modifyr   r   r   rb   )r3   rU   ru   rc   rt   rZ   s         r$   ry   zCloudKitInvitesClient.modify   s    	+##E**11% 2   
 !"35HI 	+ 	+ 	+%%c*********	+rs   )re   zone_reqr   r   c                   	 |                      |                              ||          S # t          t          t          f$ r }|                     |           Y d }~d S d }~ww xY w)N)rz   re   )rY   changesr   r   r   rb   )r3   rU   rz   re   rZ   s        r$   r|   zCloudKitInvitesClient.changes   s    	+##E**22!+ 3    !"35HI 	+ 	+ 	+%%c*********	+s   ), A#AA#short_guids	List[str]Dict[str, Any]c                F    |                      ddd |D             i          S )uD   POST ``public/records/resolve`` — preview a share without joining.z/records/resolve
shortGUIDsc                    g | ]}d |iS valuer"   .0gs     r$   
<listcomp>z1CloudKitInvitesClient.resolve.<locals>.<listcomp>       >>>QWaL>>>r#   _post_publicr3   r}   s     r$   resolvezCloudKitInvitesClient.resolve   s4      >>+>>>?
 
 	
r#   c                F    |                      ddd |D             i          S )uB   POST ``public/records/accept`` — accept a share and gain access.z/records/acceptr   c                    g | ]}d |iS r   r"   r   s     r$   r   z0CloudKitInvitesClient.accept.<locals>.<listcomp>   r   r#   r   r   s     r$   acceptzCloudKitInvitesClient.accept   s4      >>+>>>?
 
 	
r#   pathr:   c           	     D   | j         |z   }|                                 }|r| dt          |           }t                              d|           | j                            ||| j                  }t          |dd          }t          |t                    sd}|dv rt          d| d	          |d
k    rRd}	 |j                            d          }|rt          |          }n# t          $ r d}Y nw xY wt!          d|          |dk    rK	 |                                }	n!# t          $ r t          |dd          }	Y nw xY wt%          d| |	          	 |                                S # t          $ r&}
t%          dt          |dd                    |
d}
~
ww xY w)zPOST to the public-scope endpoint.

        Mirrors the auth / rate-limit / error-response handling of the common
        client's HTTP wrapper. Inlined here (rather than promoted to common)
        to keep this PR scoped to the Invites service.
        ?zCloudKit Invites POST %s)jsonr@   status_coder      )i  i  zHTTP z: unauthorizedi  NzRetry-AfterzHTTP 429: rate limitedr]   i  textr^   zInvalid JSON response)rO   _normalized_paramsr   rR   debugrK   postrN   getattrr`   intr&   headersgetfloatr[   r(   r   r9   )r3   r   r:   urlparamsrespcoder+   hdrbodyrZ   s              r$   r   z"CloudKitInvitesClient._post_public   s    $&((** 	/..9V,,..C/666}!!#GT]!KKt]A..$$$ 	D:"#?4#?#?#?@@@3;;+/K#l&&}55 -"'**K # # #"#$%=;WWWW3;;3 IIKK 3 3 3tVT223!.$..$????	99;; 	 	 	!'fd33   	s<   :+C& &C54C5D% %EEE/ /
F9!FFDict[str, str]c                    i }| j                                         D ]6\  }}t          |t                    r
|rdnd||<   $t	          |          ||<   7|S )z@Stringify base params the same way the common HTTP wrapper does.truefalse)rM   itemsr`   rm   r*   )r3   outkeyr   s       r$   r   z(CloudKitInvitesClient._normalized_params  se     +1133 	& 	&JC%&& &%*766Cu::C
r#   r   bytesc                    	 | j                             |          S # t          t          t          f$ r }|                     |           Y d }~d S d }~ww xY wr0   )rP   download_asset_bytesr   r   r   rb   )r3   r   rZ   s      r$   r   z*CloudKitInvitesClient.download_asset_bytes   sk    	+=55c::: "35HI 	+ 	+ 	+%%c*********	+s    AAA)rA   r*   rB   r   rC   rD   r?   rE   r@   rF   r-   r.   )rU   rV   r-   r   )rZ   r[   r-   r	   )rU   rV   rh   r   rc   ri   rd   rj   re   rk   rf   rl   rg   rm   r-   r   )
rU   rV   ro   rp   rc   r   rd   rj   r-   r   )
rU   rV   ru   rv   rc   r   rt   rw   r-   r   )rU   rV   rz   r   re   rk   r-   r   )r}   r~   r-   r   )r   r*   r:   r   r-   r   )r-   r   )r   r*   r-   r   )r   r   r    r!   DEFAULT_TIMEOUTr2   rY   staticmethodrb   rh   rr   ry   r|   r   r   r   r   r   r"   r#   r$   r>   r>   S   su          6:'6: : : : : :<: : : :    \" *.,0'+&*+ + + + + +: -1+ + + + + +. "&+ + + + + +, (,+ + + + + +"
 
 
 

 
 
 
* * * *X   + + + + + +r#   r>   )(r!   
__future__r   loggingtypingr   r   r   r   r   r	   r
   urllib.parser   pyicloud.common.cloudkitr   r   r   r   r   r   r   r   r   pyicloud.common.cloudkit.clientr   r   r   r   	getLoggerr   rR   r   rV   r[   r   r&   r(   r9   r>   r"   r#   r$   <module>r      s&   , # " " " " "  I I I I I I I I I I I I I I I I I I " " " " " "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
            
	8	$	$*+( ( ( ( (9 ( ( (, , , , ,| , , ,' ' ' ' ' ' ' '    l   Q+ Q+ Q+ Q+ Q+ Q+ Q+ Q+ Q+ Q+r#   