Ë
    "ïàjsñ  ã                   ó  — d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ d	Z ej2                  e«      Zg d
¢ZddgZ G d„ de«      Z G d„ de«      Z G d„ de«      Z  G d„ de«      Z!y)a=	  
Abstract base class for DAV resource providers.

This module serves these purposes:

  1. Documentation of the DAVProvider interface
  2. Common base class for all DAV providers
  3. Default implementation for most functionality that a resource provider must
     deliver.

If no default implementation can be provided, then all write actions generate
FORBIDDEN errors. Read requests generate NOT_IMPLEMENTED errors.


**_DAVResource, DAVCollection, DAVNonCollection**

Represents an existing (i.e. mapped) WebDAV resource or collection.

A _DAVResource object is created by a call to the DAVProvider.

The resource may then be used to query different attributes like ``res.name``,
``res.is_collection``, ``res.get_content_length()``, and ``res.support_etag()``.

It also implements operations, that require an *existing* resource, like:
``get_preferred_path()``, ``create_collection()``, or ``get_property_value()``.

Usage::

    res = provider.get_resource_inst(path, environ)
    if res is not None:
        print(res.getName())



**DAVProvider**

A DAV provider represents a shared WebDAV system.

There is only one provider instance per share, which is created during
server start-up. After that, the dispatcher (``request_resolver.RequestResolver``)
parses the request URL and adds it to the WSGI environment, so it
can be accessed like this::

    provider = environ["wsgidav.provider"]

The main purpose of the provider is to create _DAVResource objects for URLs::

    res = provider.get_resource_inst(path, environ)


**Supporting Objects**
The DAVProvider takes two supporting objects:

propertyManager
   An object that provides storage for dead properties assigned for webDAV resources.

   PropertyManagers must provide the methods as described in
   ``wsgidav.interfaces.propertymanagerinterface``

   See prop_man.property_manager.PropertyManager for a sample implementation
   using shelve.

lockManager
   An object that implements locking on webDAV resources.
   It contains an instance of ``LockStorageDict``

lockStorage
   An object that provides storage for locks made on webDAV resources.

   LockStorages must provide the methods as described in
   ``wsgidav.interfaces.lockmanagerinterface``

   See lock_storage for a sample implementation using shelve.

See :doc:`reference_guide` for more information about the WsgiDAV architecture.
é    N)ÚABCÚabstractmethod)ÚOptional)ÚquoteÚunquote)ÚutilÚ	xml_tools)ÚHTTP_FORBIDDENÚHTTP_NOT_FOUNDÚDAVErrorÚ#PRECONDITION_CODE_ProtectedPropertyÚas_DAVError)ÚetreeÚreStructuredText)ú{DAV:}creationdateú{DAV:}displaynameú{DAV:}getcontenttypeú{DAV:}resourcetypeú{DAV:}getlastmodifiedú{DAV:}getcontentlengthú{DAV:}getetagz{DAV:}getcontentlanguageú{DAV:}lockdiscoveryú{DAV:}supportedlockc                   óª  — e Zd ZdZdededefd„Zd„ Ze	de
e   fd„«       Zde
e   fd	„Zde
e   fd
„Zd„ Zdefd„Zd„ Zd„ Zde
e   fd„Zde
e   fd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d„ Z!d„ Z"dddd dd!œd"„Z#d#„ Z$d$d%œd&„Z%d'„ Z&dd(œd)„Z'd*„ Z(d+„ Z)d,„ Z*d-„ Z+d.„ Z,d/„ Z-d0„ Z.d$d1œd2„Z/d3„ Z0d4„ Z1d5„ Z2d6„ Z3d7„ Z4d8„ Z5d9„ Z6d:„ Z7d;„ Z8d<„ Z9d=„ Z:y$)>Ú_DAVResourceaA  Represents a single existing DAV resource instance.

    A resource may be a collection (aka 'folder') or a non-collection (aka
    'file').
    _DAVResource is the common base class for the specialized classes::

        _DAVResource
          +- DAVCollection
          \- DAVNonCollection

    Instances of this class are created through the DAVProvider::

        res = provider.get_resource_inst(path, environ)
        if res and res.is_collection():
            print(res.get_display_name())

    In the example above, res will be ``None``, if the path cannot be mapped to
    an existing resource.
    The following attributes and methods are considered 'cheap'::

        res.path
        res.provider
        res.name
        res.is_collection
        res.environ

    Querying other attributes is considered 'expensive' and may be delayed until
    the first access.

        get_content_length()
        get_content_type()
        get_creation_date()
        get_display_name()
        get_etag()
        get_used_bytes()
        get_available_bytes()
        get_last_modified()
        support_ranges()

        support_etag()
        support_modified()
        support_content_length()

    These functions return ``None``, if the property is not available, or
    not supported.

    See also DAVProvider.get_resource_inst().
    ÚpathÚis_collectionÚenvironc                 óè   — t        j                  |«      sJ ‚|dk(  s|j                  d«      sJ ‚|d   | _        || _        || _        || _        t        j                  | j                  «      | _        y )NÚ ú/zwsgidav.provider)	r   Úis_strÚ
