
2!Vx2                 @   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	 Z	 d  d l
 m Z m 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 d  d l m Z d  d l m Z m Z m Z d  d l m  Z  d  d l! m" Z" e j# rTd  d l$ m% Z% n9 y d  d l& m% Z% Wn" e' k
 rd  d l% m% Z% Yn XGd d   d e  Z( d e( _) d S)    N)OrderedDict)fnmatch)make_option)import_module)BaseCommandCommandError)Context)six)get_template)InvalidTemplateEngineError)engines)get_offline_hexdigestwrite_offline_manifest)settings)OfflineGenerationErrorTemplateSyntaxErrorTemplateDoesNotExist)CompressorNode)get_mod_func)StringIOc               @   s   e  Z d  Z d Z e j e d d d d d d d d	 e d
 d d d d d d d d d e d d d d d d d d d e d d d d d d d d d f Z d d   Z d d   Z d d d  Z	 d% d! d"  Z
 d# d$   Z d S)&Commandz6Compress content outside of the request/response cyclez--extensionz-eactionappenddest
extensionshelpzwThe file extension(s) to examine (default: ".html", separate multiple extensions with commas, or use -e multiple times)z-fz--forcedefaultF
store_truez\Force the generation of compressed content even if the COMPRESS_ENABLED setting is not True.forcez--follow-linkszFollow symlinks when traversing the COMPRESS_ROOT (which defaults to STATIC_ROOT). Be aware that using this can lead to infinite recursion if a link points to a parent directory of itself.Zfollow_linksz--enginedjangostorez1Specifies the templating engine. jinja2 or djangoenginec             C   s   g  } xE t  j   D]7 } t | d  r | j | j j | j j   q q Wg  } x= | D]5 } t | d  r | j | j  q[ | j |  q[ W| S)Nr!   loaders)r   allhasattrextendr!   Zget_template_loadersr"   r   )selfZtemplate_source_loaderser"   loader r)   T/tmp/pip-build-0sboevxh/django-compressor/compressor/management/commands/compress.pyget_loaders9   s     zCommand.get_loadersc             C   s   | d k rC d d l  m } t j   } | d t j d |  } n= | d k rt d d l m } | d t j  } n t d   | S)	Njinja2r   )Jinja2Parsercharsetenvr   )DjangoParserz$Invalid templating engine specified.)Zcompressor.offline.jinja2r-   r   COMPRESS_JINJA2_GET_ENVIRONMENTZFILE_CHARSETZcompressor.offline.djangor0   r   )r&   r!   r-   r/   parserr0   r)   r)   r*   Z__get_parserS   s    zCommand.__get_parserNc           "      s"  | j  d d  } | j  d   |  j  p3 d g   t | j  d d   } | sc t   } n  t j s{ t d   n  t   } | d k rt   } x |  j   D] } y] t	 | j
  } t | d d	  }	 |	 d	 k r | j }	 n  | j d
 d   |	 d  D  Wq t t t f k
 r&Yq Xq W| s@t d   n  | d k rm| j d d j |  d  n  x | D]^ }
 xU t j |
 d | j  d d  D]2 \  } } | j   f d d   | D  qWqtWn} | d k rVt j d+ k rVt j       rVt   d  rV| t   f d d     j d  f d d    D  O} qVn  | skt d   n  | d k r| j d d j |  d  n  |  j |  } t   } x| D]} y | j |  } Wn t k
 r| d k r | j d |  n  wYn t k
 rT} z. | d k r?| j d  | | f  n  wWYd	 d	 } ~ Xnf t k
 r| d k r| j d! |  n  wYn2 t  k
 r| d k r| j d" |  n  Yn Xy t! | j" |   } WnT t t f k
 r)} z. | d k r| j d# | | f  n  wWYd	 d	 } ~ Xn X| r| | _# | j$ | g   j% |  qqW| snt d$   n  | d k r| j d% d j d& d   | j&   D  d  n  t j' } t( | t) j*  rDy. t+ |  \ } } t t	 |  |    } Wqet t t f k
 r@} z t d' t j' | f   WYd	 d	 } ~ XqeXn! t( | t! t, f  se| g } n  | j d(  d } } g  } t   } x`| D]X} | d 7} | j- |  } x6| j.   D](\ } } t/ |  } | | _0 | | _1 | j2 | |  s qn  x | D] } | j3   | j4 | | |  | j5 | | |  } t6 |  } | | k r]qn  y | j7 | | |  } Wn> t8 k
 r} z t9 d) | j# | f   WYd	 d	 } ~ Xn X| | | <| j:   | j; |  | d 7} qWqWqWt< |  | j d* | t= |  | f  | | f S),a'  
        Searches templates containing 'compress' nodes and compresses them
        "offline" -- outside of the request/response cycle.

        The result is cached with a cache-key derived from the content of the
        compress nodes (not the content of the possibly linked files!).
        r!   r   r   html	verbosityr   zLNo template loaders defined. You must set TEMPLATE_LOADERS in your settings.get_template_sourcesNc             s   s   |  ] } t  |  Vq d  S)N)str).0originr)   r)   r*   	<genexpr>|   s    z#Command.compress.<locals>.<genexpr> zNo template paths found. None of the configured template loaders provided template paths. See https://docs.djangoproject.com/en/1.8/topics/templates/ for more information on template loaders.   zConsidering paths:
	z
	
followlinksFc             3   sS   |  ]I     j  d   r t   f d d    D  r t j j     Vq d S).c             3   s"   |  ] } t    d  |  Vq d S)z*%sN)r   )r7   glob)namer)   r*   r9      s    z-Command.compress.<locals>.<genexpr>.<genexpr>N)
startswithanyospathjoin)r7   )r   root)r@   r*   r9      s   r,      list_templatesc                s)   g  |  ] }   j  j   |  d   q S)r;   )r(   
get_source)r7   template)r/   r)   r*   
<listcomp>   s   	 z$Command.compress.<locals>.<listcomp>Zfilter_funcc                s   t  j j |   d   k S)Nr;   )rC   rD   splitext)_path)r   r)   r*   <lambda>   s    z"Command.compress.<locals>.<lambda>z[No templates found. Make sure your TEMPLATE_LOADERS and TEMPLATE_DIRS settings are correct.zFound templates:
	zUnreadable template at: %s
zInvalid template %s: %s
zNon-existent template at: %s
z4UnicodeDecodeError while trying to read template %s
zError parsing template %s: %s
z|No 'compress' template tags found in templates.Try running compress command with --follow-links and/or--extension=EXTENSIONSzFound 'compress' tags in:
	c             s   s   |  ] } | j  Vq d  S)N)template_name)r7   tr)   r)   r*   r9      s   z/Couldn't import offline context function %s: %szCompressing... z)An error occurred during rendering %s: %szCdone
Compressed %d block(s) from %d template(s) for %d context(s).
)r;   rG   )>gethandle_extensionsintr   r   ZTEMPLATE_LOADERSr   setr+   r   
__module__getattrr5   updateImportErrorAttributeError	TypeErrorwriterE   rC   walkr   VERSIONr1   r$   rH   _Command__get_parserr   parseIOErrorr   r   UnicodeDecodeErrorlistZ
walk_nodesrP   
setdefaultr%   keysZCOMPRESS_OFFLINE_CONTEXT
isinstancer	   string_typesr   tupleZget_init_contextitemsr   _logZ_log_verbosityZprocess_templatepushZprocess_nodeZrender_nodelistr   Zrender_node	Exceptionr   popr   r   len) r&   logoptionsr!   r4   Z	templatespathsr(   moduler5   rD   dirsfilesr2   Zcompressor_nodesrP   rJ   r'   ZnodesZcontextsfunctionZblock_countZcontext_countresultsZoffline_manifestZcontext_dictZinit_contextcontextnoderenderedkeyresultr)   )r/   r   rF   r*   compress`   s    			$	!",!			 .	)
	
		
&


	zCommand.compressr3   c             C   s   g  } x0 | D]( } | j  | j d d  j d   q Wx> t |  D]0 \ } } | j d  sF d | | | | <qF qF Wt |  S)a  
        organizes multiple extensions that are separated with commas or
        passed by using --extension/-e multiple times.

        for example: running 'django-admin compress -e js,txt -e xhtml -a'
        would result in an extension list: ['.js', '.txt', '.xhtml']

        >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
        ['.html', '.js']
        >>> handle_extensions(['.html, txt,.tpl'])
        ['.html', '.tpl', '.txt']
         r:   ,r>   z.%s)r%   replacesplit	enumeraterA   rU   )r&   r   Zext_listextir)   r)   r*   rS      s    &zCommand.handle_extensionsc             K   sj   t  j r) | j d  r) t d   n  t  j sS | j d  sS t d   qS n  |  j t j |  d  S)Nr   zTCompressor is disabled. Set the COMPRESS_ENABLED setting or use --force to override.zUOffline compression is disabled. Set COMPRESS_OFFLINE or use the --force to override.)r   ZCOMPRESS_ENABLEDrR   r   ZCOMPRESS_OFFLINEr|   sysstdout)r&   rp   r)   r)   r*   handle  s    	zCommand.handle)zhtml)__name__rV   __qualname__r   r   option_listr   r+   r_   r|   rS   r   r)   r)   r)   r*   r   %   s$   r   F)*rC   r   collectionsr   r   optparser   	importlibr   r   Zdjango.core.management.baser   r   Zdjango.templater   Zdjango.utilsr	   Zdjango.template.loaderr
   Zdjango.template.utilsr   r   Zcompressor.cacher   r   Zcompressor.confr   Zcompressor.exceptionsr   r   r   Z compressor.templatetags.compressr   Zcompressor.utilsr   PY3ior   	cStringIOrY   r   Zrequires_system_checksr)   r)   r)   r*   <module>   s4   	