
    F2j}                        d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZ e	rddlmZ ddlmZmZ d	Zd	Zd	Zd	Z	 ddlZdd
lmZ ddlmZ dZn# e$ r Y nw xY wes;	 ddlZdZdZ	 ddlZdZn# e$ r Y nw xY w G d dej                  Z n# e$ r Y nw xY wes;es9	 ddlZdZ	 ddlZdZn# e$ r Y nw xY w G d dej                  Z n# e$ r Y nw xY weses ed          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. ddl/m0Z0 ddl1m2Z2m3Z3m4Z4  ej5        d          Z6ej7        dk     rddl8m9Z9 nddlm9Z9  G d de$          Z:d*de;d e
d!e:fd"Z%	 	 	 d+d#e
dz  d$e
dz  d%e;d e
d!d&f
d'Z<d e
d!d(fd)Z=dS ),z
Async-first DAVClient implementation for the caldav library.

This module provides the core async CalDAV/WebDAV client functionality.
For sync usage, see the davclient.py wrapper.
    N)Mapping)TracebackType)TYPE_CHECKINGAnyOptional)unquote)CalendarObjectResource)Calendar	PrincipalF)AsyncSession)CaseInsensitiveDictTc                   (    e Zd ZdZdeddfdZd ZdS )_HttpxBearerAuthz+httpx/httpxyz-compatible bearer token auth.passwordreturnNc                     || _         d S Nr   selfr   s     ^/home/thesage/.hermes/hermes-agent/venv/lib/python3.11/site-packages/caldav/async_davclient.py__init__z_HttpxBearerAuth.__init__4        (    c              #   6   K   d| j          |j        d<   |V  d S NzBearer Authorizationr   headersr   requests     r   	auth_flowz_HttpxBearerAuth.auth_flow7   )      3LT]3L3L0r   __name__
__module____qualname____doc__strr   r"    r   r   r   r   1   sK        ==) ) ) ) ) )    r   r   c                   (    e Zd ZdZdeddfdZd ZdS )r   z#httpx-compatible bearer token auth.r   r   Nc                     || _         d S r   r   r   s     r   r   z_HttpxBearerAuth.__init__M   r   r   c              #   6   K   d| j          |j        d<   |V  d S r   r   r    s     r   r"   z_HttpxBearerAuth.auth_flowP   r#   r   r$   r*   r   r   r   r   J   sK        55) ) ) ) ) )    r   zAn async HTTP library is required for async_davclient. Install with: pip install niquests  (or: pip install httpxyz  or: pip install httpx))__version__)BaseDAVClient)get_davclient)
FeatureSet)error)to_wire)URL)HTTPBearerAuth)CalendarQueryResultDAVResponsePropfindResultcaldav)      )Selfc            %          e Zd ZU dZdZedz  ed<   dZeed<   dZ	e
ed<   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dXdedz  dedz  d	edz  d
edz  dedz  dedz  dedz  de
ez  deeeef         z  dz  deeef         dz  de
deez  ez  dz  de
de
de
dz  dedz  dedz  ddf$dZdYdZdefdZdedz  dedz  dedz  ddfdZdYdZe	 	 dZd ed!edz  d"eeef         dz  deeef         fd#            Z	 	 	 	 d[ded ed&edeeef         dz  d'edefd(Z	 	 	 d\ded ed&edeeef         dz  def
d)Z	 	 	 	 	 d]dedz  d&ed!edeeef         dz  d*e e         dz  defd+Z!	 	 	 	 d^dedz  d&ed!edz  deeef         dz  def
d,Z"	 	 dZdedz  deeef         dz  defd-Z#	 	 d_ded&edeeef         dz  defd.Z$	 	 d_ded&edeeef         dz  defd/Z%	 	 d_ded&edeeef         dz  defd0Z&	 d`ded&edeeef         dz  defd1Z'	 d`ded&edeeef         dz  defd2Z(	 d`dedeeef         dz  defd3Z)	 	 	 	 	 	 	 	 	 dadedz  d5edz  d6edz  d7e
d8e
d9e
d:e
d!edeeef         dz  defd;Z*	 	 	 	 dbdedz  d<e e         dz  d!edeeef         dz  def
d=Z+	 	 	 	 	 dcdedz  d>edz  d*e e         dz  d!edeeef         dz  defd?Z,d@ Z-dA Z.d`dBe e         dz  ddfdCZ/dddEZ0d`dFe1dD         de dG         fdHZ2	 	 	 	 	 	 	 dedIdGd7e
d8e
d9e
d5edz  d6edz  dJe
dz  d:e
dKede dL         fdMZ3d`dNedz  de dD         fdOZ4d`dNedz  de dD         fdPZ5dddQZ6dedz  fdRZ7de
fdSZ8de
fdTZ9dedz  fdUZ:de
fdVZ;de
fdWZ<dS )fAsyncDAVClienta  
    Async WebDAV/CalDAV client.

    This is the core async implementation. For sync usage, see DAVClient
    in davclient.py which provides a thin wrapper around this class.

    The recommended way to create a client is via get_davclient():
        async with await get_davclient(url="...", username="...", password="...") as client:
            principal = await client.get_principal()
    NproxyurlF	huge_tree Tusernamer   auth	auth_typetimeoutssl_verify_certssl_certr   featuresenable_rfc6764require_tlsrate_limit_handlerate_limit_default_sleeprate_limit_max_sleepr   c           	      f   |
