o
    .j                     @  sZ  d Z ddlmZ ddlZddlmZm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 dd	lmZmZ dd
lmZ ddlmZ ddlmZmZ ddlmZ ddlmZ er`ddlmZ e dZ!ddiZ"d;d<ddZ#G dd deZ$G dd de%Z&G dd  d Z'd=d$d%Z(d>d+d,Z)			-			.	-		.d?d@d7d8Z*	-			.	-	dAdBd9d:Z+dS )Cz
Base class for DAV clients.

This module contains the BaseDAVClient class which provides shared
functionality for both sync (DAVClient) and async (AsyncDAVClient) clients.
    )annotationsN)ABCabstractmethod)Mapping)datetime)TYPE_CHECKINGAnyNoReturn)etreecdavdav)BaseElement)error)extract_auth_typesselect_auth_type)to_normal_str)URL)
FeatureSetcaldavContent-Typeztext/calendar; charset="utf-8"namestrvalue
Any | NonereturnBaseElement | Nonec              
   C  s   t jt jt jt jt jt jt jd}tj	tj
tjtjtjtjtjtjtjd	}| dr7d| v r7| ddd } |  dd}||fD ]*}||v rm|| }z|durY||W   S | W   S  tyl   |  Y   S w qCdS )	zQConvert a property name string (plain or Clark-notation) to a DAV element object.)displaynameresourcetypegetetagzcurrent-user-principalownerz
sync-tokenzsupported-report-set)	zcalendar-datazcalendar-home-setzcalendar-user-address-setzcalendar-user-typezcalendar-descriptionzcalendar-timezonez supported-calendar-component-setzschedule-inbox-urlzschedule-outbox-url{}   _-N)r   DisplayNameResourceTypeGetEtagCurrentUserPrincipalOwner	SyncTokenSupportedReportSetr   CalendarDataCalendarHomeSetCalendarUserAddressSetCalendarUserTypeCalendarDescriptionCalendarTimeZoneSupportedCalendarComponentSetScheduleInboxURLScheduleOutboxURL
startswithsplitlowerreplace	TypeError)r   r   	dav_propscaldav_props
name_lower
props_dictcls r@   G/home/thesage/.local/lib/python3.10/site-packages/caldav/base_client.py_prop_name_to_element"   s>   
"rB   c                   @  s  e Zd ZU dZdgZg dZdZded< dZded< dZ	ded	< dZ
ded
< dZded< dZded< dd ZdlddZdd ZdmddZdndoddZdpd$d%Zdqd)d*Zdrd-d.Zdsd2d3Ze		4dtdud8d9Zedndvd<d=Ze			4		4	4	4		dwdxdIdJZe	KdydzdOdPZe			Qd{d|dTdUZe				d}d~dZd[Zedd]d^ZddbdcZdddedfZdddhdiZ e!dnddjdkZ"dS )BaseDAVClienta  
    Base class for DAV clients providing shared authentication and configuration logic.

    This abstract base class contains common functionality used by both
    DAVClient (sync) and AsyncDAVClient (async). Subclasses must implement
    the abstract methods for their specific HTTP library.

    Shared functionality:
    - Authentication type extraction and selection
    - Feature set management
    - Common properties (username, password, auth_type, etc.)
    z0{urn:ietf:params:xml:ns:caldav}calendar-home-set)z{DAV:}resourcetypez{DAV:}displaynamez?{urn:ietf:params:xml:ns:caldav}supported-calendar-component-setz){http://apple.com/ns/ical/}calendar-colorz&{http://calendarserver.org/ns/}getctagN
str | Noneusernamepasswordr   auth	auth_typezFeatureSet | Nonefeaturesr   urlc                 K  s   ddl m} |dd| i|S )a>  Returns a calendar object.

        Typically, a URL should be given as a named parameter (url)

        No network traffic will be initiated by this method.

        If you don't know the URL of the calendar, use
        client.principal().calendar(...) instead, or
        client.principal().get_calendars()
        r   )CalendarclientNr@   )caldav.collectionrK   )selfkwargsrK   r@   r@   rA   calendarf   s   zBaseDAVClient.calendarr   r   c                 C  s"   |r| dst| j|S |S )zMake a URL absolute by joining with the client's base URL if needed.

        Args:
            url: URL string, possibly relative (e.g., "/calendars/user/")

        Returns:
            Absolute URL string.
        http)r6   r   rJ   join)rN   rJ   r@   r@   rA   _make_absolute_urlu   s   	z BaseDAVClient._make_absolute_urlc                 C  s   |S Nr@   )rN   r   r@   r@   rA   _value_or_coroutine      z!BaseDAVClient._value_or_coroutineheaderset[str]c                 C  s   t |S )a  Extract authentication types from WWW-Authenticate header.

        Parses the WWW-Authenticate header value and extracts the
        authentication scheme names (e.g., "basic", "digest", "bearer").

        Args:
            header: WWW-Authenticate header value from server response.

        Returns:
            Set of lowercase auth type strings.

        Example:
            >>> client.extract_auth_types('Basic realm="test", Digest realm="test"')
            {'basic', 'digest'}
        )r   )rN   rW   r@   r@   rA   r      s   z BaseDAVClient.extract_auth_types
auth_typeslist[str] | Nonec                 C  s   | j }|s|std|r |r ||vr tjd| d| d|s@|r@t|t| jt| jd}|s@d|v r@| js@tjdd|S )a  
        Select the best authentication type from available options.

        This method implements the shared logic for choosing an auth type
        based on configured credentials and server-supported types.

        Args:
            auth_types: List of acceptable auth types from server.

        Returns:
            Selected auth type string, or None if no suitable type found.

        Raises:
            AuthorizationError: If configuration conflicts with server capabilities.
        zlNo auth-type given. This shouldn't happen. Raise an issue at https://github.com/python-caldav/caldav/issues/zConfiguration specifies to use z, but server only accepts )reason)has_usernamehas_passwordbearerzeServer provides bearer auth, but no password given. The bearer token should be configured as password)rH   r   AuthorizationErrorr   boolrE   rF   )rN   rY   rH   r@   r@   rA   _select_auth_type   s,   zBaseDAVClient._select_auth_typemethodbodyheadersMapping[str, str] | Nonetuple[URL, dict]c                 C  sv   |pi }| j  }|| |du s|dkrd|v r|d= t|}td| dt| d| dt|  ||fS )zCombine headers, strip Content-Type for empty bodies, objectify URL, and log.

        Returns:
            (url_obj, combined_headers) ready to pass to the HTTP library.
        N r   zsending request - method=z, url=z
, headers=z
body:
)	rd   copyupdater   	objectifylogdebugr   r   )rN   rJ   rb   rc   rd   combined_headersurl_objr@   r@   rA   _prepare_request   s   


zBaseDAVClient._prepare_requeststatus_codeintr`   c                 C  s,   |dkod|v o| j  o| jduo| jduS )zReturn True when a 401 response warrants auth negotiation.

        True when: status is 401, WWW-Authenticate header present, no auth
        object yet, and credentials are configured.
        i  zWWW-AuthenticateN)rG   rE   rF   )rN   rp   rd   r@   r@   rA   _should_negotiate_auth   s   z$BaseDAVClient._should_negotiate_authwww_authenticateNonec                 C  s&   |  |}| | | jstddS )zBuild auth object from a WWW-Authenticate header value.

        Raises:
            NotImplementedError: If the server offers no supported auth method.
        zhThe server does not provide any of the currently supported authentication methods: basic, digest, bearerN)r   build_auth_objectrG   NotImplementedError)rN   rs   rY   r@   r@   rA   _build_auth_from_401   s   

