o
    i{G                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlmZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZm Z  e d
\Z!Z"e dd\Z#Z$e ddd\Z%Z&erd dl'm'Z' dZ(n	e dded\Z'Z(g dZ)dZ*ej+ej,ej-ej.dZ/de*ddfdLd!d"Z0e0dZ1e)2d# dMd&d'Z3dNdOd.d/Z4d0d1 Z5dPdQd5d6Z6	7		2	dRdSd;d<Z7d=d> Z8d?d@ Z9	A		2	7	dTdUdEdFZ:dVdHdIZ;	7	A		2	7		dWdXdJdKZ<dS )Y    )annotationsN)Path)TYPE_CHECKINGAny)ContentTooShortError	HTTPErrorURLError)urlparse)urlopenurlretrieve)PathLike)look_up_optionmin_versionoptional_importrequestsgdownz4.7.3bs4BeautifulSoup)name)tqdmTr   z4.47.0)
check_hashdownload_url
extractalldownload_and_extract
get_loggerSUPPORTED_HASH_TYPESz)%(asctime)s - %(levelname)s - %(message)s)md5sha1sha256sha512z
monai.appsmodule_namestrfmtdatefmt
str | Nonelogger_handlerlogging.Handler | Nonereturnlogging.Loggerc                 C  sz   | duo
| t jjjv}t | }d|_|t j |r2t t	j
}t j||d}|| || |dur;|| |S )a  
    Get a `module_name` logger with the specified format and date format.
    By default, the logger will print to `stdout` at the INFO level.
    If `module_name` is `None`, return the root logger.
    `fmt` and `datafmt` are passed to a `logging.Formatter` object
    (https://docs.python.org/3/library/logging.html#formatter-objects).
    `logger_handler` can be used to add an additional handler.
    NF)r"   r#   )loggingrootmanager
loggerDict	getLogger	propagatesetLevelINFOStreamHandlersysstdout	FormattersetFormatter
addHandler)r    r"   r#   r%   Zadds_stdout_handlerloggerhandler	formatter r:   R/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/apps/utils.pyr   3   s   



r   r7   pr   c                 C  s*   t jjt jjpd d }t|  |jS )zHget the last part of the path (removing the trailing slash if it exists) z/ )ospathsepaltsepr   rstripr   )r<   r@   r:   r:   r;   	_basenameT   s   rC   urlfilepathr   progressboolNonec                 C  s   zEt r5|r5G dd dt}|ddddt|d}t| ||jd W d	   W d	S 1 s-w   Y  W d	S t s>|r>td
 t| | W d	S  ttt	t
fyc } ztd|  d| d |d	}~ww )zT
    Retrieve file from `url` to `filepath`, optionally showing a progress bar.
    c                   @  s   e Zd ZdZddddZdS )z)_download_with_progress.<locals>.TqdmUpToz
                Provides `update_to(n)` which uses `tqdm.update(delta_n)`.
                Inspired by the example in https://github.com/tqdm/tqdm.
                   Nbintbsizetsize
int | Noner'   rH   c                 S  s&   |dur|| _ | || | j  dS )a!  
                    Args:
                        b: number of blocks transferred so far, default: 1.
                        bsize: size of each block (in tqdm units), default: 1.
                        tsize: total size (in tqdm units). if None, remains unchanged.
                    N)totalupdaten)selfrJ   rL   rM   r:   r:   r;   	update_tog   s   z3_download_with_progress.<locals>.TqdmUpTo.update_to)rI   rI   N)rJ   rK   rL   rK   rM   rN   r'   rH   )__name__
__module____qualname____doc__rS   r:   r:   r:   r;   TqdmUpToa   s    rX   BTi   rI   )unit
unit_scaleunit_divisorminitersdesc)
reporthookNzBtqdm is not installed, will not show the downloading progress bar.zDownload failed from  to .)has_tqdmr   rC   r   rS   warningswarnr   r   r   OSErrorr7   error)rD   rE   rF   rX   ter:   r:   r;   _download_with_progressZ   s   &
ri   c                 C  s   t | dr	| j}nt | dr| j}nt| }t | dr&|  r&td| t | dr6|  r6td| tj	|}tj
|sJd|tjv rQtd| tj||}tj	|}tj|}tj|}tj||g|kr{td	| |S )
zQSecurely verify compressed package member paths to prevent path traversal attacksfilenamer   issymz#Symbolic link detected in archive: islnkzHard link detected in archive: z..z!Unsafe path detected in archive: zUnsafe path: path traversal )hasattrrj   r   r!   rk   
ValueErrorrl   r>   r?   normpathisabssplitr@   joinrealpath
commonpath)memberZ
extract_toZmember_path	full_pathZextract_rootZtarget_realr:   r:   r;   safe_extract_member}   s&   

