
    qi5                         S r SSKrSSKrSSKrSSKJr  SSKJrJrJ	r	J
r
  SSKJr  Sr\R                  " S5      r " S S	5      r " S
 S\5      rg)au  
Implements two storage providers for `LockManager`.

Two alternative lock storage classes are defined here: one in-memory
(dict-based), and one persistent low performance variant using shelve.

See :class:`~wsgidav.lock_man.lock_manager.LockManager`
See :class:`~wsgidav.lock_man.lock_storage.LockStorageDict`
See :class:`~wsgidav.lock_man.lock_storage.LockStorageShelve`
    N)util)generate_lock_tokenlock_stringnormalize_lock_rootvalidate_lock)ReadWriteLockreStructuredTextzwsgidav.lock_manc                   h    \ rS rSrSrSrSrS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rSrg)LockStorageDict1   a  
An in-memory lock manager storage implementation using a dictionary.

R/W access is guarded by a thread.lock object.

Also, to make it work with a Shelve dictionary, modifying dictionary
members is done by re-assignment and we call a _flush() method.

This is obviously not persistent, but should be enough in some cases.
For a persistent implementation, see lock_storage.LockStorageShelve().

Notes:
    expire is stored as expiration date in seconds since epoch (not in
    seconds until expiration).

The dictionary is built like::

    { 'URL2TOKEN:/temp/litmus/lockme': ['opaquelocktoken:0x1d7b86...',
                                        'opaquelocktoken:0xd7d4c0...'],
      'opaquelocktoken:0x1d7b86...': {
        'depth': '0',
        'owner': "<?xml version='1.0' encoding='UTF-8'?>\n<owner xmlns="DAV:">"
            + "litmus test suite</owner>\n",
        'principal': 'tester',
        'root': '/temp/litmus/lockme',
        'scope': 'shared',
        'expire': 1261328382.4530001,
        'token': 'opaquelocktoken:0x1d7b86...',
        'type': 'write',
        },
      'opaquelocktoken:0xd7d4c0...': {
        'depth': '0',
        'owner': '<?xml version='1.0' encoding='UTF-8'?>\n<owner xmlns="DAV:">'
            + 'litmus: notowner_sharedlock</owner>\n',
        'principal': 'tester',
        'root': '/temp/litmus/lockme',
        'scope': 'shared',
        'expire': 1261328381.6040001,
        'token': 'opaquelocktoken:0xd7d4c0...',
        'type': 'write'
       },
     }
i:	 i $ c                 0    S U l         [        5       U l        g N)_dictr   _lockselfs    R/home/kali/flask_env/lib/python3.13/site-packages/wsgidav/lock_man/lock_storage.py__init__LockStorageDict.__init__a   s    
"_
    c                 .    U R                   R                  $ r   )	__class____name__r   s    r   __repr__LockStorageDict.__repr__e   s    ~~&&&r   c                     g)z$Overloaded by Shelve implementation.N r   s    r   _flushLockStorageDict._flushk       r   c                 0    U R                   b   e0 U l         g)zFCalled before first use.

May be implemented to initialize a storage.
Nr   r   s    r   openLockStorageDict.openo   s    
 zz!!!
r   c                     SU l         g)zCalled on shutdown.Nr"   r   s    r   closeLockStorageDict.closew   s	    
r   c                     g)zPurge expired locks (optional).Nr   r   s    r   cleanupLockStorageDict.cleanup{   r    r   c                 T    U R                   b  U R                   R                  5         ggzDelete all entries.N)r   clearr   s    r   r-   LockStorageDict.clear   s!    ::!JJ "r   c                 p   U R                   R                  5          U R                  R                  U5      nUcE  [        R                  SU 35        U R                  U5         U R                   R                  5         g[        US   5      nUS:  aj  U[        R                  " 5       :  aQ  [        R                  SU S[        U5       35        U R                  U5         U R                   R                  5         gUU R                   R                  5         $ ! U R                   R                  5         f = f)zReturn a lock dictionary for a token.

If the lock does not exist or is expired, None is returned.

token:
    lock token
Returns:
    Lock dictionary or <None>

Side effect: if lock is expired, it will be purged and None is returned.
NzLock purged dangling: expirer   zLock timed-out(): )r   acquire_readr   get_loggerdebugdeletereleasefloattimer   )r   tokenlockr0   s       r   r3   LockStorageDict.get   s     	

