
    g                        d 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mZmZmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ  ej6                  e      Zed   ZdgZ ed       G d d             Z  ed       G d d             Z! ed       G d d             Z" ed       G d d             Z# ed       G d d             Z$d(deee%e	f      de$fdZ&de	de"fdZ'd e(de%fd!Z)d"Z*d#e+de%fd$Z,d%e	d&e%ddfd'Z-y))z4Contains utilities to manage the HF cache directory.    N)defaultdict)	dataclass)Path)Dict	FrozenSetListLiteralOptionalSetUnion)CacheNotFoundCorruptedCacheException   )tabulate)HF_HUB_CACHE   )logging)modeldatasetspacez	.DS_StoreT)frozenc                       e Zd ZU dZeed<   eed<   eed<   eed<   eed<   eed<   e	defd	       Z
e	defd
       Ze	defd       Zy)CachedFileInfoa  Frozen data structure holding information about a single cached file.

    Args:
        file_name (`str`):
            Name of the file. Example: `config.json`.
        file_path (`Path`):
            Path of the file in the `snapshots` directory. The file path is a symlink
            referring to a blob in the `blobs` folder.
        blob_path (`Path`):
            Path of the blob file. This is equivalent to `file_path.resolve()`.
        size_on_disk (`int`):
            Size of the blob file in bytes.
        blob_last_accessed (`float`):
            Timestamp of the last time the blob file has been accessed (from any
            revision).
        blob_last_modified (`float`):
            Timestamp of the last time the blob file has been modified/created.

    <Tip warning={true}>

    `blob_last_accessed` and `blob_last_modified` reliability can depend on the OS you
    are using. See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result)
    for more details.

    </Tip>
    	file_name	file_path	blob_pathsize_on_diskblob_last_accessedblob_last_modifiedreturnc                 ,    t        | j                        S )z
        (property) Timestamp of the last time the blob file has been accessed (from any
        revision), returned as a human-readable string.

        Example: "2 weeks ago".
        )_format_timesincer   selfs    Y/var/www/openai/venv/lib/python3.12/site-packages/huggingface_hub/utils/_cache_manager.pyblob_last_accessed_strz%CachedFileInfo.blob_last_accessed_strM        !!8!899    c                 ,    t        | j                        S )z
        (property) Timestamp of the last time the blob file has been modified, returned
        as a human-readable string.

        Example: "2 weeks ago".
        )r"   r   r#   s    r%   blob_last_modified_strz%CachedFileInfo.blob_last_modified_strW   r'   r(   c                 ,    t        | j                        S )zi
        (property) Size of the blob file as a human-readable string.

        Example: "42.2K".
        _format_sizer   r#   s    r%   size_on_disk_strzCachedFileInfo.size_on_disk_stra        D--..r(   N)__name__