pi }
ddl m}  ||          }t          |t                    r|| _        nt          |          | _        || _        d| _        || _        | j        d| j        vrd| j        z   | _        || _        |	| _	        || _
        	 | j                            d          ot          pt          | _        n# t          t          f$ r
 d| _        Y nw xY w|                                  ddlm}  ||| j        |pd	||||
          \  }}|r|s|}t'          j        |          | _        d}d}| j        j        rt/          | j        j                  }| j        j        rt/          | j        j                  }||n|| _        ||n|| _        | j                                        | _        || _        || _        | j        s"| j        r|                     | j        g           | j        | _        | j
        | _        | j        | _        | j	        | _         ddtB           i| _"        | j"        #                    |
           | j                            dtH                    }|4|r0|%                    d          rd}d|v r|d         }d|v r|d         }nd}|| _&        || _'        || _(        dS )ai  
        Initialize an async DAV client.

        Args:
            url: CalDAV server URL, domain, or email address.
            proxy: Proxy server (e.g. http://proxy.example.com:8080).
            username: Username for authentication.
            password: Password for authentication.
            auth: Custom auth object (httpx.Auth or niquests AuthBase).
            auth_type: Auth type ('bearer', 'digest', or 'basic').
            timeout: Request timeout in seconds.
            ssl_verify_cert: SSL certificate verification (bool or CA bundle path).
            ssl_cert: Client SSL certificate (path or (cert, key) tuple).
            headers: Additional headers for all requests.
            huge_tree: Enable XMLParser huge_tree for large events (security consideration).
            features: FeatureSet for server compatibility workarounds.
            enable_rfc6764: Enable RFC6764 DNS-based service discovery.
            require_tls: Require TLS for discovered services (security consideration).
            rate_limit_handle: When True, automatically sleep and retry on 429/503
                responses. When None (default), auto-detected from server features.
                When False, raise RateLimitError immediately.
            rate_limit_default_sleep: Fallback sleep seconds when the server's 429
                response omits a Retry-After header. None (default) means raise
                rather than sleeping when no Retry-After is provided.
            rate_limit_max_sleep: Cap on sleep duration in seconds regardless of
                server's Retry-After value. None (default) means no cap.
        r   )resolve_featuresNz://zhttp://http.multiplexingF)	_auto_url
   )rF   rG   rJ   rC   rK   z
User-Agentzcaldav-async/z
rate-limitenableTdefault_sleep	max_sleep))caldav.configrP   
isinstancer1   rI   rA   _http2_proxy_ssl_verify_cert	_ssl_cert_timeoutis_supported_H2_AVAILABLE_USE_NIQUESTS	TypeErrorAttributeError_create_sessioncaldav.davclientrR   r4   	objectifyr@   rC   r   r   unauthrD   rE   build_auth_objectr?   rF   rG   rH   r.   r   updatedictgetrL   rM   rN   )r   r@   r?   rC   r   rD   rE   rF   rG   rH   r   rA   rI   rJ   rK   rL   rM   rN   rP   rR   url_strdiscovered_usernameurl_usernameurl_password
rate_limits                            r   r   zAsyncDAVClient.__init__   s0   ^ -R222222##H--h
++ 	1$DMM&x00DM" ;"uDK'?'?#dk1DK /!	 -445HII . KK >* 	  	  	 DKKK	  	/.....'0yMMr+)#(
 (
 (
$$  	+x 	+*H =)) 8 	6"48#455L8 	6"48#455L %-$8l$,$8l8??$$ 	"y 	5T^ 	5""DN#3444 [
 }#4 7+77(
 	G$$$]//dCC
$ *jnnX66 *$(!"j00/9//J,*,,+5k+B($)!!2(@%$8!!!s   -B? ?CCc                 4   t           rO| j        pd| j        | j        nd| j        | j        d}| j        
| j        |d<   t          j        di || _        dS 	 t          | j        pd          | _        dS # t          $ r t                      | _        Y dS w xY w)z?Create or recreate the async HTTP client with current settings.FNT)http2verifycertrF   r?   )multiplexedr*   )
_USE_HTTPXrY   r[   r\   r]   rZ   httpxAsyncClientsessionr   ra   )r   client_kwargss     r   rc   zAsyncDAVClient._create_session  s     	.-373H3T$//Z^=	# #M {&)-g& ,==}==DLLL.+8LuMMM . . .+~~.s   A6 6BBc                 
   K   | S )zAsync context manager entry.r*   r   s    r   
__aenter__zAsyncDAVClient.__aenter__&  s      r   exc_typeexc_valexc_tbc                 >   K   |                                   d{V  dS )zAsync context manager exit.N)close)r   r}   r~   r   s       r   	__aexit__zAsyncDAVClient.__aexit__*  s.       jjllr   c                    K   t          | d          rIt          r!| j                                         d{V  dS | j                                         d{V  dS dS )zClose the async client.rx   N)hasattrru   rx   acloser   r{   s    r   r   zAsyncDAVClient.close3  s      4## 	+ +l))+++++++++++l((***********		+ 	+r   methoddepthextra_headersc                 r    i }|t          |          |d<   | dv rd|d<   |r|                    |           |S )a  
        Build headers for WebDAV methods.

        Args:
            method: HTTP method name.
            depth: Depth header value (for PROPFIND/REPORT).
            extra_headers: Additional headers to merge.

        Returns:
            Dictionary of headers.
        NDepth)REPORTPROPFIND	PROPPATCH