rw   r   val	hash_typec              
     s  |du rt d| d| d|  d dS t| t}|dd}z(t| d	 t fd
ddD ]}|| q1W d   n1 sCw   Y  W n tyd } zt 	d|  W Y d}~dS d}~ww ||
 krxt 	d|
  d dS t dt|  d| d| d dS )a  
    Verify hash signature of specified file.

    Args:
        filepath: path of source file to verify hash value.
        val: expected hash value of the file.
        hash_type: type of hash algorithm to use, default is `"md5"`.
            The supported hash types are `"md5"`, `"sha1"`, `"sha256"`, `"sha512"`.
            See also: :py:data:`monai.apps.utils.SUPPORTED_HASH_TYPES`.

    Nz	Expected z is None, skip z check for file ra   TF)usedforsecurityrbc                     s
     dS )Ni   )readr:   fr:   r;   <lambda>   s   
 zcheck_hash.<locals>.<lambda>    zException in check_hash: zcheck_hash failed z
Verified 'z', z: )r7   infor   lowerr   openiterrP   	Exceptionrf   	hexdigestrC   )rE   rx   ry   Zactual_hash_funcZactual_hashchunkrh   r:   r}   r;   r      s,   
"r   r=   hash_valgdown_kwargsr   c                 K  s8  |st dt|  }td| d t |}| r=t|||s2t| d| d| d| dtd| d d	S zt	 }t |t|}t
| jd
krntsWtdd|vr_d|d< tj| | fd| i| nKt
| jdkrt| 0}| }	|	dkrt|d }
t|
||d ntd|
 d|  dd| d W d	   n1 sw   Y  nt| ||d | std|  d| d|j}|rtj|dd t| |  W d	   n1 sw   Y  W n ttfy   Y nw td|  t|||st| d|  d| d| d| d
d	S )a*  
    Download file from specified URL link, support process bar and hash check.

    Args:
        url: source URL link to download file.
        filepath: target filepath to save the downloaded file (including the filename).
            If undefined, `os.path.basename(url)` will be used.
        hash_val: expected hash value to validate the downloaded file.
            if None, skip hash validation.
        hash_type: 'md5' or 'sha1', defaults to 'md5'.
        progress: whether to display a progress bar.
        gdown_kwargs: other args for `gdown` except for the `url`, `output` and `quiet`.
            these args will only be used if download from google drive.
            details of the args of it:
            https://github.com/wkentaro/gdown/blob/main/gdown/download.py

    Raises:
        RuntimeError: When the hash validation of the ``filepath`` existing file fails.
        RuntimeError: When a network issue or denied permission prevents the
            file download from ``url`` to ``filepath``.
        URLError: See urllib.request.urlretrieve.
        HTTPError: See urllib.request.urlretrieve.
        ContentTooShortError: See urllib.request.urlretrieve.
        IOError: See urllib.request.urlretrieve.
        RuntimeError: When the hash validation of the ``url`` downloaded file fails.

    ra   zDefault downloading to ''z) check of existing file failed: filepath=, expected =zFile exists: z, skipped downloading.Ndrive.google.comzITo download files from Google Drive, please install the gdown dependency.fuzzyTquietzcloud-api.yandex.net   href)rF   zDownload of file from z, received from  r`   z2 failed due to network issue or denied permission.exist_okzDownloaded: z& check of downloaded file failed: URL=z, filepath=)r   rC   resolver7   r   existsr   RuntimeErrortempfileTemporaryDirectoryr	   netloc	has_gdownr   downloadr
   getcodejsonloadri   parentr>   makedirsshutilmovePermissionErrorNotADirectoryError)rD   rE   r   ry   rF   r   tmp_dirtmp_nameresponsecoder   Zfile_dirr:   r:   r;   r      sx   #


r   c                 C  s   t | dU}| D ]G}t||}| rqtjtj|dd |	|#}t	|d}t
|| W d    n1 s>w   Y  W d    n1 sMw   Y  qW d    d S 1 s^w   Y  d S NrTr   wb)zipfileZipFileinfolistrw   is_dirr>   r   r?   dirnamer   r   copyfileobj)rE   
output_dirzip_fileru   	safe_pathsourcetargetr:   r:   r;   _extract_zip  s   
"r   c                 C  s   t | d[}| D ]M}t||}| sqtjtj|dd |	|}|d urX|# t|d}t
|| W d    n1 sDw   Y  W d    n1 sSw   Y  qW d    d S 1 sdw   Y  d S r   )tarfiler   
getmembersrw   isfiler>   r   r?   r   extractfiler   r   )rE   r   Ztar_fileru   r   r   r   r:   r:   r;   _extract_tar!  s"   

"r   ra   r   	file_typehas_basec              	   C  s  |rt |t| dd }nt |}| r+t| ddur+td| d dS t | } |rGt| ||sGt	| d|  d| d| dtd	| d |
  }| jd
s`|d
krgt| | dS | jdsw| jdswd|v r~t| | dS td|  d| d)aK  
    Extract file to the output directory.
    Expected file types are: `zip`, `tar.gz` and `tar`.

    Args:
        filepath: the file path of compressed file.
        output_dir: target directory to save extracted files.
        hash_val: expected hash value to validate the compressed file.
            if None, skip hash validation.
        hash_type: 'md5' or 'sha1', defaults to 'md5'.
        file_type: string of file type for decompressing. Leave it empty to infer the type from the filepath basename.
        has_base: whether the extracted files have a base folder. This flag is used when checking if the existing
            folder is a result of `extractall`, if it is, the extraction is skipped. For example, if A.zip is unzipped
            to folder structure `A/*.png`, this flag should be True; if B.zip is unzipped to `*.png`, this flag should
            be False.

    Raises:
        RuntimeError: When the hash validation of the ``filepath`` compressed file fails.
        NotImplementedError: When the ``filepath`` file extension is not one of [zip", "tar.gz", "tar"].

    ra   r   NzNon-empty folder exists in z, skipped extracting.z+ check of compressed file failed: filepath=r   r   zWriting into directory: ziptarztar.gzzMUnsupported file type, available options are: ["zip", "tar.gz", "tar"]. name=z type=)r   rC   rq   r   nextiterdirr7   r   r   r   r   stripr   endswithr   r   NotImplementedError)rE   r   r   ry   r   r   	cache_dirZ