__module____qualname____doc__str__annotations__r   intfloatpropertyr&   r*   r.    r(   r%   r   r   (   sy    6 NOO: : : : : : /# / /r(   r   c                       e Zd ZU dZeed<   eed<   eed<   ee	   ed<   ee   ed<   e
ed<   edefd	       Zedefd
       Zedefd       Zy)CachedRevisionInfoaN  Frozen data structure holding information about a revision.

    A revision correspond to a folder in the `snapshots` folder and is populated with
    the exact tree structure as the repo on the Hub but contains only symlinks. A
    revision can be either referenced by 1 or more `refs` or be "detached" (no refs).

    Args:
        commit_hash (`str`):
            Hash of the revision (unique).
            Example: `"9338f7b671827df886678df2bdd7cc7b4f36dffd"`.
        snapshot_path (`Path`):
            Path to the revision directory in the `snapshots` folder. It contains the
            exact tree structure as the repo on the Hub.
        files: (`FrozenSet[CachedFileInfo]`):
            Set of [`~CachedFileInfo`] describing all files contained in the snapshot.
        refs (`FrozenSet[str]`):
            Set of `refs` pointing to this revision. If the revision has no `refs`, it
            is considered detached.
            Example: `{"main", "2.4.0"}` or `{"refs/pr/1"}`.
        size_on_disk (`int`):
            Sum of the blob file sizes that are symlink-ed by the revision.
        last_modified (`float`):
            Timestamp of the last time the revision has been created/modified.

    <Tip warning={true}>

    `last_accessed` cannot be determined correctly on a single revision as blob files
    are shared across revisions.

    </Tip>

    <Tip warning={true}>

    `size_on_disk` is not necessarily the sum of all file sizes because of possible
    duplicated files. Besides, only blobs are taken into account, not the (negligible)
    size of folders and symlinks.

    </Tip>
    commit_hashsnapshot_pathr   filesrefslast_modifiedr    c                 ,    t        | j                        S )z
        (property) Timestamp of the last time the revision has been modified, returned
        as a human-readable string.

        Example: "2 weeks ago".
        r"   r@   r#   s    r%   last_modified_strz$CachedRevisionInfo.last_modified_str        !!3!344r(   c                 ,    t        | j                        S zn
        (property) Sum of the blob file sizes as a human-readable string.

        Example: "42.2K".
        r,   r#   s    r%   r.   z#CachedRevisionInfo.size_on_disk_str   r/   r(   c                 ,    t        | j                        S )zC
        (property) Total number of files in the revision.
        )lenr>   r#   s    r%   nb_fileszCachedRevisionInfo.nb_files   s    
 4::r(   N)r0   r1   r2   r3   r4   r5   r   r6   r   r   r7   r8   rC   r.   rI   r9   r(   r%   r;   r;   k   s    &P ^$$
C.53 5 5 /# / / #  r(   r;   c                       e Zd ZU dZeed<   eed<   eed<   eed<   eed<   e	e
   ed<   eed<   eed	<   ed
efd       Zed
efd       Zed
efd       Zed
eee
f   fd       Zy)CachedRepoInfoad  Frozen data structure holding information about a cached repository.

    Args:
        repo_id (`str`):
            Repo id of the repo on the Hub. Example: `"google/fleurs"`.
        repo_type (`Literal["dataset", "model", "space"]`):
            Type of the cached repo.
        repo_path (`Path`):
            Local path to the cached repo.
        size_on_disk (`int`):
            Sum of the blob file sizes in the cached repo.
        nb_files (`int`):
            Total number of blob files in the cached repo.
        revisions (`FrozenSet[CachedRevisionInfo]`):
            Set of [`~CachedRevisionInfo`] describing all revisions cached in the repo.
        last_accessed (`float`):
            Timestamp of the last time a blob file of the repo has been accessed.
        last_modified (`float`):
            Timestamp of the last time a blob file of the repo has been modified/created.

    <Tip warning={true}>

    `size_on_disk` is not necessarily the sum of all revisions sizes because of
    duplicated files. Besides, only blobs are taken into account, not the (negligible)
    size of folders and symlinks.

    </Tip>

    <Tip warning={true}>

    `last_accessed` and `last_modified` reliability can depend on the OS you are using.
    See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result)
    for more details.

    </Tip>
    repo_id	repo_type	repo_pathr   rI   	revisionslast_accessedr@   r    c                 ,    t        | j                        S )z
        (property) Last time a blob file of the repo has been accessed, returned as a
        human-readable string.

        Example: "2 weeks ago".
        )r"   rP   r#   s    r%   last_accessed_strz CachedRepoInfo.last_accessed_str   rD   r(   c                 ,    t        | j                        S )z
        (property) Last time a blob file of the repo has been modified, returned as a
        human-readable string.

        Example: "2 weeks ago".
        rB   r#   s    r%   rC   z CachedRepoInfo.last_modified_str   rD   r(   c                 ,    t        | j                        S rF   r,   r#   s    r%   r.   zCachedRepoInfo.size_on_disk_str   r/   r(   c                 j    | j                   D ci c]  }|j                  D ]  }||  c}}S c c}}w )zQ
        (property) Mapping between `refs` and revision data structures.
        )rO   r?   )r$   revisionrefs      r%   r?   zCachedRepoInfo.refs  s0    
 /3nnVn(XnVVVs   /N)r0   r1   r2   r3   r4   r5   REPO_TYPE_Tr   r6   r   r;   r7   r8   rR   rC   r.   r   r?   r9   r(   r%   rK   rK      s    #J LOM+,,53 5 5 53 5 5 /# / / Wd3 223 W Wr(   rK   c                   z    e Zd ZU dZeed<   ee   ed<   ee   ed<   ee   ed<   ee   ed<   ede	fd       Z
dd
Zy	)DeleteCacheStrategya  Frozen data structure holding the strategy to delete cached revisions.

    This object is not meant to be instantiated programmatically but to be returned by
    [`~utils.HFCacheInfo.delete_revisions`]. See documentation for usage example.

    Args:
        expected_freed_size (`float`):
            Expected freed size once strategy is executed.
        blobs (`FrozenSet[Path]`):
            Set of blob file paths to be deleted.
        refs (`FrozenSet[Path]`):
            Set of reference file paths to be deleted.
        repos (`FrozenSet[Path]`):
            Set of entire repo paths to be deleted.
        snapshots (`FrozenSet[Path]`):
            Set of snapshots to be deleted (directory of symlinks).
    expected_freed_sizeblobsr?   repos	snapshotsr    c                 ,    t        | j                        S )zt
        (property) Expected size that will be freed as a human-readable string.

        Example: "42.2K".
        )r-   r[   r#   s    r%   expected_freed_size_strz+DeleteCacheStrategy.expected_freed_size_str(  s     D4455r(   Nc                 :   | j                   D ]  }t        |d        | j                  D ]  }t        |d        | j                  D ]  }t        |d        | j                  D ]  }t        |d        t
        j                  d| j                   d       y)	a  Execute the defined strategy.

        <Tip warning={true}>

        If this method is interrupted, the cache might get corrupted. Deletion order is
        implemented so that references and symlinks are deleted before the actual blob
        files.

        </Tip>

        <Tip warning={true}>

        This method is irreversible. If executed, cached files are erased and must be
        downloaded again.

        </Tip>
        repo)	path_typesnapshotrW   blobzCache deletion done. Saved .N)r]   _try_delete_pathr^   r?   r\   loggerinfor`   )r$   paths     r%   executezDeleteCacheStrategy.execute1  s    . JJDTV4  NNDTZ8 # IIDTU3  JJDTV4  	1$2N2N1OqQRr(   )r    N)r0   r1   r2   r3   r6   r5   r   r   r8   r4   r`   rk   r9   r(   r%   rZ   rZ     sV    $ T?
D/T?6 6 6&Sr(   rZ   c                   x    e Zd ZU dZeed<   ee   ed<   ee	   ed<   e
defd       ZdedefdZd	d
dedefdZy)HFCacheInfoa  Frozen data structure holding information about the entire cache-system.

    This data structure is returned by [`scan_cache_dir`] and is immutable.

    Args:
        size_on_disk (`int`):
            Sum of all valid repo sizes in the cache-system.
        repos (`FrozenSet[CachedRepoInfo]`):
            Set of [`~CachedRepoInfo`] describing all valid cached repos found on the
            cache-system while scanning.
        warnings (`List[CorruptedCacheException]`):
            List of [`~CorruptedCacheException`] that occurred while scanning the cache.
            Those exceptions are captured so that the scan can continue. Corrupted repos
            are skipped from the scan.

    <Tip warning={true}>

    Here `size_on_disk` is equal to the sum of all repo sizes (only blobs). However if
    some cached repos are corrupted, their sizes are not taken into account.

    </Tip>
    r   r]   warningsr    c                 ,    t        | j                        S )z
        (property) Sum of all valid repo sizes in the cache-system as a human-readable
        string.

        Example: "42.2K".
        r,   r#   s    r%   r.   zHFCacheInfo.size_on_disk_strw  s     D--..r(   rO   c                    t        |      }t        t               }| j                  D ]Q  }|j                  D ]@  }|j                  |v s||   j                  |       |j                  |j                         B S t        |      dkD  r't        j                  ddj                  |              t               }t               }t               }t               }	d}