MKCALENDARMKCOLz application/xml; charset="utf-8"Content-Type)r)   rh   )r   r   r   r   s       r   _build_method_headersz$AsyncDAVClient._build_method_headers;  sZ    " #% "5zzGG OOO&HGN#  	*NN=)))r   GETr   bodyrate_limit_time_sleptc           	        K   	 |                      ||||           d{V S # t          j        $ r}| j        s t          j        |j        | j        | j                  }|r||dz  z  }|| j        || j        k    r t          j	        |           d{V  | 
                    ||||||z              d{V cY d}~S d}~ww xY w)a  
        Send an async HTTP request, with optional rate-limit sleep-and-retry.

        Catches RateLimitError from _async_request. When rate_limit_handle is
        True and a usable sleep duration is available, sleeps then retries with
        adaptive backoff (each retry adds half the already-slept time). Stops
        retrying when rate_limit_max_sleep is exceeded or no sleep duration is
        available. Otherwise re-raises immediately.
        N   )_async_requestr2   RateLimitErrorrL   compute_sleep_secondsretry_after_secondsrM   rN   asynciosleepr!   )r   r@   r   r   r   r   esleep_secondss           r   r!   zAsyncDAVClient.request\  sE     "	,,S&$HHHHHHHHH# 	 	 	) !7%-) M
 % ;!6!::$)5)D,EEE-.........VT7,AM,Q             !	s   " CBB>8C>Cc           
      	  K   |                      ||||          \  }}t          r2|t          |          |rt          |          nd|| j        | j        d}nUd}| j        |j        | j        i}|t          |          |rt          |          nd|| j        | j        || j        | j	        d	}	  | j
        j        di | d{V }	t          r|	j        n|	j        }
t                              d|	j         d|
            |	j        dk    rd| j                            dd	          v r| j        sd
}|	j                            d          rWd |                     |	j        d                   D             }|r+|d                    d                    |                    z  }t                              |           t/          |	|           }n~# t0          $ rp | j        s| j        s t          r7| j
                            dt          |          || j                   d{V }	nZd}| j        |j        | j        i}| j
                            dt          |          || j        || j        | j	                   d{V }	t          r|	j        n|	j        }
t                              d|	j         d|
            |	j        dk    rq|	j                            d          rW|                     |	j        d                   }|                     |           | j        |d<    | j
        j        di | d{V }	t/          |	|           }Y nw xY wt7          j        |	j        t          |          |	j                            d                     |                     |	j        |	j                  r>|                     |	j        d                    |                     ||||           d{V S |	j        dk    rd|	j        v r| j        r| j         !                    dd          {| "                                 d{V  d| _#        | $                                 | j         %                    dd           |                     t          |          |||           d{V S |j&        dv r#| '                    t          |          |           t6          j(        rt7          j)        |||||           |S )z
        Async HTTP request implementation with auth negotiation.

        Handles connection-abort workaround, 429/503 rate-limit detection,
        and 401 auth negotiation (including HTTP/2 fallback).
        N)r   r@   contentr   rD   rF   )	r   r@   datar   rD   rF   proxiesrr   rs   zserver responded with    z	text/htmlr   rB   zNo authentication object was provided. HTML was returned when probing the server for supported authentication types. To avoid logging errors, consider passing the auth_type connection parameterzWWW-Authenticatec                     g | ]}|d v |	S ))basicdigestbearerr*   ).0ts     r   
<listcomp>z1AsyncDAVClient._async_request.<locals>.<listcomp>  s.     " " " === ===r   z#
Supported authentication types: {}z, r   )r   r@   r   rF   )r   r@   r   rF   r   rr   rs   z+auth type detection: server responded with rD   zRetry-AfterrQ   F)return_defaults)r   i  r*   )*_prepare_requestru   r)   r3   rD   rF   r?   schemerG   rH   rx   r!   reason_phrasereasonlogdebugstatus_coder   rj   extract_auth_typesformatjoinwarningr7   	Exceptionr   rg   r2   raise_if_rate_limited_should_negotiate_auth_build_auth_from_401r   rI   r^   r   rY   rc   set_featurestatus_raise_authorization_errordebug_dump_communication_dump_communication)r   r@   r   r   r   url_objcombined_headersrequest_kwargsr   rr   msg
auth_typesresponses                 r   r   zAsyncDAVClient._async_request  s      %)$9$9#vtW$U$U!!  	 7||,0:74===d+	<. .NN Gz%">4:6 7||)-74+	<".
. 
.N:	,*dl*<<^<<<<<<<<A(2@Q__FIIGq}GGvGGHHH$$4<#3#3NB#G#GGG	 Hc 
 9==!344 d" "!%!8!8CU9V!W!W" " "J
 " dELLTYYWaMbMbcccC   "1d++HH "	, "	, "	, y   ,.. G, L	 /         :)&~tz:G,.. G, L#/ /         )3@Q__FII\AM\\TZ\\]]]}##	6H(I(I#!44QY?Q5RSS