z"BaseDAVClient._build_auth_from_401url_strreason_sourcer	   c                 C  s0   z|j }W n ty   d}Y nw tj||d)zFRaise AuthorizationError, extracting reason from reason_source.reason.z
None given)rJ   r[   )r[   AttributeErrorr   r_   )rN   rx   ry   r[   r@   r@   rA   _raise_authorization_error   s   
z(BaseDAVClient._raise_authorization_errorFpropsallpropbytesc                   sf   |rt  t   }n| r! fdd| D }t  t  |  }nt  t   }tj| dddS )z Build PROPFIND request body XML.c                       g | ]}t |  d ur qS rT   rB   .0r   er@   rA   
<listcomp>       z6BaseDAVClient._build_propfind_body.<locals>.<listcomp>utf-8Tencodingxml_declaration)r   PropfindAllpropPropr
   tostring
xmlelement)r|   r}   propfindprop_elementsr@   r   rA   _build_propfind_body  s   z"BaseDAVClient._build_propfind_body	set_propsdict[str, Any] | Nonec                   sR   t  }| r fdd|  D }|r|t  t  |  7 }tj| dddS )z4Build PROPPATCH request body for setting properties.c                   s&   g | ]\}}t ||  d ur qS rT   r   )r   r   r   r   r@   rA   r     s
    z7BaseDAVClient._build_proppatch_body.<locals>.<listcomp>r   Tr   )r   PropertyUpdateitemsSetr   r
   r   r   )r   propertyupdateset_elementsr@   r   rA   _build_proppatch_body  s   
