U
    Ha~(                     @   s  d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
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 g ZG dd dZG dd deZG dd deZG dd deZG dd deZdddZdd Ze jdddd Z dS )    N)apps)settings)utils)Error)ImproperlyConfigured)FileSystemStorageStoragedefault_storage)	safe_join)
LazyObjectempty)import_stringc                   @   s*   e Zd ZdZdd Zd
ddZdd Zd	S )
BaseFinderzN
    A base file finder to be used for custom staticfiles finder classes.
    c                 K   s   t dd S )NzUsubclasses may provide a check() method to verify the finder is configured correctly.NotImplementedError)selfkwargs r   F/tmp/pip-unpacked-wheel-3jxiddxt/django/contrib/staticfiles/finders.pycheck   s    zBaseFinder.checkFc                 C   s   t ddS )z
        Given a relative file path, find an absolute file path.

        If the ``all`` parameter is False (default) return only the first found
        file path; if True, return a list of all found files paths.
        z5subclasses of BaseFinder must provide a find() methodNr   )r   pathallr   r   r   find   s    zBaseFinder.findc                 C   s   t ddS )z
        Given an optional list of paths to ignore, return a two item iterable
        consisting of the relative path and storage instance.
        z5subclasses of BaseFinder must provide a list() methodNr   )r   ignore_patternsr   r   r   list'   s    zBaseFinder.listN)F)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s   
	r   c                       sF   e Zd ZdZd fdd	Zdd Zddd	Zdd
dZdd Z  Z	S )FileSystemFinderz_
    A static files finder that uses the ``STATICFILES_DIRS`` setting
    to locate files.
    Nc                    s   g | _ i | _tjD ]>}t|ttfr.|\}}nd}||f| j kr| j ||f q| j D ]"\}}t|d}||_	|| j|< qXt
 j|| d S )N )location)	locationsstoragesr   STATICFILES_DIRS
isinstancer   tupleappendr   prefixsuper__init__)r   	app_namesargsr   rootr(   Zfilesystem_storage	__class__r   r   r*   4   s    


zFileSystemFinder.__init__c                 K   s   g }t tjttfs(|tdddd tjD ]l}t |ttfrh|\}}|drh|td| dd tjr.t	j
tjt	j
|kr.|td	d
d q.|S )Nz4The STATICFILES_DIRS setting is not a tuple or list.z$Perhaps you forgot a trailing comma?zstaticfiles.E001)hintid/zHThe prefix %r in the STATICFILES_DIRS setting must not end with a slash.zstaticfiles.E003)r1   zHThe STATICFILES_DIRS setting should not contain the STATIC_ROOT setting.zstaticfiles.E002)r%   r   r$   r   r&   r'   r   endswithZSTATIC_ROOTosr   abspath)r   r   errorsr-   r(   r   r   r   r   F   s.    

 
zFileSystemFinder.checkFc                 C   sR   g }| j D ]B\}}|tkr$t| | |||}|r
|sB|  S || q
|S )zW
        Look for files in the extra locations as defined in STATICFILES_DIRS.
        )r"   searched_locationsr'   find_location)r   r   r   matchesr(   r-   matched_pathr   r   r   r   _   s    
zFileSystemFinder.findc                 C   sN   |r0d|t jf }||s dS |t|d }t||}t j|rJ|S dS )z
        Find a requested static file in a location and return the found
        absolute path (or ``None`` if no match).
        z%s%sN)r4   sep
startswithlenr
   r   exists)r   r-   r   r(   r   r   r   r8   n   s    

zFileSystemFinder.find_locationc                 c   s:   | j D ].\}}| j| }t||D ]}||fV  q$qdS )z2
        List all files in all locations.
        N)r"   r#   r   	get_files)r   r   r(   r-   storager   r   r   r   r   |   s    
zFileSystemFinder.list)N)F)N)
r   r   r   r   r*   r   r   r8   r   __classcell__r   r   r.   r   r   /   s   

r   c                       sD   e Zd ZdZeZdZd fdd	Zdd Zdd	d
Z	dd Z
  ZS )AppDirectoriesFinderzu
    A static files finder that looks in the directory of each app as
    specified in the source_dir attribute.
    ZstaticNc                    s   g | _ i | _t  } r2t   fdd|D }|D ]P}| tj|j| j}tj	|j
r6|| j|j< |j| j kr6| j |j q6t j|| d S )Nc                    s   g | ]}|j  kr|qS r   )name).0acr+   r   r   
<listcomp>   s     
 z1AppDirectoriesFinder.__init__.<locals>.<listcomp>)r   r#   Zget_app_configssetstorage_classr4   r   join