startswithÚproviderr   r   r   Úget_uri_nameÚname)Úselfr   r   r   s       úC/srv/dav/.venv/lib/python3.12/site-packages/wsgidav/dav_provider.pyÚ__init__z_DAVResource.__init__­   se   € Ü�{‰{˜4Ô Ð Ð Ø�rŠz˜TŸ_™_¨SÔ1Ð1Ð1Ø%,Ð-?Ñ%@ˆŒØˆŒ	Ø#0ˆÔØ$ˆŒÜ×*Ñ*¨4¯9©9Ó5ˆ�	ó    c                 óN   — | j                   j                  › d| j                  ›d�S )Nú(ú))Ú	__class__Ú__name__r   ©r'   s    r(   Ú__repr__z_DAVResource.__repr__¶   s$   € Ø—.‘.×)Ñ)Ð*¨!¨D¯I©I¨=¸Ð:Ð:r*   Úreturnc                 ó(   — | j                   ryt        ‚)a9  Contains the Content-Length header returned by a GET without accept
        headers.

        The getcontentlength property MUST be defined on any DAV compliant
        resource that returns the Content-Length header in response to a GET.

        This method MUST be implemented by non-collections only.
        N©r   ÚNotImplementedErrorr0   s    r(   Úget_content_lengthz_DAVResource.get_content_lengthÂ   ó   € ð ×ÒØÜ!Ð!r*   c                 ó(   — | j                   ryt        ‚)a�  Contains the Content-Type header returned by a GET without accept
        headers.

        This getcontenttype property MUST be defined on any DAV compliant
        resource that returns the Content-Type header in response to a GET.
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getcontenttype

        This method MUST be implemented by non-collections only.
        Nr4   r0   s    r(   Úget_content_typez_DAVResource.get_content_typeÐ   r7   r*   c                  ó   — y)af  Records the time and date the resource was created.

        The creationdate property should be defined on all DAV compliant
        resources. If present, it contains a timestamp of the moment when the
        resource was created (i.e., the moment it had non-null state).

        This method SHOULD be implemented, especially by non-collections.
        N© r0   s    r(   Úget_creation_datez_DAVResource.get_creation_dateÞ   s   € ð r*   c                 ó    — | j                   sJ ‚y)a  Return a list of dictionaries with information for directory
        rendering.

        This default implementation return None, so the dir browser will
        traverse all members.

        This method COULD be implemented for collection resources.
        N)r   r0   s    r(   Úget_directory_infoz_DAVResource.get_directory_infoé   s   € ð ×!Ò!Ð!Ð!Ør*   c                 ó   — | j                   S )aŒ  Provides a name for the resource that is suitable for presentation to
        a user.

        The displayname property should be defined on all DAV compliant
        resources. If present, the property contains a description of the
        resource that is suitable for presentation to a user.

        This default implementation returns `name`, which is the last path
        segment.
        )r&   r0   s    r(   Úget_display_namez_DAVResource.get_display_nameõ   s   € ð �y‰yÐr*   c                 ó   — | j                   rddiS t        j                  | j                  v rO| j                  j	                  t        j                  «      d   j                  «       }t        |«      dk  rd|› d�iS ddiS )zÿReturn additional info dictionary for displaying (optional).

        This information is not part of the DAV specification, but meant for use
        by the dir browser middleware.

        This default implementation returns ``{'type': '...'}``
        ÚtypeÚ	Directoryéÿÿÿÿé   z-FileÚFile)r   ÚosÚextsepr&   ÚsplitÚupperÚlen)r'   Úexts     r(   Úget_display_infoz_DAVResource.get_display_info  ss   € ð ×ÒØ˜KÐ(Ð(Ü�Y‰Y˜$Ÿ)™)Ñ#Ø—)‘)—/‘/¤"§)¡)Ó,¨RÑ0×6Ñ6Ó8ˆCÜ�3‹x˜!Š|Ø 3 % u Ð.Ð.Ø˜ÐÐr*   c                  ó   — y)zš
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getetag

        This method SHOULD be implemented, especially by non-collections.
        Nr;   r0   s    r(   Úget_etagz_DAVResource.get_etag  ó   € ð r*   c                  ó   — y)z»Return used bytes of the DAV collection.
        See http://www.webdav.org/specs/rfc4331.html#quota-used-bytes

        This method COULD be implemented for collection resources.
        Nr;   r0   s    r(   Úget_used_bytesz_DAVResource.get_used_bytes  rP   r*   c                  ó   — y)zÅReturn available bytes of the DAV collection.
        See http://www.webdav.org/specs/rfc4331.html#quota-available-bytes

        This method COULD be implemented for collection resources.
        Nr;   r0   s    r(   Úget_available_bytesz _DAVResource.get_available_bytes"  rP   r*   c                  ó   — y)a¢  Contains the Last-Modified header returned by a GET method without
        accept headers.

        Return None, if this live property is not supported.

        Note that the last-modified date on a resource may reflect changes in
        any part of the state of the resource, not necessarily just a change to
        the response to the GET method. For example, a change in a property may
        cause the last-modified date to change. The getlastmodified property
        MUST be defined on any DAV compliant resource that returns the
        Last-Modified header in response to a GET.

        This method SHOULD be implemented, especially by non-collections.
        Nr;   r0   s    r(   Úget_last_modifiedz_DAVResource.get_last_modified*  s   € ð r*   c                  ó   — y©NFr;   r0   s    r(   Úis_linkz_DAVResource.is_link;  ó   € Ør*   c                ó   — t         ‚)z@Set last modified time for destPath to timeStamp on epoch-format©r5   )r'   Ú	dest_pathÚ
time_stampÚdry_runs       r(   Úset_last_modifiedz_DAVResource.set_last_modified>  ó   € ä!Ð!r*   c                 ó   — t         ‚)zŒReturn True, if this non-resource supports Range on GET requests.

        This method MUST be implemented by non-collections only.
        r\   r0   s    r(   Úsupport_rangesz_DAVResource.support_rangesB  ó
   € ô
 "Ð!r*   c                 ó&   — | j                  «       duS )z�Return True, if this resource supports Content-Length.

        This default implementation checks `self.get_content_length() is None`.
        N)r6   r0   s    r(   Úsupport_content_lengthz#_DAVResource.support_content_lengthI  s   € ð
 ×&Ñ&Ó(°Ð4Ð4r*   c                 ó   — t         ‚)z-Return True, if this resource supports ETags.r\   r0   s    r(   Úsupport_etagz_DAVResource.support_etagP  ra   r*   c                 ó&   — | j                  «       duS )z”Return True, if this resource supports last modified dates.

        This default implementation checks `self.get_last_modified() is None`.
        N)rV   r0   s    r(   Úsupport_modifiedz_DAVResource.support_modifiedV  s   € ð
 ×%Ñ%Ó'¨tÐ3Ð3r*   c                 ó¤   — | j                   dv ry| j                  r*| j                   j                  d«      s| j                   dz   S | j                   S )a°  Return preferred mapping for a resource mapping.

        Different URLs may map to the same resource, e.g.:
            '/a/b' == '/A/b' == '/a/b/'
        get_preferred_path() returns the same value for all these variants, e.g.:
            '/a/b/'   (assuming resource names considered case insensitive)

        @param path: a UTF-8 encoded, unquoted byte string.
        @return: a UTF-8 encoded, unquoted byte string.
        ©r    r!   r!   )r   r   Úendswithr0   s    r(   Úget_preferred_pathz_DAVResource.get_preferred_path]  sG   € ð �9‰9˜	Ñ!Øà×Ò d§i¡i×&8Ñ&8¸Ô&=Ø—9‘9˜s‘?Ð"ð �y‰yÐr*   c                 ób   — t        | j                  j                  | j                  «       z   «      S )aƒ  Return the quoted, absolute, unique URL of a resource, relative to appRoot.

        Byte string, UTF-8 encoded, quoted.
        Starts with a '/'. Collections also have a trailing '/'.

        This is basically the same as get_preferred_path, but deals with
        'virtual locations' as well.

        e.g. '/a/b' == '/A/b' == '/bykey/123' == '/byguid/abc532'

        get_ref_url() returns the same value for all these URLs, so it can be
        used as a key for locking and persistence storage.

        DAV providers that allow virtual-mappings must override this method.

        See also comments in DEVELOPERS.txt glossary.
        )r   r$   Ú
share_pathrn   r0   s    r(   Úget_ref_urlz_DAVResource.get_ref_urlt  s'   € ô$ �T—]‘]×-Ñ-°×0GÑ0GÓ0IÑIÓJÐJr*   c                 ó˜   — d}t        | j                  j                  | j                  j                  z   | j	                  «       z   |¬«      S )a*  Convert path to a URL that can be passed to XML responses.

        Byte string, UTF-8 encoded, quoted.

        See http://www.webdav.org/specs/rfc4918.html#rfc.section.8.3
        We are using the path-absolute option. i.e. starting with '/'.
        URI ; See section 3.2.1 of [RFC2068]
        z/!*'(),$-_|.)Úsafe)r   r$   Ú
mount_pathrp   rn   )r'   rs   s     r(   Úget_hrefz_DAVResource.get_href–  sK   € ð (ˆÜØ�M‰M×$Ñ$Ø�m‰m×&Ñ&ñ'à×%Ñ%Ó'ñ(ð ô	
ð 	
r*   c                 ó   — t         ‚©zñReturn child resource with a given name (None, if not found).

        This method COULD be overridden by a derived class, for performance
        reasons.
        This default implementation calls self.provider.get_resource_inst().
        r\   ©r'   r&   s     r(   Ú
get_memberz_DAVResource.get_member³  ó
   € ô "Ð!r*   c                 ó¤   — | j                   st        ‚g }| j                  «       D ](  }| j                  |«      }|€J ‚|j	                  |«       Œ* |S )zÿReturn a list of direct members (_DAVResource or derived objects).

        This default implementation calls self.get_member_names() and
        self.get_member() for each of them.
        A provider COULD overwrite this for performance reasons.
        )r   r5   Úget_member_namesry   Úappend)r'   Ú
