o
    ;h/                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dl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 d dlmZ d dlmZ dd	ed
e	jfddZG dd deZdS )    N)contextmanager)Path)sleep)time)	BaseCache)FileSystemSerializer    stringreturnc                 C   s
   t | S )zDon't access ``hashlib.md5`` until runtime. FIPS builds may not include
    md5, in which case the import and use as a default would fail before the
    developer can configure something else.
    )hashlibmd5)r	    r   @/var/www/html/venv/lib/python3.10/site-packages/cachelib/file.py	_lazy_md5   s   
r   c                   @   s  e Zd ZdZdZdZeeZe	 Z
				dAdeded	ed
eje dejf
ddZdefddZedefddZ	dBdeje deje ddfddZdeje defddZdedefddZdejeddf fddZdefdd Zd!eddfd"d#Zdefd$d%ZdCd&d'Zdefd(d)Zd*edefd+d,Z d*edejfd-d.Z!dDd*edejdeje defd/d0Z"		1dEd*edejdeje d2edef
d3d4Z#dFd*ed2edefd5d6Z$d*edefd7d8Z%d9ej&d:ejd;ejdejfd<d=Z'e(d>ed
edejfd?d@Z)dS )GFileSystemCachea1  A cache that stores the items on the file system.  This cache depends
    on being the only user of the `cache_dir`.  Make absolutely sure that
    nobody but this cache stores files there or otherwise the cache will
    randomly delete files therein.

    :param cache_dir: the directory where cache files are stored.
    :param threshold: the maximum number of items the cache stores before
                      it starts deleting some. A threshold value of 0
                      indicates no threshold.
    :param default_timeout: the default timeout that is used if no timeout is
                            specified on :meth:`~BaseCache.set`. A timeout of
                            0 indicates that the cache never expires.
    :param mode: the file mode wanted for the cache files, default 0600
    :param hash_method: Default hashlib.md5. The hash method used to
                        generate the filename for cached results.
                        Default is lazy loaded and can be overriden by
                        seeting  `_default_hash_method`
    z.__wz_cacheZ__wz_cache_count  ,  N	cache_dir	thresholddefault_timeoutmodehash_methodc              
   C   s   t | | || _|| _| j| _|d ur|| _|| _| jd u r$|  | _zt	| j W n t