source_dirisdirr!   rC   r'   r)   r*   )r   r+   r,   r   Zapp_configsZ
app_configZapp_storager.   rF   r   r*      s    zAppDirectoriesFinder.__init__c                 c   s:   | j  D ]*}|dr
t||D ]}||fV  q$q
dS )z5
        List all files in all app storages.
        r    N)r#   valuesr>   r   r?   )r   r   r@   r   r   r   r   r      s    
zAppDirectoriesFinder.listFc                 C   sX   g }| j D ]H}| j| j}|tkr,t| | ||}|r
|sH|  S || q
|S )z8
        Look for files in the app directories.
        )r   r#   r!   r7   r'   find_in_app)r   r   r   r9   appZapp_locationmatchr   r   r   r      s    

zAppDirectoriesFinder.findc                 C   s0   | j |}|r,||r,||}|r,|S dS )zL
        Find a requested static file in an app's static locations.
        N)r#   getr>   r   )r   rO   r   r@   r:   r   r   r   rN      s
    
z AppDirectoriesFinder.find_in_app)N)F)r   r   r   r   r   rI   rK   r*   r   r   rN   rA   r   r   r.   r   rB      s   	
rB   c                       s8   e Zd ZdZdZd
 fdd	ZdddZdd	 Z  ZS )BaseStorageFinderzZ
    A base static files finder to be used to extended
    with an own storage class.
    Nc                    sR   |d k	r|| _ | j d kr&td| j t| j ttfs@|   | _ t j|| d S )NzHThe staticfiles storage finder %r doesn't have a storage class assigned.)r@   r   r/   r%   r   r   r)   r*   )r   r@   r,   r   r.   r   r   r*      s    

zBaseStorageFinder.__init__Fc                 C   sj   z| j d W n tk
r$   Y nBX | j jtkr@t| j j | j |rf| j |}|rb|g}|S g S )zL
        Look for files in the default file storage, if it's local.
        r    )r@   r   r   r!   r7   r'   r>   )r   r   r   rP   r   r   r   r      s    zBaseStorageFinder.findc                 c   s$   t | j|D ]}|| jfV  qdS )z0
        List all files of the storage.
        N)r   r?   r@   )r   r   r   r   r   r   r      s    zBaseStorageFinder.list)N)F)	r   r   r   r   r@   r*   r   r   rA   r   r   r.   r   rR      s
   
rR   c                       s$   e Zd ZdZeZ fddZ  ZS )DefaultStorageFinderzF
    A static files finder that uses the default storage backend.
    c                    s2   t  j|| t| jdt}|s.td| j d S )Nbase_locationzOThe storage backend of the staticfiles finder %r doesn't have a valid location.)r)   r*   getattrr@   r   r   r/   )r   r,   r   rT   r.   r   r   r*      s    zDefaultStorageFinder.__init__)r   r   r   r   r	   r@   r*   rA   r   r   r.   r   rS      s   rS   Fc                 C   sl   g t dd< g }t D ]@}|j| |d}|s8|r8|  S t|ttfsL|g}|| q|r`|S |rhg S dS )z
    Find a static file with the given path using all enabled finders.

    If ``all`` is ``False`` (default), return the first matching
    absolute path (or ``None`` if no match). Otherwise return a list.
    N)r   )r7   get_findersr   r%   r   r&   extend)r   r   r9   finderresultr   r   r   r     s    
r   c                  c   s   t jD ]} t| V  qd S )N)r   ZSTATICFILES_FINDERS
get_finder)Zfinder_pathr   r   r   rV     s    
rV   )maxsizec                 C   s(   t | }t|ts"td|tf | S )z
    Import the staticfiles finder class described by import_path, where
    import_path is the full Python path to the class.
    z%Finder "%s" is not a subclass of "%s")r   
issubclassr   r   )Zimport_pathFinderr   r   r   rZ     s    
rZ   )F)!	functoolsr4   Zdjango.appsr   Zdjango.confr   Zdjango.contrib.staticfilesr   Zdjango.core.checksr   Zdjango.core.exceptionsr   Zdjango.core.files.storager   r   r	   Zdjango.utils._osr
   Zdjango.utils.functionalr   r   Zdjango.utils.module_loadingr   r7   r   r   rB   rR   rS   r   rV   	lru_cacherZ   r   r   r   r   <module>   s(   W?-

