o
    .j.                     @   s   d Z ddlZddlZddlZddlZddlmZ zddlZW n e	y+   ddlZY nw dZ
dZG dd dZG dd	 d	eZG d
d deZdS )aj  
Lightweight embedded CalDAV test servers.

Provides XandikosServer and RadicaleServer that are part of the installed
package so that pip-installed users can use get_davclient() with
PYTHON_CALDAV_USE_TEST_SERVER=1 without needing the full test infrastructure
from the source tree.

Docker and external server support lives in tests/test_servers/ (source only).
    N)Any<   g?c                   @   s   e Zd ZU dZd Zeed< dZeed< dZe	ed< d de
eef dB d	dfd
dZd	e	fddZed	e	fddZed	edB fddZed	edB fddZed	efddZed	efddZd!ddZd!ddZd	efddZd!ddZdS )"EmbeddedServera  
    Base class for lightweight embedded CalDAV test servers.

    Subclasses must implement ``start()``, ``stop()``, and ``is_accessible()``.

    Priority
    --------
    Both embedded servers default to priority **10**, which beats docker (20)
    and external / configured servers (30).  Override via ``priority: <int>``
    in the config dict or by setting ``_default_priority`` on the subclass.
    nameembeddedserver_type
   _default_priorityNconfigreturnc                 C   s>   |pi | _ | j dd| _| j d|  | _d| _d| _d S )Nhost	localhostportF)r
   getr   _default_portr   _started_was_stopped)selfr
    r   C/home/thesage/.local/lib/python3.10/site-packages/caldav/testing.py__init__1   s
   

zEmbeddedServer.__init__c                 C      dS Np  r   r   r   r   r   r   8      zEmbeddedServer._default_portc                 C   s   t | jd| jS )Npriority)intr
   r   r	   r   r   r   r   r   =   s   zEmbeddedServer.priorityc                 C   s$   | j dp| j dp| j dS )Nusernamecaldav_usernamecaldav_user)r
   r   r   r   r   r   r   A   s
   

zEmbeddedServer.usernamec                 C   s&   dD ]}|| j v r| j |   S qd S )N)passwordcaldav_passwordcaldav_pass)r
   )r   keyr   r   r   r!   I   s
   
zEmbeddedServer.passwordc                 C   s   ddl m} || jdg S )Nr   )resolve_featuresfeatures)caldav.configr%   r
   r   )r   r%   r   r   r   r&   P   s   zEmbeddedServer.featuresc                 C   s    d| j  d| j d| jpd S )Nhttp://:/ r   r   r   r   r   r   r   urlV   s    zEmbeddedServer.urlc                 C      t NNotImplementedErrorr   r   r   r   start\   r   zEmbeddedServer.startc                 C   r.   r/   r0   r   r   r   r   stop_   r   zEmbeddedServer.stopc                 C   r.   r/   r0   r   r   r   r   is_accessibleb   r   zEmbeddedServer.is_accessiblec                 C   sH   t tt }t|D ]}|  r d S tt q
t| j dt d)Nz failed to start after z seconds)	r   MAX_STARTUP_WAIT_SECONDSSTARTUP_POLL_INTERVALranger4   timesleepRuntimeErrorr   )r   attempts_r   r   r   _wait_for_startupe   s   z EmbeddedServer._wait_for_startupr/   r   N)__name__
__module____qualname____doc__r   str__annotations__r   r	   r   dictr   r   r   propertyr   r   r!   r&   r-   r2   r3   boolr4   r=   r   r   r   r   r       s*   
  

r   c                       ~   e Zd ZdZdZddeeef dB ddf fddZde	fdd	Z
edefd
dZdefddZdddZdddZ  ZS )XandikosServerz>Xandikos CalDAV server running in a background aiohttp thread.XandikosNr
   r   c                    s   |pi }| dd | dd | dd d|vr8dd	lm} |j }|d  d
|d  |d d< ||d< t | d | _d | _d | _	d | _
d | _d S )Nr   r   r   !#  r   sometestuserr&   r   compatibility_hintsr)   auto-connect.urldomain)
setdefaultcaldavrN   xandikoscopysuperr   	serverdir	xapp_loopxapp_runnerxappthreadr   r
   rN   r&   	__class__r   r   r   v   s   

zXandikosServer.__init__c                 C   r   )NrK   r   r   r   r   r   r      r   zXandikosServer._default_portc                 C      d| j  d| j d| j S Nr(   r)   r*   r,   r   r   r   r   r-         zXandikosServer.urlc                 C   sL   zt jdd| j d| j dddddd	}|jd
v W S  ty%   Y dS w )NPROPFINDr(   r)   0zapplication/xml)DepthzContent-TypesS   <?xml version="1.0"?><propfind xmlns="DAV:"><prop><resourcetype/></prop></propfind>   )headersdatatimeout)            F)requestsrequestr   r   status_code	Exceptionr   responser   r   r   r4      s   zXandikosServer.is_accessiblec              
      sj  j rd S js rd_ d S z ddlm} zddlm} W n ty/   ddlm} Y nw W n tyB } ztd|d }~ww dd l	 ddl
