o
    ~¨Êhb8  ã                   @   s  d dl mZmZ 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 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" d dl#m$Z$ d dl%m&Z&m'Z'm(Z( d\Z)Z*d\Z+Z,G dd„ de-ƒZ.dS )é    )Úwith_statementÚunicode_literalsN)Úimport_module)ÚVERSION)ÚContentFile)Ú	mark_safe)Úurl2pathname)Úrender_to_string)Úcached_property)Úget_hexdigestÚ	get_mtime)Úsettings)ÚCompressorErrorÚUncompressableFileErrorÚFilterDoesNotExist)ÚCachedCompilerFilter)ÚCssAbsoluteFilterÚCssRelativeFilter)Úcompressor_file_storage)Úpost_compress)Ú	get_classÚget_mod_funcÚstaticfiles)ÚinlineÚfile)ÚinputÚoutputc                   @   sð   e Zd ZdZ		d1dd„Zedd„ ƒZdd„ Zd	d
„ Zdd„ Z	d2dd„Z
dd„ Zdd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZd3dd„Zdd„ Zd3d d!„Z		d1d"d#„Zd$d%„ Zd4d'd(„Zd2d)d*„Zd5d+d,„Zd5d-d.„Zd2d/d0„ZdS )6Ú
Compressorzi
    Base compressor object to be subclassed for content type
    depending implementations details.
    Nc                 O   sr   |pd| _ |pd| _tj d¡| _tj| _g | _|pi | _	|p d| _
|p%g | _i | _ttjƒ| _tj| _d | _d S )NÚ Ú
compressedú/)ÚcontentÚoutput_prefixr   ÚCOMPRESS_OUTPUT_DIRÚstripÚ
output_dirÚDEFAULT_CHARSETÚcharsetÚsplit_contentÚcontextÚtypeÚfiltersÚextra_contextÚdictÚCOMPRESS_PRECOMPILERSÚprecompiler_mimetypesr   ÚfindersÚ_storage)Úselfr!   r"   r)   r+   ÚargsÚkwargs© r5   úA/var/www/html/env/lib/python3.10/site-packages/compressor/base.pyÚ__init__"   s   





zCompressor.__init__c                 C   s   ddl m} |S )Nr   )Údefault_storage)Úcompressor.storager8   )r2   r8   r5   r5   r6   Ústorage1   s   zCompressor.storagec                 C   s   t ‚)z…
        To be implemented in a subclass, should return an
        iterable with four values: kind, value, basename, element
        )ÚNotImplementedError©r2   r5   r5   r6   Úsplit_contents6   s   zCompressor.split_contentsc                 C   s>   zt | d| ƒ}|r|W S W n	 ty   Y nw d| j|f S )z?
        Returns the template path for the given mode.
        ztemplate_name_%szcompressor/%s_%s.html)ÚgetattrÚAttributeErrorr*   )r2   ÚmodeÚtemplater5   r5   r6   Úget_template_name=   s   ÿÿzCompressor.get_template_namec                 C   s^   z| j j}W n ty   tj}Y nw | |¡s td||f ƒ‚| |dd¡}| dd¡d S )z 
        Takes full path to a static file (eg. "/static/css/style.css") and
        returns path with storage's base url removed (eg. "css/style.css").
        zE'%s' isn't accessible via COMPRESS_URL ('%s') and can't be compressedr   é   ú?r   )	r:   Úbase_urlr?   r   ÚCOMPRESS_URLÚ
startswithr   ÚreplaceÚsplit)r2   ÚurlrE   Úbasenamer5   r5   r6   Úget_basenameI   s   
ÿ
þzCompressor.get_basenamec                 C   s^   g }|rt j |¡d }| t j |¡d ¡ | t|dƒ| jg¡ t j | j	| j
d |¡¡S )aª  
        Returns file path for an output file based on contents.

        Returned path is relative to compressor storage's base url, for
        example "CACHE/css/58a8c0714e59.css".

        When `basename` argument is provided then file name (without extension)
        will be used as a part of returned file name, for example:

        get_filepath(content, "my_file.css") -> 'CACHE/css/my_file.58a8c0714e59.css'
        rC   r   é   Ú.)ÚosÚpathrI   ÚappendÚsplitextÚextendr   r*   Újoinr%   r"   )r2   r!   rK   ÚpartsÚfilenamer5   r5   r6   Úget_filepathZ   s   zCompressor.get_filepathc                 C   s’   d}t js)z| j |¡}| j |¡sd}W n ty(   t |¡r&t |¡}Y nw |s6| jr6| j t	|ƒ¡}|r:|S t
