U
    [+d +                     @   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	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Warning)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-n7e__lmp/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+   8   s    


zFileSystemFinder.__init__c                 K   s   g }t tjttfs,|tdddd |S tjD ]}t |ttfrl|\}}|drl|td| dd tjrt	j
tjt	j
|kr|td	d
d t	j
|s2|td| ddd q2|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)r2   zHThe STATICFILES_DIRS setting should not contain the STATIC_ROOT setting.zstaticfiles.E002zThe directory 'z1' in the STATICFILES_DIRS setting does not exist.zstaticfiles.W004)r&   r   r%   r   r'   r(   r   endswithZSTATIC_ROOTosr   abspathisdirr   )r   r   errorsr.   r)   r   r   r   r   J   sR    



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   t   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)r5   sep
startswithlenr   r   exists)r   r.   r   r)   r   r   r   r:      s    

zFileSystemFinder.find_locationc                 c   sF   | j D ]:\}}tj|r| j| }t||D ]}||fV  q0qdS )z2
        List all files in all locations.
        N)r#   r5   r   r7   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   r:   r   __classcell__r   r   r/   r   r    2   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_classr5   r   join
source_dirr7   r"   rE   r(   r*   r+   )r   r,   r-   r   Zapp_configsZ
app_configZapp_storager/   rH   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   rA   )r   r   rB   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"   r9   r(   find_in_app)r   r   r   r;   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   rP   r   rB   r<   r   r   r   rO      s
    
z AppDirectoriesFinder.find_in_app)N)F)r   r   r   r   r   rK   rM   r+   r   r   rO   rC   r   r   r/   r   rD      s   	
rD   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.)rB   r   r0   r&   r	   r   r*   r+   )r   rB   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!   )rB   r   r   r"   r9   r(   r@   )r   r   r   rQ   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   rA   rB   )r   r   r   r   r   r   r     s    zBaseStorageFinder.list)N)F)	r   r   r   r   rB   r+   r   r   rC   r   r   r/   r   rS      s
   
rS   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+   getattrrB   r   r   r0   )r   r-   r   rU   r/   r   r   r+     s    zDefaultStorageFinder.__init__)r   r   r   r   r
   rB   r+   rC   r   r   r/   r   rT     s   rT   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   )r9   get_findersr   r&   r   r'   extend)r   r   r;   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   rW   6  s    
rW   )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   r[   ;  s    

r[   )F)"	functoolsr5   Zdjango.appsr   Zdjango.confr   Zdjango.contrib.staticfilesr   Zdjango.core.checksr   r   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   r9   r   r    rD   rS   rT   r   rW   	lru_cacher[   r   r   r   r   <module>   s(    kA0