!	!::>>%(D| 6ug>?E" JJ  4>*F{v		3xs;t;L:MNOE" JJ  JJ DJJ s   AD ?A"D =D D5c                    U R                   R                  5          UR                  S5      b   eUR                  S5      b   S5       eU(       a  SU;   d   eUn[        U5      nXS'   [	        UR                  S5      5      nUc  [
        R                  nO*US:  d  U[
        R                  :  a  [
        R                  nXBS'   [        R                  " 5       U-   US'   [        U5        [        5       nXRS'   X R                  U'   SU 3nX`R                  ;  a  U/U R                  U'   O.U R                  U   nUR                  U5        XpR                  U'   U R                  5         [        R                  S	U< S
[!        U5       35        UU R                   R#                  5         $ ! U R                   R#                  5         f = f)a  Create a direct lock for a resource path.

path:
    Normalized path (utf8 encoded string, no trailing '/')
lock:
    lock dictionary, without a token entry
Returns:
    New unique lock token.: <lock

**Note:** the lock dictionary may be modified on return:

- lock['root'] is ignored and set to the normalized <path>
- lock['timeout'] may be normalized and shorter than requested
- lock['token'] is added
r:   r0   zUse timeout instead of expire/roottimeoutr   
URL2TOKEN:zLockStorageDict.set(r1   )r   acquire_writer3   r   r8   r   LOCK_TIME_OUT_DEFAULTLOCK_TIME_OUT_MAXr9   r   r   r   appendr   r4   r5   r   r7   )r   pathr;   org_pathr@   r:   keytokLists           r   createLockStorageDict.create   s     	

  "+	!88G$,,,88H%-N/NN-C4K'' H&t,DL DHHY/0G)??1/*K*K K);;%O!YY[72DN$')E!M !%JJu tf%C**$#('

3 **S/u%")

3KKMMM0CD@Q?RSTJJ DJJ s   E4F+ +Gc                   XR                   ;   d   S5       eUS:X  d  US:  d   eUS:  d  U[        R                  :  a  [        R                  nU R                  R	                  5          U R                   U   nX#S'   [
        R
                  " 5       U-   US'   X0R                   U'   U R                  5         U R                  R                  5         U$ ! U R                  R                  5         f = f)a  Modify an existing lock's timeout.

token:
    Valid lock token.
timeout:
    Suggested lifetime in seconds (-1 for infinite).
    The real expiration time may be shorter than requested!
Returns:
    Lock dictionary.
    Raises ValueError, if token is invalid.
zLock must existr   r@   r0   )r   r   rD   r   rB   r9   r   r7   )r   r:   r@   r;   s       r   refreshLockStorageDict.refresh   s     

"5$55""}!++Q;'O$E$EE%77G

  "		! ::e$D%O!YY[72DN $JJuKKMJJ  JJ s   *AC C.c                    U R                   R                  5          U R                  R                  U5      n[        R                  S[        U5       35        Uc   U R                   R                  5         gSR                  UR                  S5      5      nX0R                  ;   aK  U R                  U   n[        U5      S:  a   UR                  U5        X@R                  U'   OU R                  U	 U R                  U	 U R                  5         U R                   R                  5         g! U R                   R                  5         f = f)zVDelete lock.

Returns True on success. False, if token does not exist, or is expired.
zdelete FzURL2TOKEN:{}r?      T)r   rB   r   r3   r4   r5   r   r7   formatlenremover   )r   r:   r;   rH   rI   s        r   r6   LockStorageDict.delete   s    
 	

  "	!::>>%(DMMGK$5#678|$ JJ ! !''(89Cjj **S/w<!# NN5)&-JJsO

3

5!KKMJJ  JJ s   ?D) 7BD) )Ec                t  ^ ^^
 [         R                  " U5      (       d   eU(       a  UR                  S5      (       d   eU(       d	  U(       d   eU
U U4S jn[        U5      nT R                  R                  5          SU 3nT R                  R                  U/ 5      n/ m
U(       a  U" U5        U(       aH  T R                  R                  5        H*  u  p[         R                  " Xh5      (       d  M"  U" U	5        M,     T
T R                  R                  5         $ ! T R                  R                  5         f = f)a  Return a list of direct locks for <path>.

Expired locks are *not* returned (but may be purged).

path:
    Normalized path (utf8 encoded string, no trailing '/')
include_root:
    False: don't add <path> lock (only makes sense, when include_children
    is True).
include_children:
    True: Also check all sub-paths for existing locks.
token_only:
    True: only a list of token is returned. This may be implemented
    more efficiently by some providers.
Returns:
    List of valid lock dictionaries (may be empty).
r>   c                    > U  HK  nTR                  U5      nU(       d  M  T(       a  TR                  US   5        M:  TR                  U5        MM     g )Nr:   )r3   rE   )toklistr:   r;   lockListr   
token_onlys      r   __appendLocks4LockStorageDict.get_lock_list.<locals>.__appendLocks2  s@     !xx4! W6 - !r   rA   )r   is_str
startswithr   r   r2   r   r3   itemsis_child_urir7   )r   rF   include_rootinclude_childrenrZ   _LockStorageDict__appendLocksrH   rI   ultoksrY   s   `   `     @r   get_lock_listLockStorageDict.get_lock_list  s    $ {{4    ,,,,///		. #4(

!	!tf%CjjnnS"-GHg& $

 0 0 2HA((00%e, !3 JJ DJJ s   >A1D 3D D7)r   r   N)r   
__module____qualname____firstlineno____doc__rC   rD   r   r   r   r#   r&   r)   r-   r3   rJ   rN   r6   rf   __static_attributes__r   r   r   r   r   1   sS    *X #"%'
!:<!|<>1!r   r   c                   J   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	rU =r$ )
LockStorageShelveiU  z=
A low performance lock manager implementation using shelve.
c                 j   > [         TU ]  5         [        R                  R	                  U5      U l        g r   )superr   osrF   abspath_storage_path)r   storage_pathr   s     r   r   LockStorageShelve.__init__Z  s#    WW__\:r   c                 $    SU R                   < S3$ )NzLockStorageShelve())rs   r   s    r   r   LockStorageShelve.__repr__^  s    #D$6$6#9;;r   c                 
   [         R                  S5        U R                  R                  5          U R                  R                  5         U R                  R                  5         g! U R                  R                  5         f = f)z$Write persistent dictionary to disc.z_flush()N)r4   r5   r   rB   r   syncr7   r   s    r   r   LockStorageShelve._flusha  sR    j!

  "	!JJOOJJ DJJ s   A& &Bc                    U R                   R                  5          U R                  SL nU(       a  U R                  5         [	        U R                  5      (       a4  U R                  R                  5         U R                  R                  5         U(       a  U R                  5         U R                   R                  5         g! U R                   R                  5         f = fr,   )	r   rB   r   r#   rS   r-   rz   r&   r7   )r   
was_closeds     r   r-   LockStorageShelve.clearj  s    

  "
	!t+J		4::

  "

!

JJ DJJ s   B
C Cc                     [         R                  SU R                  < S35        [        R                  " U R                  SS9U l        g )Nzopen(rw   F)	writeback)r4   r5   rs   shelver#   r   r   s    r   r#   LockStorageShelve.openy  s8    d003156 [[!3!3uE
r   c                 2   [         R                  S5        U R                  R                  5          U R                  b!  U R                  R                  5         S U l        U R                  R                  5         g ! U R                  R                  5         f = f)Nzclose())r4   r5   r   rB   r   r&   r7   r   s    r   r&   LockStorageShelve.close  se    i 

  "	!zz%

  "!
JJ DJJ s   .A: :B)r   rs   )r   rh   ri   rj   rk   r   r   r   r-   r#   r&   rl   __classcell__)r   s   @r   rn   rn   U  s,    ;<!!F! !r   rn   )rk   rq   r   r9   wsgidavr   wsgidav.lock_man.lock_managerr   r   r   r   wsgidav.rw_lockr   __docformat__get_module_loggerr4   r   rn   r   r   r   <module>r      sX   
	 
     *" 
 
 !3
4$\! \!H	6! 6!r   