o
    .jQ                     @   s  d dl Z d dlZd dlZd dlmZmZmZmZ d dlm	Z	m
Z
mZmZ d dlmZ er2ddlmZ d dlmZmZ ejdk rFd d	lmZ nd d	lmZ dd
l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# edddZ$e %dZ&	 G dd dZ'dS )    N)TYPE_CHECKINGAnyOptionalTypeVar)ParseResultSplitResultquoteunquote)etree   )	DAVClient)	CoroutineSequence)      )Self)cdavdav)BaseElement)error)errmsg)to_wire)URL_CCCalendarObjectResource)boundcaldavc                   @   s  e Zd ZU dZdZedB ed< dZedB ed< dZ	e
d ed< dZe
d  ed< 						dVde
d deeB eB eB dB de
d  dedB dedB d	dfd
dZed	efddZed	efddZ	dWdedB d	dfddZdd Zdd Zd	eeB fddZdd Z	dXdee dB ded	dfd d!Z	dXdee dB defd"d#Z			$		dY	dZd%d&Z			$		dYd'd(Z	)d[d*ed+ed	d,fd-d.Z d*ed	edB fd/d0Z!d1e"d	e"fd2d3Z#			4	4d\dee dB ded5ed6ed	d7f
d8d9Z$d:d; Z%			4	4d\dee dB ded5ed6efd<d=Z&dWde'dB d	d>fd?d@Z(d	e)fdAdBZ*d	e)fdCdDZ+d	e)fdEdFZ,d]dHdIZ-d^dJdKZ.d^dLdMZ/d_dNdOZ0ed	edB fdPdQZ1d	efdRdSZ2d	efdTdUZ3dS )`	DAVObjectz
    Base class for all DAV objects.  Can be instantiated by a client
    and an absolute or relative URL, or from the parent object.
    Nidurlr   clientparentnamereturnc                 K   s   |du r|dur|j }|| _ || _|| _|pi | _|| _|dur%|| jd< |r1|r1|j|| _n|du r9d| _nt|| _| jdurSdt	| jv rUt
d| jdS dS )a  
        Default constructor.

        Args:
          client: A DAVClient instance
          url: The url for this object.  May be a full URL or a relative URL.
          parent: The parent object - used when creating objects
          id: The resource id (UID for an Event)
          props: a dict with known properties for this object
          name: Display name (deprecated, use props={'{DAV:}displayname': name})
        Nz{DAV:}displayname zURL must not contain spaces: )r    r!   r   propsextra_init_optionsr   joinr   	objectifystr
ValueError)selfr    r   r!   r   r%   r"   extra r-   E/home/thesage/.local/lib/python3.10/site-packages/caldav/davobject.py__init__4   s"   

zDAVObject.__init__c                 C   s    | j d u r	tdt| j  S )N"Unexpected value None for self.url)r   r*   r)   	canonicalr+   r-   r-   r.   canonical_url_   s   
zDAVObject.canonical_urlc                 C   s&   | j du rdS ddlm} t| j |S )zCheck if this object is connected to an async client.

        Returns:
            True if the client is an AsyncDAVClient, False otherwise.
        NFr   )AsyncDAVClient)r    caldav.async_davclientr4   
isinstance)r+   r4   r-   r-   r.   is_async_cliente   s   
zDAVObject.is_async_clienttypezLlist[tuple[URL, Any, Any]] | Coroutine[Any, Any, list[tuple[URL, Any, Any]]]c                 C   sj   ddl m} d}| jdu rtdt g}t g}|| }| jr)| |||S | 	||}| 
||S )a  List children, using a propfind (resourcetype) on the parent object,
        at depth = 1.

        TODO: This is old code, it's querying for DisplayName and
        ResourceTypes prop and returning a tuple of those.  Those two
        are relatively arbitrary.  I think it's mostly only calendars
        having DisplayName, but it may make sense to ask for the
        children of a calendar also as an alternative way to get all
        events?  It should be redone into a more generic method, and
        it should probably return a dict rather than a tuple.  We
        should also look over to see if there is any code duplication.
        r   CalendarSetNr0   )
collectionr:   r   r*   r   DisplayNameResourceTyper7   _async_children_query_properties_children_post_process)r+   r8   r:   depthr%   
multipropsprops_multipropsresponser-   r-   r.   childrenr   s   


zDAVObject.childrenc                 C   s   ddl m} g }t g}t g}|j||d}|D ]O}|| tjj }	|| tjj }
|d u s5||	v rjt|}|jd u rBt	|}t
| |rM|tjjks^| j  | j|  krj|| j||	|
f q|S )Nr   r9   )r%   multi_value_props)r;   r:   r   r<   r=   expand_simple_propstagr   hostnamer   r6   r   Calendarr   r1   strip_trailing_slashr'   append)r+   type_rD   r:   cr%   rB   
propertiespathresource_typesresource_namer   r-   r-   r.   r@      s&   