yE } z|jtjkr; W Y d }~nd }~ww | jdkrY| jtt|  d d S d S )Nr   value)r   __init___path
_threshold_default_hash_method_hash_method_mode_get_compatible_platform_modeosmakedirsOSErrorerrnoEEXIST_update_countlenlist	_list_dir)selfr   r   r   r   r   exr   r   r   r   8   s(   


zFileSystemCache.__init__r
   c                 C   s   d}t  dkrtj}|S )Ni  Windows)platformsystemstatS_IWRITE)r*   r   r   r   r   r    Z   s   z-FileSystemCache._get_compatible_platform_modec                 C   s   |  | jpdS Nr   )get_fs_count_filer*   r   r   r   _file_count`   s   zFileSystemCache._file_countdeltar   c                 C   s<   | j dkrd S |r| j| }n|pd}| j| j|dd d S )Nr   T)mgmt_element)r   r5   setr3   )r*   r6   r   Z	new_countr   r   r   r&   d   s   
zFileSystemCache._update_counttimeoutc                 C   s*   t | |}|dkrtt | }t|S r1   )r   _normalize_timeoutintr   )r*   r9   r   r   r   r:   p   s   z"FileSystemCache._normalize_timeoutnamec                 C   s,   |  | jtjd }||kp|| jS )N)_get_filenamer3   splitr!   sependswith_fs_transaction_suffix)r*   r<   Zfshashr   r   r   _is_mgmtv   s   zFileSystemCache._is_mgmtc                    s    fddt  jD S )z2return a list of (fully qualified) cache filenamesc                 3   s*    | ]}  |stj j|V  qd S N)rC   r!   pathjoinr   ).0fnr4   r   r   	<genexpr>|   s    
z,FileSystemCache._list_dir.<locals>.<genexpr>)r!   listdirr   r4   r   r4   r   r)   z   s   

zFileSystemCache._list_dirc                 C   s   | j dko
| j| j kS r1   )r   r5   r4   r   r   r   _over_threshold   s   zFileSystemCache._over_thresholdnowc                 C   s   |   D ]U}z6| |d}td|dd }W d    n1 s#w   Y  |dkr;||k r;t| | jdd W q tyE   Y q t	t
tjfyY   tjd|dd	 Y qw d S )
NrbI   r   r=   r6   /Exception raised while handling cache file '%s'Texc_info)r)   _safe_stream_openstructunpackreadr!   remover&   FileNotFoundErrorr#   EOFErrorerrorloggingwarning)r*   rL   fnamefexpiresr   r   r   _remove_expired   s&   

zFileSystemCache._remove_expiredc                 C   s(  g }|   D ]I}z*| |d}td|dd }|||f W d    n1 s,w   Y  W q ty;   Y q tttj	fyO   t
jd|dd Y qw dd	 t|d
d dD }|D ]2}zt| | jdd W n tyw   Y n ty   t
jd|dd Y  dS w |  s dS q_dS )NrM   rN   rO   r   rQ   TrR   c                 s   s    | ]\}}|V  qd S rD   r   )rG   _r^   r   r   r   rI      s    
z0FileSystemCache._remove_older.<locals>.<genexpr>c                 S   s   | d S r1   r   )itemr   r   r   <lambda>   s    z/FileSystemCache._remove_older.<locals>.<lambda>)keyr=   rP   F)r)   rT   rU   rV   rW   appendrY   r#   rZ   r[   r\   r]   sortedr!   rX   r&   rK   )r*   Zexp_fname_tuplesr^   r_   	timestampZfname_sortedr   r   r   _remove_older   sN   

zFileSystemCache._remove_olderc                 C   s0   |   rt }| | |   r|   d S d S rD   )rK   r   ra   ri   )r*   rL   r   r   r   _prune   s   
zFileSystemCache._prunec              	   C   sx   t |  D ]-\}}zt| W q ty   Y q ty3   tjd|dd | j| d Y  dS w | jdd dS )NrQ   TrR   rP   Fr   r   )		enumerater)   r!   rX   rY   r#   r\   r]   r&   )r*   ir^   r   r   r   clear   s    zFileSystemCache.clearre   c                 C   sF   t |tr|d}| | }n	tdt| tj	| j
|S )Nzutf-8z$Key must be a string, received type )
isinstancestrencoder   	hexdigest	TypeErrortyper!   rE   rF   r   )r*   re   ZbkeyZ	bkey_hashr   r   r   r>      s
   

zFileSystemCache._get_filenamec              
   C   s   |  |}z=| |d,}td|dd }|dks!|t kr/| j|W  d    W S W d    W d S 1 s;w   Y  W d S  tyL   Y d S  t	t
tjfya   tjd|dd Y d S w )NrM   rN   rO   r   rQ   TrR   )r>   rT   rU   rV   rW   r   
serializerloadrY   r#   rZ   r[   r\   r]   r*   re   filenamer_   Zpickle_timer   r   r   r2      s.   

zFileSystemCache.getc                 C   s(   |  |}tj|s| |||S dS NF)r>   r!   rE   existsr8   )r*   re   r   r9   rw   r   r   r   add   s   
zFileSystemCache.addFr7   c                 C   s
  |rd}n|    | |}| |}tj|}zKtj| j| j	d\}}t
|d}	|	td| | j||	 W d    n1 sFw   Y  | tj|| | tj|| j t| j}
W n tyv   tjd|dd Y dS w |s|s| jd	d
 |
dkS )Nr   )suffixdirwbrN   rQ   TrR   F   rP   )rj   r:   r>   r!   rE   isfiletempfilemkstemprB   r   fdopenwriterU   packrt   dump_run_safelyreplacechmodr   r   r/   st_sizer#   r\   r]   r&   )r*   re   r   r9   r7   rw   	overwritefdtmpr_   fsizer   r   r   r8      s8   


	zFileSystemCache.setc                 C   s^   z
t | | W n ty   Y dS  ty$   tjddd Y dS w |s-| jdd dS )NTz*Exception raised while handling cache filerR   Fr=   rP   )r!   rX   r>   rY   r#   r\   r]   r&   )r*   re   r7   r   r   r   delete  s   zFileSystemCache.deletec              
   C   s   |  |}z:| |d)}td|dd }|dks!|t kr+	 W d    W dS 	 W d    W dS 1 s8w   Y  W d S  tyI   Y dS  tttj	fy^   t
jd|dd Y dS w )	NrM   rN   rO   r   TFrQ   rR   )r>   rT   rU   rV   rW   r   rY   r#   rZ   r[   r\   r]   rv   r   r   r   has*  s&   
(zFileSystemCache.hasrH   argskwargsc                 O   s   t  dkr9d}d}d}d}||k r7z||i |}W 	 |S  ty2   t| ||7 }|d9 }Y nw ||k s|S ||i |}|S )ztOn Windows os.replace, os.chmod and open can yield
        permission errors if executed by two different processes.r,   NgMbP?g      $@g           )r-   r.   PermissionErrorr   )r*   rH   r   r   outputZ	wait_stepZmax_sleep_timeZtotal_sleep_timer   r   r   r   =  s&   zFileSystemCache._run_safelyrE   c                 c   s<    |  t||}|d u rtz
|V  W |  d S |  w rD   )r   openr#   close)r*   rE   r   fsr   r   r   rT   T  s   z!FileSystemCache._safe_stream_open)r   r   NN)NN)r
   NrD   rx   )F)*__name__
__module____qualname____doc__rB   r3   staticmethodr   r   r   rt   ro   r;   _tOptionalAnyr   r    propertyr5   r&   r:   boolrC   	Generatorr)   rK   floatra   ri   rj   rm   r>   r2   rz   r8   r   r   Callabler   r   rT   r   r   r   r   r      sz    
"

#$

+"r   )r   )r$   r   r\   r!   r-   r/   rU   r   typingr   
contextlibr   pathlibr   r   r   Zcachelib.baser   Zcachelib.serializersr   bytesr   r   r   r   r   r   r   <module>   s"    