|j                         D ]*  \  }}|j                  |z
  }t        |      dk(  r+|j                  |j                         |
|j                  z  }
O|D ]  }|	j                  |j                         |j                  D ]#  }|j                  |j                  dz  |z         % |j                   D ]y  }|j"                  |vsd}|D ]4  }|j                   D ]  }|j"                  |j"                  k(  sd} n |r4 n |sP|j                  |j"                         |
|j                  z  }
{  - t%        t'        |      t'        |      t'        |      t'        |	      |
      S )a  Prepare the strategy to delete one or more revisions cached locally.

        Input revisions can be any revision hash. If a revision hash is not found in the
        local cache, a warning is thrown but no error is raised. Revisions can be from
        different cached repos since hashes are unique across repos,

        Examples:
        ```py
        >>> from huggingface_hub import scan_cache_dir
        >>> cache_info = scan_cache_dir()
        >>> delete_strategy = cache_info.delete_revisions(
        ...     "81fd1d6e7847c99f5862c9fb81387956d99ec7aa"
        ... )
        >>> print(f"Will free {delete_strategy.expected_freed_size_str}.")
        Will free 7.9K.
        >>> delete_strategy.execute()
        Cache deletion done. Saved 7.9K.
        ```

        ```py
        >>> from huggingface_hub import scan_cache_dir
        >>> scan_cache_dir().delete_revisions(
        ...     "81fd1d6e7847c99f5862c9fb81387956d99ec7aa",
        ...     "e2983b237dccf3ab4937c97fa717319a9ca1a96d",
        ...     "6c0e6080953db56375760c0471a8c5f2929baf11",
        ... ).execute()
        Cache deletion done. Saved 8.6G.
        ```

        <Tip warning={true}>

        `delete_revisions` returns a [`~utils.DeleteCacheStrategy`] object that needs to
        be executed. The [`~utils.DeleteCacheStrategy`] is not meant to be modified but
        allows having a dry run before actually executing the deletion.

        </Tip>
        r   z,Revision(s) not found - cannot delete them: , r?   TF)r\   r?   r]   r^   r[   )setr   r]   rO   r<   addremoverH   rh   warningjoinitemsrN   r   r=   r?   r>   r   rZ   	frozenset)r$   rO   hashes_to_deleterepos_with_revisionsrb   rV   delete_strategy_blobsdelete_strategy_refsdelete_strategy_reposdelete_strategy_snapshots#delete_strategy_expected_freed_sizeaffected_reporevisions_to_deleteother_revisionsrevision_to_deleterW   fileis_file_alonerev_files                      r%   delete_revisionszHFCacheInfo.delete_revisions  s4   L &)^NYZ]N^JJD NN''+;;(.228<$++H,@,@A +   1$NNI$))TdJeIfgh+.5*-%+.5/2u!./+2F2L2L2N.M.+558KKO ?#q(%))-*A*AB3}7Q7QQ3 ':")--.@.N.NO .22C(,,]-D-Dv-MPS-ST 3 /44D~~-BB(,(7H,4NN#'>>X5G5G#G49M$) -; $1 % )8 )155dnnE?4CTCTT? 5 ': 3OL #12/012 9: C
 	