z DAVObject._children_post_processc                    s    |  ||I d H }| ||S N)r?   r@   )r+   r8   rC   rA   rD   r-   r-   r.   r>      s   zDAVObject._async_childrenc                 C   s.   |rt |drtj| ddtjdS |S dS )z=Serialize a DAV element (or raw bytes/str) to a request body.
xmlelementzutf-8T)encodingxml_declarationpretty_print )hasattrr
   tostringrT   r   debug_dump_communication)r+   rootr-   r-   r.   _build_xml_body   s   
zDAVObject._build_xml_bodyc                 C   s0   |durt |dkrt | }t | S dS )zBBuild a Propfind XML element from a list of props, or return None.Nr   )lenr   PropPropfind)r+   r%   propr-   r-   r.   _build_propfind_root   s   zDAVObject._build_propfind_rootr   r%   rA   Any | Coroutine[Any, Any, Any]c                 C   s$   | j r	| ||S | | ||S )a  
        This is an internal method for doing a propfind query.  It's a
        result of code-refactoring work, attempting to consolidate
        similar-looking code into a common method.

        For async clients, returns a coroutine that must be awaited.
        )r7   _async_query_properties_queryrb   r+   r%   rA   r-   r-   r.   r?      s   
zDAVObject._query_propertiesc                    s   |  | ||I dH S )z*Async implementation of _query_properties.N)re   rb   rf   r-   r-   r.   rd      s   z!DAVObject._async_query_propertiespropfindc                 C   s   | j r| |||||S | |}|du r| j}t| j||||}|jdkr.tt	||dur7|j|ks<|jdkret
|}|jdkr\d|vr\d|v r\|dd}| |||||S tj| t	||S )a  
        This is an internal method for doing a query.  It's a
        result of code-refactoring work, attempting to consolidate
        similar-looking code into a common method.

        For async clients, returns a coroutine that must be awaited.
        N      	   D:getetag   <C:calendar-data   <D:getetag/><C:calendar-data)r7   _async_queryr]   r   getattrr    statusr   NotFoundErrorr   r   replacere   exception_by_methodr+   r\   rA   query_methodr   expected_return_valuebodyretr-   r-   r.   re      s    


