a
    lc&                     @   s(  d Z ddlmZ dZzddlmZ W n eyB   ddlmZ Y n0 ddlZddl	Z	ddl
Z
zddlmZ W n ey   ddlZY n0 zddlZW n ey   ddlZY n0 ddlZddlZejd dkrefZneefZdd Ze ZG d	d
 d
ejZG dd dZdd Zedkr$e  dS )a   PickleShare - a small 'shelve' like datastore with concurrency support

Like shelve, a PickleShareDB object acts like a normal dictionary. Unlike
shelve, many processes can access the database simultaneously. Changing a
value in database is immediately visible to other processes accessing the
same database.

Concurrency is possible because the values are stored in separate files. Hence
the "database" is a directory where *all* files are governed by PickleShare.

Example usage::

    from pickleshare import *
    db = PickleShareDB('~/testpickleshare')
    db.clear()
    print "Should be empty:",db.items()
    db['hello'] = 15
    db['aku ankka'] = [1,2,313]
    db['paths/are/ok/key'] = [1,(5,46)]
    print db.keys()
    del db['aku ankka']

This module is certainly not ZODB, but can be used for low-load
(non-mission-critical) situations where tiny code size trumps the
advanced features of a "real" object database.

Installation guide: pip install pickleshare

Author: Ville Vainio <vivainio@gmail.com>
License: MIT open source license.

    )print_functionz0.7.5)PathN   c                 C   s   dt t| d  dd  S )Nz%02x   )abshash)key r
   G/var/www/html/django/DPS/env/lib/python3.9/site-packages/pickleshare.pygethashfile@   s    r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zed
fddZ	dd Z
dd Zdd Zdd Zd%ddZdd Zdd Zdd Zd&dd Zd!d" Zd#d$ ZdS )'PickleShareDBz7 The main 'connection' object for PickleShare database c              
   C   s   t |tst|}tjtj|}t|| _| j	 sz| jj
dd W n2 ty~ } z|jtjkrj W Y d}~n
d}~0 0 i | _dS )z: Return a db object that will manage the specied directoryTparentsN)
isinstancestring_typesstrospathabspath
expanduserr   rootis_dirmkdirOSErrorerrnoEEXISTcache)selfr   er
   r
   r   __init__G   s    


zPickleShareDB.__init__c                 C   s   | j | }z| tj }W n ty6   t|Y n0 || jv rb|| j| d krb| j| d S z<|d}t|	 }W d   n1 s0    Y  W n   t|Y n0 ||f| j|< |S )z db['key'] reading    r   rbN)
r   statST_MTIMEr   KeyErrorr   openpickleloadsread)r   r	   filmtimefobjr
   r
   r   __getitem__Y   s    
0zPickleShareDB.__getitem__c              
   C   s   | j | }|j}|r(| s(|jdd |d }tj||dd W d   n1 sX0    Y  z|| jf| j	|< W n2 t
y } z|jtjkr W Y d}~n
d}~0 0 dS )z db['key'] = 5 Tr   wb   )protocolN)r   parentr   r   r&   r'   dumpr#   st_mtimer   r   r   ENOENT)r   r	   valuer*   r2   r,   r   r
   r
   r   __setitem__m   s    
.zPickleShareDB.__setitem__c                 C   sL   | j | }| s|  |t| }| |i }|||i || |< dS )z hashed set N)r   r   r   r   getupdate)r   hashrootr	   r6   hroothfiledr
   r
   r   hset}   s    
zPickleShareDB.hsetTc                 C   sX   | j | }|t| }| |t}|tu rL|rB|tu r>t||S | |}|||S )z hashed get )r   r   r8   	_sentinelr%   hdict)r   r:   r	   defaultZ	fast_onlyr;   r<   r=   r
   r
   r   hget   s    

