o
    )j7                     @   s   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mZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZ e Zeed  dkZ	 G d	d
 d
eZG dd deZdS )    N)movermtree)Dict)	FILE_HASH)MODELSCOPE_ENABLE_DEFAULT_HASH_VALIDATION)compute_hash)
get_loggerFalsetruec                   @   s|   e Zd ZdZdZdZdZ	 defddZdd	 Z	d
d Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )FileSystemCachez.mscz.mdlidz.mvcache_root_locationc                 K   s*   t  | _tj|dd || _|   dS )zBase file system cache interface.

        Args:
            cache_root_location (str): The root location to store files.
            kwargs(dict): The keyword arguments.
        Texist_okN)	threadingRLock_cache_lockosmakedirsr   
load_cache)selfr   kwargs r   ]/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/hub/utils/caching.py__init__    s   
zFileSystemCache.__init__c                 C   s   | j S N)r   r   r   r   r   get_root_location1   s   z!FileSystemCache.get_root_locationc                 C   s   g | _ tj| jtj}tj|rzz2t|d}t	
|}W d    n1 s(w   Y  t|tr8|| _ W d S td|t|j W d S  tyy } z)td|| z
t||d  W n	 tyf   Y nw W Y d }~d S W Y d }~d S d }~ww d S )Nrbz1Cache index %s has unexpected type %s, resetting.uk   Failed to load cache index %s: %s. Resetting — already-downloaded files will be re-validated on next run.
.corrupted)cached_filesr   pathjoinr   r   KEY_FILE_NAMEexistsopenpickleload
isinstancelistloggerwarningtype__name__	ExceptionreplaceOSError)r   cache_keys_file_pathfdataer   r   r   r   4   sB   


zFileSystemCache.load_cachec                 C   s   t j| jtj}tjd| jd\}}z3t |d}t	
t| j| |  t |  W d   n1 s9w   Y  t || W dS  tyj   zt | W n	 ty]   Y nw t j|rit |  w )z8Write .msc atomically. Caller must hold ``_cache_lock``.z.tmp)suffixdirwbN)r   r!   r"   r   r   r#   tempfilemkstempfdopenr&   dumpr)   r    flushfsyncfilenor/   r.   closer0   r$   unlink)r   r1   fdZtemp_filenamer2   r   r   r   _save_cached_files_unlockedN   s.   


z+FileSystemCache._save_cached_files_unlockedc                 C   s4   | j  |   W d   dS 1 sw   Y  dS )a  
        Save cache metadata in order to verify that the cached content is consistent with the remote content.

        Example of the cached content:
            [{'Path': 'configuration.json', 'Revision': 'f01dxxx'}, {'Path': 'model.bin', 'Revision': '1159xxx'}, ...]
        N)r   rB   r   r   r   r   save_cached_filesc   s   
"z!FileSystemCache.save_cached_filesc                 C      dS )zCheck the key is in the cache, if exist, return the file, otherwise return None.

        Args:
            key(str): The cache key.

        Raises:
            None
        Nr   r   keyr   r   r   get_filem   s   	zFileSystemCache.get_filec                 C   rD   )zPut file to the cache.

        Args:
            key (str): The cache key
            location (str): Location of the file, we will move the file to cache.

        Raises:
            None
        Nr   )r   rF   locationr   r   r   put_filex   s   
zFileSystemCache.put_filec                 C   s&   || j v r| j | |   dS dS )zvRemove cache key in index, The file is removed manually

        Args:
            key (dict): The cache key.
        N)r    removerC   rE   r   r   r   
remove_key   s   
zFileSystemCache.remove_keyc                 C   s   | j D ]	}||kr dS qdS )NTF)r    )r   rF   Z
cache_filer   r   r   r$      s
   
zFileSystemCache.existsc                 C   s   t | j |   dS )zRemove all files and metadata from the cache
        In the case of multiple cache locations, this clears only the last one,
        which is assumed to be the read/write one.
        N)r   r   r   r   r   r   r   clear_cache   s   
zFileSystemCache.clear_cachec                 C   s   t |  S r   )hashlibsha256encode	hexdigestrE   r   r   r   	hash_name   s   zFileSystemCache.hash_nameN)r-   
__module____qualname__r#   MODEL_META_FILE_NAMEMODEL_META_MODEL_IDMODEL_VERSION_FILE_NAMEstrr   r   r   rB   rC   rG   rI   rK   r$   rL   rQ   r   r   r   r   r      s&    


r   c                       s   e Zd ZdZd fdd	Zdd Zdd Zd	efd
dZdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Z  ZS )ModelFileSystemCachezLocal cache file layout
       cache_root/owner/model_name/individual cached files and cache index file '.mcs'
       Save only one version for each file.
    Nc                    sp   |du s|du rt  tj| |   nt  tj||| tjd||f i| _| 	  | 
 | _dS )a\  Put file to the cache
        Args:
            cache_root(`str`): The modelscope local cache root(default: ~/.cache/modelscope/hub)
            owner(`str`): The model owner.
            name('str'): The name of the model
        Returns:
        Raises:
            None
        <Tip>
            model_id = {owner}/{name}
        </Tip>
        Nz%s/%s)superr   r   r!   r"   load_model_metar   rU   
model_metasave_model_metaload_model_versionZcached_model_revision)r   Z
cache_rootownername	__class__r   r   r      s   
zModelFileSystemCache.__init__c                 C   s   t j| jtj}t j|rjz-t|d}t	|}W d    n1 s%w   Y  t
|tr5|| _W d S td| W n- tyi } z!td|| z
t ||d  W n	 ty^   Y nw W Y d }~nd }~ww tjdi| _d S )Nr   z-Model meta %s has unexpected type, resetting.z,Failed to load model meta %s: %s. Resetting.r   unknown)r   r!   r"   r   r   rT   r$   r%   r&   r'   r(   dictr[   r*   r+   r.   r/   r0   rU   )r   meta_file_pathr2   r3   r4   r   r   r   rZ      s4   

