U
    9%e!                     @  s   U d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ zd dl	Z
W n  ek
rj   esfd dl
Z
Y nX erd dlmZmZmZmZ d dlmZ ddlmZ eeef Zd	ed
< G dd dZdS )    )annotationsN)TYPE_CHECKING)atomic_write)AnyDictIteratorLiteral)	TypeAlias   )CachingFileSystemr	   Detailc                   @  s   e Zd ZdZddddZdddd	d
ZddddddZd0dddddZddddddZdddddZ	ddd d!Z
d"ddd#d$d%Zdd&d'd(d)Zddd*d+Zdddd,d-d.Zd/S )1CacheMetadataa\  Cache metadata.

    All reading and writing of cache metadata is performed by this class,
    accessing the cached files and blocks is not.

    Metadata is stored in a single file per storage directory in JSON format.
    For backward compatibility, also reads metadata stored in pickle format
    which is converted to JSON when next saved.
    z	list[str])storagec                 C  s$   |st d|| _i g| _d| _dS )z

        Parameters
        ----------
        storage: list[str]
            Directories containing cached files, must be at least one. Metadata
            is stored in the last of these directories by convention.
        z3CacheMetadata expects at least one storage locationFN)
ValueError_storagecached_files_force_save_pickle)selfr    r   d/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/fsspec/implementations/cache_metadata.py__init__%   s
    	zCacheMetadata.__init__strr   )fnreturnc                 C  st   z.t |d}t|W  5 Q R  W S Q R X W n@ tk
rn   t |d}t|W  5 Q R   Y S Q R X Y nX dS )z6Low-level function to load metadata from specific filerrbN)openjsonloadr   pickle)r   r   fr   r   r   _load8   s    "zCacheMetadata._loadNone)metadata_to_saver   r   c              	   C  sP   | j r(t|}t|| W 5 Q R X n$t|dd}t|| W 5 Q R X dS )z4Low-level function to save metadata to specific filew)modeN)r   r   r   dumpr   )r   r#   r   r    r   r   r   _saveA   s
    
zCacheMetadata._saveFboolzIterator[tuple[str, str, bool]])writable_onlyr   c                 c  sN   t | j}t| jD ]4\}}||d k}|r2|s2qtj|d||fV  qdS )a  Yield locations (filenames) where metadata is stored, and whether
        writable or not.

        Parameters
        ----------
        writable: bool
            Set to True to only yield writable locations.

        Returns
        -------
        Yields (str, str, bool)
        r
   cacheN)lenr   	enumerateospathjoin)r   r)   nir   writabler   r   r   _scan_locationsJ   s    
zCacheMetadata._scan_locationszCachingFileSystem | Nonez#Literal[False] | tuple[Detail, str])r.   cfsr   c                 C  s   t |  | jD ]\\}}}}||kr(q||  }|dk	rv|jrX|d |j|krXq|jrvt |d  |jkrvqt	j
||d }t	j
|r||f  S qdS )zIf path is in cache return its details, otherwise return ``False``.

        If the optional CachingFileSystem is specified then it is used to
        perform extra checks to reject possible matches, such as if they are
        too old.
        Nuidtimer   F)zipr3   r   copyZcheck_filesfsZukeyZexpiryr6   r-   r.   r/   exists)r   r.   r4   r   base_r*   detailr   r   r   
check_file`   s    	zCacheMetadata.check_fileintztuple[list[str], bool])expiry_timer   c                 C  s   g }| j d   D ]h\}}t |d  |kr|dd}|sPtd| tj| j	d |}|
| | j d | q| j d rtj| j	d d}| | j d | | j d  }||fS )zRemove expired metadata from the cache.

        Returns names of files corresponding to expired metadata and a boolean
        flag indicating whether the writable cache is empty. Caller is
        responsible for deleting the expired files.
        r6   r    z)Cache metadata does not contain 'fn' for r*   )r   r8   itemsr6   getRuntimeErrorr-   r.   r/   r   appendpopr'   )r   r@   Zexpired_filesr.   r=   r   
cache_pathZwritable_cache_emptyr   r   r   clear_expired{   s     

zCacheMetadata.clear_expired)r   c                 C  s   g }|   D ]b\}}}tj|rd| |}| D ]"}t|d tr4t|d |d< q4|	| q|	i  q|pxi g| _
dS )z>Load all metadata from disk and store in ``self.cached_files``blocksN)r3   r-   r.   r:   r!   values
isinstancelistsetrF   r   )r   r   r   r<   Zloaded_cached_filescr   r   r   r      s    
zCacheMetadata.loadr   )r    r.   r   c                 C  s>   | j d | }|d dk	r:t|d |j |jkr:d|d< dS )zPerform side-effect actions on closing a cached file.

        The actual closing of the file is the responsibility of the caller.
        rA   rJ   TN)r   r+   	blocksizesize)r   r    r.   rO   r   r   r   on_close_cached_file   s    $z"CacheMetadata.on_close_cached_filez
str | None)r.   r   c                 C  sR   |  |d}|sdS |\}}|| jd rF| jd | |   ntd|S )zRemove metadata of cached file.

        If path is in the cache, return the filename of the cached file,
        otherwise return ``None``.  Caller is responsible for deleting the
        cached file.
        NrA   z<Can only delete cached file in last, writable cache location)r>   
startswithr   r   rG   savePermissionError)r   r.   detailsr<   r   r   r   r   pop_file   s    
zCacheMetadata.pop_filec           	      C  sN  t |  | jD ]6\\}}}}|s&qtj|r| |}| D ]\}}||krD|d dksp|| d dkrzd|d< n"|| d }||d  ||d< t	|d || d |d< || d |d< qD| D ]\}}||kr|||< qn|}dd | D }|
 D ]&}t|d tr
t|d |d< q
| || || jd< qdS )	zSave metadata to diskrJ   Tr6   r5   c                 S  s   i | ]\}}||  qS r   )r8   ).0kvr   r   r   
<dictcomp>   s      z&CacheMetadata.save.<locals>.<dictcomp>rA   N)r7   r3   r   r-   r.   r:   r!   rC   updatemaxrK   rL   rN   rM   r'   )	r   r   r<   r2   r*   r   rY   rO   rJ   r   r   r   rT      s0     

zCacheMetadata.save)r.   r=   r   c                 C  s   || j d |< dS )z8Update metadata for specific file in memory, do not saverA   N)r   )r   r.   r=   r   r   r   update_file   s    zCacheMetadata.update_fileN)F)__name__
__module____qualname____doc__r   r!   r'   r3   r>   rI   r   rR   rW   rT   r^   r   r   r   r   r      s   
	
 
$r   )
__future__r   r-   r   r6   typingr   Zfsspec.utilsr   Zujsonr   ImportErrorr   r   r   r   Ztyping_extensionsr	   cachedr   r   r   __annotations__r   r   r   r   r   <module>   s"    