
    5pjk                        S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKJrJr  SSKJr  SSKJr  SSKJr  SSK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#J$r$J%r%J&r&  S
SK'J(r(J)r)J*r*J+r+J,r,J-r-  S
SK.J/r/J0r0  S
SK1J2r2  \(       a  S
SK3J4r4  S
SK5J6r6  \2" S5      r7Sr8 " S S5      r9 " S S\95      r:Sr;\Rx                  SS.S!S jj5       r=S"S jr>S#S jr?S$S jr@ S%             S&S jjrA " S S 5      rBg)'a  Internal file download implementation.

Supports single-file and whole-repo (snapshot) downloads with:
- HTTP Range-based resume
- SHA256 integrity verification
- tqdm progress display
- Parallel downloads via ThreadPoolExecutor
- Parallel range download (split large files into parts)
- Per-file download retry with backoff
- File lock for multiprocess safety
- User-agent / snapshot headers
- Intra-cloud acceleration
- Local-files-only (offline) mode
- Custom progress callbacks
- Local snapshot cache directory management
    )annotationsN)ThreadPoolExecutoras_completed)Path)TYPE_CHECKING)urlparse)tqdm)Retry   )
DOWNLOAD_CHUNK_SIZEDOWNLOAD_PARALLEL_THRESHOLDDOWNLOAD_PARALLELSDOWNLOAD_PART_SIZEDOWNLOAD_RETRY_TIMESDOWNLOAD_TIMEOUTENV_FILE_LOCKENV_INTER_CLOUD_REGIONSENV_INTRA_CLOUD_ACCELERATIONENV_INTRA_CLOUD_REGION)CacheNotFoundFileIntegrityErrorNetworkErrorNotExistErrorPermissionDeniedErrorRequestTimeoutError)compute_hash
ensure_dir)
get_logger)LegacyClient)	HubConfigdownload   c                  6    \ rS rSrSrSS jrS	S jrS
S jrSrg)ProgressCallbackK   zBase class for download progress callbacks.

Subclass and override :meth:`update` / :meth:`end` to track download
progress. Instances are created per-file by
``callback_cls(filename, file_size)``.
c                    Xl         X l        g N)filename	file_size)selfr(   r)   s      T/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/modelscope_hub/_download.py__init__ProgressCallback.__init__S   s     "    c                    g r'    r*   sizes     r+   updateProgressCallback.updateW       r.   c                    g r'   r0   r*   s    r+   endProgressCallback.endZ   r5   r.   )r)   r(   Nr(   strr)   intr2   r<   returnNoner>   r?   )	__name__
__module____qualname____firstlineno____doc__r,   r3   r8   __static_attributes__r0   r.   r+   r$   r$   K   s    #r.   r$   c                  D   ^  \ rS rSrSrSU 4S jjrSS jrS	S jrSrU =r	$ )
TqdmCallback^   z!Progress callback backed by tqdm.c           
     x   > [         TU ]  X5        [        SSSUS:  a  UOSSSU R                   S3SS9U l        g )	NBTi   r   r   zDownloading [])unit
unit_scaleunit_divisortotalinitialdescleave)superr,   r	   r(   progress)r*   r(   r)   	__class__s      r+   r,   TqdmCallback.__init__a   sF    -(1})! q1
r.   c                :    U R                   R                  U5        g r'   )rU   r3   r1   s     r+   r3   TqdmCallback.updatem   s    T"r.   c                8    U R                   R                  5         g r'   )rU   closer7   s    r+   r8   TqdmCallback.endp   s    r.   )rU   r:   r=   r@   )
rA   rB   rC   rD   rE   r,   r3   r8   rF   __classcell__)rV   s   @r+   rH   rH   ^   s    +