z$ModelFileSystemCache.load_model_metac                 C   s\   t j| jtj}t j|r,t|d}| 	 W  d    S 1 s%w   Y  d S d S )Nr)
r   r!   r"   r   r   rV   r$   r%   readstrip)r   model_version_file_pathr2   r   r   r   r]      s   
$z'ModelFileSystemCache.load_model_versionrevision_infoc                 C   s   t j| jtj}t|d+}t|tr$d|d |d f }|	| n|	| W d    d S W d    d S 1 s<w   Y  d S )NwzRevision:%s,CreatedAt:%sRevisionZ	CreatedAt)
r   r!   r"   r   r   rV   r%   r(   rc   write)r   ri   rh   r2   Zversion_info_strr   r   r   save_model_version   s   
"z'ModelFileSystemCache.save_model_versionc                 C   s   | j tj S r   )r[   r   rU   r   r   r   r   get_model_id   s   z!ModelFileSystemCache.get_model_idc                 C   sP   t j| jtj}t|d}t| j	| W d    d S 1 s!w   Y  d S )Nr7   )
r   r!   r"   r   r   rT   r%   r&   r;   r[   )r   rd   r2   r   r   r   r\      s   
"z$ModelFileSystemCache.save_model_metac                 C   sN   | j D ]!}||d kr$tj| j|d }tj|r|  S | | qdS )zRetrieve the cache if there is file match the path.

        Args:
            file_path (str): The file path in the model.

        Returns:
            path: the full path of the file.
        PathN)r    r   r!   r"   r   r$   rK   )r   	file_pathcached_filecached_file_pathr   r   r   get_file_by_path   s   
	

z%ModelFileSystemCache.get_file_by_pathc                 C   sj   | j D ]/}||d kr2|d |s||d r2tj| j|d }tj|r-|  S | | qdS )zRetrieve the cache if there is file match the path.

        Args:
            file_path (str): The file path in the model.
            commit_id (str): The commit id of the file

        Returns:
            path: the full path of the file.
        ro   rk   N)r    
startswithr   r!   r"   r   r$   rK   )r   rp   	commit_idrq   rr   r   r   r   get_file_by_path_and_commit_id  s   



z3ModelFileSystemCache.get_file_by_path_and_commit_idc                 C   sZ   |  |}| jD ]"}||kr*tj| j|d }tj|r"|  S | |  dS qdS )zCheck if exist cache file.

        Args:
            model_file_info (ModelFileInfo): The file information of the file.

        Returns:
            str: The file path.
        ro   N)$_ModelFileSystemCache__get_cache_keyr    r   r!   r"   r   r$   rK   )r   model_file_info	cache_keyrq   	orig_pathr   r   r   get_file_by_info  s   
	


	z%ModelFileSystemCache.get_file_by_infoc                 C   s   |d |d d}|S )Nro   rk   )ro   rk   r   )r   rx   ry   r   r   r   Z__get_cache_key2  s   z$ModelFileSystemCache.__get_cache_keyc           	      C   s   |  |}d}|d }tj| j|d }| jD ]B}|d |krZ|d |d s2|d |d rZ|t }|durZtj|rZt	rGt
|}n|}||krQd} n
td| d q|rjtj|redS | | dS )a  Check the file is cached or not. Note existence check will also cover digest check

        Args:
            model_file_info (CachedFileInfo): The cached file info

        Returns:
            bool: If exists and has the same hash, return True otherwise False
        Fro   rk   NTzFile [z?] exists in cache but with a mismatched hash, will re-download.)rw   r   r!   r"   r   r    rt   r   r$   enable_default_hash_validationr   r*   inforK   )	r   rx   rF   Z	is_existsrp   Zcache_file_pathZ
cached_keyZexpected_hashZcache_file_sha256r   r   r   r$   9  sB   
	



zModelFileSystemCache.existsc                 C   sZ   | j D ]'}|d |d kr*| | tj| j|d }tj|r't|  dS qdS )zWe in cache, remove it.

        Args:
            model_file_info (ModelFileInfo): The model file information from server.
        ro   N)r    rK   r   r!   r"   r   r$   rJ   )r   rx   rq   rp   r   r   r   remove_if_existsb  s   



z%ModelFileSystemCache.remove_if_existsc                 C   s   |  | | |}tj| j|d }tj|}tj|s'tj|dd t	|| | j
 | j| |   W d   |S 1 sEw   Y  |S )a[  Put model on model_file_location to cache, the model first download to /tmp, and move to cache.

        Args:
            model_file_info (str): The file description returned by get_model_files.
            model_file_location (str): The location of the temporary file.

        Returns:
            str: The location of the cached file.
        ro   Tr   N)r~   rw   r   r!   r"   r   dirnamer$   r   r   r   r    appendrB   )r   rx   Zmodel_file_locationry   Zcache_full_pathZcache_file_dirr   r   r   rI   q  s    






zModelFileSystemCache.put_file)NN)r-   rR   rS   __doc__r   rZ   r]   r   rm   rn   r\   rs   rv   r{   rw   r$   r~   rI   __classcell__r   r   r`   r   rX      s    	)rX   )rM   r   r&   r8   r   shutilr   r   typingr   Zmodelscope.hub.constantsr   r   Zmodelscope.hub.utils.utilsr   Zmodelscope.utils.loggerr   r*   getenvrg   lowerr|   objectr   rX   r   r   r   r   <module>   s"    
