
    ITh                        S r SSKrSSKrSSKrSSKJr  SSKJr  SSKJ	r	  SSK
JrJrJrJrJrJrJr  SSKJrJr  SS	KJr  SS
KJr  SSKJr  \R6                  " \5      r\S   rS/r\" SS9 " S S5      5       r \" SS9 " S S5      5       r!\" SS9 " S S5      5       r"\" SS9 " S S5      5       r#\" SS9 " S S5      5       r$S(S\\\%\	4      S\$4S jjr&S\	S\"4S jr'S \(S\%4S! jr)S"r*S#\+S\%4S$ jr,S%\	S&\%SS4S' jr-g))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                       \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \	\S'   \	\S'   \
S	\4S
 j5       r\
S	\4S j5       r\
S	\4S j5       rSrg)CachedFileInfo(   a  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                 ,    [        U R                  5      $ )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    \/var/www/auris/envauris/lib/python3.13/site-packages/huggingface_hub/utils/_cache_manager.pyblob_last_accessed_str%CachedFileInfo.blob_last_accessed_strM        !!8!899    c                 ,    [        U R                  5      $ )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_str%CachedFileInfo.blob_last_modified_strW   r)   r*   c                 ,    [        U R                  5      $ )zQ
(property) Size of the blob file as a human-readable string.

Example: "42.2K".
_format_sizer   r$   s    r&   size_on_disk_strCachedFileInfo.size_on_disk_stra        D--..r*    N)__name__
__module____qualname____firstlineno____doc__str__annotations__r   intfloatpropertyr'   r,   r1   __static_attributes__r4   r*   r&   r   r   (   sy    6 NOO: : : : : : /# / /r*   r   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \	\
   \S'   \	\   \S'   \\S'   \S	\4S
 j5       r\S	\4S j5       r\S	\4S j5       rSrg)CachedRevisionInfok   a  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                 ,    [        U R                  5      $ )z
(property) Timestamp of the last time the revision has been modified, returned
as a human-readable string.

Example: "2 weeks ago".
r#   rG   r$   s    r&   last_modified_str$CachedRevisionInfo.last_modified_str        !!3!344r*   c                 ,    [        U R                  5      $ zV
(property) Sum of the blob file sizes as a human-readable string.

Example: "42.2K".
r/   r$   s    r&   r1   #CachedRevisionInfo.size_on_disk_str   r3   r*   c                 ,    [        U R                  5      $ )z3
(property) Total number of files in the revision.
)lenrE   r$   s    r&   nb_filesCachedRevisionInfo.nb_files   s    
 4::r*   r4   N)r5   r6   r7   r8   r9   r:   r;   r   r<   r   r   r=   r>   rJ   r1   rR   r?   r4   r*   r&   rA   rA   k   s    &P ^$$
C.53 5 5 /# / / #  r*   rA   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \	\S'   \	\S'   \
\   \S'   \\S	'   \\S
'   \S\4S j5       r\S\4S j5       r\S\4S j5       r\S\\\4   4S j5       rSrg)CachedRepoInfo   a  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   rR   	revisionslast_accessedrG   r!   c                 ,    [        U R                  5      $ )z
(property) Last time a blob file of the repo has been accessed, returned as a
human-readable string.

Example: "2 weeks ago".
)r#   r[   r$   s    r&   last_accessed_str CachedRepoInfo.last_accessed_str   rL   r*   c                 ,    [        U R                  5      $ )z
(property) Last time a blob file of the repo has been modified, returned as a
human-readable string.

Example: "2 weeks ago".
rI   r$   s    r&   rJ    CachedRepoInfo.last_modified_str   rL   r*   c                 ,    [        U R                  5      $ rN   r/   r$   s    r&   r1   CachedRepoInfo.size_on_disk_str   r3   r*   c                 r    U R                    VVs0 s H  oR                    H  o"U_M     M     snn$ s  snnf )zA
(property) Mapping between `refs` and revision data structures.
)rZ   rF   )r%   revisionrefs      r&   rF   CachedRepoInfo.refs  s,    
 /3nnVn(XnVVVs   3r4   N)r5   r6   r7   r8   r9   r:   r;   REPO_TYPE_Tr   r<   r   rA   r=   r>   r]   rJ   r1   r   rF   r?   r4   r*   r&   rU   rU      s    #J LOM+,,53 5 5 53 5 5 /# / / Wd3 223 W Wr*   rU   c                       \ rS rSr% Sr\\S'   \\   \S'   \\   \S'   \\   \S'   \\   \S'   \	S\
4S	 j5       rSS jrSrg
)DeleteCacheStrategyi  a  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blobsrF   repos	snapshotsr!   c                 ,    [        U R                  5      $ )z\
(property) Expected size that will be freed as a human-readable string.