z#BaseDAVClient._build_proppatch_bodystartdatetime | Noneendexpandcomp_filtereventtodojournallist[BaseElement] | Nonefilterstuple[bytes, str | None]c	                 C  s  t  }	|r| r
|std|	t | |7 }	|	g|rt|ng  }
t |
 }t d}|p<|r3dn	|r7dn|r;dnd}|rCt|ng }| sI|rR|	t 
| | |rdt |}|r_||7 }||7 }n|rj||7 }t  |t  | g }tj| ddd	|fS )
zmBuild calendar-query REPORT request body.

        Returns (XML bytes, component type name or None).
        z!can't expand without a date range	VCALENDARVEVENTVTODOVJOURNALNr   Tr   )r   r-   r   ReportErrorExpandlistr   r   
CompFilterappend	TimeRangeCalendarQueryFilterr
   r   r   )r   r   r   r   r   r   r   r|   r   data
props_listprop	vcalendar	comp_typefilter_listcomp_filter_elemrootr@   r@   rA   _build_calendar_query_body$  s2   



z(BaseDAVClient._build_calendar_query_bodyThrefs	list[str]include_datac                 C  sX   g }|r| t t   | D ]
}| t| qt | }tj|	 dddS )z,Build calendar-multiget REPORT request body.r   Tr   )
r   r   r   r   r-   HrefCalendarMultiGetr
   r   r   )r   r   elementshrefmultigetr@   r@   rA   _build_calendar_multiget_bodyS  s   z+BaseDAVClient._build_calendar_multiget_body1
sync_token
sync_levelc                   s   t j| pddt j|dg}|r% fdd|D }|r$|t  |  n|t  t  t g  t  | }t	j
| dddS )z*Build sync-collection REPORT request body.rg   r   c                   r   rT   r   r   r   r@   rA   r   m  r   z=BaseDAVClient._build_sync_collection_body.<locals>.<listcomp>r   Tr   )r   r+   	SyncLevelr   r   r(   r   r-   SyncCollectionr
   r   r   )r   r|   r   r   r   sync_collectionr@   r   rA   _build_sync_collection_bodya  s   
z)BaseDAVClient._build_sync_collection_bodyr   descriptiontimezonesupported_componentsc                 C  s   t  }| r|t | 7 }|r|t|7 }|r|t|7 }|r5t }|D ]	}|t|7 }q'||7 }|t  t 	 t
 g 7 }t t  |  }tj| dddS )zBuild MKCALENDAR request body.r   Tr   )r   r   r&   r   r1   r2   r3   Compr'   
CollectionrK   
Mkcalendarr   r
   r   r   )r   r   r   r   r   sccscomp
mkcalendarr@   r@   rA   _build_mkcalendar_bodyu  s   z$BaseDAVClient._build_mkcalendar_bodyr   c                 C  sb   | rt  t  t  g g t j| d gng }t  | t  t t  g }t	|
 S )z:Build the XML body for a principal-property-search REPORT.r   )r   PropertySearchr   r&   MatchPrincipalPropertySearchr   r.   r
   r   r   )r   name_filterqueryr@   r@   rA   _build_principal_search_query  s   ,z+BaseDAVClient._build_principal_search_queryprincipal_dictdictr   c              	   C  s  ddl m}m} ddlm}m} g }|D ]x}|| }|jj|vr!q||jj j}	t	
