o
    i%!                     @  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mZ d dl	m
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 d dlmZmZmZ d d	lmZmZmZ e
ed
f ZG dd deZG dd dZdS )    )annotationsN)	parsedate)Union)get_route_path)URLHeaders)HTTPException)FileResponseRedirectResponseResponse)ReceiveScopeSendzos.PathLike[str]c                      s"   e Zd ZdZd fddZ  ZS )NotModifiedResponse)zcache-controlzcontent-locationdateetagexpiresvaryheadersr   c                   s&   t  jd fdd| D d d S )Ni0  c                   s    i | ]\}}| j v r||qS  )NOT_MODIFIED_HEADERS).0namevalueselfr   L/home/app/Keep/.python/lib/python3.10/site-packages/starlette/staticfiles.py
<dictcomp>#   s     z0NotModifiedResponse.__init__.<locals>.<dictcomp>)status_coder   )super__init__items)r   r   	__class__r   r   r        s   
zNotModifiedResponse.__init__)r   r   )__name__
__module____qualname__r   r    __classcell__r   r   r"   r   r      s    	r   c                   @  s~   e Zd Zddddddd6ddZ		d7d8ddZd9ddZd:ddZd;d!d"Zd<d$d%Z	&d=d>d-d.Z	d?d/d0Z
d@d4d5ZdS )AStaticFilesNFT)	directorypackageshtml	check_dirfollow_symlinkr)   PathLike | Noner*   "list[str | tuple[str, str]] | Noner+   boolr,   r-   returnNonec                C  s`   || _ || _| ||| _|| _d| _|| _|r*|d ur,tj	|s.t
d| dd S d S d S )NFDirectory 'z' does not exist)r)   r*   get_directoriesall_directoriesr+   config_checkedr-   ospathisdirRuntimeError)r   r)   r*   r+   r,   r-   r   r   r   r    (   s   	zStaticFiles.__init__list[PathLike]c                 C  s   g }|dur| | |pg D ]P}t|tr|\}}nd}tj|}|dus/J d|d|jdus<J d|dtj	tj
|jd|}tj|sZJ d|d|d| | q|S )z
        Given `directory` and `packages` arguments, return a list of all the
        directories that should be used for serving static files from.
        NZstaticszPackage z could not be found.z..r3   z' in package )append
isinstancetuple	importlibutil	find_specoriginr7   r8   normpathjoinr9   )r   r)   r*   directoriespackageZstatics_dirspecZpackage_directoryr   r   r   r4   :   s    	


zStaticFiles.get_directoriesscoper   receiver   sendr   c                   s^   |d dks	J | j s|  I dH  d| _ | |}| ||I dH }||||I dH  dS )z'
        The ASGI entry point.
        typehttpNT)r6   check_configget_pathget_response)r   rH   rI   rJ   r8   responser   r   r   __call__W   s   
zStaticFiles.__call__strc                 C  s"   t |}tjtjj|d S )z
        Given the ASGI scope, return the `path` string to serve up,
        with OS specific path separators, and any '..', '.' components removed.
        /)r   r7   r8   rC   rD   split)r   rH   Z
route_pathr   r   r   rN   e   s   zStaticFiles.get_pathr8   r   c              
     sz  |d dvrt ddztj| j|I dH \}}W n$ ty'   t dd ty? } z|jtjkr9t dd|d}~ww |rOt	
|jrO| |||S |rt	|jr| jrtj|d}tj| j|I dH \}}|durt	
|jr|d	 d
st|d}|j|jd
 d}t|dS | |||S | jrtj| jdI dH \}}|rt	
|jrt||ddS t dd)z`
        Returns an HTTP response, given the incoming path, method and request headers.
        method)GETHEADi  )r   Ni  i  z
index.htmlr8   rS   rH   )r8   )urlz404.html)stat_resultr   )r   anyio	to_threadrun_synclookup_pathPermissionErrorOSErrorerrnoZENAMETOOLONGstatS_ISREGst_modefile_responseS_ISDIRr+   r7   r8   rD   endswithr   replacer
   r	   )r   r8   rH   	full_pathrZ   excZ
index_pathrY   r   r   r   rO   m   s:   





zStaticFiles.get_response!tuple[str, os.stat_result | None]c              
   C  s   | j D ]G}tj||}| jrtj|}tj|}ntj|}tj|}tj||gt|kr5qz
|t	|fW   S  t
tfyJ   Y qw dS )N) N)r5   r7   r8   rD   r-   abspathrealpath
commonpathrR   rb   FileNotFoundErrorNotADirectoryError)r   r8   r)   Zjoined_pathri   r   r   r   r^      s   
zStaticFiles.lookup_path   ri   PathLikerZ   os.stat_resultr   intc                 C  s4   t |d}t|||d}| |j|rt|jS |S )NrX   )r   rZ   )r   r	   is_not_modifiedr   r   )r   ri   rZ   rH   r   request_headersrP   r   r   r   re      s
   

zStaticFiles.file_responsec                   s   | j du rdS ztjtj| j I dH }W n ty&   td| j  dw t|j	s<t
|j	s>td| j  ddS dS )z
        Perform a one-off configuration check that StaticFiles is actually
        pointed at a directory, so that we can raise loud errors rather than
        just returning 404 responses.
        NzStaticFiles directory 'z' does not exist.zStaticFiles path 'z' is not a directory.)r)   r[   r\   r]   r7   rb   rp   r:   rf   rd   S_ISLNK)r   rZ   r   r   r   rM      s   
zStaticFiles.check_configresponse_headersr   rw   c                 C  s   | d }r|d }|dd |dD v S z$t|d }t|d }|dur3|dur6||kr9W d	S W d
S W d
S W d
S  tyE   Y d
S w )z
        Given the request and response headers, return `True` if an HTTP
        "Not Modified" response could be returned instead.
        zif-none-matchr   c                 S  s   g | ]}| d qS )z W/)strip)r   tagr   r   r   
<listcomp>   s    z/StaticFiles.is_not_modified.<locals>.<listcomp>,zif-modified-sincezlast-modifiedNTF)getrT   r   KeyError)r   ry   rw   Zif_none_matchr   Zif_modified_sinceZlast_modifiedr   r   r   rv      s$   zStaticFiles.is_not_modified)r)   r.   r*   r/   r+   r0   r,   r0   r-   r0   r1   r2   )NN)r)   r.   r*   r/   r1   r;   )rH   r   rI   r   rJ   r   r1   r2   )rH   r   r1   rR   )r8   rR   rH   r   r1   r   )r8   rR   r1   rk   )rr   )
ri   rs   rZ   rt   rH   r   r   ru   r1   r   )r1   r2   )ry   r   rw   r   r1   r0   )r$   r%   r&   r    r4   rQ   rN   rO   r^   re   rM   rv   r   r   r   r   r(   '   s$    



*
r(   ) 
__future__r   ra   importlib.utilr?   r7   rb   email.utilsr   typingr   r[   Zanyio.to_threadZstarlette._utilsr   Zstarlette.datastructuresr   r   Zstarlette.exceptionsr   Zstarlette.responsesr	   r
   r   Zstarlette.typesr   r   r   rR   rs   r   r(   r   r   r   r   <module>   s"    