Example: "42.2K".
)r0   rj   r$   s    r&   expected_freed_size_str+DeleteCacheStrategy.expected_freed_size_str(  s     D4455r*   Nc                 2   U R                    H  n[        USS9  M     U R                   H  n[        USS9  M     U R                   H  n[        USS9  M     U R                   H  n[        USS9  M     [
        R                  SU R                   S35        g)	ab  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snapshotre   blobzCache deletion done. Saved .N)rl   _try_delete_pathrm   rF   rk   loggerinforo   )r%   paths     r&   executeDeleteCacheStrategy.execute1  s    . JJDTV4  NNDTZ8 # IIDTU3  JJDTV4  	1$2N2N1OqQRr*   r4   )r!   N)r5   r6   r7   r8   r9   r<   r;   r   r   r>   r:   ro   r{   r?   r4   r*   r&   ri   ri     sV    $ T?
D/T?6 6 6&Sr*   ri   c                       \ rS rSr% Sr\\S'   \\   \S'   \	\
   \S'   \S\4S j5       rS\S\4S	 jrS
S.S\S\4S jjrSrg)HFCacheInfoiZ  aD  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   rl   warningsr!   c                 ,    [        U R                  5      $ )zk
(property) Sum of all valid repo sizes in the cache-system as a human-readable
string.

Example: "42.2K".
r/   r$   s    r&   r1   HFCacheInfo.size_on_disk_strw  s     D--..r*   rZ   c                    [        U5      n[        [         5      nU R                   HV  nUR                   HC  nUR                  U;   d  M  X4   R                  U5        UR                  UR                  5        ME     MX     [        U5      S:  a'  [        R                  SSR                  U5       35        [        5       n[        5       n[        5       n[        5       n	Sn
UR                  5        GHD  u  pUR                  U-
  n[        U5      S:X  a+  UR                  UR                  5        XR                  -  n
MO  U H  nU	R                  UR                  5        UR                   H$  nUR                  UR                  S-  U-  5        M&     UR                    H  nUR"                  U;  d  M  SnU H=  nUR                    H!  nUR"                  UR"                  :X  d  M  Sn  O   U(       a  M=    O   U(       d  Mc  UR                  UR"                  5        U
UR                  -  n
M     M     GMG     [%        ['        U5      ['        U5      ['        U5      ['        U	5      U
S9$ )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: , rF   TF)rk   rF   rl   rm   rj   )setr   rl   rZ   rC   addremoverQ   rx   warningjoinitemsrY   r   rD   rF   rE   r   ri   	frozenset)r%   rZ   hashes_to_deleterepos_with_revisionsrr   rd   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_deletere   fileis_file_alonerev_files                      r&   delete_revisionsHFCacheInfo.delete_revisions  s1   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37Q7Q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                B   US:X  a  [        [        U R                  S S9 Vs/ s H  nUR                  UR                  SR                  UR                  5      UR                  UR                  UR                  SR                  [        UR                  5      5      [        UR                  5      /PM     sn/ SQS9$ [        [        U R                  S S9 VVs/ s H  n[        UR                  S	 S9  H  nUR                  UR                  UR                  SR                  UR                  5      UR                  UR                  SR                  [        UR                  5      5      [        UR                   5      /PM     M     snn/ S
QS9$ s  snf s  snnf )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                     U R                   $ NrY   rr   s    r&   <lambda>-HFCacheInfo.export_as_table.<locals>.<lambda>      DNNr*   )keyz{:>12}r   )REPO ID	REPO TYPESIZE ON DISKNB FILESLAST_ACCESSEDLAST_MODIFIEDREFS
LOCAL PATH)rowsheadersc                     U R                   $ r   r   r   s    r&   r   r   7  r   r*   c                     U R                   $ r   )rC   )rd   s    r&   r   r   8  s    PXPdPdr*   )r   r   REVISIONr   r   r   r   r   )r   sortedrl   rW   rX   formatr1   rR   r]   rJ   r   rF   r:   rY   rZ   rC   rD   )r%   r   rr   rd   s       r&   export_as_table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B1F
r4   N)r5   r6   r7   r8   r9   r<   r;   r   rU   r   r   r>   r:   r1   ri   r   r   r?   r4   r*   r&   r~   r~   Z  sx    . ^$$*++/# / /e
3 e
3F e
N 34 \C \ \ \r*   r~   	cache_dirr!   c                 *   U c  [         n [        U 5      R                  5       R                  5       n U R	                  5       (       d  [        SU  S3U S9eU R                  5       (       a  [        SU  S35      e[        5       n/ nU R                  5        H0  nUR                  S:X  a  M   UR                  [        U5      5        M2     [        [!        U5      [#        S U 5       5      US9$ ! [         a  nUR                  U5         SnAMy  SnAff = f)	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   8   #    U  H  oR                   v   M     g 7fr   )r   ).0rr   s     r&   	<genexpr>!scan_cache_dir.<locals>.<genexpr>  s     =ut**u   )rl   r   r   )r   r   
expanduserresolveexistsr   is_file
ValueErrorr   iterdirnamer   _scan_cached_repor   appendr~   r   sum)r   rl   r   rY   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6DDrY   c                 8	  ^ U R                  5       (       d  [        SU  35      eSU R                  ;  a  [        SU  35      eU R                  R                  SSS9u  pUSS nUR	                  SS5      nUS	;  a  [        S
U SU  S35      e0 mU S-  nU S-  nUR                  5       (       a  UR                  5       (       d  [        SU 35      e[        [        5      nUR                  5       (       a  UR                  5       (       a  [        SU 35      eUR                  S5       H  nUR                  5       (       d  UR                  [        ;   a  M.  [        UR                  U5      5      nUR                  5        nUR                  5       n	SSS5        UW	   R                  U5        M     [        5       n
UR!                  5        GH  nUR                  [        ;   a  M  UR                  5       (       a  [        SU 35      e[        5       nUR                  S5       H  nUR                  5       (       a  M  [#        U5      R%                  5       nUR                  5       (       d  [        SU 35      eUT;  a  UR'                  5       TU'   UR                  [)        UR                  UTU   R*                  UTU   R,                  TU   R.                  S95        M     [1        U5      S:  a  [3        U4S jU 5       5      nOUR'                  5       R.                  nU
R                  [5        UR                  [7        U5      [7        UR9                  UR                  [        5       5      5      [;        U4S j[        S U 5       5       5       5      UUS95        GM     [1        U5      S:  a  [        S[=        U5       SU  S35      e[1        T5      S:  aA  [3        S TR?                  5        5       5      n[3        S TR?                  5        5       5      nO(U R'                  5       nUR,                  nUR.                  n[A        [1        T5      UU U[7        U
5      [;        S TR?                  5        5       5      UUS9$ ! , (       d  f       GN= f) z~Scan 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).rm   rF   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   V   >#    U  H  nTUR                      R                  v   M      g 7fr   )r   st_mtime)r   r   
blob_statss     r&   r   $_scan_cached_repo.<locals>.<genexpr>  s#     (fYeQUDNN)C)L)LYes   &)c              3   B   >#    U  H  nTU   R                   v   M     g 7fr   st_size)r   r   r   s     r&   r   r     s       !CoiJy)11Cos   c              3   8   #    U  H  oR                   v   M     g 7fr   )r   )r   r   s     r&   r   r      s     FobnZ^~~bnr   )rC   rE   rF   r   rD   rG   z-Reference(s) refer to missing commit hashes: z (c              3   8   #    U  H  oR                   v   M     g 7fr   )st_atimer   stats     r&   r   r   0        O;N4;Nr   c              3   8   #    U  H  oR                   v   M     g 7fr   )r   r   s     r&   r   r   1  r   r   c              3   8   #    U  H  oR                   v   M     g 7fr   r   r   s     r&   r   r   >  s     F2E$2Er   )rR   rW   rY   rX   rZ   r   r[   rG   )!is_dirr   r   splitreplacer   r   r   r   globFILES_TO_IGNOREr:   relative_toopenreadr   r   r   r   r   r   r   r   r   rQ   maxrA   r   popr   dictvaluesrU   )rY   rX   rW   snapshots_path	refs_pathrefs_by_hashref_pathref_namefrC   cached_revisionsrevision_pathcached_filesr   r   revision_last_modifiedrepo_last_accessedrepo_last_modified
repo_statsr   s                      @r&   r   r     sU   
 %(Fyk&RSS9>>!%(^_h^i&jkk"--dQ-?I#2IoodC(G55%FykQTU^T__ab
 	
 .0J,NF"I  "".*?*?*A*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   R


R	numc                 p    [        U 5      nS H   n[        U5      S:  a	  US U 3s  $ US-  nM"     US S3$ )zcFormat 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)r=   abs)r   num_funits      r&   r0   r0   D  sM    
 #JE7u:D\$(( 8 C[?r*   ))secondr   <   )minuter  r  )houri     )dayiQ    )weeki:	 r	  )monthi '    )yeari3Ntsc                     [         R                   " 5       U -
  nUS:  a  g[         H  u  p#n[        X-  5      nUc  M  XT::  d  M    O   W SW US:  a  S S3$ S S3$ )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#   ]  st    
 IIK"Erz"%6!	eo& U%7 &7 WAeWEAIS6d;;26d;;r*   rz   rs   c                 b   [         R                  SU SU  35         U R                  5       (       a  [        R                  " U 5        g	[
        R                  " U 5        g	! [         a    [         R                  SU SU  S3SS9   g	[         a    [         R                  SU SU  S3SS9   g	f = f)
a)  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)
rx   ry   r   osr   shutilrmtreeFileNotFoundErrorr   PermissionError)rz   rs   s     r&   rw   rw   l  s     KK')Btf-.b<<>>IIdOMM$ _))4FtfANY]^ b))4I$qQ\`abs   +A  	A   %B.$B.-B.r   ).r9   r  r  r  collectionsr   dataclassesr   pathlibr   typingr   r   r   r	   r
   r   r   huggingface_hub.errorsr   r   commands._cli_utilsr   	constantsr   r   r   
get_loggerr5   rx   rg   r   r   rA   rU   ri   r~   r:   r   r   r<   r0   r  r=   r#   rw   r4   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*   