memberListr&   Úmembers       r(   Úget_member_listz_DAVResource.get_member_list¼  s`   € ð ×!Ò!Ü%Ð%Øˆ
Ø×)Ñ)Ó+ò 	&ˆDØ—_‘_ TÓ*ˆFØÐ%Ð%Ð%Ø×Ñ˜fÕ%ð	&ð Ðr*   c                 ó   — t         ‚)z™Return list of (direct) collection member names (UTF-8 byte strings).

        Every provider MUST provide this method for collection resources.
        r\   r0   s    r(   r|   z_DAVResource.get_member_namesÌ  rd   r*   TFÚinfinity©ÚcollectionsÚ	resourcesÚdepth_firstÚdepthÚadd_selfc          
      óä  — |dv sJ ‚g }|r|s|j                  | «       |dk7  r¸| j                  r¬| j                  «       D ]™  }|s| j                  «        |xr |j                  xs |xr |j                   }|r|s|j                  |«       |j                  r*|dk(  r%|j                  |j	                  ||||d¬«      «       |sŒ†|sŒ‰|j                  |«       Œ› |r|r|j                  | «       |S )ac  Return a list _DAVResource objects of a collection (children,
        grand-children, ...).

        This default implementation calls self.get_member_list() recursively.

        This function may also be called for non-collections (with add_self=True).

        :Parameters:
            depth_first : bool
                use <False>, to list containers before content.
                (e.g. when moving / copying branches.)
                Use <True>, to list content before containers.
                (e.g. when deleting branches.)
            depth : string
                '0' | '1' | 'infinity'
        )Ú0Ú1r‚   rŠ   r‚   Frƒ   )r}   r   r€   ÚextendÚget_descendants)	r'   r„   r…   r†   r‡   rˆ   ÚresÚchildÚwants	            r(   r�   z_DAVResource.get_descendantsÓ  s  € ð2 Ð.Ñ.Ð.Ð.ØˆÙ™KØ�J‰J�tÔØ�CŠ<˜D×.Ò.Ø×-Ñ-Ó/ò &�ÙØ×(Ñ(Ô*Ø#Ò;¨×(;Ñ(;ò ØÒ9 e×&9Ñ&9Ð"9ð ñ ¡Ø—J‘J˜uÔ%Ø×&Ò&¨5°JÒ+>Ø—J‘JØ×-Ñ-Ø(3Ø&/Ø(3Ø"'Ø%*ð .ó ôò šKØ—J‘J˜uÕ%ð'&ñ( ™Ø�J‰J�tÔØˆ
r*   c                ó˜  — g }|j                  d«       | j                  «       �|j                  d«       | j                  «       �| j                  rJ ‚|j                  d«       | j	                  «       �|j                  d«       | j                  «       �|j                  d«       | j                  «       �|j                  d«       | j                  «       �|j                  d«       | j                  «       �|j                  d«       | j                  «       �|j                  d	«       | j                  j                  r%| j                  «       s|j                  t        «       | j                  j                  rO| j!                  «       }|j                  | j                  j                  j#                  || j$                  «      «       |S )
a  Return list of supported property names in Clark Notation.

        Note that 'allprop', despite its name, which remains for
        backward-compatibility, does not return every property, but only dead
        properties and the live properties defined in RFC4918.

        This default implementation returns a combination of:

        - Supported standard live properties in the {DAV:} namespace, if the
          related getter method returns not None.
        - {DAV:}lockdiscovery and {DAV:}supportedlock, if a lock manager is
          present
        - If a property manager is present, then a list of dead properties is
          appended

        A resource provider may override this method, to add a list of
        supported custom live property names.
        r   r   r   r   ú{DAV:}quota-used-bytesú{DAV:}quota-available-bytesr   r   r   )r}   r<   r6   r   r9   rR   rT   rV   r@   rO   r$   Úlock_managerÚprevent_lockingrŒ   Ú_lockPropertyNamesÚprop_managerrq   Úget_propertiesr   )r'   Ú
is_allpropÚpropNameListÚrefUrls       r(   Úget_property_namesz_DAVResource.get_property_names  s�  € ð( ˆà×ÑÐ0Ô1à×!Ñ!Ó#Ð/Ø×ÑÐ 4Ô5Ø×"Ñ"Ó$Ð0Ø×)Ò)Ð)Ð)Ø×ÑÐ 8Ô9Ø× Ñ Ó"Ð.Ø×ÑÐ 6Ô7Ø×ÑÓ Ð,Ø×ÑÐ 8Ô9Ø×#Ñ#Ó%Ð1Ø×ÑÐ =Ô>Ø×!Ñ!Ó#Ð/Ø×ÑÐ 7Ô8Ø× Ñ Ó"Ð.Ø×ÑÐ 3Ô4Ø�=‰=‹?Ð&Ø×Ñ Ô0ð �=‰=×%Ò%¨d×.BÑ.BÔ.DØ×ÑÔ 2Ô3ð �=‰=×%Ò%Ø×%Ñ%Ó'ˆFØ×ÑØ—‘×*Ñ*×9Ñ9¸&À$Ç,Á,ÓOôð Ðr*   N)Ú	name_listc                ó  — |dv sJ ‚|dv r|�J ‚| j                  |dk(  ¬«      }n|€J ‚g }|dk(  }|D ]=  }	 |r|j                  |df«       n$| j                  |«      }|j                  ||f«       Œ? |S # t        $ r}|j                  ||f«       Y d}~Œcd}~wt        $ rc}|j                  |t        |«      f«       | j                  j                  dk\  r$t        j                  dt        j                  «       Y d}~ŒÍd}~ww xY w)	a  Return properties as list of 2-tuples (name, value).

        If mode is 'name', then None is returned for the value.

        name
            the property name in Clark notation.
        value
            may have different types, depending on the status:
            - string or unicode: for standard property values.
            - etree.Element: for complex values.
            - DAVError in case of errors.
            - None: if mode == 'name'.

        @param mode: "allprop", "name", or "named"
        @param name_list: list of property names in Clark Notation (required for mode 'named')

        This default implementation basically calls self.get_property_names() to
        get the list of names, then call self.get_property_value on each of them.
        )Úallpropr&   Únamed)rŸ   r&   NrŸ   )r™   r&   é   é
   )rœ   r}   Úget_property_valuer   Ú	Exceptionr   r$   ÚverboseÚ	tracebackÚ	print_excÚsysÚstdout)r'   Úmoder�   ÚpropListÚ	namesOnlyr&   ÚvalueÚes           r(   r˜   z_DAVResource.get_propertiesB  s  € ð( Ð3Ñ3Ð3Ð3àÐ&Ñ&ð Ð$Ð$Ð$Ø×/Ñ/¸4À9Ñ;LÐ/ÓM‰IàÐ(Ð(Ð(àˆØ˜F‘Nˆ	Øò 	8ˆDð8ÙØ—O‘O T¨4 LÕ1à ×3Ñ3°DÓ9�EØ—O‘O T¨5 MÔ2øð	8ð ˆøô ò +Ø—‘  q 	×*Ñ*ûÜò 8Ø—‘ ¤{°1£~Ð 6Ô7Ø—=‘=×(Ñ(¨AÒ-Ü×'Ñ'¨¬C¯J©JÔ7ÿøð8ús$   ¶:A4Á4	DÁ=BÂDÂ!AC?Ã?Dc           	      ó~
  — | j                  «       }| j                  j                  }|�r)|dk(  �r#|j                  |«      }t	        j
                  |«      }|D �]õ  }t	        j                  |d«      }t	        j                  |d«      }t	        j                  |dj                  d|d   «      «       t	        j                  |d«      }	t	        j                  |	dj                  d|d   «      «       |d	   t	        j                  |d
«      _        |d   r)t        j                  |d   «      }
|j                  |
«       |d   }|dk  rd}n1|d   }dt        t        |t        j                  «       z
  «      «      z   }|t	        j                  |d«      _        t	        j                  |d«      }|d   t	        j                  |d«      _        | j                  j                  |d   «      }| j                  j!                  || j"                  «      }|j%                  «       }t	        j                  |d«      }|t	        j                  |d«      _        �Œø |S |rø|dk(  rót	        j
                  |«      }t	        j                  |d«      }t	        j                  |d«      }	t	        j                  |	d«       t	        j                  |d«      }t	        j                  |d«       t	        j                  |d«      }t	        j                  |d«      }	t	        j                  |	d«       t	        j                  |d«      }t	        j                  |d«       |S |j'                  d«      �r…|dk(  r3| j)                  «       �#t+        j,                  | j)                  «       «      S |dk(  r | j/                  «       �| j/                  «       S |dk(  r:| j0                  r-t	        j
                  |«      }t	        j                  |d«       |S y |d!k(  r| j3                  «       S |d"k(  r| j5                  «       S |d#k(  r3| j7                  «       �#t+        j8                  | j7                  «       «      S |d$k(  r)| j;                  «       �t        | j;                  «       «      S |d%k(  r | j=                  «       �| j=                  «       S |d&k(  r | j?                  «       �| j?                  «       S tA        tB        «      ‚| j                  jD                  }|r4|jG                  ||| j"                  «      }|�t        j                  |«      S tA        tB        «      ‚)'aô  Return the value of a property.

        name:
            the property name in Clark notation.
        return value:
            may have different types, depending on the status:

            - string or unicode: for standard property values.
            - lxml.etree.Element: for complex values.

            If the property is not available, a DAVError is raised.

        This default implementation handles ``{DAV:}lockdiscovery`` and
        ``{DAV:}supportedlock`` using the associated lock manager.

        All other *live* properties (i.e. name starts with ``{DAV:}``) are
        delegated to the self.xxx() getters.

        Finally, other properties are considered *dead*, and are handled  by
        the associated property manager.
        r   z{DAV:}activelockz{DAV:}locktypez{}{}ú{DAV:}rB   z{DAV:}lockscopeÚscoper‡   z{DAV:}depthÚownerÚtimeoutr   ÚInfiniteÚexpirezSecond-z{DAV:}timeoutz{DAV:}locktokenÚtokenz
{DAV:}hrefÚrootz{DAV:}lockrootr   z{DAV:}lockentryz{DAV:}exclusivez{DAV:}writez{DAV:}sharedr   r   r   z{DAV:}collectionr    r’   r“   r   r   r   r   )$rq   r$   r”   Úget_url_lock_listr   ÚElementÚ
SubElementÚformatÚtextr	   Ústring_to_xmlr}   ÚstrÚintÚtimeÚref_url_to_pathÚget_resource_instr   ru   r#   r<   r   Úget_rfc3339_timer9   r   rR   rT   rV   Úget_rfc1123_timer6   rO   r@   r   r   r—   Úget_property)r'   r&   r›   ÚlmÚactivelocklistÚlockdiscoveryELÚlockÚactivelockELÚ
locktypeELÚlockscopeELÚownerELr³   rµ   ÚlocktokenELÚlockPathÚlockResÚlockHrefÚ
lockrootELÚsupportedlockELÚlockentryELÚresourcetypeELÚpmr­   s                          r(   r£   z_DAVResource.get_property_valuer  s°  € ð, ×!Ñ!Ó#ˆð �]‰]×'Ñ'ˆÚ�$Ð/Ó/ð  ×1Ñ1°&Ó9ˆNÜ#Ÿm™m¨DÓ1ˆOØ&ó (K�Ü$×/Ñ/°ÐASÓT�ä"×-Ñ-¨lÐ<LÓM�
ä× Ñ  ¨V¯]©]¸8ÀTÈ&Á\Ó-RÔSä#×.Ñ.¨|Ð=NÓO�ä× Ñ  ¨f¯m©m¸HÀdÈ7ÁmÓ.TÔUàEIÈ'Á]”× Ñ  ¨}Ó=ÔBØ˜’=ô (×5Ñ5°d¸7±mÓD�GØ ×'Ñ'¨Ô0à˜y™/�Ø˜Q’;Ø(‘Gð " (™^�FØ'¬#¬c°&¼4¿9¹9»;Ñ2FÓ.GÓ*HÑH�GØGN”× Ñ  ¨Ó?ÔDä#×.Ñ.¨|Ð=NÓO�ØCGÈÁ=”× Ñ  ¨lÓ;Ô@ð  Ÿ=™=×8Ñ8¸¸f¹ÓF�ØŸ-™-×9Ñ9¸(ÀDÇLÁLÓQ�à"×+Ñ+Ó-�ä"×-Ñ-¨lÐ<LÓM�
ØBJ”× Ñ  ¨\Ó:Ö?ðQ(KðT #Ð"á�DÐ1Ò1ô $Ÿm™m¨DÓ1ˆOä×*Ñ*¨?Ð<MÓNˆKÜ×*Ñ*¨;Ð8IÓJˆKÜ×Ñ˜[Ð*;Ô<Ü×)Ñ)¨+Ð7GÓHˆJÜ×Ñ˜Z¨Ô7ä×*Ñ*¨?Ð<MÓNˆKÜ×*Ñ*¨;Ð8IÓJˆKÜ×Ñ˜[¨.Ô9Ü×)Ñ)¨+Ð7GÓHˆJÜ×Ñ˜Z¨Ô7à"Ð"à�_‰_˜XÕ&àÐ+Ò+°×0FÑ0FÓ0HÐ0Tä×,Ñ,¨T×-CÑ-CÓ-EÓFÐFØÐ/Ò/°D×4IÑ4IÓ4KÐ4WØ×,Ñ,Ó.Ð.ØÐ-Ò-Ø×%Ò%Ü%*§]¡]°4Ó%8�NÜ×$Ñ$ ^Ð5GÔHØ)Ð)ØØÐ1Ò1Ø×*Ñ*Ó,Ð,ØÐ6Ò6Ø×/Ñ/Ó1Ð1àÐ/Ò/°D×4JÑ4JÓ4LÐ4Xô ×,Ñ,¨T×-CÑ-CÓ-EÓFÐFàÐ0Ò0Ø×+Ñ+Ó-Ð9ô ˜4×2Ñ2Ó4Ó5Ð5Ø˜Ò(¨T¯]©]«_Ð-HØ—}‘}“Ð&ØÐ,Ò,°×1FÑ1FÓ1HÐ1TØ×,Ñ,Ó.Ð.ô œ>Ó*Ð*ð �]‰]×'Ñ'ˆÙØ—O‘O F¨D°$·,±,Ó?ˆEØÐ Ü ×.Ñ.¨uÓ5Ð5ô ”~Ó&Ð&r*   ©r_   c                óJ  — |�t        j                  |«      sJ ‚|t        v rt        t        t
        ¬«      ‚| j                  d   }|j                  dg «      }|j                  d«      rH|t        v r@||v r<|dv r)	 | j                  | j                  |j                  |¬«      S t        t        «      ‚|j                  d	«      r‡| j                  j                  d
d«      }t!        j"                  |dd¬«      }|j                  dd«      }|r?d|vr;d|v r(| j                  | j                  |j                  |¬«      S d|v ryd|v ryd|v ry| j$                  j&                  }	|	ru|j                  d«      sd| j)                  «       }
|€|	j+                  |
||| j                  «      S t-        j.                  |«      }|	j1                  |
|||| j                  «      S t        t        «      ‚# t        $ r4 t        j                  d| j                  › d�«       Y t        t        «      ‚w xY w)aÒ  Set a property value or remove a property.

        value == None means 'remove property'.
        Raise HTTP_FORBIDDEN if property is read-only, or not supported.

        When dry_run is True, this function should raise errors, as in a real
        run, but MUST NOT change any data.

        This default implementation

        - raises HTTP_FORBIDDEN, if trying to modify a locking property
        - raises HTTP_FORBIDDEN, if trying to modify an immutable {DAV:}
          property
        - handles Windows' Win32LastModifiedTime to set the getlastmodified
          property, if enabled
        - stores everything else as dead property, if a property manager is
          present.
        - raises HTTP_FORBIDDEN, else

        Removing a non-existing prop is NOT an error.

        Note: RFC 4918 states that {DAV:}displayname 'SHOULD NOT be protected'

        A resource provider may override this method, to update supported custom
        live properties.
        )Úerr_conditionúwsgidav.configÚmutable_live_propsr°   )r   z{DAV:}last_modifiedr×   z/Provider does not support set_last_modified on ú.z{urn:schemas-microsoft-com:}ÚHTTP_USER_AGENTÚNoneÚhotfixesT)Úas_dictÚemulate_win32_lastmodFzMiniRedir/6.1ÚWin32LastModifiedTimeÚWin32FileAttributesÚWin32CreationTimeÚWin32LastAccessTime)r	   Úis_etree_elementr–   r   r
   r   r   Úgetr#   Ú_standardLivePropNamesr`   r   r¼   r¤   Ú_loggerÚwarningr   Úget_dict_valuer$   r—   rq   Úremove_propertyr   ÚtostringÚwrite_property)r'   r&   r­   r_   ÚconfigÚmutableLivePropsÚagentrß   Ú	win32_emurÖ   r›   s              r(   Úset_property_valuez_DAVResource.set_property_valueþ  s%  € ð6 ˆ}¤	× :Ñ :¸5Ô AÐAÐAàÔ%Ñ%äÜÔ.Qôð ð
 —‘Ð.Ñ/ˆà!Ÿ:™:Ð&:¸BÓ?Ðð �O‰O˜HÔ%ØÔ.Ñ.ØÐ(Ñ(ð ÐGÑGðØ×1Ñ1ØŸ	™	 5§:¡:°wð 2ó ð ô œ>Ó*Ð*ð
 �?‰?Ð9Ô:Ø—L‘L×$Ñ$Ð%6¸Ó?ˆEÜ×*Ñ*¨6°:ÀtÔLˆHØ Ÿ™Ð%<¸eÓDˆIÙ˜_°EÑ9Ø*¨dÑ2Ø×1Ñ1ØŸ	™	 5§:¡:°wð 2ó ð ð +¨dÑ2ØØ(¨DÑ0ØØ*¨dÑ2Øð �]‰]×'Ñ'ˆÙ�d—o‘o hÔ/Ø×%Ñ%Ó'ˆFØˆ}Ø×)Ñ)¨&°$¸ÀÇÁÓNÐNäŸ™ uÓ-�Ø×(Ñ(¨°°u¸gÀtÇ|Á|ÓTÐTä”~Ó&Ð&øôK !ò Ü—O‘OØIÈ$Ï)É)ÈÐTUÐVõô
 œ>Ó*Ð*ðús   Á:'G% Ç%,H"È!H"c                ó®   — | j                   j                  r?| j                   j                  j                  | j                  «       | j                  «       yy)z&Remove all associated dead properties.N)r$   r—   Úremove_propertiesrq   r   ©r'   Ú	recursives     r(   Úremove_all_propertiesz"_DAVResource.remove_all_properties\  s>   € à�=‰=×%Ò%Ø�M‰M×&Ñ&×8Ñ8Ø× Ñ Ó" D§L¡Lõð &r*   c                  ó   — y)zôReturn True, to prevent locking.

        This default implementation returns ``False``, so standard processing
        takes place: locking (and refreshing of locks) is implemented using
        the lock manager, if one is configured.
        Fr;   r0   s    r(   r•   z_DAVResource.prevent_lockinge  s   € ð r*   c                 ó–   — | j                   j                  €y| j                   j                  j                  | j                  «       «      S )zReturn True, if URI is locked.F)r$   r”   Úis_url_lockedrq   r0   s    r(   Ú	is_lockedz_DAVResource.is_lockedn  s9   € à�=‰=×%Ñ%Ð-ØØ�}‰}×)Ñ)×7Ñ7¸×8HÑ8HÓ8JÓKÐKr*   c                óœ   — | j                   j                  r6| j                   j                  j                  | j                  «       |¬«       y y )N)r÷   )r$   r”   Úremove_all_locks_from_urlrq   rö   s     r(   Úremove_all_locksz_DAVResource.remove_all_lockst  s@   € Ø�=‰=×%Ò%Ø�M‰M×&Ñ&×@Ñ@Ø× Ñ Ó"¨ið Aõ ð &r*   c                 ó<   — | j                   sJ ‚t        t        «      ‚©aô  Create and return an empty (length-0) resource as member of self.

        Called for LOCK requests on unmapped URLs.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        Returns a DAVResuource.

        This method MUST be implemented by all providers that support write
        access.
        This default implementation simply raises HTTP_FORBIDDEN.
        ©r   r   r
   rx   s     r(   Úcreate_empty_resourcez"_DAVResource.create_empty_resource|  s   € ð" ×!Ò!Ð!Ð!Ü”~Ó&Ð&r*   c                 ó<   — | j                   sJ ‚t        t        «      ‚©a�  Create a new collection as member of self.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        This method MUST be implemented by all providers that support write
        access.
        This default implementation raises HTTP_FORBIDDEN.
        r  rx   s     r(   Úcreate_collectionz_DAVResource.create_collection�  ó   € ð ×!Ò!Ð!Ð!Ü”~Ó&Ð&r*   c                 ó*   — | j                   rJ ‚t        ‚)a
  Open content as a stream for reading.

        Returns a file-like object / stream containing the contents of the
        resource specified.
        The calling application will close() the stream.

        This method MUST be implemented by all providers.
        r4   r0   s    r(   Úget_contentz_DAVResource.get_content   s   € ð ×%Ò%Ð%Ð%Ü!Ð!r*   ©Úcontent_typec                ó<   — | j                   rJ ‚t        t        «      ‚©z‹Open content as a stream for writing.

        This method MUST be implemented by all providers that support write
        access.
        r  ©r'   r  s     r(   Úbegin_writez_DAVResource.begin_write¬  s   € ð ×%Ò%Ð%Ð%Ü”~Ó&Ð&r*   c                 ó   — y©zhCalled when PUT has finished writing.

        This is only a notification that MAY be handled.
        Nr;   ©r'   Úwith_errorss     r(   Ú	end_writez_DAVResource.end_writeµ  s   € ð
 r*   c                  ó   — y)aê  Handle a DELETE request natively.

        This method is called by the DELETE handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_delete() did not do anything. WsgiDAV will process the request
            by calling delete() for every resource, bottom-up.
        True:
            handle_delete() has successfully performed the DELETE request.
            HTTP_NO_CONTENT will be reported to the DAV client.
        List of errors:
            handle_delete() tried to perform the delete request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_delete() refuses to perform the delete request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example deleting '/by_tag/cool/myres' may simply remove the 'cool'
        tag from 'my_res'.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.
        Fr;   r0   s    r(   Úhandle_deletez_DAVResource.handle_delete¼  ó   € ðF r*   c                 ó*   — | j                   sJ ‚t        ‚)zÈReturn True, if delete() may be called on non-empty collections
        (see comments there).

        This method MUST be implemented for collections (not called on
        non-collections).
        r4   r0   s    r(   Úsupport_recursive_deletez%_DAVResource.support_recursive_deleteá  s   € ð ×!Ò!Ð!Ð!Ü!Ð!r*   c                 ó   — t         ‚)a”  Remove this resource (recursive).

        Preconditions (ensured by caller):

          - there are no conflicting locks or If-headers
          - if support_recursive_delete() is False, and this is a collection,
            all members have already been deleted.

        When support_recursive_delete is True, this method must be prepared to
        handle recursive deletes. This implies that child errors must be
        reported as tuple list [ (<ref-url>, <DAVError>), ... ].
        See http://www.webdav.org/specs/rfc4918.html#delete-collections

        This function

          - removes this resource
          - if this is a non-empty collection, also removes all members.
            Note that this may only occur, if support_recursive_delete is True.
          - For recursive deletes, return a list of error tuples for all failed
            resource paths.
          - removes associated direct locks
          - removes associated dead properties
          - raises HTTP_FORBIDDEN for read-only resources
          - raises HTTP_INTERNAL_ERROR on error

        This method MUST be implemented by all providers that support write
        access.
        r\   r0   s    r(   Údeletez_DAVResource.deleteë  s
   € ô: "Ð!r*   c                 ó   — y)añ  Handle a COPY request natively.

        This method is called by the COPY handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_copy() did not do anything. WsgiDAV will process the request
            by calling copy_move_single() for every resource, bottom-up.
        True:
            handle_copy() has successfully performed the COPY request.
            HTTP_NO_CONTENT/HTTP_CREATED will be reported to the DAV client.
        List of errors:
            handle_copy() tried to perform the copy request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_copy() refuses to perform the copy request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example copying '/by_tag/cool/myres' to '/by_tag/hot/myres' may
        simply add a 'hot' tag.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.
        Fr;   )r'   r]   Údepth_infinitys      r(   Úhandle_copyz_DAVResource.handle_copy
  r  r*   c                ó   — t         ‚)aÏ  Copy or move this resource to destPath (non-recursive).

        Preconditions (ensured by caller):

          - there must not be any conflicting locks on destination
          - overwriting is only allowed (i.e. destPath exists), when source and
            dest are of the same type ((non-)collections) and a Overwrite='T'
            was passed
          - destPath must not be a child path of this resource

        This function

          - Overwrites non-collections content, if destination exists.
          - MUST NOT copy collection members.
          - MUST NOT copy locks.
          - SHOULD copy live properties, when appropriate.
            E.g. displayname should be copied, but creationdate should be
            reset if the target did not exist before.
            See http://www.webdav.org/specs/rfc4918.html#dav.properties
          - SHOULD copy dead properties.
          - raises HTTP_FORBIDDEN for read-only providers
          - raises HTTP_INTERNAL_ERROR on error

        When is_move is True,

          - Live properties should be moved too (e.g. creationdate)
          - Non-collections must be moved, not copied
          - For collections, this function behaves like in copy-mode:
            destination collection must be created and properties are copied.
            Members are NOT created.
            The source collection MUST NOT be removed.

        This method MUST be implemented by all providers that support write
        access.
        r\   ©r'   r]   Úis_moves      r(   Úcopy_move_singlez_DAVResource.copy_move_single/  s   € ôH "Ð!r*   c                  ó   — y)a9  Handle a MOVE request natively.

        This method is called by the MOVE handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_move() did not do anything. WsgiDAV will process the request
            by calling delete() and copy_move_single() for every resource,
            bottom-up.
        True:
            handle_move() has successfully performed the MOVE request.
            HTTP_NO_CONTENT/HTTP_CREATED will be reported to the DAV client.
        List of errors:
            handle_move() tried to perform the move request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_move() refuses to perform the move request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example moving '/by_tag/cool/myres' to '/by_tag/hot/myres' may
        simply remove the 'cool' tag from 'my_res' and add a 'hot' tag instead.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.
        Fr;   ©r'   r]   s     r(   Úhandle_movez_DAVResource.handle_moveU  s   € ðH r*   c                 ó*   — | j                   sJ ‚t        ‚)úCReturn True, if move_recursive() is available (see comments there).r4   r$  s     r(   Úsupport_recursive_movez#_DAVResource.support_recursive_move{  s   € à×!Ò!Ð!Ð!Ü!Ð!r*   c                 ó    — t        t        «      ‚)a“  Move this resource and members to destPath.

        This method is only called, when support_recursive_move() returns True.

        MOVE is frequently used by clients to rename a file without changing its
        parent collection, so it's not appropriate to reset all live properties
        that are set at resource creation. For example, the DAV:creationdate
        property value SHOULD remain the same after a MOVE.

        Preconditions (ensured by caller):

          - there must not be any conflicting locks or If-header on source
          - there must not be any conflicting locks or If-header on destination
          - destPath must not exist
          - destPath must not be a member of this resource

        This method must be prepared to handle recursive moves. This implies
        that child errors must be reported as tuple list
        [ (<ref-url>, <DAVError>), ... ].
        See http://www.webdav.org/specs/rfc4918.html#move-collections

        This function

          - moves this resource and all members to destPath.
          - MUST NOT move associated locks.
            Instead, if the source (or children thereof) have locks, then
            these locks should be removed.
          - SHOULD maintain associated live properties, when applicable
            See http://www.webdav.org/specs/rfc4918.html#dav.properties
          - MUST maintain associated dead properties
          - raises HTTP_FORBIDDEN for read-only resources
          - raises HTTP_INTERNAL_ERROR on error

        An implementation may choose to apply other semantics.
        For example copying '/by_tag/cool/myres' to '/by_tag/new/myres' may
        simply add a 'new' tag to 'my_res'.

        This method is only called, when self.support_recursive_move() returns
        True. Otherwise, the request server implements MOVE using delete/copy.

        This method MAY be implemented in order to improve performance.
        ©r   r
   r$  s     r(   Úmove_recursivez_DAVResource.move_recursive€  s   € ôV ”~Ó&Ð&r*   c                 ó   — t         ‚)z½Return a _DAVResource object for the path (None, if not found).

        `path_info`: is a URL relative to this object.

        DAVCollection.resolve() provides an implementation.
        r\   ©r'   Úscript_nameÚ	path_infos      r(   Úresolvez_DAVResource.resolve­  rz   r*   c                  ó   — y)zÁPerform custom operations on the response headers.

        This gets called before the response is started.
        It enables adding additional headers or modifying the default ones.
        Nr;   )r'   r   Úresponse_headerss      r(   Úfinalize_headersz_DAVResource.finalize_headers¶  rP   r*   );r/   Ú