r(   r   )	verbosityr   c                L   |dk(  rt        t        | j                  d       D cg c]  }|j                  |j                  dj                  |j                        |j                  |j                  |j                  dj                  t        |j                              t        |j                        g c}g d      S t        t        | j                  d       D cg c]  }t        |j                  d	       D ]  }|j                  |j                  |j                  dj                  |j                        |j                  |j                  dj                  t        |j                              t        |j                         g  c}}g d
      S c c}w c c}}w )a}  Generate a table from the [`HFCacheInfo`] object.

        Pass `verbosity=0` to get a table with a single row per repo, with columns
        "repo_id", "repo_type", "size_on_disk", "nb_files", "last_accessed", "last_modified", "refs", "local_path".

        Pass `verbosity=1` to get a table with a row per repo and revision (thus multiple rows can appear for a single repo), with columns
        "repo_id", "repo_type", "revision", "size_on_disk", "nb_files", "last_modified", "refs", "local_path".

        Example:
        ```py
        >>> from huggingface_hub.utils import scan_cache_dir

        >>> hf_cache_info = scan_cache_dir()
        HFCacheInfo(...)

        >>> print(hf_cache_info.export_as_table())
        REPO ID                                             REPO TYPE SIZE ON DISK NB FILES LAST_ACCESSED LAST_MODIFIED REFS LOCAL PATH
        --------------------------------------------------- --------- ------------ -------- ------------- ------------- ---- --------------------------------------------------------------------------------------------------
        roberta-base                                        model             2.7M        5 1 day ago     1 week ago    main ~/.cache/huggingface/hub/models--roberta-base
        suno/bark                                           model             8.8K        1 1 week ago    1 week ago    main ~/.cache/huggingface/hub/models--suno--bark
        t5-base                                             model           893.8M        4 4 days ago    7 months ago  main ~/.cache/huggingface/hub/models--t5-base
        t5-large                                            model             3.0G        4 5 weeks ago   5 months ago  main ~/.cache/huggingface/hub/models--t5-large

        >>> print(hf_cache_info.export_as_table(verbosity=1))
        REPO ID                                             REPO TYPE REVISION                                 SIZE ON DISK NB FILES LAST_MODIFIED REFS LOCAL PATH
        --------------------------------------------------- --------- ---------------------------------------- ------------ -------- ------------- ---- -----------------------------------------------------------------------------------------------------------------------------------------------------
        roberta-base                                        model     e2da8e2f811d1448a5b465c236feacd80ffbac7b         2.7M        5 1 week ago    main ~/.cache/huggingface/hub/models--roberta-base/snapshots/e2da8e2f811d1448a5b465c236feacd80ffbac7b
        suno/bark                                           model     70a8a7d34168586dc5d028fa9666aceade177992         8.8K        1 1 week ago    main ~/.cache/huggingface/hub/models--suno--bark/snapshots/70a8a7d34168586dc5d028fa9666aceade177992
        t5-base                                             model     a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1       893.8M        4 7 months ago  main ~/.cache/huggingface/hub/models--t5-base/snapshots/a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1
        t5-large                                            model     150ebc2c4b72291e770f58e6057481c8d2ed331a         3.0G        4 5 months ago  main ~/.cache/huggingface/hub/models--t5-large/snapshots/150ebc2c4b72291e770f58e6057481c8d2ed331a
        ```

        Args:
            verbosity (`int`, *optional*):
                The verbosity level. Defaults to 0.

        Returns:
            `str`: The table as a string.
        r   c                     | j                   S NrN   rb   s    r%   <lambda>z-HFCacheInfo.export_as_table.<locals>.<lambda>      DNNr(   )keyz{:>12}rq   )REPO ID	REPO TYPESIZE ON DISKNB FILESLAST_ACCESSEDLAST_MODIFIEDREFS