&&z222)-v&.$,.@@@@@@@@@@"1d++HHHE"	,J 	#AM3w<<}A]A]^^^ &&q}ai@@ 	R%%ai0B&CDDD,,S&$HHHHHHHHH MS  "ai//	 0**+>PU*VV^ **,,DK  """M%%&95AAA,,S\\64QQQQQQQQQ ?j((++CLL(CCC) 	U%fc3CT8TTTs   -DG E8MMpropsc                 F  K   |*|s(|                      |                              d          }|                     d||          }|                     |pt	          | j                  d||           d{V }|j        dv r |j        r|                                |_	        |S )a  
        Send a PROPFIND request.

        Args:
            url: Target URL (defaults to self.url).
            body: XML properties request (legacy, use props instead).
            depth: Maximum recursion depth.
            headers: Additional headers.
            props: List of property names to request (uses protocol layer).

        Returns:
            DAVResponse with results attribute containing parsed PropfindResult list.
        Nutf-8r         )
_build_propfind_bodydecoder   r!   r)   r@   r   _rawparse_propfindresults)r   r@   r   r   r   r   final_headersr   s           r   propfindzAsyncDAVClient.propfind  s      , T,,U33::7CCD22:ugNNc&:S]]Jm\\\\\\\\?j((X]('6688Hr   c                    K   |                      d||          }|                     |pt          | j                  d||           d{V S )a~  
        Send a REPORT request.

        Args:
            url: Target URL (defaults to self.url).
            body: XML report request.
            depth: Maximum recursion depth. None means don't send Depth header
                (required for calendar-multiget per RFC 4791 section 7.9).
            headers: Additional headers.

        Returns:
            DAVResponse
        r   N)r   r!   r)   r@   )r   r@   r   r   r   r   s         r   reportzAsyncDAVClient.report-  sV      ( 228UGLL\\#"6TX$VVVVVVVVVr   c                 j   K   |                      |pt          | j                  dd|           d{V S )z
        Send an OPTIONS request.

        Args:
            url: Target URL (defaults to self.url).
            headers: Additional headers.

        Returns:
            DAVResponse
        OPTIONSrB   N)r!   r)   r@   r   r@   r   s      r   optionszAsyncDAVClient.optionsD  s?       \\#"6TX	2wOOOOOOOOOr   c                 p   K   |                      d|          }|                     |d||           d{V S )z
        Send a PROPPATCH request.

        Args:
            url: Target URL (required).
            body: XML property update request.
            headers: Additional headers.

        Returns:
            DAVResponse
        r   r   Nr   r!   r   r@   r   r   r   s        r   	proppatchzAsyncDAVClient.proppatchW  sJ      " 22;g2VV\\#{D-HHHHHHHHHr   c                 p   K   |                      d|          }|                     |d||           d{V S )a0  
        Send a MKCOL request.

        MKCOL creates a WebDAV collection. For CalDAV, use mkcalendar instead.

        Args:
            url: Target URL (required).
            body: XML request (usually empty).
            headers: Additional headers.

        Returns:
            DAVResponse
        r   r   Nr   r   s        r   mkcolzAsyncDAVClient.mkcolk  sJ      & 227'2RR\\#wmDDDDDDDDDr   c                 p   K   |                      d|          }|                     |d||           d{V S )z
        Send a MKCALENDAR request.

        Args:
            url: Target URL (required).
            body: XML request (usually contains calendar properties).
            headers: Additional headers.

        Returns:
            DAVResponse
        r   r   Nr   r   s        r   
mkcalendarzAsyncDAVClient.mkcalendar  sJ      " 22<w2WW\\#|T=IIIIIIIIIr   c                 B   K   |                      |d||           d{V S )z
        Send a PUT request.

        Args:
            url: Target URL (required).
            body: Request body (e.g., iCalendar data).
            headers: Additional headers.

        Returns:
            DAVResponse
        PUTNr!   r   r@   r   r   s       r   putzAsyncDAVClient.put  s2      " \\#udG<<<<<<<<<r   c                 B   K   |                      |d||           d{V S )z
        Send a POST request.

        Args:
            url: Target URL (required).
            body: Request body.
            headers: Additional headers.

        Returns:
            DAVResponse
        POSTNr   r   s       r   postzAsyncDAVClient.post  s2      " \\#vtW=========r   c                 B   K   |                      |dd|           d{V S )z
        Send a DELETE request.

        Args:
            url: Target URL (required).
            headers: Additional headers.

        Returns:
            DAVResponse
        DELETErB   Nr   r   s      r   deletezAsyncDAVClient.delete  s2       \\#xW=========r      startendeventtodojournalexpandc
                 P  K   |                      ||||||          \  }
}|                     d||	          }|                     |pt          | j                  d|
                    d          |           d{V }|j        dv r |j        r|                                |_	        |S )aR  
        Execute a calendar-query REPORT to search for calendar objects.

        Args:
            url: Target calendar URL (defaults to self.url).
            start: Start of time range filter.
            end: End of time range filter.
            event: Include events (VEVENT).
            todo: Include todos (VTODO).
            journal: Include journals (VJOURNAL).
            expand: Expand recurring events.
            depth: Search depth.
            headers: Additional headers.

        Returns:
            DAVResponse with results containing List[CalendarQueryResult].
        )r   r   r   r   r   r   r   r   Nr   )