__module__Ú__qualname__Ú__doc__r¾   ÚboolÚdictr)   r1   r   r   r¿   r6   r9   Úfloatr<   r>   r@   rM   rO   rR   rT   rV   rY   r`   rc   rf   rh   rj   rn   rq   ru   ry   r€   r|   r�   rœ   r˜   r£   ró   rø   r•   rü   rÿ   r  r  r	  r  r  r  r  r  r  r"  r%  r(  r+  r0  r3  r;   r*   r(   r   r   {   s‰  „ ñ/ðb6˜Sð 6°ð 6Àó 6ò;ð ð" H¨S¡Mò "ó ð"ð" (¨3¡-ó "ð	 8¨E¡?ó 	ò
ð #ó ò ò ð ¨¡ó ð X¨c¡]ó òò"ò"ò"ò5ò"ò4òò.KòD
ò:"òò "ð ØØØØô4òp5ðn 15ô .ò`J'ðX :?ô \'ò|òòLòò'ò('ò 
"ð +/ô 'òò#òJ"ò"ò>#òJ$"òL$òL"ò
+'òZ"ór*   r   c                   ó�   ‡ — e Zd ZdZdedefˆ fd„Zed„ «       Zd„ Z	ed„ «       Z
ed„ «       Zed	„ «       Zd
„ Zddœd„Zd„ Zd„ Zˆ xZS )ÚDAVNonCollectionz¿
    A DAVNonCollection is a _DAVResource, that has content (like a 'file' on
    a filesystem).

    A DAVNonCollecion is able to read and write file content.

    See also _DAVResource
    r   r   c                 ó(   •— t         ‰| �  |d|«       y rX   ©Úsuperr)   ©r'   r   r   r.   s      €r(   r)   zDAVNonCollection.__init__Ì  s   ø€ Ü‰Ñ˜˜u gÕ.r*   c                 ó   — t         ‚)z‚Returns the byte length of the content.

        MUST be implemented.

        See also _DAVResource.get_content_length()
        r\   r0   s    r(   r6   z#DAVNonCollection.get_content_lengthÏ  s
   € ô "Ð!r*   c                 ó`   — | j                   d   }t        j                  | j                  |«      S )aŠ  Contains the Content-Type header returned by a GET without accept
        headers.

        This getcontenttype property MUST be defined on any DAV compliant
        resource that returns the Content-Type header in response to a GET.
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getcontenttype

        This default implementation guesses the type from the filen name.
        rÚ   )r   r   Úguess_mime_typer   )r'   rï   s     r(   r9   z!DAVNonCollection.get_content_typeÙ  s*   € ð —‘Ð.Ñ/ˆÜ×#Ñ# D§I¡I¨vÓ6Ð6r*   c                 ó   — t         ‚)a  Open content as a stream for reading.

        Returns a file-like object / stream containing the contents of the
        resource specified.
        The application will close() the stream.

        This method MUST be implemented by all providers.
        r\   r0   s    r(   r	  zDAVNonCollection.get_contentæ  s
   € ô "Ð!r*   c                  ó   — y)a.  
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getetag

        This method SHOULD be implemented, especially by non-collections.
        Return None if not supported for this resource instance.
        See also `DAVNonCollection.support_etag()` and `util.get_file_etag(path)`.
        Nr;   r0   s    r(   rO   zDAVNonCollection.get_etagò  ó   � r*   c                  ó   — y)zgReturn True, if this resource supports ETags.

        See also `DAVNonCollection.get_etag()`.
        Nr;   r0   s    r(   rh   zDAVNonCollection.support_etagü  rE  r*   c                  ó   — y)z~Return True, if this non-resource supports Range on GET requests.

        This default implementation returns False.
        Fr;   r0   s    r(   rc   zDAVNonCollection.support_ranges  s   € ð
 r*   Nr
  c                ó    — t        t        «      ‚r  r*  r  s     r(   r  zDAVNonCollection.begin_write
  s   € ô ”~Ó&Ð&r*   c                 ó   — yr  r;   r  s     r(   r  zDAVNonCollection.end_write  s   € ð
 	r*   c                 ó   — |dv r| S y)z§Return a _DAVResource object for the path (None, if not found).

        Since non-collection don't have members, we return None if path is not
        empty.
        rl   Nr;   r-  s      r(   r0  zDAVNonCollection.resolve  s   € ð ˜	Ñ!ØˆKØr*   )r/   r4  r5  r6  r¾   r8  r)   r   r6   r9   r	  rO   rh   rc   r  r  r0  Ú__classcell__©r.   s   @r(   r;  r;  Â  s‰   ø„ ñð/˜Sð /¨4õ /ð ñ"ó ð"ò7ð ñ	"ó ð	"ð ñó ðð ñó ðòð +/ô 'òör*   r;  c                   ó°   ‡ — e Zd ZdZdededdfˆ fd„Zdee   fd„Z	dee   fd„Z
d	edefd
„Zd„ Zd„ Zd„ Zed„ «       Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zˆ xZS )ÚDAVCollectiona  
    A DAVCollection is a _DAVResource, that has members (like a 'folder' on
    a filesystem).

    A DAVCollecion 'knows' its members, and how to obtain them from the backend
    storage.
    There is also optional built-in support for member caching.

    See also _DAVResource
    r   r   r2   Nc                 ó(   •— t         ‰| �  |d|«       y )NTr=  r?  s      €r(   r)   zDAVCollection.__init__3  s   ø€ Ü‰Ñ˜˜t WÕ-r*   c                  ó   — y ©Nr;   r0   s    r(   r6   z DAVCollection.get_content_lengthZ  ó   € Ør*   c                  ó   — y rQ  r;   r0   s    r(   r9   zDAVCollection.get_content_type]  rR  r*   r&   c                 ó    — t        t        «      ‚r  r*  rx   s     r(   r  z#DAVCollection.create_empty_resource`  s   € ô" ”~Ó&Ð&r*   c                 ó<   — | j                   sJ ‚t        t        «      ‚r  r  rx   s     r(   r  zDAVCollection.create_collections  r  r*   c                  ó   — y)zÔ
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getetag

        For non-collections we default to None, because it is harder to implement.
        See also `DAVCollection.support_etag()`.
        Nr;   r0   s    r(   rO   zDAVCollection.get_etagƒ  s   € ð r*   c                 ó¦   — | j                   sJ ‚| j                  j                  t        j                  | j
                  |«      | j                  «      S rw   )r   r$   rÂ   r   Újoin_urir   r   rx   s     r(   ry   zDAVCollection.get_memberŒ  sB   € ð ×!Ò!Ð!Ð!Ø�}‰}×.Ñ.Ü�M‰M˜$Ÿ)™) TÓ*¨D¯L©Ló
ð 	
r*   c                 ó*   — | j                   sJ ‚t        ‚)zxReturn list of (direct) collection member names (UTF-8 byte strings).

        This method MUST be implemented.
        r4   r0   s    r(   r|   zDAVCollection.get_member_names˜  s   € ð ×!Ò!Ð!Ð!Ü!Ð!r*   c                  ó   — y)z¸Return True, if this resource supports ETags.

        For non-collections we default to False, because it is harder to implement.
        See also `DAVCollection.get_etag()`.
        Fr;   r0   s    r(   rh   zDAVCollection.support_etag¡  ó   € ð r*   c                  ó   — y)zšReturn True, if delete() may be called on non-empty collections
        (see comments there).

        This default implementation returns False.
        Fr;   r0   s    r(   r  z&DAVCollection.support_recursive_delete©  r[  r*   c                 ó    — t        t        «      ‚)z Remove this resource (possibly recursive).

        This method MUST be implemented if resource allows write access.

        See _DAVResource.delete()
        r*  r0   s    r(   r  zDAVCollection.delete±  ó   € ô ”~Ó&Ð&r*   c                ó    — t        t        «      ‚)z·Copy or move this resource to destPath (non-recursive).

        This method MUST be implemented if resource allows write access.

        See _DAVResource.copy_move_single()
        r*  r   s      r(   r"  zDAVCollection.copy_move_singleº  r^  r*   c                  ó   — y)r'  Fr;   r$  s     r(   r(  z$DAVCollection.support_recursive_moveÃ  s   € àr*   c                 ó    — t        t        «      ‚)z}Move this resource and members to destPath.

        This method MAY be implemented in order to improve performance.
        r*  r$  s     r(   r+  zDAVCollection.move_recursiveÇ  s   € ô
 ”~Ó&Ð&r*   c                 óâ   — |dv r| S |j                  d«      sJ ‚t        j                  |«      \  }}| j                  |«      }|�|dv r|S |j	                  t        j
                  ||«      |«      S )z€Return a _DAVResource object for the path (None, if not found).

        `path_info`: is a URL relative to this object.
        rl   r!   )r#   r   Úpop_pathry   r0  rX  )r'   r.  r/  r&   ÚrestrŽ   s         r(   r0  zDAVCollection.resolveÎ  sr   € ð
 ˜	Ñ!ØˆKØ×#Ñ# CÔ(Ð(Ð(Ü—]‘] 9Ó-‰