||jj    t	
||jj    ||jj }
t	
|
   t	
|
j  |
 }t	
t|dk t	
|d    t	
|d    |d j}|| |d}||| ||	|d q|S )zFParse principal-property-search REPORT results into Principal objects.r   )CalendarSet	Principalr   r#   )rL   rJ   )rL   rJ   r   calendar_home_set)rM   r   r   caldav.elementsr   r   r&   tagtextr   assert_getchildrenr   r.   lenr   )rN   r   r   r   r   r   retxpr   chschs_hrefchs_urlr   r@   r@   rA    _parse_principal_search_response  s.   
z.BaseDAVClient._parse_principal_search_responserP   c                 C  s   | j |d||dS )zGet events from a calendar, optionally filtered by date range.

        For sync clients returns a list directly.
        For async clients returns a coroutine that must be awaited.
        T)r   r   r   search_calendar)rN   rP   r   r   r@   r@   rA   
get_events  s   zBaseDAVClient.get_eventsinclude_completedc                 C  s   | j |d|dS )zGet todos from a calendar.

        For sync clients returns a list directly.
        For async clients returns a coroutine that must be awaited.
        T)r   r   r   )rN   rP   r   r@   r@   rA   	get_todos  s   zBaseDAVClient.get_todosc                 C  s   dS )a5  
        Build authentication object based on configured credentials.

        This method must be implemented by subclasses to create the
        appropriate auth object for their HTTP library (requests, httpx, etc.).

        Args:
            auth_types: List of acceptable auth types from server.
        Nr@   )rN   rY   r@   r@   rA   ru     s   zBaseDAVClient.build_auth_object)rJ   r   r   r   )rW   r   r   rX   rT   )rY   rZ   r   rD   )
rJ   r   rb   r   rc   r   rd   re   r   rf   )rp   rq   rd   r   r   r`   )rs   r   r   rt   )rx   r   ry   r   r   r	   NF)r|   rZ   r}   r`   r   r~   )r   r   r   r~   )	NNFNFFFNN)r   r   r   r   r   r`   r   rD   r   r`   r   r`   r   r`   r|   r   r   r   r   r   )T)r   r   r   r`   r   r~   )NNr   )r   rD   r|   rZ   r   r   r   r~   )NNNN)
r   rD   r   rD   r   rD   r   rZ   r   r~   )r   rD   r   r~   )r   r   r   r   NN)rP   r   r   r   r   r   r   r   )F)rP   r   r   r`   r   r   )rY   rZ   r   rt   )#__name__
__module____qualname____doc__CALENDAR_HOME_SET_PROPSCALENDAR_LIST_PROPSrE   __annotations__rF   rG   rH   rI   rJ   rP   rS   rU   r   ra   ro   rr   rw   r{   staticmethodr   r   r   r   r   r   r   r   r   r   r   ru   r@   r@   r@   rA   rC   F   sr   
 	


/


.
rC   c                      s^   e Zd ZdZ			dd fdd	Zed
d Zdd Zdd Zdd Z	dd Z
dd Z  ZS )CalendarCollectiona  
    A list of calendars that can be used as a context manager.

    This class extends list to provide automatic cleanup of the underlying
    DAV client connection when used with a `with` statement.

    Example::

        from caldav import get_calendars

        # As context manager (recommended) - auto-closes connection
        with get_calendars(url="...", username="...", password="...") as calendars:
            for cal in calendars:
                print(cal.get_display_name())

        # Without context manager - must close manually
        calendars = get_calendars(url="...", username="...", password="...")
        # ... use calendars ...
        if calendars:
            calendars[0].client.close()
    N	calendarslist | NonerL   r   clientsc                   sD   t  |pg  |d urt|| _d S |d ur|g| _d S g | _d S rT   )super__init__r   _clients)rN   r   rL   r   	__class__r@   rA   r    s   