LOCAL PATH)rowsheadersc                     | j                   S r   r   r   s    r%   r   z-HFCacheInfo.export_as_table.<locals>.<lambda>7  r   r(   c                     | j                   S r   )r<   )rV   s    r%   r   z-HFCacheInfo.export_as_table.<locals>.<lambda>8  s    PXPdPdr(   )r   r   REVISIONr   r   r   r   r   )r   sortedr]   rL   rM   formatr.   rI   rR   rC   rv   r?   r4   rN   rO   r<   r=   )r$   r   rb   rV   s       r%   export_as_tablezHFCacheInfo.export_as_table  sr   P > !'tzz7R S !T  (=(=>....		&"34DNN+	 !T	 4  !'tzz7R S !T$*4>>?d$e  ,, (A(AB )) 22		&"78H223	 %f	 !T	 34s   BF!B.F 
N)r0   r1   r2   r3   r6   r5   r   rK   r   r   r8   r4   r.   rZ   r   r   r9   r(   r%   rm   rm   Z  sr    . ^$$*++/# / /e
3 e
3F e
N 34 \C \ \r(   rm   	cache_dirr    c                    | t         } t        |       j                         j                         } | j	                         st        d|  d|       | j                         rt        d|  d      t               }g }| j                         D ]-  }|j                  dk(  r	 |j                  t        |             / t        t!        |      t#        d |D              |      S # t        $ r}|j                  |       Y d}~vd}~ww xY w)	at  Scan the entire HF cache-system and return a [`~HFCacheInfo`] structure.

    Use `scan_cache_dir` in order to programmatically scan your cache-system. The cache
    will be scanned repo by repo. If a repo is corrupted, a [`~CorruptedCacheException`]
    will be thrown internally but captured and returned in the [`~HFCacheInfo`]
    structure. Only valid repos get a proper report.

    ```py
    >>> from huggingface_hub import scan_cache_dir

    >>> hf_cache_info = scan_cache_dir()
    HFCacheInfo(
        size_on_disk=3398085269,
        repos=frozenset({
            CachedRepoInfo(
                repo_id='t5-small',
                repo_type='model',
                repo_path=PosixPath(...),
                size_on_disk=970726914,
                nb_files=11,
                revisions=frozenset({
                    CachedRevisionInfo(
                        commit_hash='d78aea13fa7ecd06c29e3e46195d6341255065d5',
                        size_on_disk=970726339,
                        snapshot_path=PosixPath(...),
                        files=frozenset({
                            CachedFileInfo(
                                file_name='config.json',
                                size_on_disk=1197
                                file_path=PosixPath(...),
                                blob_path=PosixPath(...),
                            ),
                            CachedFileInfo(...),
                            ...
                        }),
                    ),
                    CachedRevisionInfo(...),
                    ...
                }),
            ),
            CachedRepoInfo(...),
            ...
        }),
        warnings=[
            CorruptedCacheException("Snapshots dir doesn't exist in cached repo: ..."),
            CorruptedCacheException(...),
            ...
        ],
    )
    ```

    You can also print a detailed report directly from the `huggingface-cli` using:
    ```text
    > huggingface-cli scan-cache
    REPO ID                     REPO TYPE SIZE ON DISK NB FILES REFS                LOCAL PATH
    --------------------------- --------- ------------ -------- ------------------- -------------------------------------------------------------------------
    glue                        dataset         116.3K       15 1.17.0, main, 2.4.0 /Users/lucain/.cache/huggingface/hub/datasets--glue
    google/fleurs               dataset          64.9M        6 main, refs/pr/1     /Users/lucain/.cache/huggingface/hub/datasets--google--fleurs
    Jean-Baptiste/camembert-ner model           441.0M        7 main                /Users/lucain/.cache/huggingface/hub/models--Jean-Baptiste--camembert-ner
    bert-base-cased             model             1.9G       13 main                /Users/lucain/.cache/huggingface/hub/models--bert-base-cased
    t5-base                     model            10.1K        3 main                /Users/lucain/.cache/huggingface/hub/models--t5-base
    t5-small                    model           970.7M       11 refs/pr/1, main     /Users/lucain/.cache/huggingface/hub/models--t5-small

    Done in 0.0s. Scanned 6 repo(s) for a total of 3.4G.
    Got 1 warning(s) while scanning. Use -vvv to print details.
    ```

    Args:
        cache_dir (`str` or `Path`, `optional`):
            Cache directory to cache. Defaults to the default HF cache directory.

    <Tip warning={true}>

    Raises:

        `CacheNotFound`
          If the cache directory does not exist.

        [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
          If the cache directory is a file, instead of a directory.

    </Tip>

    Returns: a [`~HFCacheInfo`] object.
    NzCache directory not found: zM. Please use `cache_dir` argument or set `HF_HUB_CACHE` environment variable.)r   z1Scan cache expects a directory but found a file: z.locksc              3   4   K   | ]  }|j                     y wr   )r   ).0rb   s     r%   	<genexpr>z!scan_cache_dir.<locals>.<genexpr>  s     =ut**u   )r]   r   rn   )r   r   
