Ë
    "ïàjyb  ã                   óš  — d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
mZmZmZ ddlmZmZmZ ddlmZ d	Z ej*                  e«      Zd
Z	 dZdddddgddej4                  j7                  ed«      ej4                  j7                  ed«      gdœdddddgddej4                  j7                  ed«      gdœddj9                  «       ddgddej4                  j7                  ed«      gdœgZd „ Zd!„ Z G d"„ d#e«      Z  G d$„ d%e«      Z! G d&„ d'e«      Z" G d(„ d)e«      Z# G d*„ d+e«      Z$ G d,„ d-e$«      Z% G d.„ d/e$«      Z& G d0„ d1e«      Z'y)2aN  
Sample implementation of a DAV provider that provides a browsable,
multi-categorized resource tree.

Note that this is simply an example with no concrete real world benefit.
But it demonstrates some techniques to customize WsgiDAV.

Compared to a published file system, we have these main differences:

#. A resource like ``My doc 1`` has several attributes like ``key``,
   ``orga``, ``tags``, ``status``, ``description``.
   Also there may be a list of attached files.
#. These attributes are used to dynamically create a virtual hierarchy.
   For example, if ``status`` is ``draft``, a collection
   ``<share>/by_status/draft/`` is created and the resource is mapped to
   ``<share>/by_status/draft/My doc 1``.
#. The resource ``My doc 1`` is rendered as a collection, that contains
   some virtual descriptive files and the attached files.
#. The same resource may be referenced using different paths
   For example ``<share>/by_tag/cool/My doc 1``,
   ``<share>/by_tag/hot/My doc 1``, and ``<share>/by_key/1`` map to the same
   resource.
   Only the latter is considered the *real-path*, all others are
   *virtual-paths*.
#. The attributes are exposed as live properties, like "{virtres:}key",
   "{virtres:}tags", and "{virtres:}description".
   Some of them are even writable. Note that modifying an attribute may also
   change the dynamically created tree structure.
   For example changing "{virtres:}status" from 'draft' to 'published' will
   make the resource appear as ``<share>/by_status/published/My doc 1``.
#. This provider implements native delete/move/copy methods, to change the
   semantics of these operations for the virtual '/by_tag/' collection.
   For example issuing a DELETE on ``<share>/by_tag/cool/My doc 1`` will
   simply remove the 'cool' tag from that resource.
#. Virtual collections and artifacts cannot be locked.
   However a resource can be locked.
   For example locking ``<share>/by_tag/cool/My doc 1`` will also lock
   ``<share>/by_key/1``.
#. Some paths may be hidden, i.e. by_key is not browsable (but can be referenced)
   TODO: is this WebDAV compliant?

The *database* is a simple hard coded variable ``_resourceData``, that contains
a list of resource description dictionaries.

A resource is served as an collection, which is generated on-the-fly and
contains some virtual files (*artifacts*).

In general, a URL is interpreted like this::

  <share>/<category-type>/<category-key>/<resource-name>/<artifact-name>


An example layout::

    <share>/
        by_tag/
            cool/
                My doc 1/
                    .Info.html
                    .Info.txt
                    .Description.txt
                    MySpec.pdf
                    MySpec.doc
                My doc 2/
            hot/
                My doc 1/
                My doc 2/
            nice/
                My doc 2/
                My doc 3
        by_orga/
            development/
                My doc 3/
            marketing/
                My doc 1/
                My doc 2/
        by_status/
            draft/
                My doc 2
            published/
                My doc 1
                My doc 3
        by_key/
            1/
            2/
            3/

When accessed using WebDAV, the following URLs both return the same resource
'My doc 1'::

    <share>/by_tag/cool/My doc 1
    <share>/by_tag/hot/My doc 1
    <share>/by_key/1