zCalendarCollection.__init__c                 C  s"   | j r| j d S | r| d jS dS )z(The underlying DAV client, if available.r   N)r  rL   rN   r@   r@   rA   rL     s
   

zCalendarCollection.clientc                 C  s   | S rT   r@   r  r@   r@   rA   	__enter__  rV   zCalendarCollection.__enter__c                 C  s\   t  }| jD ]}t||vr|||| |t| q| js,| r,| d j||| dS )Nr   F)setr  id__exit__addrL   rN   exc_typeexc_valexc_tbseencr@   r@   rA   r
    s   

zCalendarCollection.__exit__c                   s   | S rT   r@   r  r@   r@   rA   
__aenter__  s   zCalendarCollection.__aenter__c                   s   t  }| jD ]&}t||vr-t|dr||||I d H  n|||| |t| q| jsP| rP| d j}t|drI||||I d H  dS |||| dS )N	__aexit__r   F)r  r  r	  hasattrr  r
  r  rL   r  r@   r@   rA   r    s    




zCalendarCollection.__aexit__c                 C  sX   t  }| jD ]}t||vr|  |t| q| js(| r*| d j  dS dS dS )z,Close all underlying DAV client connections.r   N)r  r  r	  closer  rL   )rN   r  r  r@   r@   rA   r  %  s   

zCalendarCollection.close)NNN)r   r   rL   r   r   r   )r   r   r   r   r  propertyrL   r  r
  r  r  r  __classcell__r@   r@   r  rA   r     s    
	
r   c                   @  sl   e Zd ZdZddddZedd	 Zed
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )CalendarResulta  
    A single calendar result that can be used as a context manager.

    This wrapper holds a single Calendar (or None) and provides automatic
    cleanup of the underlying DAV client connection when used with a
    `with` statement.

    Example::

        from caldav import get_calendar

        # As context manager (recommended) - auto-closes connection
        with get_calendar(calendar_name="Work", url="...") as calendar:
            if calendar:
                events = calendar.date_search(start=..., end=...)

        # Without context manager
        result = get_calendar(calendar_name="Work", url="...")
        calendar = result.calendar  # or just use result directly
        # ... use calendar ...
        result.close()
    NrP   r   rL   c                 C  s   || _ || _d S rT   )	_calendar_client)rN   rP   rL   r@   r@   rA   r  H  s   
zCalendarResult.__init__c                 C     | j S )z#The calendar, or None if not found.r  r  r@   r@   rA   rP   L  s   zCalendarResult.calendarc                 C  s   | j r| j S | jr| jjS dS )zThe underlying DAV client.N)r  r  rL   r  r@   r@   rA   rL   Q  s
   zCalendarResult.clientc                 C  r  rT   r  r  r@   r@   rA   r  Z  s   zCalendarResult.__enter__c                 C  s   | j }|r|||| dS r   )rL   r
  rN   r  r  r  rL   r@   r@   rA   r
  ]  s   zCalendarResult.__exit__c                   s   | j S rT   r  r  r@   r@   rA   r  c  s   zCalendarResult.__aenter__c                   s@   | j }|rt|dr||||I d H  dS |||| dS )Nr  F)rL   r  r  r
  r  r@   r@   rA   r  f  s   
zCalendarResult.__aexit__c                 C  s   | j }|r|  dS dS )z+Close the underlying DAV client connection.N)rL   r  )rN   rL   r@   r@   rA   r  o  s   zCalendarResult.closec                 C  s
   | j d uS rT   r  r  r@   r@   rA   __bool__v  s   
zCalendarResult.__bool__c                 C  s&   | j d u rtd| dt| j |S )Nz"No calendar found, cannot access '')r  rz   getattr)rN   r   r@   r@   rA   __getattr__y  s   
zCalendarResult.__getattr__r   )rP   r   rL   r   )r   r   r   r   r  r  rP   rL   r  r
  r  r  r  r  r!  r@   r@   r@   rA   r  0  s    

	r  objr   r   c                 C  s$   | sg S t | ttB r| gS t| S )z8Convert a string or None to a list for uniform handling.)
