

_V9                 @   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 m 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 d  d	 l m Z m Z d  d
 l m Z m Z d  d l m Z d  d l m  Z  m! Z! m" Z" m# Z# Gd d   d e  Z$ Gd d   d e%  Z& Gd d   d e&  Z' Gd d   d e%  Z( Gd d   d e&  Z) Gd d   d e) e$  Z* Gd d   d e' e$  Z+ Gd d   d e  Z, e,   Z- d S)    )unicode_literalsN)OrderedDict)settings)check_settingsmatches_patterns)InvalidCacheBackendErrorcachecaches)ImproperlyConfigured)ContentFile)FileSystemStorageget_storage_class)force_bytes
force_text)
LazyObject)unquote	urldefragurlsplit
urlunsplitc                   s@   e  Z d  Z d Z d d   f d d  Z   f d d   Z   S)StaticFilesStoragez
    Standard file system storage for static files.

    The defaults for ``location`` and ``base_url`` are
    ``STATIC_ROOT`` and ``STATIC_URL``.
    Nc                sx   | d  k r t  j } n  | d  k r0 t  j } n  t |  t t |   j | | | |  | st d  |  _ d  |  _ n  d  S)N)	r   ZSTATIC_ROOTZ
STATIC_URLr   superr   __init__Zbase_locationlocation)selfr   base_urlargskwargs)	__class__ D/tmp/pip-build-ghmbqnp_/Django/django/contrib/staticfiles/storage.pyr       s    

	zStaticFilesStorage.__init__c                s.   |  j  s t d   n  t t |   j |  S)NzaYou're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.)r   r
   r   r   path)r   name)r   r   r   r    .   s    	zStaticFilesStorage.path)__name__
__module____qualname____doc__r   r    r   r   )r   r   r      s   r   c                   s   e  Z d  Z d Z d Z   f d d   Z d d	 d
  Z d d d  Z d   f d d  Z d d d  Z	 d d d  Z
 d d   Z d d   Z d d   Z   S)HashedFilesMixinz	url("%s")*.css#(url\(['"]{0,1}\s*(.*?)["']{0,1}\))(@import\s*["']\s*(.*?)["'])@import url("%s")c                s   t  t |   j | |   t   |  _ i  |  _ x |  j D] \ } } xr | D]j } t | t t	 f  ru | \ } } n	 |  j
 } t j | t j  } |  j j | g   j | | f  qK Wq8 Wd  S)N)r   r&   r   r   	_patternshashed_filespatterns
isinstancetuplelistdefault_templaterecompile
IGNORECASE
setdefaultappend)r   r   r   	extensionr-   patterntemplateZcompiled)r   r   r   r   ?   s    		zHashedFilesMixin.__init__Nc             C   sT   | d k r d St  j   } x! | j   D] } | j |  q) W| j   d d  S)zV
        Returns a hash of the file with the given name and optional content.
        N   )hashlibmd5chunksupdate	hexdigest)r   r!   contentr<   chunkr   r   r   	file_hashL   s    zHashedFilesMixin.file_hashc             C   sp  t  t |   } | j j   } d } | d  k r |  j |  s[ t d | |  f   n  y |  j |  } Wn t k
 r | SYn Xd } n  z |  j | |  } Wd  | r | j	   n  Xt
 j j |  \ } } t
 j j |  \ }	 }
 | d  k	 rd | } n  t
 j j | d |	 | |
 f  } t |  } | | d <d | k rf| d rf| d d	 7<n  t |  S)
NFz)The file '%s' could not be found with %r.Tz.%sz%s%s%s   z?#   ?)r   r   r    stripexists
ValueErroropenIOErrorrB   closeossplitsplitextjoinr0   r   )r   r!   r@   Zparsed_name
clean_nameZopenedrB   r    filenamerootexthashed_nameZunparsed_namer   r   r   rT   W   s6    		
zHashedFilesMixin.hashed_nameFc       	         s   t  j r  | r  | d } } nB t |  \ } } t |  j j d  rS | } n |  j |  } t t |   j	 |  } d | k } | s | r t
 t |   } | r | d r | | d <n  | r | d r | d d 7<n  t |  } n  t |  S)z5
        Returns the real URL in DEBUG mode.
         /z?#   rD   rC   rE   )r   DEBUGr   r   r    endswithstored_namer   r&   urlr0   r   r   )	r   r!   forcerT   fragmentrP   Z	final_urlZquery_fragmenturlparts)r   r   r   r[   x   s     	zHashedFilesMixin.urlc                s4    d k r  j   n      f d d   } | S)zK
        Returns the custom URL converter for the given file name.
        Nc                s  |  j    \ } } | j d  r% | S  j t j  } t j |  } | j d  } | j d  | j d  } } | j d  r | d 8} | d d	  } n  | s | j d  r | d | } } n@ | r | d k r | d 8} n  | d } } n d | d } } d j | d	 |  | | d	   }	  j	 t
 |	  d
 d }
 |
 j d  d d	  } d j | j d  d	 d  |  }  t
 |  S)z
            Converts the matched URL depending on the parent level (`..`)
            and returns the normalized and hashed URL using the url method
            of the storage.
            #http:https:data://rV   z..   Nr\   T)r_   r`   ra   rb   rc   re   )groups
