U
    Ed/                     @   s  d 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mZmZ ddlmZ ddlmZ ddlmZ ddlmZ ee	d	d
Zdd Zdd Zdd Zdd Z dd Z!dd Z"dd Z#d9ddZ$d:ddZ%e
j&dkr
e$Z'ne%Z'd;dd Z(d!d" Z)d<d#d$Z*d=d%d&Z+d'd( Z,d)d* Z-d+d, Z.e
j&dkr^e-Z/ne.Z/d-d. Z0d/d0 Z1d1d2 Z2d3d4 Z3d5d6 Z4d7d8 Z5dS )>zNotebook related utilities    N)LooseVersion)quoteunquoteurlparseurljoin)pathname2url)Future)gen)	py3compat	UF_HIDDENi   c                 C   s*   zt |  W n tk
r$   Y dS X dS )zcReplacement for `os.path.exists` which works for host mapped volumes
    on Windows containers
    FT)oslstatOSErrorpath r   -lib/python3.8/site-packages/notebook/utils.pyexists   s
    r   c                  G   sf   | d  d}| d d}dd | D }ddd |D }|rJd| }|rV|d }|dkrbd}|S )	zJoin components of url into a relative url

    Use to prevent double slash when joining subpath. This will leave the
    initial and final / in place
    r   /c                 S   s   g | ]}| d qS )r   )strip.0sr   r   r   
<listcomp>2   s     z!url_path_join.<locals>.<listcomp>c                 s   s   | ]}|r|V  qd S )Nr   r   r   r   r   	<genexpr>3   s      z url_path_join.<locals>.<genexpr>z//)
startswithendswithjoin)piecesinitialfinalstrippedresultr   r   r   url_path_join*   s       r$   c                 C   s   t | jdS )z)Determine whether a given URL is absoluter   )r   r   r   )urlr   r   r   url_is_absolute9   s    r&   c                 C   s6   dd |  tjD }|d dkr*d|d< t| }|S )z"Convert a local file path to a URLc                 S   s   g | ]}t |qS r   r   r   pr   r   r   r   ?   s     zpath2url.<locals>.<listcomp>r    r   )splitr   sepr$   )r   r   r%   r   r   r   path2url=   s
    r-   c                 C   s$   dd |  dD }tjj| }|S )z"Convert a URL to a local file pathc                 S   s   g | ]}t |qS r   )r   r(   r   r   r   r   H   s     zurl2path.<locals>.<listcomp>r   )r+   r   r   r   )r%   r   r   r   r   r   url2pathF   s    r.   c                 C   s(   t j| ddd}ddd |D S )zVEscape special characters in a URL path

    Turns '/foo bar/' into '/foo%20bar/'
    utf8encodingr   c                 S   s   g | ]}t |qS r   r'   r(   r   r   r   r   R   s     zurl_escape.<locals>.<listcomp>)r
   unicode_to_strr+   r   )r   partsr   r   r   
url_escapeL   s    r4   c                 C   s$   d dd tj| dddD S )zXUnescape special characters in a URL path

    Turns '/foo%20bar/' into '/foo bar/'
    r   c                 S   s   g | ]}t jt|d dqS )r/   r0   )r
   Zstr_to_unicoder   r(   r   r   r   r   Y   s   z url_unescape.<locals>.<listcomp>r/   r0   )r   r
   r2   r+   r   r   r   r   url_unescapeT   s    
r5   c                 C   s`   t j| drdS d}ztjjt	| }W n t
k
rF   Y nX |dkr\||@ r\dS dS )a  Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        Ignored on Windows, exists for compatibility with POSIX version of the
        function.
    .T   r   F)r   r   basenamer   ctypeswindllkernel32ZGetFileAttributesWr
   Zcast_unicodeAttributeError)abs_pathstat_resZwin32_FILE_ATTRIBUTE_HIDDENZattrsr   r   r   is_file_hidden_win_   s    r?   c              
   C   s   t j| drdS |dks*t|jrtzt | }W n: tk
rr } z|jtj	kr`W Y 
dS  W 5 d}~X Y nX t
|jrt | t jt jB sdS t|ddt@ rdS dS )a  Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        The result of calling stat() on abs_path. If not passed, this function
        will call stat() internally.
    r6   TNFst_flagsr   )r   r   r8   r   statS_ISLNKst_moder   errnoENOENTS_ISDIRaccessX_OKR_OKgetattrr   )r=   r>   er   r   r   is_file_hidden_posix   s    
rL   win32r*   c                 C   s   t j| t j|krdS t| r(dS |sD| t jdd t j }| t|d }tdd |t jD rrdS t j| }|r|	|r||krt
|st j|}q~zt |}W n tk
r   Y dS X t|ddt@ rdS t j|}q~dS )	a  Is a file hidden or contained in a hidden directory?

    This will start with the rightmost path element and work backwards to the
    given root to see if a path is hidden or in a hidden directory. Hidden is
    determined by either name starting with '.' or the UF_HIDDEN flag as
    reported by stat.

    If abs_path is the same directory as abs_root, it will be visible even if
    that is a hidden folder. This only checks the visibility of files
    and directories *within* abs_root.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check for hidden directories.
    abs_root : unicode
        The absolute path of the root directory in which hidden directories
        should be checked for.
    FT   r   Nc                 s   s   | ]}| d V  qdS )r6   N)r   )r   partr   r   r   r      s     zis_hidden.<locals>.<genexpr>r@   )r   r   normpathis_file_hiddenr+   r,   lenanydirnamer   r   r   r   rJ   r   )r=   Zabs_rootZinside_rootr   str   r   r   	is_hidden   s,    rV   c                 C   s,   t | }t |}|  | ko*||kS )ao  
    Fill in for os.path.samefile when it is unavailable (Windows+py2).

    Do a case-insensitive string comparison in this case
    plus comparing the full stat result (including times)
    because Windows + py2 doesn't support the stat fields
    needed for identifying if it's the same file (st_ino, st_dev).

    Only to be used if os.path.samefile is not available.

    Parameters
    -----------
    path:       String representing a path to a file
    other_path: String representing a path to another file

    Returns
    -----------
    same:   Boolean that is True if both path and other path are the same
    )r   rA   lower)r   Z