ˆˆdØ�o‰o˜dÓ#ˆØˆ;˜$ )Ñ+ØˆJØ�{‰{œ4Ÿ=™=¨°dÓ;¸TÓBÐBr*   )r/   r4  r5  r6  r¾   r8  r)   r   r¿   r6   r9   r   r  r  rO   ry   r   r|   rh   r  r  r"  r(  r+  r0  rK  rL  s   @r(   rN  rN  '  s�   ø„ ñ	ð.˜Sð .¨4ð .°Dõ .ðN H¨S¡Mó ð (¨3¡-ó ð'¨#ð '°,ó 'ò&'ò ò

ð ñ"ó ð"òòò'ò'òò'öCr*   rN  c                   ó€   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zed
edefd„«       Zd
edefd„Zd
edefd„Zd„ Zy)ÚDAVProviderz‚Abstract base class for DAV resource providers.

    There will be only one DAVProvider instance per share (not per request).
    c                 óf   — d| _         d | _        d | _        d | _        d| _        d| _        d| _        y )Nr    é   r   )rt   rp   r”   r—   r¥   Ú_count_get_resource_instÚ_count_get_resource_inst_initr0   s    r(   r)   zDAVProvider.__init__è  s7   € ØˆŒØˆŒØ ˆÔØ ˆÔØˆŒà()ˆÔ%Ø-.ˆÕ*r*   c                 ó.   — | j                   j                  S rQ  )r.   r/   r0   s    r(   r1   zDAVProvider.__repr__ô  s   € Ø�~‰~×&Ñ&Ð&r*   c                  ó   — yrX   r;   r0   s    r(   Úis_readonlyzDAVProvider.is_readonly÷  rZ   r*   c                 ób   — |dv s$|j                  d«      r|j                  d«      rJ ‚|| _        y)zSet application root for this resource provider.

        This is the value of SCRIPT_NAME, when WsgiDAVApp is called.
        rl   r!   N)r#   rm   rt   )r'   rt   s     r(   Úset_mount_pathzDAVProvider.set_mount_pathú  s:   € ð
 ˜YÑ&Ø×!Ñ! #Ô&¨z×/BÑ/BÀ3Ô/Gð	