startswithrM   rL   sep	posixpathnormpathcountrO   r[   r   )Zmatchobjmatchedr[   Z
name_partsZ	url_partsZparent_levelZ	sub_levelstartendZjoined_resultZ
hashed_url	file_nameZrelative_url)r!   r   r9   r   r   	converter   s,    
(&z1HashedFilesMixin.url_converter.<locals>.converter)r1   )r   r!   r9   rp   r   )r!   r   r9   r   url_converter   s    $zHashedFilesMixin.url_converterc             +   sW  | r
 d St    }  f d d       f d d   | D } d d   } xt | j   d | d d	 D]} | | \ } }	 | j |	  }
  j | |
  } t |
 d
  r |
 j d  n   j |  } d } | | k r|
 j   j	 t
 j  } x  j j   D]{ } xr | D]j \ } }  j | |  } y | j | |  } Wqt k
 r} z | d | f VWYd d } ~ XqXqWqW| r j |  n  t t |   }  j | |  } t  j |   } d	 } n6 | sd	 }  j | |
  } t  j |   } n  | |  j |  <| | | f VWd QXqi W j j |  d S)a  
        Post process the given OrderedDict of files (called from collectstatic).

        Processing is actually two separate operations:

        1. renaming files to include a hash of their content for cache-busting,
           and copying those files to the target storage.
        2. adjusting files which contain references to other files so they
           refer to the cache-busting filenames.

        If either of these are performed on a file, then that file is considered
        post-processed.
        Nc                s   t  |    j j    S)N)r   r+   keys)r    )r   r   r   <lambda>   s    z/HashedFilesMixin.post_process.<locals>.<lambda>c                s"   g  |  ] }   |  r |  q Sr   r   ).0r    )matchesr   r   
<listcomp>   s   	 z1HashedFilesMixin.post_process.<locals>.<listcomp>c             S   s   t  |  j t j   S)N)lenrM   rL   rh   )r!   r   r   r   rs      s    keyreverseTseekr   F)r   sortedrr   rI   rT   hasattrrz   rG   readdecoder   ZFILE_CHARSETr+   valuesrq   subrH   deleter   r   _saver   rP   hash_keyr,   r>   )r   pathsdry_runoptionsr,   Zadjustable_pathsZ
path_levelr!   Zstorager    Zoriginal_filerT   Zhashed_file_exists	processedr@   r-   r8   r9   rp   exccontent_fileZ
saved_namer   )ru   r   r   post_process   sH    	%)	zHashedFilesMixin.post_processc             C   s   | j  d d  S)N\rV   )replace)r   r!   r   r   r   rP     s    zHashedFilesMixin.clean_namec             C   s   | S)Nr   )r   r!   r   r   r   r     s    zHashedFilesMixin.hash_keyc             C   sY   |  j  |  } |  j j |  } | d  k rU |  j |  j |   } | |  j | <n  | S)N)r   r,   getrP   rT   )r   r!   r   Z
cache_namer   r   r   rZ     s    zHashedFilesMixin.stored_namer)   r*   r(   r   r'   r   )r   )r"   r#   r$   r1   r-   r   rB   rT   r[   rq   r   rP   r   rZ   r   r   )r   r   r&   6   s     !-Mr&   c                   sd   e  Z d  Z d Z d Z   f d d   Z d d   Z d d   Z   f d	 d
   Z d d   Z	   S)ManifestFilesMixinz1.0zstaticfiles.jsonc                s,   t  t |   j | |   |  j   |  _ d  S)N)r   r   r   load_manifestr,   )r   r   r   )r   r   r   r   #  s    zManifestFilesMixin.__init__c             C   sO   y2 |  j  |  j   } | j   j d  SWd  QXWn t k
 rJ d  SYn Xd  S)Nzutf-8)rI   manifest_namer}   r~   rJ   )r   manifestr   r   r   read_manifest'  s
    z ManifestFilesMixin.read_manifestc             C   s   |  j    } | d  k r t   Sy t j | d t } Wn t k
 rL Yn/ X| j d  } | d k r{ | j d t    St d |  j |  j f   d  S)Nobject_pairs_hookversionz1.0r   z(Couldn't load manifest '%s' (version %s))r   r   jsonloadsrH   r   r   manifest_version)r   r@   Zstoredr   r   r   r   r   .  s    z ManifestFilesMixin.load_manifestc             /   sK   t    |  _ t t |   j | |   } x | D] } | Vq. W|  j   d  S)N)r   r,   r   r   r   save_manifest)r   r   r   Zall_post_processedZpost_processed)r   r   r   r   =  s    	zManifestFilesMixin.post_processc             C   st   i |  j  d 6|  j d 6} |  j |  j  r? |  j |  j  n  t j |  j d  } |  j |  j t	 |   d  S)Nr   r   zutf-8)
r,   r   rG   r   r   r   dumpsencoder   r   )r   payloadcontentsr   r   r   r   E  s
    z ManifestFilesMixin.save_manifest)