zDAVObject._queryc                    s   |  |}|du r| j}t| j||||I dH }|jdkr&tt||dur/|j|ks4|jdkr`t|}|jdkrWd|vrWd|v rW|	dd}| 
|||||I dH S tj| t||S )zAsync implementation of _query.Nrh   ri   rj   rk   rl   rm   )r]   r   ro   r    rp   r   rq   r   r   rr   re   rs   rt   r-   r-   r.   rn     s   
	

zDAVObject._async_queryFra   
use_cached,str | None | Coroutine[Any, Any, str | None]c                 K   sZ   |r|j | jv r| j| j|j  S | jr| j|fi |S | j|gfi ||j dS )a  
        Wrapper for the :class:`get_properties`, when only one property is wanted

        Args:

         prop: the property to search for
         use_cached: don't send anything to the server if we've asked before

        TODO: use_cached default is False, should probably be True?

        Other parameters are sent directly to the :class:`get_properties` method

        For async clients, returns a coroutine that must be awaited.
        N)rH   r%   r    _value_or_coroutiner7   _async_get_propertyget_propertiesget)r+   ra   ry   passthroughr-   r-   r.   get_property   s
   zDAVObject.get_propertyc                    s&   | j |gfi |I dH |jdS )z%Async implementation of get_property.N)r}   r~   rH   )r+   ra   r   r-   r-   r.   r|   7  s   $zDAVObject._async_get_propertyrO   c                 C   sF  ddl m} | jdu rtdt| jj}|dr!|dd }n|d }||v r.|| }nm||v rHt| |sCt	d| d| d	 || }nS| j|v rS|| j }nHd
|v ra|d
ra|d
 }n:d|v rv|
dd|v rv||
dd }n%t|dkrt| d }nt	d| dt|   td i S | j| |S )a  Resolve the correct property dict from a PROPFIND response.

        Servers may return hrefs that don't exactly match the request-URI.
        RFC 4918, Section 9.1: "Clients MUST be able to handle the case
        where the href in the response does not match the request-URI."

        This method handles various known mismatches (trailing slashes,
        double slashes, iCloud quirks) and returns the resolved property
        dict, also updating self.props as a side effect.
        r   )	PrincipalNr0   /z	The path z& was not found in the properties, but z? was. This may indicate a server bug or a trailing slash issue.z/principal/z//r   z&Path handling problem. Path expected: z, paths found: F)r;   r   r   r*   r	   rP   endswithr6   logwarningrr   r^   listvalueskeysr   assert_r%   update)r+   rO   r   rP   exchange_pathrcr-   r-   r.   _resolve_properties;  s@   








zDAVObject._resolve_propertiesTparse_response_xmlparse_propsz,dict | Any | Coroutine[Any, Any, dict | Any]c                 C   s2   | j r| ||||S | ||}| ||||S )a  Get properties (PROPFIND) for this object.

        With parse_response_xml and parse_props set to True a
        best-attempt will be done on decoding the XML we get from the
        server - but this works only for properties that don't have
        complex types.  With parse_response_xml set to False, a
        DAVResponse object will be returned, and it's up to the caller
        to decode.  With parse_props set to false but
        parse_response_xml set to true, xml elements will be returned
        rather than values.

        Args:
         props: ``[dav.ResourceType(), dav.DisplayName(), ...]``

        Returns:
          ``{proptag: value, ...}``

        For async clients, returns a coroutine that must be awaited.
        )r7   _async_get_propertiesr?   _post_get_propertiesr+   r%   rA   r   r   rD   r-   r-   r.   r}   u  s   zDAVObject.get_propertiesc           	      C   s   |s|S |r.|j r.i }|j D ]}i }|r!|D ]
}|jr d||j< q||j |||j< qn|s5| }n||}t| | 	|S )zDShared post-processing for get_properties and _async_get_properties.N)
resultsrH   r   rO   href_find_objects_and_propsrG   r   r   r   )	r+   rD   r%   r   r   rO   resultresult_propsra   r-   r-   r.   r     s&   







zDAVObject._post_get_propertiesc                    s$   |  ||I dH }| ||||S )z'Async implementation of get_properties.N)r?   r   r   r-   r-   r.   r     s   zDAVObject._async_get_propertiesz Self | Coroutine[Any, Any, Self]c                 C   s   |du rg n|}t  | }t  | }t  | }| |}| jdu r(td| jdu r1td| jr9| 	|S | 
| jt| j|S )z
        Set properties (PROPPATCH) for this object.

         * props = [dav.DisplayName('name'), ...]

        For async clients, returns a coroutine that must be awaited.

        Returns:
         * self
        Nr0   %Unexpected value None for self.client)r   r_   SetPropertyUpdater]   r   r*   r    r7   _async_set_properties_post_set_properties	proppatchr)   )r+   r%   ra   set_elemr\   rw   r-   r-   r.   set_properties  s   



zDAVObject.set_propertiesc                 C   s   |j dkrtt|| S )Nri   )rp   r   PropsetErrorr   r+   rr-   r-   r.   r     s   
zDAVObject._post_set_propertiesc                    s"   |  | jt| j|I dH S )z'Async implementation of set_properties.N)r   r    r   r)   r   )r+   rw   r-   r-   r.   r     s    zDAVObject._async_set_propertiesc                 C   s   t  )z
        Save the object. This is an abstract method, that all classes
        derived from DAVObject implement.

        Returns:
         * self
        )NotImplementedErrorr2   r-   r-   r.   save  s   zDAVObject.save None | Coroutine[Any, Any, None]c                 C   sJ   | j du rdS | jdu rtd| jr|  S | | jt| j  dS )a	  
        Delete the object.

        For sync clients, deletes and returns None.
        For async clients, returns a coroutine that must be awaited.

        Example (sync):
            obj.delete()

        Example (async):
            await obj.delete()
        Nr   )r   r    r*   r7   _async_delete_post_deletedeleter)   r2   r-   r-   r.   r     s   

zDAVObject.deletec                 C   s   |j dvrtt|d S )N)      rh   )rp   r   DeleteErrorr   r   r-   r-   r.   r     s   
zDAVObject._post_deletec                    s$   |  | jt| jI dH  dS )zAsync implementation of delete.N)r   r    r   r)   r   r2   r-   r-   r.   r     s   "zDAVObject._async_deletec                 C   s   | j t ddS )zB
        Get display name (calendar, principal, ...more?)
        Try   )r   r   r<   r2   r-   r-   r.   get_display_name	  s   zDAVObject.get_display_namec                 C   s   t jdtdd |  S )z
        Display name of this DAV object.

        .. deprecated:: 3.0
            Use :meth:`get_display_name` instead.
        zCThe 'name' attribute is deprecated. Use get_display_name() instead.   )
stacklevel)warningswarnDeprecationWarningr   r2   r-   r-   r.   r"     s   zDAVObject.namec                 C   s<   zt | jt ddp| jW S  ty   t | j Y S w )NTr   )r)   r   r   r<   r   	Exceptionr2   r-   r-   r.   __str__  s
   zDAVObject.__str__c                 C   s   d| j j| jf S )Nz%s(%s))	__class____name__r   r2   r-   r-   r.   __repr__$  s   zDAVObject.__repr__)NNNNNNrS   )Nr   )Nr   rg   NN)r#   rc   )F)Nr   TT)r#   r   )r#   N)r#   rz   )4r   
__module____qualname____doc__r   r)   __annotations__r   r   r    r   r!   r   r   r/   propertyr3   boolr7   rE   r@   r>   bytesr]   rb   r   r   intr?   rd   re   rn   r   r|   dictr   r}   r   r   r   r   r   r   r   r   r   r   r   r   r"   r   r   r-   r-   r-   r.   r   )   s   
 	
+
!"




&

<

 






r   )(loggingsysr   typingr   r   r   r   urllib.parser   r   r   r	   lxmlr
   	davclientr   collections.abcr   r   version_infotyping_extensionsr   elementsr   r   elements.baser   libr   	lib.errorr   lib.python_utilitiesr   lib.urlr   r   	getLoggerr   r   r-   r-   r-   r.   <module>   s,    