zPickleShareDB.hgetc              	   C   s   |  |d }|  t|r&|d p(d}|drF|g|dd  }i }|D ]F}z|| |  W n$ ty   td|d | |= Y n0 | | qN|S )z> Get all data contained in hashed category 'hashroot' as dict /* xxNZCorruptz!deleted - hset is not threadsafe!)keyssortlenendswithr9   r%   printuncache)r   r:   hfileslastallr,   r
   r
   r   r@      s    
zPickleShareDB.hdictc                 C   sl   |  |d }i }|D ]}|| |  | | q|| |d < |D ]"}| j| }|jdkr^qD|  qDdS )z Compress category 'hashroot', so hset is fast again

        hget will fail if fast_only is True for compressed items (that were
        hset before hcompress).

        rC   z/xxrF   N)rG   r9   rL   r   nameunlink)r   r:   rM   rO   r,   pr
   r
   r   	hcompress   s    

zPickleShareDB.hcompressc                 C   s<   | j | }| j|d z|  W n ty6   Y n0 dS )z del db["key"] N)r   r   poprQ   r   )r   r	   r*   r
   r
   r   __delitem__   s    
zPickleShareDB.__delitem__c                 C   s   t || jddS )z% Make a key suitable for user's eyes \/)r   relative_tor   replace)r   rR   r
   r
   r   _normalized   s    zPickleShareDB._normalizedNc                    s4   |du r j d}n j |} fdd|D S )z, All keys in DB, or all keys matching a globN*c                    s   g | ]}|  r |qS r
   )is_filerZ   ).0rR   r   r
   r   
<listcomp>       z&PickleShareDB.keys.<locals>.<listcomp>)r   rglobglob)r   Zglobpatfilesr
   r^   r   rG      s    zPickleShareDB.keysc                 C   s   t |  S N)iterrG   r^   r
   r
   r   __iter__   s    zPickleShareDB.__iter__c                 C   s   t |  S rd   )rI   rG   r^   r
   r
   r   __len__   s    zPickleShareDB.__len__c                 G   s&   |s
i | _ |D ]}| j |d qdS )z Removes all, or specified items from cache

        Use this after reading a large amount of large objects
        to free up memory, when you won't be needing the objects
        for a while.

        N)r   rT   )r   itemsitr
   r
   r   rL      s    zPickleShareDB.uncache<   c                 C   s   dgd dgd  dg }d}d}z| | }|W S  t yB   Y n0 ||krTt |t||  ||| 7 }|t|d k r"|d7 }q"dS )a   Wait (poll) for a key to get a value

        Will wait for `maxwaittime` seconds before raising a KeyError.
        The call exits normally if the `key` field in db gets a value
        within the timeout period.

        Use this for synchronizing different processes or for ensuring
        that an unfortunately timed "db['key'] = newvalue" operation
        in another process (which causes all 'get' operation to cause a
        KeyError for the duration of pickling) won't screw up your program
        logic.
        g?r   g      ?r0   r!   r   N)r%   timesleeprI   )r   r	   ZmaxwaittimeZwtimestriesZwaitedvalr
   r
   r   waitget   s    zPickleShareDB.waitgetc                 C   s
   t | |S )z, Get a convenient link for accessing items  )PickleShareLink)r   folderr
   r
   r   getlink  s    zPickleShareDB.getlinkc                 C   s
   d| j  S )NzPickleShareDB('%s'))r   r^   r
   r
   r   __repr__  s    zPickleShareDB.__repr__)N)rj   )__name__
__module____qualname____doc__r    r.   r7   r>   r?   rB   r@   rS   rU   rZ   rG   rf   rg   rL   ro   rr   rs   r
   r
   r
   r   r   E   s"   
	
 r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )rp   z A shortdand for accessing nested PickleShare data conveniently.

    Created through PickleShareDB.getlink(), example::

        lnk = db.getlink('myobjects/test')
        lnk.foo = 2
        lnk.bar = lnk.foo + 5

    c                 C   s   | j t  d S rd   )__dict__r9   locals)r   dbkeydirr
   r
   r   r    (  s    zPickleShareLink.__init__c                 C   s   | j d | j d d |  S )Nrz   r{   rW   )rx   )r   r	   r
   r
   r   __getattr__+  s    zPickleShareLink.__getattr__c                 C   s   || j | jd | < d S )NrW   )rz   r{   )r   r	   rn   r
   r
   r   __setattr__-  s    zPickleShareLink.__setattr__c                 C   s@   | j d }|| j d d }d| j d ddd |D f S )Nrz   r{   rC   z<PickleShareLink '%s': %s>;c                 S   s   g | ]}t | qS r
   )r   basename)r]   kr
   r
   r   r_   4  r`   z,PickleShareLink.__repr__.<locals>.<listcomp>)rx   rG   join)r   rz   rG   r
   r
   r   rs   /  s    
zPickleShareLink.__repr__N)rt   ru   rv   rw   r    r|   r}   rs   r
   r
   r
   r   rp     s
   	rp   c                  C   s  dd l } | d}t}dd l}t|jdk r8t| d S |jd }|jdd  }|dkr|sbdg}||d }dd l}||  n|dkr|j	
 }||d }t|}	|  | D ]\}
}|||
< qnB|dkr||d }|  t|d	 n|d
krt  t  d S )Nr   z    pickleshare - manage PickleShare databases

    Usage:

        pickleshare dump /path/to/db > dump.txt
        pickleshare load /path/to/db < dump.txt
        pickleshare test /path/to/db
    r0   r!   r3   .loadZtestwaitZ250test)textwrapdedentr   sysrI   argvrK   pprintrh   stdinr)   evalclearro   r   Zstress)r   usageZDBr   cmdargsrz   r   contdatar   vr
   r
   r   main6  s8    
	



r   __main__)rw   
__future__r   __version__pathlibr   ImportErrorZpathlib2r   r#   rk   collections.abcabccollections_abccollectionscPickler'   r   r   version_infor   r   unicoder   objectr?   MutableMappingr   rp   r   rt   r
   r
   r
   r   <module>   s8   ! Z'