other_pathZ	path_statZother_path_statr   r   r   samefile_simple   s
    

rX   c                 C   s<   |  dd}dd |D }tjj|f| } tj| S )zConvert an API path to a filesystem path

    If given, root will be prepended to the path.
    root must be a filesystem path already.
    r   c                 S   s   g | ]}|d kr|qS r*   r   r(   r   r   r   r      s      zto_os_path.<locals>.<listcomp>)r   r+   r   r   r   rP   )r   rootr3   r   r   r   
to_os_path   s    r[   c                 C   sN   |  |r| t|d } | tjjtjj}dd |D }d|}|S )zConvert a filesystem path to an API path

    If given, root will be removed from the path.
    root must be a filesystem path already.
    Nc                 S   s   g | ]}|d kr|qS rY   r   r(   r   r   r   r     s      zto_api_path.<locals>.<listcomp>r   )r   rR   r   r   r   r,   r+   r   )Zos_pathrZ   r3   r   r   r   r   to_api_path  s    

r\   c                 C   s.   zt | t |kW S  tk
r(   Y dS X dS )zcheck version string v >= check

    If dev/prerelease tags result in TypeError for string-number comparison,
    it is assumed that the dependency is satisfied.
    Users on dev branches are responsible for keeping their own packages up to date.
    TN)r   	TypeError)vcheckr   r   r   check_version  s    r`   c                 C   s4   dd l }|jjdd| }|r,|jj| t|S )Nr   rN   )r9   r:   r;   ZOpenProcessZCloseHandlebool)pidr9   Zhandler   r   r   _check_pid_win32  s
    rc   c              
   C   sj   zt | d W nP tk
r` } z2|jtjkr8W Y  dS |jtjkrNW Y 
dS  W 5 d}~X Y nX dS dS )z'Copy of IPython.utils.process.check_pidr   FTN)r   killr   rD   ZESRCHEPERM)rb   errr   r   r   _check_pid_posix'  s    

rg   c                 C   sF   t | rt| S t| tjjr,t| S t }|	|  |S dS )zxLike tornado's deprecated gen.maybe_future

    but more compatible with asyncio for recent versions
    of tornado
    N)
inspectisawaitableasyncioensure_future
isinstance
concurrentZfuturesr   Zwrap_futureZ
set_result)objfr   r   r   maybe_future;  s    



rp   c                    s    t  s S  fdd}| S )a  If async, runs maybe_async and blocks until it has executed,
    possibly creating an event loop.
    If not async, just returns maybe_async as it is the result of something
    that has already executed.
    Parameters
    ----------
    maybe_async : async or non-async object
        The object to be executed, if it is async.
    Returns
    -------
    result :
        Whatever the async object returns, or the object itself.
    c               
      s   d} zt  }W n tk
r(   d} Y nX | r6d} | rLt  }t | z| }W n8 tk
r } zt|dkrt  }W 5 d }~X Y nX |S )NFTz"This event loop is already running)	rj   Zget_event_loopRuntimeErrorZ	is_closedZnew_event_loopZset_event_loopZrun_until_completestrrk   )Zcreate_new_event_loopZloopr#   rK   maybe_asyncr   r   wrapped_  s     

zrun_sync.<locals>.wrapped)rh   ri   )rt   ru   r   rs   r   run_syncL  s    
rv   c                 C   s   |  ddS )zREncodes a UNIX socket path string from a socket path for the `http+unix` URI form.r   %2Freplacesocket_pathr   r   r   urlencode_unix_socket_pathu  s    r|   c                 C   s   |  ddS )zWDecodes a UNIX sock path string from an encoded sock path for the `http+unix` URI form.rw   r   rx   rz   r   r   r   urldecode_unix_socket_pathz  s    r}   c                 C   s   dt |  S )zJEncodes a UNIX socket URL from a socket path for the `http+unix` URI form.zhttp+unix://)r|   rz   r   r   r   urlencode_unix_socket  s    r~   c                 C   sf   t j| sdS zFzttjtj}||  W n tk
rJ   Y W dS X W dS W 5 |  X dS )zSChecks whether a UNIX socket path on disk is in use by attempting to connect to it.FTN)	r   r   r   closesocketZAF_UNIXZSOCK_STREAMZconnectr   )r{   Zsockr   r   r   unix_socket_in_use  s    r   )N)N)r*   )r*   )r*   )6__doc__rj   concurrent.futuresrm   r9   rD   rh   r   r   rA   sysZdistutils.versionr   Zurllib.parser   r   r   r   Zurllib.requestr   Ztornado.concurrentr   ZTornadoFutureZtornador	   Zipython_genutilsr
   rJ   r   r   r$   r&   r-   r.   r4   r5   r?   rL   platformrQ   rV   rX   r[   r\   r`   rc   rg   Z	check_pidrp   rv   r|   r}   r~   r   r   r   r   r   <module>   sX   	
 
'
2


)