expanduserresolveexistsr   is_file
ValueErrorrr   iterdirnamers   _scan_cached_repor   appendrm   rx   sum)r   r]   rn   rN   es        r%   scan_cache_dirr   G  s   l  	Y**,446I))  5B  C
 	

 ?	{  KX  Y
 	
 "%E.0H&&(	>>X%	II'	23	 ) =u==  ' 	OOA	s    C##	D,DDrN   c                    | j                         st        d|        d| j                  vrt        d|        | j                  j                  dd      \  }}|dd }|j	                  dd      }|d	vrt        d
| d|  d      i | dz  }| dz  }|j                         r|j                         st        d|       t        t              }|j                         r|j                         rt        d|       |j                  d      D ]|  }|j                         s|j                  t        v r&t        |j                  |            }|j                         5 }|j                         }	ddd       |	   j                  |       ~ t               }
|j!                         D ]  }|j                  t        v r|j                         rt        d|       t               }|j                  d      D ]  }|j                         rt#        |      j%                         }|j                         st        d|       |vr|j'                         |<   |j                  t)        |j                  ||   j*                  ||   j,                  |   j.                                t1        |      dkD  rt3        fd|D              }n|j'                         j.                  }|
j                  t5        |j                  t7        |      t7        |j9                  |j                  t                           t;        fdt        d |D              D              ||              t1        |      dkD  rt        dt=        |       d|  d      t1              dkD  rAt3        d j?                         D              }t3        d j?                         D              }n(| j'                         }|j,                  }|j.                  }tA        t1              || |t7        |
      t;        d j?                         D              ||      S # 1 sw Y   xY w) zScan a single cache repo and return information about it.

    Any unexpected behavior will raise a [`~CorruptedCacheException`].
    zRepo path is not a directory: z--z6Repo path is not a valid HuggingFace cache directory: r   )maxsplitN/>   r   r   r   z8Repo type must be `dataset`, `model` or `space`, found `z` (z).r^   r?   z,Snapshots dir doesn't exist in cached repo: z!Refs directory cannot be a file: z**/*z*Snapshots folder corrupted. Found a file: zBlob missing (broken symlink): )r   r   r   r   r   r   r   c              3   P   K   | ]  }|j                      j                    y wr   )r   st_mtime)r   r   