m t _j  |jj}|dj d |jdj ddd	 ||jdd
djdjffdd} _jjdd| d fdd}tj|dd_j    d_ d S )NTr   )XandikosApp)SingleUserFilesystemBackend)XandikosBackendzXandikos is not installed)webr*   )create_defaults)current_user_principalstrictrn   r   c                    s     | dI d H S )Nr*   )aiohttp_handler)rn   )mainappr   r   xandikos_handler   s   z.XandikosServer.start.<locals>.xandikos_handler*z/{path_info:.*}c                     sB      _ j dfdd} j|   j  d S )Nr   c                     sF     j _ j I d H   j j j} |  I d H  d S r/   )	AppRunnerrY   rX   setupTCPSiter   r   r2   )site)r   rv   r   r   	start_app   s
   z>XandikosServer.start.<locals>.run_in_thread.<locals>.start_appr>   )new_event_looprW   set_event_looprun_until_completerun_forever)r   )asyncior   rv   r   r   run_in_thread   s
   
z+XandikosServer.start.<locals>.run_in_thread)targetdaemonr>   )r   r   r4   xandikos.webrs   rt   ImportErrorru   r:   r   aiohttprv   tempfileTemporaryDirectoryrV   	__enter__r   _mark_as_principalr   create_principalRequestResponseApplicationrY   router	add_route	threadingThreadrZ   r2   r=   )r   rs   ru   ebackendr|   r   r   )r   r{   r   rv   r   r2      sB   





zXandikosServer.startc                    s   dd l } jr4 jr4d
 fdd}z||  jjdd W n ty3    jr1 j jj Y nw  jr? j jj  jrL jj	dd d  _ j
rZ j
d d d  d  _
d  _d  _d  _d _d	 _d S )Nr   r   c                      s     j  I d H   j  d S r/   )rX   cleanuprW   r3   r   r   r   r   cleanup_and_stop   s   z-XandikosServer.stop.<locals>.cleanup_and_stopr   rg      FTr>   )r   rW   rX   run_coroutine_threadsaferesultrp   call_soon_threadsafer3   rZ   joinrV   __exit__rY   r   r   )r   r   r   r   r   r   r3      s2   

zXandikosServer.stopr/   r>   r?   r@   rA   rB   r   rE   rC   r   r   r   r   rF   r-   rG   r4   r2   r3   __classcell__r   r   r\   r   rI   q   s    $
6rI   c                       rH   )RadicaleServerz6Radicale CalDAV server running in a background thread.RadicaleNr
   r   c                    s   |pi }| dd | dd | dd | dd d	|vr>d
dlm} |j }|d  d|d  |d d< ||d	< t | d | _d | _d | _	d | _
d S )Nr   r   r   r   r   user1r!   r+   r&   r   rM   r)   rO   rP   )rQ   rR   rN   radicalerT   rU   r   rV   shutdown_socketshutdown_socket_outrZ   r[   r\   r   r   r      s   

zRadicaleServer.__init__c                 C   r   r   r   r   r   r   r   r     r   zRadicaleServer._default_portc                 C   r^   r_   r,   r   r   r   r   r-     r`   zRadicaleServer.urlc                 C   sH   zt jd| j d| j d| j dd}|jdv W S  ty#   Y dS w )Nr(   r)   r*   rd   r   )rh   rj   rk   rl   F)rm   r   r   r   r   ro   rp   rq   r   r   r   r4     s   zRadicaleServer.is_accessiblec              
   C   sL  | j rd S | js|  rd| _ d S zdd l}dd l}dd l}W n ty0 } ztd|d }~ww t	 | _
| j
  |jd}|d| j
jiddid t \| _| _tj|jj|| jfdd	| _| j  |   d
| j d| j d| j d}ztjd|dd}|j dvrtjd|!ddd W n	 t"y   Y nw d| _ d S )NTr   zRadicale is not installedr+   filesystem_foldertypenone)storageauth)r   argsr   r(   r)   r*   MKCOLr   r   )rh         i  )#r   r   r4   r   radicale.configradicale.serverr   r:   r   r   rV   r   r
   loadupdater   socket
socketpairr   r   r   r   serverserverZ   r2   r=   r   r   r   rm   rn   ro   rstriprp   )r   r   r   configurationuser_urlrr   r   r   r2   !  sN   






zRadicaleServer.startc                 C   sb   | j r| j   d | _ d | _| jr| jjdd d | _| jr)| jd d d  d | _d| _d| _d S )Nr   r   FT)	r   closer   rZ   r   rV   r   r   r   r   r   r   r   r3   N  s   

zRadicaleServer.stopr/   r>   r   r   r   r\   r   r      s    $

-r   )rB   r   r   r   r8   typingr   niquestsrm   r   r5   r6   r   rI   r   r   r   r   r   <module>   s"    Q 