d|t j| jrDdpEdf ƒ‚)z†
        Returns full path to a file, for example:

        get_filename('css/one.css') -> '/full/path/to/static/css/one.css'
        Nz3'%s' could not be found in the COMPRESS_ROOT '%s'%sz or with staticfiles.rN   )r   ÚDEBUGr:   rP   Úexistsr;   r   r0   Úfindr   r   ÚCOMPRESS_ROOT)r2   rK   rV   r5   r5   r6   Úget_filenamem   s.   €

€ý
ÿÿÿzCompressor.get_filenamec                 C   sš   |dkrd}t  |d|¡�6}z| ¡ W W  d  ƒ S  ty. } ztd||f ƒ‚d}~w tyB } z	td|||f ƒ‚d}~ww 1 sFw   Y  dS )zS
        Reads file contents using given `charset` and returns it as text.
        zutf-8z	utf-8-sigÚrNz!IOError while processing '%s': %sz<UnicodeDecodeError while processing '%s' with charset %s: %s)ÚcodecsÚopenÚreadÚIOErrorr   ÚUnicodeDecodeError)r2   rV   r'   ÚfdÚer5   r5   r6   Úget_filecontent�   s$   þÿ€ý€ÿúzCompressor.get_filecontentc                 C   s   t tjƒ| jƒS ©N)r   r   ÚCOMPRESS_PARSERr!   r<   r5   r5   r6   Úparser    ó   zCompressor.parserc                 C   s   dd„ | j D ƒS )Nc                 S   s   g | ]}t |ƒ‘qS r5   )r   )Ú.0Ú
filter_clsr5   r5   r6   Ú
<listcomp>¦   s    z-Compressor.cached_filters.<locals>.<listcomp>)r+   r<   r5   r5   r6   Úcached_filters¤   ri   zCompressor.cached_filtersc                 C   s   dd„ |   ¡ D ƒS )Nc                 S   s(   g | ]\}}}}|t krtt|ƒƒ‘qS r5   )ÚSOURCE_FILEÚstrr   )rj   ÚkindÚvaluerK   Úelemr5   r5   r6   rl   ª   s
    

þz%Compressor.mtimes.<locals>.<listcomp>)r=   r<   r5   r5   r6   Úmtimes¨   s   ÿzCompressor.mtimesc                 C   s"   t d | jg| j ¡ | j¡dƒS )Nr   rM   )r   rT   r!   rs   Úencoder'   r<   r5   r5   r6   Úcachekey®   s
   ÿ
ÿzCompressor.cachekeyFc                 c   s  � t jp|}|  ¡ D ]\}}}}d}| j |¡}| d| j¡}	t||||	dœ}
|tkr7t	|
|d�}
|  
||	¡}| jrE| j|fi |
¤Ž\}}|rT| j|| jfi |
¤ŽV  q
|r‚t| jv rg| j|tgfi |
¤Ž}nt| jv rw| j|tgfi |
¤Ž}| j||d|d�V  q
| j |¡V  q
dS )zß
        The heart of content parsing, iterates over the
        list of split contents and looks at its kind
        to decide what to do with it. Should yield a
        bunch of precompiled and/or rendered hunks.
        Fr'   )Úmethodrr   rp   rK   r'   )rV   T)ÚforcedrK   N)r   ÚCOMPRESS_ENABLEDr=   rh   Úelem_attribsÚgetr'   ÚMETHOD_INPUTrn   r-   re   r/   Ú
precompileÚfilterrm   r   r   Úhandle_outputÚelem_str)r2   rw   Úenabledrp   rq   rK   rr   ÚprecompiledÚattribsr'   Úoptionsr5   r5   r6   Úhunks³   s:   €
û