_build_calendar_query_bodyr   r!   r)   r@   r   r   r   parse_calendar_queryr   )r   r@   r   r   r   r   r   r   r   r   r   _r   r   s                 r   calendar_queryzAsyncDAVClient.calendar_query  s      < 11 2 
 
a 228UGLL 3tx==(DKK,@,@-
 
 
 
 
 
 
 
 ?j((X]('<<>>Hr   hrefsc                 B  K   |                      |pg           }|                     d||          }|                     |pt          | j                  d|                    d          |           d{V }|j        dv r |j        r|                                |_	        |S )a  
        Execute a calendar-multiget REPORT to fetch specific calendar objects.

        Args:
            url: Target calendar URL (defaults to self.url).
            hrefs: List of object URLs to retrieve.
            depth: Search depth.
            headers: Additional headers.

        Returns:
            DAVResponse with results containing List[CalendarQueryResult].
        r   r   Nr   )
_build_calendar_multiget_bodyr   r!   r)   r@   r   r   r   r   r   )r   r@   r   r   r   r   r   r   s           r   calendar_multigetz AsyncDAVClient.calendar_multiget   s      & 11%+2>>228UGLL 3tx==(DKK,@,@-
 
 
 
 
 
 
 
 ?j((X]('<<>>Hr   
sync_tokenc                 h  K   |                      ||          }|                     d||          }|                     |pt          | j                  d|                    d          |           d{V }|j        dv r3|j        r,|                                }	|	j	        |_
        |	j        |_        |S )a  
        Execute a sync-collection REPORT for efficient synchronization.

        Args:
            url: Target calendar URL (defaults to self.url).
            sync_token: Previous sync token (None for initial sync).
            props: Properties to include in response.
            depth: Search depth.
            headers: Additional headers.

        Returns:
            DAVResponse with results containing SyncCollectionResult.
        )r   r   r   r   Nr   )_build_sync_collection_bodyr   r!   r)   r@   r   r   r   parse_sync_collectionchangedr   r   )
r   r@   r   r   r   r   r   r   r   sync_results
             r   sync_collectionzAsyncDAVClient.sync_collection  s      * //:U/SS228UGLL 3tx==(DKK,@,@-
 
 
 
 
 
 
 
 ?j((X]("88::K*2H"-"8Hr   c                 ,    |                      |          S r   )_async_value_or_coroutiner   values     r   _value_or_coroutinez"AsyncDAVClient._value_or_coroutineB  s    --e444r   c                 
   K   |S r   r*   r  s     r   r  z(AsyncDAVClient._async_value_or_coroutineE  s      r   r   c                 @   |                      |          }|dk    r=t          rt          | j                  | _        dS t          | j                  | _        dS |dk    rPt          r&t          j        | j        | j                  | _        dS ddl	m
}  || j        | j                  | _        dS |dk    rPt          r&t          j        | j        | j                  | _        dS ddl	m}  || j        | j                  | _        dS |rt          j        d|           dS )	a!  Build authentication object for the httpx/niquests library.

        Uses shared auth type selection logic from BaseDAVClient, then
        creates the appropriate auth object for this HTTP library.

        Args:
            auth_types: List of acceptable auth types from server.
        r   r   r   )AsyncHTTPDigestAuthr   )HTTPBasicAuthzUnsupported auth type: N)_select_auth_typeru   r   r   rD   r5   rv   
DigestAuthrC   niquests.authr  	BasicAuthr  r2   AuthorizationError)r   r   rE   r  r  s        r   rg   z AsyncDAVClient.build_auth_objectJ  s?    **:66	    :,T];;			*4=99			("" N!,T]DMJJ			======//t}MM			'!! H!ODM4=II			777777)M$-GG			 	R*+PY+P+PQQQ	R 	Rr   r   c                 $  K   ddl m} |                     t          | j                  dgd           d{V }d}|j        r*|j        D ]"}|j                            d          }|r|} n#|st          | j                  } || |          }|S )a  Get the principal (user) for this CalDAV connection.

        This method fetches the current-user-principal from the server and returns
        a Principal object that can be used to access calendars and other resources.

        Returns:
            Principal object for the authenticated user.

        Example:
            async with await get_davclient(url="...", username="...", password="...") as client:
                principal = await client.get_principal()
                calendars = await client.get_calendars(principal)
        r   )r   z{DAV:}current-user-principalr   r   N)clientr@   )caldav.collectionr   r   r)   r@   r   
propertiesrj   )r   r   r   principal_urlresultcup	principals          r   get_principalzAsyncDAVClient.get_principalp  s       	0/////
 MM12 ' 
 
 
 
 
 
 
 
  	"*  '++,JKK $'ME  	*MMM IT}===	r   r  r
   c                    K   ddl m ddl m} ddl m} |                                  d{V }                     t          |j                   j        d           d{V } ||j	                  }|sg S  
                    |          }                     | j        d           d{V } ||j	                  } fd|D             S )	a'  Get all calendars for the given principal.

        This method fetches calendars from the principal's calendar-home-set
        and returns a list of Calendar objects.

        Args:
            principal: Principal object (if None, fetches principal first)

        Returns:
            List of Calendar objects.

        Example:
            principal = await client.get_principal()
            calendars = await client.get_calendars(principal)
            for cal in calendars:
                print(f"Calendar: {cal.get_display_name()}")
        r   )r
   )'_extract_calendar_home_set_from_results)(_extract_calendars_from_propfind_resultsNr  r   c                 L    g | ] } |j         |j        |j                   !S ))r  r@   nameid)r@   r"  cal_id)r   infor
   r   s     r   r   z0AsyncDAVClient.get_calendars.<locals>.<listcomp>  sB     
 
 
 HDdhTY4;OOO
 
 
