o
    /ѹg/                     @   s   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                   @   st   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S )FileSystemCachez.mscz.mdlidz.mvcache_root_locationc                 K   s    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)osmakedirsr   
load_cache)selfr   kwargs r   `/Users/admin/.pyenv/versions/3.10.0/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_location.   s   z!FileSystemCache.get_root_locationc                 C   sd   g | _ tj| jtj}tj|r0t|d}t	
|| _ W d    d S 1 s)w   Y  d S d S )Nrb)cached_filesr   pathjoinr   r   KEY_FILE_NAMEexistsopenpickleload)r   cache_keys_file_pathfr   r   r   r   1   s   
"zFileSystemCache.load_cachec                 C   sd   t j| jtj}t \}}t|d}t	
| j| W d   n1 s&w   Y  t|| dS )zSave cache metadata.wbN)r   r   r   r   r   r   tempfilemkstempr!   r"   dumpr   r   )r   r$   fdfnr%   r   r   r   save_cached_files9   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_fileD   s   	zFileSystemCache.get_filec                 C   r-   )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   r/   locationr   r   r   put_fileO   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   remover,   r.   r   r   r   
remove_key[   s   
zFileSystemCache.remove_keyc                 C   s   | j D ]	}||kr dS qdS )NTF)r   )r   r/   Z
cache_filer   r   r   r    e   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_cachel   s   
zFileSystemCache.clear_cachec                 C   s   t |  S r   )hashlibsha256encode	hexdigestr.   r   r   r   	hash_namet   s   zFileSystemCache.hash_nameN)__name__
__module____qualname__r   MODEL_META_FILE_NAMEMODEL_META_MODEL_IDMODEL_VERSION_FILE_NAMEstrr   r   r   r,   r0   r2   r4   r    r5   r:   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 )aY  Put file to the cache
        Args:
            cache_root(`str`): The modelscope local cache root(default: ~/.cache/modelscope/)
            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   r?   
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   sj   t j| jtj}t j|r-t|d}t	|| _
W d    d S 1 s&w   Y  d S tjdi| _
d S )Nr   unknown)r   r   r   r   r   r>   r    r!   r"   r#   rE   r?   r   Zmeta_file_pathr%   r   r   r   rD      s   
"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   r@   r    r!   readstrip)r   model_version_file_pathr%   r   r   r   rG      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   r@   r!   
isinstancedictwrite)r   rR   rQ   r%   Zversion_info_strr   r   r   save_model_version   s   
"z'ModelFileSystemCache.save_model_versionc                 C   s   | j tj S r   )rE   r   r?   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 )Nr&   )
r   r   r   r   r   r>   r!   r"   r)   rE   rM   r   r   r   rF      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    r4   )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.
        rZ   rT   N)r   
startswithr   r   r   r   r    r4   )r   r[   	commit_idr\   r]   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.
        rZ   N)$_ModelFileSystemCache__get_cache_keyr   r   r   r   r   r    r4   )r   model_file_info	cache_keyr\   	orig_pathr   r   r   get_file_by_info   s   
	


	z%ModelFileSystemCache.get_file_by_infoc                 C   s   |d |d d}|S )NrZ   rT   )rZ   rT   r   )r   rc   rd   r   r   r   Z__get_cache_key   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} q[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
        FrZ   rT   NTzFile [z?] exists in cache but with a mismatched hash, will re-download.)rb   r   r   r   r   r   r_   r   r    enable_default_hash_validationr   loggerinfor4   )	r   rc   r/   Z	is_existsr[   Zcache_file_pathZ
cached_keyZexpected_hashZcache_file_sha256r   r   r   r      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.
        rZ   N)r   r4   r   r   r   r   r    r3   )r   rc   r\   r[   r   r   r   remove_if_exists-  s   



z%ModelFileSystemCache.remove_if_existsc                 C   sp   |  | | |}tj| j|d }tj|}tj|s'tj|dd t	|| | j
| |   |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.
        rZ   Tr   N)rj   rb   r   r   r   r   dirnamer    r   r   r   appendr,   )r   rc   Zmodel_file_locationrd   Zcache_full_pathZcache_file_dirr   r   r   r2   <  s   



zModelFileSystemCache.put_file)NN)r;   r<   r=   __doc__r   rD   rG   r   rX   rY   rF   r^   ra   rf   rb   r    rj   r2   __classcell__r   r   rJ   r   rB   x   s    		)rB   )r6   r   r"   r'   shutilr   r   typingr   Zmodelscope.hub.constantsr   r   Zmodelscope.hub.utils.utilsr   Zmodelscope.utils.loggerr   rh   getenvrP   lowerrg   objectr   rB   r   r   r   r   <module>   s   a