ð 
ð %ˆ�r*   c                 ó~   — |dk(  s|j                  d«      sJ ‚|dk(  rd}|dv s|j                  d«      rJ ‚|| _        y)z€Set application location for this resource provider.

        @param share_path: a UTF-8 encoded, unquoted byte string.
        r    r!   rl   N)r#   rm   rp   )r'   rp   s     r(   Úset_share_pathzDAVProvider.set_share_path  sN   € ð ˜RÒ :×#8Ñ#8¸Ô#=Ð=Ð=Ø˜ÒØˆJØ˜YÑ&¨j×.AÑ.AÀ#Ô.FÐFÐFØ$ˆ�r*   c                 óD   — |rt        |d«      st        d«      ‚|| _        y )NÚcheck_write_permissionzAMust be compatible with wsgidav.lock_man.lock_manager.LockManager)ÚhasattrÚ
ValueErrorr”   )r'   r”   s     r(   Úset_lock_managerzDAVProvider.set_lock_manager  s)   € Ù¤¨Ð6NÔ OÜØSóð ð )ˆÕr*   c                 óD   — |rt        |d«      st        d«      ‚|| _        y )NÚcopy_propertieszIMust be compatible with wsgidav.prop_man.property_manager.PropertyManager)rt  ru  r—   )r'   r—   s     r(   Úset_prop_managerzDAVProvider.set_prop_manager  s)   € Ù¤¨Ð6GÔ HÜØ[óð ð )ˆÕr*   c                 óx   — dt        t        j                  || j                  «      «      j	                  d«      z   S )z˜Convert a refUrl to a path, by stripping the share prefix.

        Used to calculate the <path> from a storage key by inverting get_ref_url().
        r!   )r   r   Úremoveprefixrp   Úlstrip)r'   Úref_urls     r(   rÁ   zDAVProvider.ref_url_to_path  s1   € ð
 ”WœT×.Ñ.¨w¸¿¹ÓHÓI×PÑPÐQTÓUÑUÐUr*   r   r   c                 ó   — t         ‚)aÝ  Return a _DAVResource object for path.

        Should be called only once per request and resource::

            res = provider.get_resource_inst(path, environ)
            if res and not res.is_collection:
                print(res.get_content_type())

        If <path> does not exist, None is returned.
        <environ> may be used by the provider to implement per-request caching.

        See _DAVResource for details.

        This method MUST be implemented.
        r\   ©r'   r   r   s      r(   rÂ   zDAVProvider.get_resource_inst&  s
   € ô" "Ð!r*   c                 ó*   — | j                  ||«      duS )a  Return True, if path maps to an existing resource.

        This method should only be used, if no other information is queried
        for <path>. Otherwise a _DAVResource should be created first.

        This method SHOULD be overridden by a more efficient implementation.
        N)rÂ   r  s      r(   ÚexistszDAVProvider.exists9  s   € ð ×%Ñ% d¨GÓ4¸DÐ@Ð@r*   c                 óF   — | j                  ||«      }|xr |j                  S )zÙReturn True, if path maps to an existing collection resource.

        This method should only be used, if no other information is queried
        for <path>. Otherwise a _DAVResource should be created first.
        )rÂ   r   )r'   r   r   rŽ   s       r(   r   zDAVProvider.is_collectionC  s'   € ð ×$Ñ$ T¨7Ó3ˆØÒ(�s×(Ñ(Ð(r*   c                 ó   —  |||«      S )zöOptionally implement custom request handling.

        requestmethod = environ["REQUEST_METHOD"]
        Either

        - handle the request completely
        - do additional processing and call default_handler(environ, start_response)
        r;   )r'   r   Ústart_responseÚdefault_handlers       r(   Úcustom_request_handlerz"DAVProvider.custom_request_handlerL  s   € ñ ˜w¨Ó7Ð7r*   N)r/   r4  r5  r6  r)   r1   rm  ro  rq  rv  ry  rÁ   r   r¾   r8  rÂ   r�  r   r†  r;   r*   r(   rf  rf  â  s€   „ ñò
/ò'òò%ò%ò)ò)òVð ð" cð "°Dò "ó ð"ð$A˜3ð A¨ó Að) #ð )°ó )ó	8r*   rf  )"r6  rG   r¨   rÀ   r¦   Úabcr   r   Útypingr   Úurllib.parser   r   Úwsgidavr   r	   Úwsgidav.dav_errorr
   r   r   r   r   Úwsgidav.utilr   Ú__docformat__Úget_module_loggerr/   ré   rè   r–   r   r;  rN  rf  r;   r*   r(   ú<module>r�     sŸ   ðñ
KóZ 
Û 
Û Û ß #Ý ß 'ç #÷õ õ à"€à
 ˆ$×
 Ñ
  Ó
*€ò
Ð ð ,Ð-BÐCÐ ôA�3ô AôN"_�|ô _ôJsC�Lô sCôvs8�#õ s8r*   