isinstancer   r~   r   )r"  r@   r@   rA   _normalize_to_list  s
   r$  rL   calendar_urlcalendar_nameraise_errorsr`   c                   s   ddl }|d  fdd}|| ji d}|sg S g }t|}t|}	|D ]$}
dt|
v r6|j|
d}n|j|
d	}||ji d
|
 rK|| q'|	D ]}||jd|id| d}|rd|| qN|sv|sv|	sv||ji d}|rv|}|S )z
    Fetch calendars from a single connected client, optionally filtered.

    Returns a (possibly empty) list of Calendar objects.  On error the
    behaviour is controlled by ``raise_errors``.
    r   Nr   c              
     sn   z| di |}|d u rt d| |W S  ty6 } z d| d|  r+ W Y d }~d S d }~ww )NzMethod returned None: z(Problems fetching calendar information: z - r@   )
ValueError	Exceptionr   )methrO   errmsgr   r   rk   r'  r@   rA   _try  s   z)_fetch_calendars_for_client.<locals>._tryzgetting principal/)cal_url)cal_idz	calendar r   zcalendar by name 'r  zgetting all calendars)	logging	getLogger	principalr$  r   rP   get_display_namer   get_calendars)rL   r%  r&  r'  r1  r-  r3  r   calendar_urlscalendar_namesr/  rP   cal_nameall_calsr@   r,  rA   _fetch_calendars_for_client  s<   



r:  TFclient_classtypecheck_config_fileconfig_filerD   config_section
testconfigenvironmentc
              
     sl  ddl m} td| d|||||d|
}|dur&t||||	}t||dS |s1|	r.tdt S |}|rA|sAddl}|jd}|}|rQ|sQddl}|jd	}|	||}|sb|	r_tdt S dd
l
m  g }g }|D ]A}|dd}|dd}|dur|n|}|dur|n|} fdd| D }| di |}t||||	}|| || qnt||dS )u
  
    Get calendars from one or more CalDAV servers.

    Configuration is read from multiple sources in priority order:

    1. Explicit keyword arguments (``url``, ``username``, ``password``, …)
    2. Test server (``testconfig=True`` or ``PYTHON_CALDAV_USE_TEST_SERVER``)
    3. Environment variables (``CALDAV_URL``, …)
    4. Config file — supports meta-sections so a single ``config_section``
       can expand to multiple servers (see below)

    **Multi-server / meta-sections**

    Sources 1–3 always produce a single connection.  When the config file is
    used (source 4) the ``config_section`` value is passed through
    ``expand_config_section``, which supports:

    * ``"*"`` – every non-disabled section in the file
    * ``"all"`` – a meta-section defined as ``{"contains": ["work", "personal"]}``
    * Glob patterns such as ``"work_*"``
    * A plain section name (normal single-server behaviour)

    Each expanded leaf section can carry its own ``calendar_name`` or
    ``calendar_url`` to filter which calendars are returned for that server.
    Function-level ``calendar_name`` / ``calendar_url`` arguments override
    per-section values when provided.

    The returned :class:`CalendarCollection` is a list that can be used as a
    context manager; on exit **all** underlying connections are closed.

    Args:
        client_class: The client class to use (``DAVClient`` or ``AsyncDAVClient``).
        calendar_url: URL(s) or ID(s) of specific calendars to fetch.
        calendar_name: Name(s) of specific calendars to fetch by display name.
        check_config_file: Whether to look for config files (default: True).
        config_file: Explicit path to config file.
        config_section: Section name in config file (default: ``"default"``).
            Supports ``*``, meta-sections, and glob patterns.
        testconfig: Whether to use test server configuration.
        environment: Whether to read from environment variables (default: True).
        name: Name of test server to use (for testconfig).
        raise_errors: If True, raise exceptions on errors; if False, log and skip.
        **config_data: Explicit connection parameters (url, username, password, …).

    Returns:
        :class:`CalendarCollection` of matching calendars (may be empty).

    Example — single server::

        from caldav import get_calendars

        with get_calendars(url="https://...", username="...", password="...") as cals:
            for cal in cals:
                print(cal.get_display_name())

    Example — all sections in config file::

        with get_calendars(config_section="*") as cals:
            for cal in cals:
                print(cal.get_display_name())
    r   configF)r;  r=  r>  r?  r@  rA  r   N)rL   z4Could not create DAV client - no configuration foundCALDAV_CONFIG_FILECALDAV_CONFIG_SECTIONCONNKEYSr%  r&  c                   s   i | ]\}}| v r||qS r@   r@   )r   kvrF  r@   rA   
<dictcomp>I  s    z!get_calendars.<locals>.<dictcomp>)r   r@   )r   rC  get_davclientr:  r   r(  osenvirongetget_all_file_connection_paramscaldav.configrG  popr   extendr   )r;  r%  r&  r=  r>  r?  r@  rA  r   r'  config_data_configrL   r   resolved_config_filerL  resolved_section
all_paramsall_calendarsall_clientsparamssec_cal_urlsec_cal_nameeff_cal_urleff_cal_nameconn_paramsr  section_calsr@   rF  rA   r5    s\   J
r5  c              	   K  s   ddl m} |jd	||||||d|}	|	du rdS |	dd}
|	dd}|	dd}|	dd | d	i |	}|
durA|
|_|durH||_|durO||_|S )
aS  
    Get a DAV client instance with configuration from multiple sources.

    This is the canonical implementation used by both sync and async clients.
    Configuration is read from various sources in priority order:

    1. Explicit parameters (url=, username=, password=, etc.)
    2. Test server config (if testconfig=True or PYTHON_CALDAV_USE_TEST_SERVER env var)
    3. Environment variables (CALDAV_URL, CALDAV_USERNAME, CALDAV_PASSWORD)
    4. Config file (CALDAV_CONFIG_FILE env var or ~/.config/caldav/)

    Args:
        client_class: The client class to instantiate (DAVClient or AsyncDAVClient).
        check_config_file: Whether to look for config files (default: True).
        config_file: Explicit path to config file.
        config_section: Section name in config file (default: "default").
        testconfig: Whether to use test server configuration.
        environment: Whether to read from environment variables (default: True).
        name: Name of test server to use (for testconfig).
        **config_data: Explicit connection parameters passed to client constructor.
            Common parameters include:
            - url: CalDAV server URL, domain, or email address
            - username: Username for authentication
            - password: Password for authentication
            - ssl_verify_cert: Whether to verify SSL certificates
            - auth_type: Authentication type ("basic", "digest", "bearer")

    Returns:
        Client instance, or None if no configuration is found.

    Example (sync)::

        from caldav import get_davclient
        client = get_davclient(url="https://caldav.example.com", username="user", password="pass")

    Example (async)::

        from caldav.async_davclient import get_davclient
        client = await get_davclient(url="https://caldav.example.com", username="user", password="pass")
    r   rB  )r=  r>  r?  r@  rA  r   N_setup	_teardown_server_nameprotocolr@   )r   rC  get_connection_paramsrQ  setupteardownserver_name)r;  r=  r>  r?  r@  rA  r   rS  rC  r_  
setup_functeardown_funcrh  rL   r@   r@   rA   rK  R  s2   2
rK  rT   )r   r   r   r   r   r   )r"  r   r   r   )
rL   r   r%  r   r&  r   r'  r`   r   r   )	NNTNNFTNF)r;  r<  r%  r   r&  r   r=  r`   r>  rD   r?  rD   r@  r`   rA  r`   r   rD   r'  r`   r   r   )TNNFTN)r;  r<  r=  r`   r>  rD   r?  rD   r@  r`   rA  r`   r   rD   r   r   ),r   
__future__r   r1  abcr   r   collections.abcr   r   typingr   r   r	   lxmlr
   r   r   r   caldav.elements.baser   
caldav.libr   caldav.lib.authr   r   caldav.lib.python_utilitiesr   caldav.lib.urlr   caldav.compatibility_hintsr   r2  rk   ICALHrB   rC   r   r   r  r$  r:  r5  rK  r@   r@   r@   rA   <module>   sZ    
$   [
O
	? 