é    N)ÚBytesIO)Úquote)Úutil)ÚHTTP_FORBIDDENÚHTTP_INTERNAL_ERRORÚDAVErrorÚ#PRECONDITION_CODE_ProtectedProperty)ÚDAVCollectionÚDAVNonCollectionÚDAVProvider)Újoin_urizreStructuredText eni    zc:\temp\virtfilesÚ1zMy doc 1ÚdevelopmentÚcoolÚhotÚdraftz/This resource contains two specification files.z
MySpec.docz
MySpec.pdf)ÚkeyÚtitleÚorgaÚtagsÚstatusÚdescriptionÚresPathListÚ2zMy doc 2ÚniceÚ	publishedz This resource contains one file.z
My URS.docÚ3u   My doc (euro:â‚¬, uuml:ï¿½ï¿½)Ú	marketingzLong text describing itc                 ó^  — | t         j                  v sJ ‚| dk(  r)t        D �cg c]  }|j                  d«      |k(  sŒ|‘Œ c}S | dk(  r*t        D �cg c]  }|j                  d«      |k(  sŒ|‘Œ }}|S | dk(  r't        D �cg c]  }||j                  d«      v sŒ|‘Œ }}S c c}w c c}w c c}w )ú Ú	by_statusr   Úby_orgar   Úby_tagr   )ÚRootCollectionÚ_visibleMemberNamesÚ_resourceDataÚget)ÚattrNameÚattrValÚdataÚresLists       úS/srv/dav/.venv/lib/python3.12/site-packages/wsgidav/samples/virtual_dav_provider.pyÚ_get_res_list_by_attrr-   ¤   s¯   € à”~×9Ñ9Ñ9Ð9Ð9Ø�;ÒÜ!.ÖP˜°$·(±(¸8Ó2DÈÓ2O’ÒPÐPØ	�YÒ	Ü$1ÖQ˜D°T·X±X¸fÓ5EÈÓ5P’4ÐQˆÐQð €Nð 
�XÒ	Ü$1ÖQ˜D°WÀÇÁÈÓ@PÒ5P’4ÐQˆÐQØ€Nùò QùâQùâQs"   ¢B ¼B ÁB%Á*B%Á?B*ÂB*c                 ó2   — t         D ]  }|d   | k(  sŒ|c S  y)r    r   N)r&   )r   r*   s     r,   Ú_get_res_by_keyr/   °   s'   € äò ˆØ�‰;˜#ÓØŠKðð ó    c                   ó<   ‡ — e Zd ZdZdZedz   Zˆ fd„Zd„ Zd„ Zˆ xZ	S )r$   zResolve top-level requests '/'.)r"   r#   r!   )Úby_keyc                 ó&   •— t         ‰| �  d|«       y )Nú/©ÚsuperÚ__init__)ÚselfÚenvironÚ	__class__s     €r,   r7   zRootCollection.__init__Á   s   ø€ Ü‰Ñ˜˜gÕ&r0   c                 ó   — | j                   S ©N)r%   ©r8   s    r,   Úget_member_nameszRootCollection.get_member_namesÄ   s   € Ø×'Ñ'Ð'r0   c                 ót   — || j                   v r*t        t        | j                  |«      | j                  «      S y r<   )Ú_validMemberNamesÚCategoryTypeCollectionr   Úpathr9   )r8   Únames     r,   Ú
get_memberzRootCollection.get_memberÇ   s/   € à�4×)Ñ)Ñ)Ü)¬(°4·9±9¸dÓ*CÀTÇ\Á\ÓRÐRØr0   )
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r%   r@   r7   r>   rD   Ú__classcell__©r:   s   @r,   r$   r$   »   s&   ø„ Ù)à<ÐØ+¨kÑ9Ðô'ò(ör0   r$   c                   ó4   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zˆ xZS )rA   z/Resolve '/catType' URLs, for example '/by_tag'.c                 ó&   •— t         ‰| �  ||«       y r<   r5   ©r8   rB   r9   r:   s      €r,   r7   zCategoryTypeCollection.__init__Ñ   ó   ø€ Ü‰Ñ˜˜wÕ'r0   c                 ó
   — ddiS )NÚtypezCategory type© r=   s    r,   Úget_display_infoz'CategoryTypeCollection.get_display_infoÔ   s   € Ø˜Ð(Ð(r0   c                 óP  — g }t         D ]Š  }| j                  dk(  r|d   |vsŒ|j                  |d   «       Œ/| j                  dk(  r|d   |vsŒF|j                  |d   «       Œ[| j                  dk(  sŒk|d   D ]  }||vsŒ|j                  |«       Œ ŒŒ |j                  «        |S )Nr!   r   r"   r   r#   r   )r&   rC   ÚappendÚsort)r8   Únamesr*   Útags       r,   r>   z'CategoryTypeCollection.get_member_names×   s©   € ØˆÜ!ò 
	*ˆDØ�y‰y˜KÒ'Ø˜‘>¨Ò.Ø—L‘L  h¡Õ0Ø—‘˜iÒ'Ø˜‘< uÒ,Ø—L‘L  f¡Õ.Ø—‘˜hÓ&Ø ™<ò *�CØ %Ò'ØŸ™ SÕ)ñ*ð
	*ð 	�
‰
ŒØˆr0   c                 óü   — | j                   dk(  r9t        |«      }|r+t        t        | j                  |«      | j
                  |«      S y t        t        | j                  |«      | j
                  | j                   «      S )Nr2   )rC   r/   ÚVirtualResourcer   rB   r9   ÚCategoryCollection©r8   rC   r*   s      r,   rD   z!CategoryTypeCollection.get_memberè   s_   € Ø�9‰9˜Ò Ü" 4Ó(ˆDÙÜ&¤x°·	±	¸4Ó'@À$Ç,Á,ÐPTÓUÐUàÜ!¤(¨4¯9©9°dÓ";¸T¿\¹\È4Ï9É9ÓUÐUr0   ©	rE   rF   rG   rH   r7   rR   r>   rD   rI   rJ   s   @r,   rA   rA   Î   s   ø„ Ù9ô(ò)òö"Vr0   rA   c                   ó4   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zˆ xZS )rZ   z8Resolve '/catType/cat' URLs, for example '/by_tag/cool'.c                 ó4   •— t         ‰| �  ||«       || _        y r<   )r6   r7   ÚcatType)r8   rB   r9   r_   r:   s       €r,   r7   zCategoryCollection.__init__õ   s   ø€ Ü‰Ñ˜˜wÔ'Øˆ�r0   c                 ó
   — ddiS )NrP   ÚCategoryrQ   r=   s    r,   rR   z#CategoryCollection.get_display_infoù   s   € Ø˜
Ð#Ð#r0   c                 ó�   — t        | j                  | j                  «      D �cg c]  }|d   ‘Œ	 }}|j                  «        |S c c}w ©Nr   )r-   r_   rC   rU   )r8   r*   rV   s      r,   r>   z#CategoryCollection.get_member_namesü   sD   € ä&;¸D¿L¹LÈ$Ï)É)Ó&Tö
Ø"ˆD�‹Mð
ˆð 
ð 	�
‰
ŒØˆùò	
s   £Ac                 ó¸   — t        | j                  | j                  «      D ]7  }|d   |k(  sŒt        t	        | j
                  |«      | j                  |«      c S  y rc   )r-   r_   rC   rY   r   rB   r9   r[   s      r,   rD   zCategoryCollection.get_member  sR   € Ü)¨$¯,©,¸¿	¹	ÓBò 	VˆDØ�G‰} Ó$Ü&¤x°·	±	¸4Ó'@À$Ç,Á,ÐPTÓUÒUð	Vð r0   r\   rJ   s   @r,   rZ   rZ   ò   s   ø„ ÙBôò$òör0   rZ   c                   ót   ‡ — e Zd ZdZdZg d¢Zˆ fd„Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ Zˆ fd„Zˆ fd„Zdd„Zˆ xZS )rY   zGA virtual 'resource', displayed as a collection of artifacts and files.)ú	.Info.txtú