ÿàzCompressor.hunksc                 C   s   | j || jtd�S )zl
        Passes the concatenated content to the 'output' methods
        of the compressor filters.
        )rv   )r}   rm   ÚMETHOD_OUTPUT)r2   r!   r5   r5   r6   Úfilter_outputÞ   s   zCompressor.filter_outputc                 C   s"   g }|   |¡D ]}| |¡ q|S )zk
        Passes each hunk (file or code) to the 'input' methods
        of the compressor filters.
        )r„   rQ   )r2   rw   r!   Úhunkr5   r5   r6   Úfilter_inputå   s   zCompressor.filter_inputc                 K   s  |sd|fS | j  |¡}| dd¡}|du rd|fS | j |¡}	|	du r2|dv r,d|fS td| ƒ‚t|	ƒ\}
}zt|
ƒ}W n  ttfy^   t	|| j
|||	|d�}d|jd
i |¤Žf Y S w zt||ƒ}W n tys   td|	 ƒ‚w |||| j
||d	�}d|jd
i |¤ŽfS )z
        Processes file using a pre compiler.

        This is the place where files like coffee script are processed.
        Fr*   N)ztext/cssztext/javascriptzQCouldn't find any precompiler in COMPRESS_PRECOMPILERS setting for mimetype '%s'.)r!   Úfilter_typerV   r'   ÚcommandÚmimetypeTzCould not find "%s".)Úattrsr‰   r'   rV   r5   )rh   ry   rz   r/   r   r   r   ÚImportErrorÚ	TypeErrorr   r*   r   r>   r?   r   )r2   r!   rp   rr   rV   r'   r4   rŒ   r‹   Úfilter_or_commandÚmod_nameÚcls_nameÚmodr}   Úprecompiler_classr5   r5   r6   r|   ï   sB   þþüÿ
þzCompressor.precompilec              	   K   sN   |D ]"}t ||| jd�|ƒ}zt|ƒr|di |¤Ž}W q ty$   Y qw |S )N)r‰   r5   )r>   r*   Úcallabler;   )r2   r!   r+   rv   r4   rk   Úfilter_funcr5   r5   r6   r}     s   ÿ€ÿzCompressor.filterr   c                 C   s>   d  |  |¡¡}|sdS tjs|r|  |¡}|  |||¡S |S )zÆ
        The general output method, override in subclass if you need to do
        any custom modification. Calls other mode specific methods or simply
        returns the content directly.
        Ú
r   )rT   rˆ   r   rx   r†   r~   )r2   r@   rw   r   Úfiltered_outputr5   r5   r6   r   !  s   

zCompressor.outputc                 C   s2   t | d| d ƒ}t|ƒr|||||ƒS td| ƒ‚)Nz	output_%sz)Couldn't find output method for mode '%s')r>   r”   r   )r2   r@   r!   rw   rK   Úoutput_funcr5   r5   r6   r~   2  s   ÿzCompressor.handle_outputc                 C   sX   | j ||d�}| j |¡r|r| j |t| | j¡ƒ¡ t| j |¡ƒ}|  	|d|i¡S )z†
        The output method that saves the content to a file and renders
        the appropriate template with the file's URL.
        )rK   rJ   )
rW   r:   rY   Úsaver   rt   r'   r   rJ   Úrender_output)r2   r@   r!   rw   rK   Únew_filepathrJ   r5   r5   r6   Úoutput_file;  s
   zCompressor.output_filec                 C   s   |   |d|i¡S )za
        The output method that directly returns the content for inline
        display.
        r!   )rš   )r2   r@   r!   rw   rK   r5   r5   r6   Úoutput_inlineF  s   zCompressor.output_inlinec                 C   sŒ   d| j vr
i | j d< | j d  |pi ¡ | j d  | j¡ t| j dƒr-tdkr-| j  ¡ }n| j }tj| j| j	||d� |  
|¡}t||d�S )z~
        Renders the compressor output with the appropriate template for
        the given mode and template context.
        r   Úflatten)rC   é	   )Úsenderr*   r@   r)   )r)   )r)   Úupdater,   Úhasattrr   rž   r   ÚsendÚ	__class__r*   rB   r	   )r2   r@   r)   Úfinal_contextÚtemplate_namer5   r5   r6   rš   M  s   

ÿ
zCompressor.render_output)NNNNrf   )F)r   F)FN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r7   r
   r:   r=   rB   rL   rW   r\   re   rh   rm   rs   ru   r„   r†   rˆ   r|   r}   r   r~   rœ   r�   rš   r5   r5   r5   r6   r      sB    
ÿ

 




+


ÿ'


	
r   )/Ú
__future__r   r   rO   r^   Ú	importlibr   Údjangor   Údjango.core.files.baser   Údjango.utils.safestringr   Ú%django.utils.six.moves.urllib.requestr   Údjango.template.loaderr	   Údjango.utils.functionalr
   Úcompressor.cacher   r   Úcompressor.confr   Úcompressor.exceptionsr   r   r   Úcompressor.filtersr   Úcompressor.filters.css_defaultr   r   r9   r   Úcompressor.signalsr   Úcompressor.utilsr   r   r   ÚSOURCE_HUNKrn   r{   r…   Úobjectr   r5   r5   r5   r6   Ú<module>   s*    