# r.   rH   i   Tenabledc          	   #    #    U(       a  U c  Sv   gSSK JnJnJn  U R                  R                  SSS9  SnU" [        U 5      US9nSnSn  UR                  US9    Uv    UR-                  5         g! U a    X-  nU(       a  U[        :  a   [        R                  " 5       U R                  5       R                  -
  n	O! [         a    Sn	 Of = fU	[        :  a=  [        R                  S	U	U 5         U R                  SS
9  O! [         a     Of = fSn M  [        R!                  SU 5         O["         aD  n
S[        U
5      ;   a/  [        R                  SU 5        U" [        U 5      US9nSn Sn
A
GM.  e Sn
A
f[         a~  n
U
R$                  [$        R&                  [$        R(                  [+        [$        SS5      4;   a:  [        R                  SU
R$                  U 5        U" [        U 5      US9nSn Sn
A
GM  e Sn
A
ff = fGM  ! [         a%     U R                  5          g! [         a      gf = ff = f!  UR-                  5         f ! [         a%     U R                  5          f ! [         a      f f = ff = f= f7f)z4Acquire a file lock when *enabled*, otherwise no-op.Nr   )FileLockSoftFileLockTimeoutTparentsexist_ok<   timeoutFz4Removing possibly stale SoftFileLock (age=%.0fs): %s
missing_okz#Still waiting to acquire lock on %szuse SoftFileLock insteadzFFilesystem does not support flock, falling back to SoftFileLock for %s	EREMOTEIOz7OSError (errno=%d) on %s, falling back to SoftFileLock.)filelockra   rb   rc   parentmkdirr;   acquire_STALE_LOCK_SECONDStimestatst_mtimeOSErrorloggerwarningunlinkinfoNotImplementedErrorerrnoESTALEENOENTgetattrrelease)	lock_pathr_   ra   rb   rc   default_intervallockis_softwaitedageexcs              r+   _optional_file_lockr   z   sk     i'884$7C	N,<=DGF
/	LL!1L2\ 	
	LLNg  	&F6%88))+	(8(A(AAC C--NNN!
!((D(9" FKK5 # 		)SX5\ $C	N<LM 
	yyU\\5<<UW9XYYMII
 $C	N<LM
	I n  	  " 		LLN 	  " 	sE  AJA5 JH> $H 4J5H0CHCHC$H6DH
DHDHJH1J3	H<7E;3J:E;;HA1H9J HHJ
H;H)'J)
H73H;4J6H77H;;J>J IJ
J I.,J.
I<	8J 9J;I<	<J  JJc                 (    SSK Jn   U " [        S5      $ )z6Check whether file locking is enabled via environment.r   	_env_boolT)	constantsr   r   r   s    r+   _file_lock_enabledr      s    $]D))r.   c                    U(       d  gU HW  n[         R                   " X5      (       a    gSU;   d  M(  UR                  SS5      n[         R                   " X5      (       d  MW    g   g)zCheck if path matches any of the glob patterns.

Also accepts legacy regex-style patterns (e.g. ``.*\.bin``) by
converting ``.*`` to ``*`` before matching.
FTz.**)fnmatchreplace)pathpatternspatglob_pats       r+   _matches_patternsr      sT     ??4%%3;{{4-Ht..  r.   c           	        U u  pp4pVpxUc  0 O[         R                  " U5      n	[        R                  " 5       R                  U	S'   [        [        SS/S9n
U SU SU 3n  Sn[        R                  R                  U5      (       aO  [        US	5       nUR                  S[        R                  5      nU H  nUR                  U5        M     SSS5        X<-   nX:  a  gS
U SU 3U	S'   [        US5       n[        R                   " USU	U["        S9nUR%                  5         UR'                  [(        S9 H@  nU(       d  M  UR+                  U5        U H  nUR                  [-        U5      5        M     MB     SSS5        g! , (       d  f       N= f! , (       d  f       N = f! [.         aB  nU
R1                  SUUS9n
[2        R5                  SX4U5        U
R7                  5          SnAOSnAff = fGM  )z4Download a byte range with retry and resume support.NX-Request-IDr   GETrP   backoff_factorallowed_methods_Tr   rbbytes=-Rangezab+)streamheaderscookiesri   
chunk_sizeerrorz-Downloading part %s-%s failed: %s, will retry)copydeepcopyuuiduuid4hexr
   r   osr   existsopenseekioSEEK_ENDr3   requestsgetr   raise_for_statusiter_contentr   writelen	Exception	incrementrw   rx   sleep)params	file_pathprogress_callbacksstartr8   url	file_namer   r   get_headersretrypart_file_namepartial_lengthfcbdownload_startrchunkr   s                      r+   _download_part_with_retryr      s   RXOI5sw"T]]7-CK"&**,"2"2K"E
 "{!E7!C51N
	Nww~~n--.$/1%&VVAr{{%;N0		.1 1 0 #3N#%+N+;1SE#BK ne,LL'#, ""$^^7J^KEu"4BIIc%j1 #5 L - - 0/ -,  	OOE3cO:ENNJEX[\KKMM	7 sU   !2F& ;FF&  F& 7AF8F;F& 
FF& 
F#F& &
G208G--G2c                X   U=(       d    / n[         n/ n[        U5      n	UR                  R                  SSS9  X'-  n
[	        U
5       H1  nX-  nUS-   U-  S-
  nUR                  XXXR                  X445        M3     X-  nX:  a"  UR                  XXS-
  XR                  X445        [        [        S5      n[        USS9 n[        UR                  [        U5      5        SSS5        U H  nUR                  5         M     [        R                  " 5       nUR!                  UR"                  S-   5      n[%        US	5       nU H  nUS
    SUS    SUS    3n[%        US5       n UR'                  S[(        -  5      nU(       d  O$UR+                  U5        UR-                  U5        MD  SSS5        [.        R0                  " U5        M     SSS5        UR3                  U5        UR5                  5       $ ! , (       d  f       GN= f! , (       d  f       Nc= f! , (       d  f       NR= f)zkSplit a large file into parts and download in parallel.

Returns the SHA256 hex digest of the merged file.
Trd   r      r!   )max_workersthread_name_prefixNz.parallel_tmpwbr   r      r"   r   )r   r;   ro   rp   rangeappendnameminr   r   listmapr   r8   hashlibsha256with_suffixsuffixr   readr   r   r3   r   remover   	hexdigest)r   targetr)   r   r   r   	callbacks	part_sizetasksr   num_full_partsidxr   r8   remainder_start	parallelsexecutorr   hash_sha256
tmp_targetoutput_filetaskr   	part_filer   s                            r+   _parallel_downloadr     s    #(bI"IEFI
MMt4+N^$Qw)#a'iE[['[\ % %0O"iO]CQ\Q\^eop&+I		j	QU]X\\3U;< 
R 
  .."K##FMMO$CDJ	j$	;D $Qy$q'!DG9=Nnd+y%NN20C+CDE %%e,&&u-  , IIn%  
  v  "") 
R	Q ,+ 
 	s1    G8%H'AH
-"H8
H

HH
H)c                  X   \ rS rSrSrSS jrSSS jjrSS jr\R                  " S5      r
\SS j5       r\  S         SS	 jj5       rSS
 jr  S          S!S jjr S   S"S jjr         S#                         S$S jjr         S%                       S&S jjr          S'S jr\S(S j5       r S       S)S jjr S       S*S jjr  S          S+S jjrSSSS.                 S,S jjrS-S jrSrg).DownloadManageriH  zoInternal file download implementation.

Dependencies are injected via constructor to keep this class testable.
c                l    Xl         X l        S U l        0 U l        [        R
                  " 5       U l        g r'   )_client_config_cached_region_inter_region_cache	threadingLock_inter_region_lock)r*   legacy_clientconfigs      r+   r,   DownloadManager.__init__N  s/    $*. SU "+.."2r.   Nc                L    SSK Jn  U" U R                  R                  5       US9$ )Nr   )build_user_agent)
session_idextra)utilsr   r   get_session_id)r*   
user_agentr   s      r+   _build_user_agent!DownloadManager._build_user_agentZ  s%    +||224
 	
r.   c                T   U R                   b  U R                   $ U R                  R                  nU S3nSS jnSnU" US5      nUbZ  UR                  5       nSnSU;   a  US   R	                  SS5      nU(       a&  U" US5      nUb  UR
                  R                  5       nX@l         U$ )z<Detect Alibaba cloud region ID for intra-cloud acceleration.z&/api/v1/repos/internalAccelerationInfoc                     [         R                  " XS9nUR                  5         U$ ! [         R                  R                   a     g f = f)Nrh   )r   r   r   
exceptionsRequestException)r   ri   resps      r+   _get,DownloadManager._detect_region.<locals>._getj  sD    ||C9%%'&&77 s   %( A	A	 g?DataInternalRegionQueryAddress)r   r;   ri   float)r   r   endpointjsonr   textstrip)	r*   r  internal_urlr
  	region_idr	  data
query_addrdomain_resps	            r+   _detect_regionDownloadManager._detect_regionb  s    *&&&<<(("#IJ	 	L#&99;DJ~!&\--.JBO
":s3* + 0 0 6 6 8I'r.   z".*\.oss.*-internal\.aliyuncs\.com$c                     [        U 5      R                  =(       d    Sn[        [        R
                  R                  U5      5      $ ! [         a     gf = f)zCheck if a URL points to an OSS internal (intranet) endpoint.

Matches hostnames like:
    modelhub-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com
r  F)r   hostnamer   boolr   _OSS_INTERNAL_REmatch)r   hosts     r+   _is_oss_internal_url$DownloadManager._is_oss_internal_url  sM    	C=))/RD O44::4@AA  		s   A 
AAc                     [         R                  " U UUSUS9nUR                  S;   a  UR                  R	                  SS5      $  g! [         R
                  R                   a     gf = f)zHSend a HEAD request without following redirects to get the 302 Location.F)r   r   allow_redirectsri   )i-  i.  i/  i3  i4  Locationr  )r   headstatus_coder   r   r  r  )r   r   r   ri   r   s        r+   _probe_redirect_url#DownloadManager._probe_redirect_url  su    	 %A }} 99yy}}Z44 :  ""33 		s   AA A)(A)c                    SSK Jn  U" [        S5      =(       d    SnUR                  S5       Vs/ s H7  o3R	                  5       (       d  M  UR	                  5       R                  5       PM9     sn$ s  snf )z;Read the inter-cloud peer region list from the environment.r   )_env INTER_CLOUD_ACCELERATION_REGIONSr  ,)r   r+  r   splitr  lower)r*   r+  rawr   s       r+   _get_inter_cloud_regions(DownloadManager._get_inter_cloud_regions  sO    #*,NOUSU+.99S>G>aWWY!	!>GGGs   A1"A1c                   Uc  U R                  5       nU(       d  US4$ UR                  SS5      R                  5       nU R                  XU5      nU R	                  U5      (       a  [
        R                  S5        US4$ U HV  nXu:X  a  M
  0 UESU0EnU R                  XU5      nU R	                  U5      (       d  M<  [
        R                  SU5        US4s  $    [
        R                  S5        US4$ )	u  Probe peer regions and return headers with the best region for OSS internal download.

Steps:
1. Probe with current (local) region — if already OSS internal, return as-is.
2. Try each peer region in order (skip duplicates of local) — first OSS internal hit wins.
3. If all miss, fall back to original headers (default path).

Returns:
    (headers, source) where source is "local", "peer", or "default".
defaultx-aliyun-region-idr  zEInter-region: local region already yields OSS internal URL, skipping.localzAInter-region acceleration: using peer region "%s" (OSS internal).peerzIInter-region: no peer region yields OSS internal URL, using default path.)r1  r   r/  r(  r!  rw   debug)	r*   r   r   r   peer_regionscurrent_regionredirect_urlpeer_regionprobe_headerss	            r+   _resolve_inter_region_headers-DownloadManager._resolve_inter_region_headers  s    " 88:LI%% %92>DDF //gF$$\22LL`aG## (K,JwJ(<kJM33CPL((66W %f,, ( 	`a	!!r.   c                N   SSK JnJn  U R                  U5      [        R
                  " 5       R                  S.nU" [        S5      (       aG  U" [        S5      =(       d    SR                  5       nU(       d   U R                  5       nU(       a  XTS'   U$ ! [         a    Sn Nf = f)Nr   )r+  r   )z
user-agentzsnapshot-identifierTINTRA_CLOUD_ACCELERATION_REGIONr  r5  )r   r+  r   r  r   r   r   r   r   r  r  r   )r*   r  r+  r   r   regions         r+   _build_download_headers'DownloadManager._build_download_headers  s     	/ 00<#'::<#3#3#
 148813TU[Y[bbdF !002F 06,-	 !  F s   8B B$#B$c                ~   Ub  [        U5      U-  nO7U R                  XU5      nUb  X-  nOU R                  XU5      nUS-  U-  U-  nU	(       a4  UR                  5       (       a  U$ [	        S[        UR                  5      S9eU(       d  U R                  X5      (       a  U$ [        5       nU(       a  U R                  XXSS9OSn[        UUS9   U(       d!  U R                  X5      (       a  UsSSS5        $ [        UR                  5        [        [        5       H4  nU R                  UUUUUU
UUS9  U(       d    O U R                  X5          O   SSS5        U$ ! [          a@    U[        S-
  :  a1  ["        R%                  S	UUS-   [        5        UR'                  S
S9   M  e f = f! , (       d  f       U$ = f)a8  Download a single file from a repository.

When *local_dir* is provided the file is placed directly under that
directory (preserving relative path structure).  Otherwise the
standard cache layout is used::

    {cache_dir}/{type}s/{owner}--{name}/snapshots/{revision}/{file_path}

Parameters
----------
repo_id:
    Repository identifier (``owner/name``).
repo_type:
    One of the :class:`~.constants.RepoType` values.
file_path:
    Path within the repository.
revision:
    Branch, tag, or commit hash.
cache_dir:
    Override for the default cache directory.
local_dir:
    When set, download directly into this directory instead of cache.
force:
    Re-download even if file exists in cache.
expected_sha256:
    When provided, verify downloaded file hash and use it for
    cache hit validation.
local_files_only:
    When ``True``, return the cached path without network access.
    Raises ``ValueError`` if the file is not cached.
file_size:
    Known file size (enables parallel range download for large files).
user_agent:
    Custom user-agent info appended to the default UA string.
progress_callbacks:
    List of :class:`ProgressCallback` *classes* (not instances).
    Each class is instantiated per-file with ``(filename, file_size)``.

Returns
-------
Path
    Absolute path to the downloaded (or cached) file on disk.
N	snapshotsCannot find the requested files in the cached path and outgoing traffic has been disabled. To enable look-ups and downloads online, set 'local_files_only' to False.	cache_dir)rI  r   r^   r)   r  r   r   z/Hash validation failed for %s, retrying (%d/%d)Trj   )r   _find_legacy_repo_dir_repo_cache_dirr   r   r;   ro   
_cache_hitr   
_lock_pathr   r   r   DOWNLOAD_HASH_RETRY_TIMES_download_with_resumeverify_filer   rw   rx   ry   )r*   repo_id	repo_typer   revisionrI  	local_dirforceexpected_sha256local_files_onlyr)   r  r   r   legacyrootuse_lockr   attempts                      r+   download_fileDownloadManager.download_file  s   t  )_y0F //INF!+++G	J+h6B}}< fmm,	  AAM%'emDOOG)Oasw	 H=T__VEE >=
 v}}% !:;**')'9 + 	 '$$V=# < >J  * 
!:Q!>>M%#aK5	 6
3 >=J s8   F-:AF-E F- AF*%F-(F**F--
F<c                   Ub  [        [        U5      5      nOSU R                  XU5      nUb  [        R	                  SU5        UnUnO#U R                  XU5      n[        US-  U-  5      nU	(       aI  [        UR                  5       5      (       a  [        R                  SU5        U$ [        S[        U5      S9eUS;   a  U R                  UUUUS9$ US	;   a  U R                  R                  UUS
9nOU R                  R                  UUUSS9n/ nU GHH  nUR                  S5      =(       d2    UR                  S5      =(       d    UR                  S5      =(       d    SnUR                  S5      =(       d    UR                  S5      =(       d    SnUS:X  a  M  U(       d  M  U(       a  [!        UU5      (       d  M  U(       a  [!        UU5      (       a  M  UR                  S5      =(       d    UR                  S5      =(       d    SnUR                  S5      =(       d    UR                  S5      nU(       a  [#        U5      OSnUR%                  UUU45        GMK     U(       d  [        R	                  SX5        U$ [        R	                  S['        U5      X5        / n[)        US9 nU VVVs0 s H+  u  nnnUR+                  U R,                  UUUUUUUUU
US9U_M-     nnnn[/        ['        U5      SSS9 n[1        U5       H*  nUU   n UR3                  5         UR9                  S"5        M,     SSS5        SSS5        U(       a  [        R                  S#['        U5      5        U$ s  snnnf ! [4         a7  nUR%                  U S U 35        [        R7                  S!UU5         SnANSnAff = f! UR9                  S"5        f = f! , (       d  f       N= f! , (       d  f       N= f)$ad  Download an entire repository (snapshot download).

Parameters
----------
repo_id:
    Repository identifier (``owner/name``).
repo_type:
    One of the :class:`~.constants.RepoType` values.
revision:
    Branch, tag, or commit hash.
cache_dir:
    Override for the default cache directory.
local_dir:
    When set, download directly into this directory instead of cache.
allow_patterns:
    Only files matching these globs will be downloaded.
ignore_patterns:
    Files matching these globs will be skipped.
max_workers:
    Number of parallel download threads.
local_files_only:
    When ``True``, return the cached snapshot path without network.
user_agent:
    Custom user-agent info for download headers.
progress_callbacks:
    List of :class:`ProgressCallback` *classes* (not instances).

Returns
-------
Path
    Absolute path to the snapshot/local directory.
Nz"Found legacy cache at %s, reusing.rF  z2Cannot confirm the cached file is for revision: %srG  rH  )skillskills)rR  rS  rT  
output_dir)datasetdatasets)rR  rT  T)rR  rS  rT  	recursiver   r   Namer  TypetypeblobtreeSha256r   Sizer2   zNo files to download for %s@%szDownloading %d files from %s@%s)r   )
rR  rS  r   rT  rI  rU  rW  r)   r  r   Downloadingfile)rP   rR   rM   : zFailed to download %s: %sr   z%d file(s) failed to download)r   r   rK  rw   rz   rL  anyiterdirrx   r   r;   _download_archiver   list_dataset_files_paginatedlist_repo_filesr   r   r<   r   r   r   submitr]  r	   r   resultr   r   r3   )r*   rR  rS  rT  rI  rU  allow_patternsignore_patternsr   rX  r  r   rb  rY  rZ  filesdownload_itemsr   r   ftyper   raw_sizer2   errorsr   fpfuturespbarfuturer   s                                 r+   download_repoDownloadManager.download_repor  s   \  #DO4J //INF!8 $
"	++G	J'{(:X(EF
:%%'((SU]^!!< j/	  ++))#!%	 *   //LL==! > E
 LL00#!	 1 E DFA55=HAEE&MHQUU6]HbDEE&M<QUU6]<fE&7n&M&M#4T?#K#KUU8_?h?4FuuV}5fH$,3x=$D!!4"67   KK8'L5s>7JG^K8H )7 )7$B &&#' %''$*")'9     )7  " C/m&QUY*73F B'
 A 4 R% 9: NN:CKH?, % KBsen5%@"cJJK A RQ% 98sl   ,O!32M/
%O!=OM6"O7O!/O!6
N7	 -N2	-N:2N7	7N::O	O
O	O!!
O/c                   SSK nSSKnSSKnSn U R                  R	                  UUUS9n	UR                  SSS9 n
[        U
R                  5      nU	R                  [        S9 H  nU(       d  M  U
R                  U5        M     SSS5        UR                  US5       nUR                  U5        SSS5        UR                  5        Vs/ s H  oPM     nn[        U5      S	:X  au  US   R                  5       (       a]  US   nUR                  5        H4  nUR!                  [#        U5      [#        UUR                  -  5      5        M6     UR%                  5         Ub  UR'                  S
S9  [(        R+                  SX5        U$ ! , (       d  f       GN= f! , (       d  f       N= fs  snf ! Ub  UR'                  S
S9  f f = f)zDownload a repo via its zip archive endpoint and extract.

Skill repos do not support per-file ``/repo?FilePath=...`` download.
The old SDK uses ``/archive/zip/{revision}`` for these.
r   N)rR  rS  rT  z.zipF)r   deleter   r   r   Trj   zExtracted archive for %s to %s)shutiltempfilezipfiler   download_archiveNamedTemporaryFiler   r   r   r   r   ZipFile
extractallrq  r   is_dirmover;   rmdirry   rw   rz   )r*   rR  rS  rT  rb  r  r  r  tmp_pathr	  tmpr   zfeentriesnesteditems                    r+   rr  !DownloadManager._download_archive  s    	 $	1<<00#! 1 D ,,F5,IS>!..:M.NEu		%( O J 3/2j) 0 #-"4"4"67"6Qq"6G77|q WQZ%6%6%8%8 "NN,DKKD	3zDII/E+FG -#404gJ+ JI 0/ 8 #40 $sM   +F. 1F0FF. F1F. F)BF. 
FF. 
F&"F. .Gc                    U R                  5       (       d  gU(       a?  [        U S5      nX!:w  a  [        R                  SU 5        g[        R                  SU 5        g[        R                  SU 5        g)z>Return True if *target* exists and passes optional hash check.Fr   zCache stale (hash mismatch): %szCache hit (hash verified): %szCache hit: %sT)r   r   rw   r8  )r   rW  actuals      r+   rM  DownloadManager._cache_hit?  s`     }}!&(3F(>GLL8&A  LL&1r.   c                    U=(       d    U R                   R                  nUR                  S5      (       d  U S3OUnUR                  SS5      n[	        XE-  U-  5      $ )z-Compute the cache directory for a given repo.s/z--)r   rI  endswithr   r   )r*   rR  rS  rI  basesegmentsafe_ids          r+   rL  DownloadManager._repo_cache_dirN  sW     2DLL22)2););C)@)@YKq/i//#t,$.7233r.   c                   U=(       d    U R                   R                  nUR                  S5      (       d  U S3OUnUR                  SS5      n[	        U5      S:w  a  gUu  pxUR                  SS5      n	XE-  U-  U	-  US-  U-  U-  U	-  4n
U
 H=  nUR                  5       (       d  M   [        UR                  5       5      (       a  Us  $ M?     g! [         a     MO  f = f)	a  Check for old SDK (<=1.37) cache layout and return it if non-empty.

Old SDKs encoded dots in the repo name as ``___`` and, when no
``MODELSCOPE_CACHE`` was set, stored everything under a ``hub/``
sub-directory of the cache root. Both historical layouts are probed,
in priority order::

    {base}/{type}s/{owner}/{name___}        # MODELSCOPE_CACHE explicitly set
    {base}/hub/{type}s/{owner}/{name___}    # default cache (~/.cache/modelscope/hub)

e.g.  ~/.cache/modelscope/hub/models/Qwen/Qwen3___5-0___8B/

Returns the first existing, non-empty candidate, or ``None`` when the
cache is clean (so the caller falls back to the new layout).
r  r  r   r   N.___hub)
r   rI  r  r.  r   r   r  rp  rq  rv   )r*   rR  rS  rI  r  r  partsownerr   	safe_name
candidateslegacy_paths               r+   rK  %DownloadManager._find_legacy_repo_dirZ  s    * 2DLL22)2););C)@)@YKq/ic1%u:?LLe,	NU"Y.5L7"U*Y6

 &K%%''{**,--&& .	 &   s   *C
CCc                    U=(       d    U R                   R                  nUR                  SS5      nUb3  UR                  SS5      R                  SS5      nUS-  U SU SU S3-  $ US-  U SU S3-  $ )z4Compute the lock file path for a given repo or file.r  r  r  r   z.lock)r   rI  r   )r*   rR  rS  rI  r   r  r  	safe_files           r+   rN  DownloadManager._lock_path  s     2DLL22//#u- !))#u5==c3GI'>yk7)1YKu$MMMg~9+Qwiu ===r.   rJ  c          
     |   USL=(       a    U[         :  =(       a	    [        S:  n	U R                  U5      n
SnU R                  5       nU(       a  X4nU R                     U R
                  R                  U5      nUc   U R                  R                  UUUU5      nSnU R                  R                  (       a  SU R                  R                  0nU R                  UU
UUS9u  n
nU
R                  S5      nUU4U R
                  U'   SSS5        Wc  U R
                  R                  U5      nUb  Uu  nnUb  UU
S'   S	S
SS.U   nU	(       a  Uc   eU R                  R                  UUUU5      nSnU R                  R                  (       a  SU R                  R                  0n/ nU(       a  U Vs/ s H  nU" X65      PM     nn[        UUUU
UUS9  U$ [        U=(       d    / 5      nU Vs/ s H  nU" X6=(       d    S5      PM     nn[!        ["        SS/S9nUR%                  UR&                  S-   5      n  SnUR)                  5       (       a4  UR+                  5       R,                  nU H  nUR/                  U5        M     [0        R2                  " U
5      n[4        R6                  " 5       R8                  US'   US:  a  SU S3US'   [        R;                  SU5         U R                  R=                  UUUUUS9nURJ                  R                  S5      nU(       a  [M        U5      OSnURN                  S:H  n U (       a  U(       a  UU-  nU (       a  SOS n!U (       d  Sn[Q        UUS!SU [S        U5      RT                   3S"S#9 n"[W        UU!5       n#URY                  [Z        S$9 HZ  n$U$(       d  M  U#R]                  U$5        U"R/                  [_        U$5      5        U H  nUR/                  [_        U$5      5        M     M\     SSS5        SSS5        URa                  U5        U H  nURc                  5         M     [        R;                  S%U5        U$ ! [         a2  n[        R                  SU5        SU R
                  U'   Sn SnAGNSnAff = f! , (       d  f       GN= fs  snf s  snf ! [>        R@                   a  n[C        SU SU 35      UeSnAf[>        RD                   a  n[G        SU SU 35      UeSnAf[>        RH                   a  n[G        SU SU 35      UeSnAff = f! , (       d  f       GN4= f! , (       d  f       GN>= f! [d        [f        4 a    e [         aB  nURi                  SUUS&9n[        R                  S'UU5        URk                  5          SnAOSnAff = fGM  )(z9Download a file with HTTP Range resume support and retry.Nr   r  m_session_id)r9  r5  zIFailed to resolve inter-region acceleration: %s. Falling back to default.)Nr4  u   ⚡ u   ⇄ z  )r6  r7  r4  )r   r   r)   r   r   r   r   r   r   z.incompleteTr   r   r   r   zResuming download from byte %d)rR  rS  r   rT  r   zDownload timed out for ro  zDownload connection failed for zDownload failed for zContent-Length   abr   rK   F)rP   rQ   rM   rN   rR   rS   r   zDownloaded: %sr   z&Download failed for %s: %s, will retry)6r   r   rC  r1  r   r   r   r   get_download_urltokenr>  r   rw   rx   r   r   r
   r   r   r   r   rt   st_sizer3   r   r   r   r   r   r8  download_streamr   rc   r   ConnectionErrorr   r  r   r<   r'  r	   r   r   r   r   r   r   r   r   r8   r   r   r   r   )%r*   rR  rS  r   rT  r   r)   r  r   use_paralleldownload_headerssource_prefixr9  	cache_keycached	probe_urlr   sourceresolved_regionr   r   cb_instancescls
cb_classesr   r  existing_sizer   extra_headersr	  content_length
total_size
is_resumedmoder  fhr   s%                                        r+   rP  %DownloadManager._download_with_resume  s    !,s=X1Xs]ors]s77
C 446 ,I((1155i@>3$(LL$A$A#%%$	%	 #'<<--'5t||7I7I&JG373U3U%,#)5	 4V 40(& +;*>*>?S*T?NPV>W00;- )> ~1155i@!*0'".=L$%9:&%#! 	! (((,,//	C G||!!)4<<+=+=>L!EWXEWcI 9EWX#(#/ M ,23
BLM*3I~A6*M&"G

 %%fmmm&CDB !??$$$,MMO$;$;M*		-0 + 15>N0O04

0@0@n- 1$/5m_A-FM'*LL!A=Q[<<77 '"+"+!) - 8 D "&!1!12B!C4BS0
!--4
*-/J)tt!$%M$)#)?4	?+?+?*@A h-%)%6%6BU%6%VE$u " $CJ 7*6B$&IIc%j$9 +7	 &W .    (&BFFH '-v6m % 3g ?P00;!23/ )(t  Y N>  '' e-0G	{RTUXTY.Z[add// f&)HSUVYUZ'[\bee00 [&)=i[3%'PQWZZ[, .- , "#89  yDGTWXA s   R>B
Q3R./R3<B(U %R8 B
U U
T89AT8U
A	U 
R''RRRR
R+8T5ST55TT5T00T55U 8
U	U


UU V868V33V8c           
     p    [        US5      nX2:w  a%  [        SUR                   SUSS  SUSS  S35      eg)	zbVerify a downloaded file's SHA256 hash.

Raises :class:`~.errors.FileIntegrityError` on mismatch.
r   zHash mismatch for z: expected Nr   z	..., got z...T)r   r   r   )r*   r   rW  r  s       r+   rQ  DownloadManager.verify_fileB  s\    
 i2$$$Y^^$4KPSQS@T?UU^_efigi_j^kkno  r.   )r   r   r   r   r   )r   r   r   r    r>   r?   r'   )r  dict | str | Noner>   r;   )r>   r;   )r   r;   r>   r  )Ng      @)
r   r;   r   dict[str, str]r   dict | Noneri   r  r>   r;   )r>   z	list[str])NN)
r   r;   r   r  r   r  r9  list[str] | Noner>   ztuple[dict[str, str], str])r  r  r>   r  )	masterNNFNFNNN)rR  r;   rS  r;   r   r;   rT  r;   rI  Path | NonerU  r  rV  r  rW  
str | NonerX  r  r)   
int | Noner  r  r   #list[type[ProgressCallback]] | Noner>   r   )	r  NNNN   FNN)rR  r;   rS  r;   rT  r;   rI  r  rU  r  rw  r  rx  r  r   r<   rX  r  r  r  r   r  r>   r   )
rR  r;   rS  r;   rT  r;   rb  r   r>   r   )r   r   rW  r  r>   r  )rR  r;   rS  r;   rI  r  r>   r   )rR  r;   rS  r;   rI  r  r>   r  )
rR  r;   rS  r;   rI  r  r   r  r>   r   )rR  r;   rS  r;   r   r;   rT  r;   r   r   r)   r  r  r  r   r  r>   r   )r   r   rW  r;   r>   r  )rA   rB   rC   rD   rE   r,   r  r  recompiler  staticmethodr!  r(  r1  r>  rC  r]  r  rr  rM  rL  rK  rN  rP  rQ  rF   r0   r.   r+   r   r   H  s   
3
D zz"GH
B 
B   $	  	
 
 *H  $)--"-"  -" 	-"
 '-" 
$-"b )-% 
: !!%!%&*!& $(,BFyy y 	y
 y y y y $y y y &y @y 
y~ !!%!%+/,0!&(,BFVV V 	V
 V V )V *V V V &V @V 
Vv-- - 	-
 - 
-d  $ "&	
4
4 
4 	
4
 

4  "&	(( ( 	(
 
(\ "& $>> > 	>
 > 
>. !%(,BFmm m 	m
 m m m &m @m 
m^
r.   r   )r   r  r_   r  )r>   r  )r   r;   r   r  r>   r  )r   tupler>   r?   r'   )r   r;   r   r   r)   r<   r   zdict[str, str] | Noner   r  r   zlist[ProgressCallback] | Noner>   r;   )CrE   
__future__r   
contextlibr   r|   r   r   r   r   r  r   rs   r   concurrent.futuresr   r   pathlibr   typingr   urllib.parser   r   	tqdm.autor	   urllib3.util.retryr
   r   r   r   r   r   r   r   r   r   r   r   r}  r   r   r   r   r   r   utils.file_utilsr   r   utils.loggerr   _legacy_apir   r   r    rw   rO  r$   rH   rr   contextmanagerr   r   r   r   r   r   r0   r.   r+   <module>r     s'  " #      	 	 	    ?    !   $    7 $)!	J	  &# 2   CG I IX**)d 9=0#	0#0# 0# #	0#
 0# 60# 	0#lD Dr.   