.Info.htmlú.Description.txt)ú{virtres:}keyú{virtres:}titleú{virtres:}statusú{virtres:}orgaú{virtres:}tagsú{virtres:}descriptionc                 ó4   •— t         ‰| �  ||«       || _        y r<   ©r6   r7   r*   ©r8   rB   r9   r*   r:   s       €r,   r7   zVirtualResource.__init__  s   ø€ Ü‰Ñ˜˜wÔ'Øˆ�	r0   c                 ó
   — ddiS )NrP   zVirtual ResourcerQ   r=   s    r,   rR   z VirtualResource.get_display_info#  s   € ØÐ*Ð+Ð+r0   c                 ó¸   — t        | j                  «      }| j                  d   D ]2  }t        j                  j                  |«      }|j                  |«       Œ4 |S ©Nr   )ÚlistÚ_artifactNamesr*   ÚosrB   ÚbasenamerT   )r8   rV   ÚfrC   s       r,   r>   z VirtualResource.get_member_names&  sQ   € Ü�T×(Ñ(Ó)ˆØ—‘˜=Ñ)ò 	ˆAÜ—7‘7×#Ñ# AÓ&ˆDØ�L‰L˜Õð	ð ˆr0   c                 ój  — || j                   v r5t        t        | j                  |«      | j                  | j
                  «      S | j
                  d   D ]^  }t        j                  j                  |«      }||k(  sŒ(t        t        | j                  |«      | j                  | j
                  |«      c S  y rt   )	rv   ÚVirtualArtifactr   rB   r9   r*   rw   rx   ÚVirtualResFile)r8   rC   Ú	file_pathÚfnames       r,   rD   zVirtualResource.get_member-  s“   € Ø�4×&Ñ&Ñ&Ü"¤8¨D¯I©I°tÓ#<¸d¿l¹lÈDÏIÉIÓVÐVØŸ™ =Ñ1ò 	ˆIÜ—G‘G×$Ñ$ YÓ/ˆEØ˜‹}Ü%Ü˜TŸY™Y¨Ó-¨t¯|©|¸T¿Y¹YÈ	óò ð	ð r0   c                 ó  — d| j                   vrt        t        «      ‚t        j                  | j                   j                  d«      dd«      \  }}}|dk(  sJ ‚|| j                  d   v sJ ‚| j                  d   j                  |«       y)z2Change semantic of DELETE to remove resource tags.ú/by_tag/r4   é   r#   r   T)rB   r   r   r   Ú
save_splitÚstripr*   Úremove)r8   r_   rW   Ú_rests       r,   Úhandle_deletezVirtualResource.handle_delete8  s€   € ð ˜TŸY™YÑ&Üœ>Ó*Ð*ä"Ÿo™o¨d¯i©i¯o©o¸cÓ.BÀCÈÓKÑˆ��eØ˜(Ò"Ð"Ð"Ø�d—i‘i Ñ'Ñ'Ð'Ð'Ø�	‰	�&Ñ× Ñ  Ô%Ør0   c                óê   — d|vrt        t        «      ‚t        j                  |j	                  d«      dd«      \  }}}|dk(  sJ ‚|| j
                  d   vr| j
                  d   j                  |«       y)z-Change semantic of COPY to add resource tags.r€   r4   r�   r#   r   T)r   r   r   r‚   rƒ   r*   rT   )r8   Ú	dest_pathÚdepth_infinityr_   rW   r…   s         r,   Úhandle_copyzVirtualResource.handle_copyD  sr   € ð ˜YÑ&Üœ>Ó*Ð*Ü"Ÿo™o¨i¯o©o¸cÓ.BÀCÈÓKÑˆ��eØ˜(Ò"Ð"Ð"Ø�d—i‘i Ñ'Ñ'Ø�I‰I�fÑ×$Ñ$ SÔ)Ør0   c                 óü  — d| j                   vrt        t        «      ‚d|vrt        t        «      ‚t        j                  | j                   j                  d«      dd«      \  }}}|dk(  sJ ‚|| j                  d   v sJ ‚| j                  d   j                  |«       t        j                  |j                  d«      dd«      \  }}}|dk(  sJ ‚|| j                  d   vr| j                  d   j                  |«       y)z0Change semantic of MOVE to change resource tags.r€   r4   r�   r#   r   T)	rB   r   r   r   r‚   rƒ   r*   r„   rT   )r8   rˆ   r_   rW   r…   s        r,   Úhandle_movezVirtualResource.handle_moveO  së   € ð ˜TŸY™YÑ&Üœ>Ó*Ð*Ø˜YÑ&Üœ>Ó*Ð*Ü"Ÿo™o¨d¯i©i¯o©o¸cÓ.BÀCÈÓKÑˆ��eØ˜(Ò"Ð"Ð"Ø�d—i‘i Ñ'Ñ'Ð'Ð'Ø�	‰	�&Ñ× Ñ  Ô%Ü"Ÿo™o¨i¯o©o¸cÓ.BÀCÈÓKÑˆ��eØ˜(Ò"Ð"Ð"Ø�d—i‘i Ñ'Ñ'Ø�I‰I�fÑ×$Ñ$ SÔ)Ør0   c                 ój   — d| j                   d   z  }t        | j                  j                  |z   «      S )Nz