blob_statss     r%   r   z$_scan_cached_repo.<locals>.<genexpr>  s$     (fYeQUDNN)C)L)LYes   #&c              3   <   K   | ]  }|   j                     y wr   st_size)r   r   r   s     r%   r   z$_scan_cached_repo.<locals>.<genexpr>  s!      !CoiJy)11Cos   c              3   4   K   | ]  }|j                     y wr   )r   )r   r   s     r%   r   z$_scan_cached_repo.<locals>.<genexpr>   s     FobnZ^t~~bnr   )r<   r>   r?   r   r=   r@   z-Reference(s) refer to missing commit hashes: z (c              3   4   K   | ]  }|j                     y wr   )st_atimer   stats     r%   r   z$_scan_cached_repo.<locals>.<genexpr>0        O;N4;Nr   c              3   4   K   | ]  }|j                     y wr   )r   r   s     r%   r   z$_scan_cached_repo.<locals>.<genexpr>1  r   r   c              3   4   K   | ]  }|j                     y wr   r   r   s     r%   r   z$_scan_cached_repo.<locals>.<genexpr>>  s     F2E$2Er   )rI   rL   rN   rM   rO   r   rP   r@   )!is_dirr   r   splitreplacer   r   rr   r   globFILES_TO_IGNOREr4   relative_toopenreadrs   r   r   r   r   r   r   r   r   rH   maxr;   rx   popr   dictvaluesrK   )rN   rM   rL   snapshots_path	refs_pathrefs_by_hashref_pathref_namefr<   cached_revisionsrevision_pathcached_filesr   r   revision_last_modifiedrepo_last_accessedrepo_last_modified
repo_statsr   s                      @r%   r   r     s<   
 %(Fyk&RSS9>>!%(^_h^i&jkk"--dQ-?Iw#2IoodC(G55%FykQTU^T__ab
 	
 .0J,NF"I  ".*?*?*A%(TUcTd&eff
 )4C(8L ),Mi[*YZZ!v.H HMM_$D8//	:;HAffh ! %))(3 / 14'//10  "),VWdVe*fggu&++F3I!Y//1I##%-0OPY{.[\\
*(1(8
9%'nn'!+I!6!>!>''1)'<'E'E'1)'<'E'E	 42 |q %((fYe(f%f"%2%7%7%9%B%B")..-|//0B0BCEJK  !CFFobnFoCo!  ,4		
M 2h <1%;D<N;OrR[Q\\^_
 	
 :  O:;L;L;N OO  O:;L;L;N OO^^%
'00'00 Z,-F*2C2C2EFF((	 	W !s   !QQ	numc                 j    t        |       }dD ]  }t        |      dk  r	|d| c S |dz  }  |ddS )zkFormat size in bytes into a human-readable string.

    Taken from https://stackoverflow.com/a/1094933
    ) KMGTPEZg     @@z3.1fz.1fY)r7   abs)r   num_funits      r%   r-   r-   D  sM    
 #JE7u:D\$(( 8 C[?r(   ))secondr   <   )minuter   r   )houri     )dayiQ    )weeki:	 r   )monthi '    )yeari3Ntsc                     t        j                          | z
  }|dk  ryt        D ]  \  }}}t        ||z        }|||k  s n  d |dkD  rd dS d dS )zFormat timestamp in seconds into a human-readable string, relative to now.

    Vaguely inspired by Django's `timesince` formatter.
       za few seconds ago r   sr   z ago)time_TIMESINCE_CHUNKSround)r   deltalabeldivider	max_valuevalues         r%   r"   r"   ]  sz    
 IIK"Erz"%6!w	ego& Ui%7 &7 WAeWEAIS6d;;26d;;r(   rj   rc   c                 \   t         j                  d| d|         	 | j                         rt        j                  |        y	t        j                  |        y	# t        $ r! t         j                  d| d|  dd       Y y	t        $ r! t         j                  d| d|  dd       Y y	w xY w)
aE  Try to delete a local file or folder.

    If the path does not exists, error is logged as a warning and then ignored.

    Args:
        path (`Path`)
            Path to delete. Can be a file or a folder.
        path_type (`str`)
            What path are we deleting ? Only for logging purposes. Example: "snapshot".
    zDelete z: zCouldn't delete z: file not found ()T)exc_infoz: permission denied (N)
rh   ri   r   osrt   shutilrmtreeFileNotFoundErrorru   PermissionError)rj   rc   s     r%   rg   rg   l  s     KK')Btf-.b<<>IIdOMM$ _))4FtfANY]^ b))4I$qQ\`abs   %A A 'B+&B+*B+r   ).r3   r  r  r   collectionsr   dataclassesr   pathlibr   typingr   r   r   r	   r
   r   r   huggingface_hub.errorsr   r   commands._cli_utilsr   	constantsr   r   r   
get_loggerr0   rh   rX   r   r   r;   rK   rZ   rm   r4   r   r   r6   r-   r   r7   r"   rg   r9   r(   r%   <module>r     s   ; 	   # !  G G G I * $  
		H	%12 - $?/ ?/ ?/D $I I IX $RW RW RWj $HS HS HSV $i i iXshuS$Y'78 sK slD D. DN
c 
c 
	 <% <C <b4 bC bD br(   