r   )r  r
   r  r   r  r   r)   r@   CALENDAR_HOME_SET_PROPSr   _make_absolute_urlCALENDAR_LIST_PROPS)r   r  extract_home_setextract_calendarsr   calendar_home_urlcalendar_infosr
   s   `      @r   get_calendarszAsyncDAVClient.get_calendars  s     $ 	/.....	
 	
 	
 	
 	
 	
	
 	
 	
 	
 	
 	
 "0022222222I 	. ' 
 
 
 
 
 
 
 

 -,X-=>>  	I !334EFF * ' 
 
 
 
 
 
 
 
 +*8+;<<
 
 
 
 
&
 
 
 	
r   calendarinclude_completedkwargsr	   c	                 r   K   ddl m}
  |
||||||          }|||_         |j        |fi |	 d{V }|S )a  Search a calendar for events, todos, or journals.

        This method provides a clean interface to calendar search using the
        operations layer for building queries and processing results.

        Args:
            calendar: Calendar to search
            event: Search for events (VEVENT)
            todo: Search for todos (VTODO)
            journal: Search for journals (VJOURNAL)
            start: Start of date range
            end: End of date range
            include_completed: Include completed todos (default: False for todos)
            expand: Expand recurring events
            **kwargs: Additional search parameters

        Returns:
            List of Event/Todo/Journal objects.

        Example:
            # Get all events in January 2024
            events = await client.search_calendar(
                calendar,
                event=True,
                start=datetime(2024, 1, 1),
                end=datetime(2024, 1, 31),
            )

            # Get pending todos
            todos = await client.search_calendar(
                calendar,
                todo=True,
                include_completed=False,
            )
        r   )CalDAVSearcher)r   r   r   r   r   r   N)caldav.searchr2  r/  async_search)r   r.  r   r   r   r   r   r/  r   r0  r2  searcherr   s                r   search_calendarzAsyncDAVClient.search_calendar  s      ^ 	100000 ">
 
 
 ():H& .-hAA&AAAAAAAAr   r"  c                 F  K   |                      |          }|                     t          | j                  |           d{V }|j        dk    r+t          j        |j         d|j         d|j                   | 	                    |
                                          S )a=  
        Search for principals on the server.

        Instead of returning the current logged-in principal, this method
        attempts to query for all principals (or principals matching a name).
        This may or may not work depending on the permissions and
        implementation of the calendar server.

        Args:
            name: Optional name filter to search for specific principals

        Returns:
            List of Principal objects found on the server

        Raises:
            ReportError: If the server doesn't support principal search
        Ni,  r   z - )_build_principal_search_queryr   r)   r@   r   r2   ReportErrorr   raw _parse_principal_search_response_find_objects_and_props)r   r"  r   r   s       r   search_principalsz AsyncDAVClient.search_principals  s      $ 11$77S]]D99999999?c!!#x$[$[$[$[X\$[$[\\\44X5U5U5W5WXXXr   c                    K   ddl }|                    dt          d           |                     |           d{V S )z
        Deprecated. Use :meth:`search_principals` instead.

        This method searches for principals on the server.
        r   Nz;principals() is deprecated, use search_principals() insteadr   )
stacklevelr"  )warningswarnDeprecationWarningr=  )r   r"  rA  s      r   
principalszAsyncDAVClient.principals-  s`       	I 	 	
 	
 	

 +++666666666r   c                 :   K   |                                   d{V S )z
        Legacy method. Use :meth:`get_principal` for new code.

        Returns the Principal object for the authenticated user.
        N)r  r{   s    r   r  zAsyncDAVClient.principal<  s,       '')))))))))r   c                 ,  K   	 |                                   d{V }|                     |j                   d{V }n=# t          $ r0 |                     t	          | j                             d{V }Y nw xY w|j                            d          S )z
        Check if the server supports DAV.

        Returns the DAV header from an OPTIONS request, or None if not supported.
        NDAV)r  r   r@   r   r)   r   rj   )r   r  r   s      r   check_dav_supportz AsyncDAVClient.check_dav_supportD  s      	9"nn........I!\\)-88888888HH 	9 	9 	9!\\#dh--88888888HHH	9##E***s   :? 7A98A9c                 J   K   |                                   d{V }|duod|v S )z
        Check if the server supports CalDAV.

        Returns True if the server indicates CalDAV support in DAV header.
        Nzcalendar-accessrH  r   
dav_headers     r   check_cdav_supportz!AsyncDAVClient.check_cdav_supportQ  sA        1133333333
%I*;z*IIr   c                 J   K   |                                   d{V }|duod|v S )z
        Check if the server supports RFC6638 scheduling.

        Returns True if the server indicates scheduling support in DAV header.
        Nzcalendar-auto-schedulerJ  rK  s     r   check_scheduling_supportz'AsyncDAVClient.check_scheduling_supportZ  sA        1133333333