_file_typer:   r:   r;   r   /  s,   
 
r   data_urlc              
   C  s   zNt j| dd}|jd}|rtd|}|rt|d W S d| v rJt | }d|jdd	v rJt|jd
}|	dddi}|rJt|	djW S t
| W S  tyb } ztd| |d}~ww )z-
    Get the filename from the URL link.
    T)allow_redirectszContent-Dispositionzfilename="?([^";]+)"?r   r   z	text/htmlzContent-Typer=   zhtml.parserspanclasszuc-name-sizeazError processing URL: N)r   headheadersgetrefindallr!   r   textfindrC   r   )r   r   content_dispositionrj   soupZfilename_divrh   r:   r:   r;   get_filename_from_urlf  s&   

r   c                 C  s   d tt| j}d tt|j}	|dvr0|	dkr0t||}
td| d|
  |
}|	r@|	|kr@td| d|	 t	
 %}|pOt|t|  }t| ||||d t||||d W d	   d	S 1 slw   Y  d	S )
ak  
    Download file from URL and extract it to the output directory.

    Args:
        url: source URL link to download file.
        filepath: the file path of the downloaded compressed file.
            use this option to keep the directly downloaded compressed file, to avoid further repeated downloads.
        output_dir: target directory to save extracted files.
            default is the current directory.
        hash_val: expected hash value to validate the downloaded file.
            if None, skip hash validation.
        hash_type: 'md5' or 'sha1', defaults to 'md5'.
        file_type: string of file type for decompressing. Leave it empty to infer the type from url's base file name.
        has_base: whether the extracted files have a base folder. This flag is used when checking if the existing
            folder is a result of `extractall`, if it is, the extraction is skipped. For example, if A.zip is unzipped
            to folder structure `A/*.png`, this flag should be True; if B.zip is unzipped to `*.png`, this flag should
            be False.
        progress: whether to display progress bar.
    r=   )r=   ra   z	filepath=z=, which missing file extension. Auto-appending extension to: z,File extension mismatch: expected extension z
, but get )rD   rE   r   ry   rF   )rE   r   r   r   N)rr   r   r   suffixesrC   with_suffixr7   warningrn   r   r   r   r   r   )rD   rE   r   r   ry   r   r   rF   Zurl_filename_extZfilepath_extZnew_filepathr   rj   r:   r:   r;   r   }  s    
"r   )
r    r!   r"   r!   r#   r$   r%   r&   r'   r(   )r<   r   r'   r!   )T)rD   r!   rE   r   rF   rG   r'   rH   )Nr   )rE   r   rx   r$   ry   r!   r'   rG   )r=   Nr   T)rD   r!   rE   r   r   r$   ry   r!   rF   rG   r   r   r'   rH   )ra   Nr   r=   T)rE   r   r   r   r   r$   ry   r!   r   r!   r   rG   r'   rH   )r   r!   r'   r!   )r=   ra   Nr   r=   TT)rD   r!   rE   r   r   r   r   r$   ry   r!   r   r!   r   rG   rF   rG   r'   rH   )=
__future__r   hashlibr   r)   r>   r   r   r2   r   r   rc   r   pathlibr   typingr   r   urllib.errorr   r   r   urllib.parser	   urllib.requestr
   r   monai.config.type_definitionsr   monai.utilsr   r   r   r   has_requestsr   r   r   Zhas_bs4r   rb   __all__ZDEFAULT_FMTr   r   r   r   r   r   r7   appendrC   ri   rw   r   r   r   r   r   r   r   r:   r:   r:   r;   <module>   s|   

# $V
7