/by_key/%sr   )r*   r   ÚproviderÚ
share_path©r8   ÚrefPaths     r,   Úget_ref_urlzVirtualResource.get_ref_url`  s/   € Ø §¡¨5Ñ!1Ñ1ˆÜ�T—]‘]×-Ñ-°Ñ7Ó8Ð8r0   c                óf   •— t         ‰| �  |¬«      }|j                  t        j                  «       |S )zqReturn list of supported property names in Clark Notation.

        See DAVResource.get_property_names()
        )Ú
is_allprop)r6   Úget_property_namesÚextendrY   Ú_supportedProps)r8   r”   ÚpropNameListr:   s      €r,   r•   z"VirtualResource.get_property_namesd  s1   ø€ ô ‘wÑ1¸ZÐ1ÓHˆà×ÑœO×;Ñ;Ô<ØÐr0   c                 ó0  •— |dk(  r| j                   d   S |dk(  r| j                   d   S |dk(  r| j                   d   S |dk(  r| j                   d   S |d	k(  rd
j                  | j                   d   «      S |dk(  r| j                   d   S t        ‰| �  |«      S )zJReturn the value of a property.

        See get_property_value()
        ri   r   rj   r   rk   r   rl   r   rm   ú,r   rn   r   )r*   Újoinr6   Úget_property_value)r8   rC   r:   s     €r,   rœ   z"VirtualResource.get_property_valueo  s­   ø€ ð �?Ò"Ø—9‘9˜UÑ#Ð#ØÐ&Ò&Ø—9‘9˜WÑ%Ð%ØÐ'Ò'Ø—9‘9˜XÑ&Ð&ØÐ%Ò%Ø—9‘9˜VÑ$Ð$ØÐ%Ò%à—8‘8˜DŸI™I fÑ-Ó.Ð.ØÐ,Ò,Ø—9‘9˜]Ñ+Ð+ä‰wÑ)¨$Ó/Ð/r0   c                 ó*  — |€t        t        «      ‚|dk(  r)|j                  j                  d«      | j                  d<   y|dk(  r|j                  | j                  d<   y|t
        j                  v rt        t        t        ¬«      ‚t        t        «      ‚)zTSet or remove property value.

        See DAVResource.set_property_value()
        Nrm   rš   r   rn   r   )Úerr_condition)r   r   ÚtextÚsplitr*   rY   r—   r	   )r8   rC   ÚvalueÚdry_runs       r,   Úset_property_valuez"VirtualResource.set_property_value…  s‘   € ð
 ˆ=äœ>Ó*Ð*ØÐ#Ò#à %§
¡
× 0Ñ 0°Ó 5ˆD�I‰I�fÑð 	ð Ð,Ò,à',§z¡zˆD�I‰I�mÑ$ð 	ð ”_×4Ñ4Ñ4äÜÔ.Qôð ô
 œ>Ó*Ð*r0   )F)rE   rF   rG   rH   rv   r—   r7   rR   r>   rD   r†   rŠ   rŒ   r’   r•   rœ   r£   rI   rJ   s   @r,   rY   rY     sK   ø„ ÙQð€Nò€Oôò,òò	ò
ò	òò"9ô	ô0÷,r0   rY   c                   óR   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zˆ xZS )Ú_VirtualNonCollectionz5Abstract base class for all non-collection resources.c                 ó&   •— t         ‰| �  ||«       y r<   r5   rM   s      €r,   r7   z_VirtualNonCollection.__init__¥  rN   r0   c                  ó   — y r<   rQ   r=   s    r,   Úget_content_lengthz(_VirtualNonCollection.get_content_length¨  ó   € Ør0   c                  ó   — y r<   rQ   r=   s    r,   Úget_content_typez&_VirtualNonCollection.get_content_type«  r©   r0   c                  ó   — y r<   rQ   r=   s    r,   Úget_creation_datez'_VirtualNonCollection.get_creation_date®  r©   r0   c                 ó   — | j                   S r<   )rC   r=   s    r,   Úget_display_namez&_VirtualNonCollection.get_display_name±  s   € Ø�y‰yÐr0   c                 ó   — t         ‚r<   )ÚNotImplementedErrorr=   s    r,   rR   z&_VirtualNonCollection.get_display_info´  s   € Ü!Ð!r0   c                  ó   — y r<   rQ   r=   s    r,   Úget_etagz_VirtualNonCollection.get_etag·  r©   r0   c                  ó   — y r<   rQ   r=   s    r,   Úget_last_modifiedz'_VirtualNonCollection.get_last_modifiedº  r©   r0   c                  ó   — y)NFrQ   r=   s    r,   Úsupport_rangesz$_VirtualNonCollection.support_ranges½  s   € Ør0   )rE   rF   rG   rH   r7   r¨   r«   r­   r¯   rR   r³   rµ   r·   rI   rJ   s   @r,   r¥   r¥   ¢  s3   ø„ Ù?ô(òòòòò"òòör0   r¥   c                   óF   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
ˆ xZS )	r{   z1A virtual file, containing resource descriptions.c                 ó4   •— t         ‰| �  ||«       || _        y r<   rp   rq   s       €r,   r7   zVirtualArtifact.__init__Ï  s   ø€ ä‰Ñ˜˜wÔ'Øˆ�	r0   c                 óP   — t        | j                  «       j                  «       «      S r<   )ÚlenÚget_contentÚreadr=   s    r,   r¨   z"VirtualArtifact.get_content_lengthÔ  s   € Ü�4×#Ñ#Ó%×*Ñ*Ó,Ó-Ð-r0   c                 ó<   — | j                   j                  d«      ryy)Nz.txtz
text/plainú	text/html)rC   Úendswithr=   s    r,   r«   z VirtualArtifact.get_content_type×  s   € Ø�9‰9×Ñ˜fÔ%ØØr0   c                 ó
   — ddiS )NrP   zVirtual info filerQ   r=   s    r,   rR   z VirtualArtifact.get_display_infoÜ  s   € ØÐ+Ð,Ð,r0   c                  ó   — y)NTrQ   r=   s    r,   Úprevent_lockingzVirtualArtifact.prevent_lockingß  r©   r0   c                 ó˜   — dj                  | j                  d   | j                  «      }t        | j                  j
                  |z   «      S ©Nz/by_key/{}/{}r   )Úformatr*   rC   r   rŽ   r�   r�   s     r,   r’   zVirtualArtifact.get_ref_urlâ  s;   € Ø!×(Ñ(¨¯©°5Ñ)9¸4¿9¹9ÓEˆÜ�T—]‘]×-Ñ-°Ñ7Ó8Ð8r0   c                 ó   — | j                   d   D �cg c](  }dt        j                  j                  |«      › d|› d�‘Œ* }}| j                   j	                  «       }dj                  |«      |d<   | j                  dk(  rd|z  }né| j                  d	k(  rž| j                   d
   dt        | j                   d
   «      z  | j                   d   dd| j                   d   z  d| j                   d   z  ddj                  | j                   d   «      z  d| j                   d   z  g}dj                  |«      }n<| j                  dk(  r| j                   d   }nt        t        d| j                  z  «      ‚t        t        j                  |«      «      S c c}w )Nr   z	<a href='z'>z</a>
z, Ú	fileLinksrg   a0              <html><head>
            <title>%(title)s</title>
            </head><body>
            <h1>%(title)s</h1>
            <table>
            <tr>
                <td>Description</td>
                <td>%(description)s</td>
            </tr><tr>
                <td>Status</td>
                <td>%(status)s</td>
            </tr><tr>
                <td>Tags</td>
                <td>%(tags)s</td>
            </tr><tr>
                <td>Orga unit</td>
                <td>%(orga)s</td>
            </tr><tr>
                <td>Files</td>
                <td>%(fileLinks)s</td>
            </tr><tr>
                <td>Key</td>
                <td>%(key)s</td>
            </tr>
            </table>
            <p>This is a virtual WsgiDAV resource called '%(title)s'.</p>
            </body></html>rf   r   ú=r   Ú z
Status: %sr   zOrga:   %8sr   zTags:   '%s'z', 'r   z
Key:    %sr   ú
rh   zInvalid artifact '%s')r*   rw   rB   rx   Úcopyr›   rC   r»   r   r   r   r   Úto_bytes)r8   ry   rÈ   ÚdictÚhtmlÚliness         r,   r¼   zVirtualArtifact.get_contentæ  s~  € ð —Y‘Y˜}Ñ-ö
àð œŸ™×(Ñ(¨Ó+Ð,¨B¨q¨c°Ò8ð
ˆ	ð 
ð �y‰y�~‰~ÓˆØ ŸI™I iÓ0ˆˆ[ÑØ�9‰9˜Ò$ðð8 ñ9ñ ð> �Y‰Y˜+Ò%à—	‘	˜'Ñ"Ø”c˜$Ÿ)™) GÑ,Ó-Ñ-Ø—	‘	˜-Ñ(ØØ˜tŸy™y¨Ñ2Ñ2Ø §	¡	¨&Ñ 1Ñ1Ø §¡¨T¯Y©Y°vÑ->Ó!?Ñ?Ø˜tŸy™y¨Ñ/Ñ/ð	ˆEð —9‘9˜UÓ#‰DØ�Y‰YÐ,Ò,Ø—9‘9˜]Ñ+‰DäÔ.Ð0GÈ$Ï)É)Ñ0SÓTÐTÜ”t—}‘} TÓ*Ó+Ð+ùòm
s   ’-F)rE   rF   rG   rH   r7   r¨   r«   rR   rÃ   r’   r¼   rI   rJ   s   @r,   r{   r{   Ì  s)   ø„ Ù;ôò
.òò
-òò9ö7,r0   r{   c                   óL   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zˆ xZS )
r|   zCRepresents an existing file, that is a member of a VirtualResource.c                 ó°   •— t         j                  j                  |«      st        j	                  d|z  «       t
        ‰| �  ||«       || _        || _        y )Nz"VirtualResFile(%r) does not exist.)	rw   rB   ÚexistsÚ_loggerÚerrorr6   r7   r*   r}   )r8   rB   r9   r*   r}   r:   s        €r,   r7   zVirtualResFile.__init__&  sB   ø€ Ü�w‰w�~‰~˜iÔ(Ü�M‰MÐ>ÀÑJÔKÜ‰Ñ˜˜wÔ'ØˆŒ	Ø"ˆ�r0   c                 óf   — t        j                  | j                  «      }|t        j                     S r<   )rw   Ústatr}   ÚST_SIZE©r8   Ústatresultss     r,   r¨   z!VirtualResFile.get_content_length-  s#   € Ü—g‘g˜dŸn™nÓ-ˆØœ4Ÿ<™<Ñ(Ð(r0   c                 ó”   — t         j                  j                  | j                  «      syt	        j
                  | j                  «      S )Nr¿   )rw   rB   Úisfiler}   r   Úguess_mime_typer=   s    r,   r«   zVirtualResFile.get_content_type1  s0   € Ü�w‰w�~‰~˜dŸn™nÔ-Øô
 ×#Ñ# D§N¡NÓ3Ð3r0   c                 óf   — t        j                  | j                  «      }|t        j                     S r<   )rw   r×   r}   ÚST_CTIMErÙ   s     r,   r­   z VirtualResFile.get_creation_date:  ó#   € Ü—g‘g˜dŸn™nÓ-ˆØœ4Ÿ=™=Ñ)Ð)r0   c                 ó
   — ddiS )NrP   zContent filerQ   r=   s    r,   rR   zVirtualResFile.get_display_info>  s   € Ø˜Ð'Ð'r0   c                 óf   — t        j                  | j                  «      }|t        j                     S r<   )rw   r×   r}   ÚST_MTIMErÙ   s     r,   rµ   z VirtualResFile.get_last_modifiedA  rà   r0   c                 óÒ   — dj                  | j                  d   t        j                  j	                  | j
                  «      «      }t        | j                  j                  |z   «      S rÅ   )	rÆ   r*   rw   rB   rx   r}   r   rŽ   r�   r�   s     r,   r’   zVirtualResFile.get_ref_urlE  sO   € Ø!×(Ñ(Ø�I‰I�eÑœbŸg™g×.Ñ.¨t¯~©~Ó>ó
ˆô �T—]‘]×-Ñ-°Ñ7Ó8Ð8r0   c                 ó8   — t        | j                  dt        «      S )NÚrb)Úopenr}   ÚBUFFER_SIZEr=   s    r,   r¼   zVirtualResFile.get_contentK  s   € ô
 �D—N‘N D¬+Ó6Ð6r0   )rE   rF   rG   rH   r7   r¨   r«   r­   rR   rµ   r’   r¼   rI   rJ   s   @r,   r|   r|   #  s.   ø„ ÙMô#ò)ò4ò*ò(ò*ò9ö7r0   r|   c                   ó(   ‡ — e Zd ZdZˆ fd„Zd„ Zˆ xZS )ÚVirtualResourceProviderzG
    DAV provider that serves a VirtualResource derived structure.
    c                 ó8   •— t         ‰| �  «        t        | _        y r<   )r6   r7   r&   ÚresourceData)r8   r:   s    €r,   r7   z VirtualResourceProvider.__init__[  s   ø€ Ü‰ÑÔÜ)ˆÕr0   c                 ó–   — t         j                  d|z  «       | xj                  dz  c_        t        |«      }|j	                  d|«      S )zðReturn _VirtualResource object for path.

        path is expected to be
            categoryType/category/name/artifact
        for example:
            'by_tag/cool/My doc 2/info.html'

        See DAVProvider.get_resource_inst()
        zget_resource_inst('%s')é   rÊ   )rÔ   ÚinfoÚ_count_get_resource_instr$   Úresolve)r8   rB   r9   Úroots       r,   Úget_resource_instz)VirtualResourceProvider.get_resource_inst_  sB   € ô 	�‰Ð.°Ñ5Ô6Ø×%Ò%¨Ñ*Õ%Ü˜gÓ&ˆØ�|‰|˜B Ó%Ð%r0   )rE   rF   rG   rH   r7   ró   rI   rJ   s   @r,   rê   rê   V  s   ø„ ñô*ö&r0   rê   )(rH   rw   r×   Úior   Úurllib.parser   Úwsgidavr   Úwsgidav.dav_errorr   r   r   r	   Úwsgidav.dav_providerr
   r   r   Úwsgidav.utilr   Ú__docformat__Úget_module_loggerrE   rÔ   rè   ÚFILE_FOLDERrB   r›   Úencoder&   r-   r/   r$   rA   rZ   rY   r¥   r{   r|   rê   rQ   r0   r,   ú<module>rþ      s�  ðñ]ó~ 
Û Ý Ý å ÷ó ÷ NÑ MÝ !à%€à
 ˆ$×
 Ñ
  Ó
*€à€ð
ð #€ð ØØØ˜�ØØHà�G‰G�L‰L˜ lÓ3Ø�G‰G�L‰L˜ lÓ3ð
ñð ØØØ˜Ð ØØ9ØŸ™Ÿ™ [°,Ó?Ð@ñð Ø4×;Ñ;Ó=ØØ�ØØ0ØŸ™Ÿ™ [°,Ó?Ð@ñð-€òD	òô�]ô ô&!V˜]ô !VôH˜ô ô6O�mô OôjÐ,ô ôTQ,Ð+ô Q,ôn-7Ð*ô -7ôf&˜kõ &r0   