%P*Bj*PPr   c                 :   K   |                                   d{V S )zl
        Check if the server supports DAV.

        This is an alias for :meth:`check_dav_support`.
        NrJ  r{   s    r   supports_davzAsyncDAVClient.supports_davc  s,       ++---------r   c                 :   K   |                                   d{V S )zp
        Check if the server supports CalDAV.

        This is an alias for :meth:`check_cdav_support`.
        N)rM  r{   s    r   supports_caldavzAsyncDAVClient.supports_caldavk  s,       ,,.........r   c                 :   K   |                                   d{V S )z
        Check if the server supports RFC6638 scheduling.

        This is an alias for :meth:`check_scheduling_support`.
        N)rO  r{   s    r   supports_schedulingz"AsyncDAVClient.supports_schedulings  s,       22444444444r   )rB   NNNNNNTNNFNTTNNN)r   N)NN)r   rB   Nr   )r   rB   N)NrB   r   NN)NrB   r   N)rB   Nr   )	NNNFFFFr   N)NNr   N)NNNr   N)r   r   )FFFNNNF)=r%   r&   r'   r(   r?   r)   __annotations__r@   r4   rA   boolr   inttupler   r1   ri   r   rc   r<   r|   typeBaseExceptionr   r   r   staticmethodr   floatr7   r!   r   listr   r   r   r   r   r   r   r   r   r   r   r  r
  r  rg   r  r   r-  r6  r=  rD  r  rH  rM  rO  rQ  rS  rU  r*   r   r   r>   r>   p   s        	 	 E3:COOOIt  ## $"&*15,037# )-/3+/%Q9 Q94ZQ9 TzQ9 *	Q9
 *Q9 DjQ9 :Q9 tQ9 Q9 c3h'$.Q9 c"T)Q9 Q9 t#c)D0Q9 Q9 Q9   $;!Q9" #&*#Q9$ "Dj%Q9& 
'Q9 Q9 Q9 Q9f. . . .&$    + % $	
 
   + + + +  !26 Tz sCx(4/ 
c3h	   \F ,0'(% %% % 	%
 c"T)%  %% 
% % % %T ,0D DD D 	D
 c"T)D 
D D D DV ,0"& 4Z  	
 c"T) Cy4 
   F ,0W W4ZW W Tz	W
 c"T)W 
W W W W2 ,0P P4ZP c"T)P 
	P P P P, ,0	I II I c"T)	I
 
I I I I. ,0	E EE E c"T)	E
 
E E E E2 ,0	J JJ J c"T)	J
 
J J J J0 -1	= == = c"T)	=
 
= = = =. -1	> >> > c"T)	>
 
> > > >, -1> >> c"T)> 
	> > > >,  ,0/ /4Z/ Tz/ 4Z	/
 / / / / / c"T)/ 
/ / / /f "&,0 4Z Cy4 	
 c"T) 
   B !%"&,0! !4Z! $J! Cy4	!
 ! c"T)! 
! ! ! !F5 5 5  
!R !RDI,< !R !R !R !R !RL' ' ' 'R8
 8
Xk-B 8
dS]N^ 8
 8
 8
 8
z  )-@ @@ @ 	@
 @ Tz@ 4Z@  $;@ @ @ 
&	'@ @ @ @DY YC$J Y${BS Y Y Y Y07 7S4Z 74;L 7 7 7 7* * * *+t + + + +J$ J J J JQ Q Q Q Q.C$J . . . ./t / / / /54 5 5 5 5 5 5r   r>   prober0  r   c                   K   t          t          fi |}|t          d          | r	 |                                 d{V }t                              d|j                    |j                            dd          }|st          	                    d           nt          
                    d|            nL# t          $ r?}|                                 d{V  t          j        d|j         d	|           |d}~ww xY w|S )
aB  
    Get an async DAV client instance with configuration from multiple sources.

    See :func:`caldav.base_client.get_davclient` for full documentation.

    Args:
        probe: Verify connectivity with OPTIONS request (default: True).
        **kwargs: All other arguments passed to base get_davclient.

    Returns:
        AsyncDAVClient instance.

    Raises:
        ValueError: If no configuration is found.

    Example::

        async with await get_davclient(url="...", username="...", password="...") as client:
            principal = await client.principal()
    NztNo configuration found. Provide connection parameters, set CALDAV_URL environment variable, or create a config file.zConnected to CalDAV server: rG  rB   z:Server did not return DAV header - may not be a DAV serverzServer DAV capabilities: z&Failed to connect to CalDAV server at : )_base_get_davclientr>   
ValueErrorr   r   r%  r@   r   rj   r   r   r   r   r2   DAVError)r_  r0  r  r   rL  r   s         r   r0   r0     sO     * !::6::F~L
 
 	
  d	d#^^--------HHH@FJ@@AAA ")--eR88J DXYYYY		BjBBCCC 	d 	d 	d,,..       .![&*![![XY![![\\bcc	d Ms   BB; ;