r"   r#   r$   r   r   r   r   r   r   r   r   r   )r   r   r     s   r   c               @   sa   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z d d d  Z	 d S)_MappingCachezG
    A small dict-like wrapper for a given cache backend instance.
    c             C   s   | |  _  d  S)N)r   )r   r   r   r   r   r   Q  s    z_MappingCache.__init__c             C   s   |  j  j | |  d  S)N)r   set)r   rx   valuer   r   r   __setitem__T  s    z_MappingCache.__setitem__c             C   s5   |  j  j |  } | d  k r1 t d |   n  | S)NzCouldn't find a file name '%s')r   r   KeyError)r   rx   r   r   r   r   __getitem__W  s    z_MappingCache.__getitem__c             C   s   |  j  j   d  S)N)r   clear)r   r   r   r   r   ]  s    z_MappingCache.clearc             C   s   |  j  j |  d  S)N)r   Zset_many)r   datar   r   r   r>   `  s    z_MappingCache.updateNc             C   s)   y |  | SWn t  k
 r$ | SYn Xd  S)N)r   )r   rx   defaultr   r   r   r   c  s    z_MappingCache.get)
r"   r#   r$   r%   r   r   r   r   r>   r   r   r   r   r   r   M  s   r   c                   s.   e  Z d  Z   f d d   Z d d   Z   S)CachedFilesMixinc                sX   t  t |   j | |   y t t d  |  _ Wn! t k
 rS t t  |  _ Yn Xd  S)NZstaticfiles)r   r   r   r   r	   r,   r   default_cache)r   r   r   )r   r   r   r   k  s
    zCachedFilesMixin.__init__c             C   s,   t  j t |  j |    j   } d | S)Nzstaticfiles:%s)r;   r<   r   rP   r?   )r   r!   rx   r   r   r   r   s  s    $zCachedFilesMixin.hash_key)r"   r#   r$   r   r   r   r   )r   r   r   j  s   r   c               @   s   e  Z d  Z d Z d S)CachedStaticFilesStoragezh
    A static file system storage backend which also saves
    hashed copies of the files it saves.
    N)r"   r#   r$   r%   r   r   r   r   r   x  s   r   c               @   s   e  Z d  Z d Z d S)ManifestStaticFilesStoragezh
    A static file system storage backend which also saves
    hashed copies of the files it saves.
    N)r"   r#   r$   r%   r   r   r   r   r     s   r   c               @   s   e  Z d  Z d d   Z d S)ConfiguredStoragec             C   s   t  t j    |  _ d  S)N)r   r   ZSTATICFILES_STORAGEZ_wrapped)r   r   r   r   _setup  s    zConfiguredStorage._setupN)r"   r#   r$   r   r   r   r   r   r     s   r   ).
__future__r   r;   r   rL   ri   r2   collectionsr   Zdjango.confr   Z django.contrib.staticfiles.utilsr   r   Zdjango.core.cacher   r   r   r	   Zdjango.core.exceptionsr
   Zdjango.core.files.baser   Zdjango.core.files.storager   r   Zdjango.utils.encodingr   r   Zdjango.utils.functionalr   Z#django.utils.six.moves.urllib.parser   r   r   r   r   objectr&   r   r   r   r   r   r   Zstaticfiles_storager   r   r   r   <module>   s0   ".