D:C??Dcalendar_urlcalendar_nameraise_errorsCalendarCollectionc                   K   ddl m}m} fd}	 t          dddi| d{V }nA# t          $ r4}r t
                              d|             |            cY d}~S d}~ww xY w	 |                                 d{V }	|	s |dd            ||	          S g }
 ||           } ||          }|D ]}d
t          |          v r|		                    |          }n|		                    |          }	 |
                                 d{V }||
                    |           s# t          $ r-}t
                              d| d|            r Y d}~d}~ww xY w|D ]p}	 |		                    |           d{V }|r|
                    |           7# t          $ r-}t
                              d| d|            r Y d}~id}~ww xY w|
s[|sY|sW	 |	                                 d{V }|r|}
n7# t          $ r*}t
                              d|            r Y d}~nd}~ww xY w ||
|	          S # t          $ r |                    ddd           d{V   w xY w)a  
    Get calendars from a CalDAV server asynchronously.

    This is the async version of :func:`caldav.get_calendars`.

    Args:
        calendar_url: URL(s) or ID(s) of specific calendars to fetch.
        calendar_name: Name(s) of specific calendars to fetch by display name.
        raise_errors: If True, raise exceptions on errors; if False, log and skip.
        **kwargs: Connection parameters (url, username, password, etc.)

    Returns:
        :class:`~caldav.base_client.CalendarCollection` of matching calendars.
        Use as an async context manager to auto-close the connection::

            async with await aio.get_calendars() as calendars:
                for cal in calendars:
                    print(await cal.get_display_name())
    r   )rh  _normalize_to_listc                 h    | .t                               d|            rt          |          | S )z)Handle errors based on raise_errors flag.Nz(Problems fetching calendar information: )r   r2   rc  )coro_resulterrmsgrg  s     r   _tryzget_calendars.<locals>._try  s@    IIIIIJJJ ) (((r   r_  TNzFailed to create async client: zgetting principalr  /)cal_url)r$  zProblems fetching calendar ra  r@  z$Problems fetching calendar by name 'z': z!Problems fetching all calendars: r*   )caldav.base_clientrh  rj  r0   r   r   r2   r  r)   r.  get_display_nameappendr-  r   )re  rf  rg  r0  rh  rj  rn  r  r   r  	calendarscalendar_urlscalendar_namesrq  r.  display_namecal_nameall_calss     `               r   r-  r-    s     2 JIIIIIII    $$::4:6:::::::: $ $ $ 			7A77888!!########	$4 ..00000000	 	5D*+++%%V4444	**<88++M:: % 	 	Gc'll""$--g->>$--W-==%-%>%>%@%@@@@@@@+$$X...   		FFF1FFGGG      ' 	 	H!*!3!3!3!B!BBBBBBB /$$X...   		QQQaQQRRR       	 	~ 	!*!8!8!:!::::::: ) (I   		AaAABBB     
 "!)F;;;;   tT4000000000s   ' 
A%)A A% A%)3I AI 81D*)I *
E!4#EI E!!I )3FI 
G'#G
I G	I G= <I =
H1 H,'I ,H11I )I*CalendarResultc                  r   K   ddl m} t          di |  d{V }|r|d         nd} |||j                  S )a`  
    Get a single calendar from a CalDAV server asynchronously.

    This is a convenience function for the common case where only one
    calendar is needed.  Use as an async context manager to auto-close
    the connection::

        async with await aio.get_calendar() as cal:
            events = await cal.search(event=True)

    Args:
        Same as :func:`get_calendars`.

    Returns:
        :class:`~caldav.base_client.CalendarResult` wrapping the first
        matching calendar (or None).  Behaves like the calendar via
        ``__getattr__`` delegation when not used as a context manager.
    r   )r{  Nro  r*   )rr  r{  r-  r  )r0  r{  
collectioncals       r   get_calendarr    si      & 211111$..v........J%
/*Q--4C>#j&78888r   )T)NNF)>r(   r   loggingsyscollections.abcr   typesr   typingr   r   r   urllib.parser   caldav.calendarobjectresourcer	   r  r
   r   ru   _USE_HTTPXYZr`   r_   niquestsr   niquests.structuresr   ImportErrorhttpxyzrv   h2Authr   r9   r.   rr  r/   r0   rb  caldav.compatibility_hintsr1   
caldav.libr2   caldav.lib.python_utilitiesr3   caldav.lib.urlr4   caldav.requestsr5   caldav.responser6   r7   r8   	getLoggerr   version_infotyping_extensionsr<   r>   rW  r-  r  r*   r   r   <module>r     s      



 # # # # # #       / / / / / / / / / /             6DDDDDD55555555 
	OOO%%%%%%777777MM 	 	 	D	  
	III MM 	 	 	D		 	 	 	 	uz 	 	 	 	      \ 
	III MM 	 	 	D		 	 	 	 	uz 	 	 	 	      - 
+	_         , , , , , , C C C C C C 1 1 1 1 1 1       / / / / / /       * * * * * * L L L L L L L L L Lg!!g&&&&&&&I5 I5 I5 I5 I5] I5 I5 I5^ . .t .c .n . . . .d  $ $_ _*_:_ _ 	_
 _ _ _ _D9 9)9 9 9 9 9 9 9s~   A AA%B .A5 4B 5A=:B <A==B BB$C +B2 1C 2B:7C 9B::C CC