o
    a"<f<                     @   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 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 d dlmZ d dlmZmZm Z  d\Z!Z"d\Z#Z$G dd dZ%dS )    N)import_module)url2pathname)ContentFile)	mark_safe)render_to_string)cached_property)get_hexdigest	get_mtime)settings)CompressorErrorUncompressableFileErrorFilterDoesNotExist)CachedCompilerFilter)compressor_file_storage)post_compress)	get_classget_mod_funcstaticfiles)inlinefile)inputoutputc                   @   s  e Zd ZdZi Z		d6ddZdd Zedd	 Zd
d Z	dd Z
dd Zd7ddZdd Zdd Zedd Zedd Zedd Zedd Zd8dd Zd!d" Zd8d#d$Z		d9d%d&Zd'd( Zd:d*d+Zd7d,d-Zd;d.d/Zd;d0d1Zd;d2d3Zd7d4d5ZdS )<
Compressorzi
    Base compressor object to be subclassed for content type
    depending implementations details.
    N   c           
      O   s   |d u rt j| | _n|| _|d u r|| _n|| _|pd| _t jd| _t j| _	g | _
|p/i | _|| _i | _tt j| _tj| _d | _|| _|| _d S )N /)r
   COMPRESS_FILTERSfiltersoutput_prefixcontentCOMPRESS_OUTPUT_DIRstrip
output_dirDEFAULT_CHARSETcharsetsplit_contentcontextresource_kindextra_contextdictCOMPRESS_PRECOMPILERSprecompiler_mimetypesr   finders_storagelog	verbosity)
selfr'   r   r   r&   r   r.   r/   argskwargs r3   F/var/www/html/kck/venv/lib/python3.10/site-packages/compressor/base.py__init__!   s$   


zCompressor.__init__c                 K   s6   t | j| j| j| jd}|| | j| jfi |S )N)r   r&   r   r   )r)   r   r&   r   r   update	__class__r'   )r0   r2   keywordsr3   r3   r4   copy8   s   
zCompressor.copyc                 C   s   ddl m} |S )Nr   )default_storage)compressor.storager:   )r0   r:   r3   r3   r4   storageA   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r0   r3   r3   r4   split_contentsF   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'   )r0   modetemplater3   r3   r4   get_template_nameM   s   zCompressor.get_template_namec                 C   sf   z| j j}W n ty   tj}Y nw t|}||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   )
r<   base_urlrA   r
   COMPRESS_URLstr
startswithr   replacesplit)r0   urlrF   basenamer3   r3   r4   get_basenameY   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'
        r   r      .)ospathrK   appendsplitextextendr   r'   joinr"   r   )r0   r   rM   partsfilenamer3   r3   r4   get_filepathq   s   zCompressor.get_filepathc                 C   s  d}t jsHz!| jr| jdkr| jd| | j|}| j|s%d}W n! t	yG   | jr;| jdkr;| jd t
|rEt
|}Y nw |ss| jrs| jrk| jdkrkt jsb| jd| n	| jd| | jt|}|rw|S td|t j| jrdpd	f )
z
        Returns full path to a file, for example:

        get_filename('css/one.css') -> '/full/path/to/static/css/one.css'
        N   zLooking for '{}' in storage
zCRemote storages don't implement path, looking for the file locally
z4'{}' was not found in storage, using static finders
zUsing static finders for '{}'
z3'%s' could not be found in the COMPRESS_ROOT '%s'%sz or with staticfiles.rP   )r
   DEBUGr.   r/   writeformatr<   rR   existsr=   r   r,   findr   r   COMPRESS_ROOT)r0   rM   rX   r3   r3   r4   get_filename   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)r0   rX   r$   fder3   r3   r4   get_filecontent   s$   zCompressor.get_filecontentc                 C   s   t tj| jS N)r   r
   COMPRESS_PARSERr   r>   r3   r3   r4   parser      zCompressor.parserc                 C   s   dd | j D S )Nc                 S   s   g | ]}t |qS r3   )r   ).0
filter_clsr3   r3   r4   
<listcomp>   s    z-Compressor.cached_filters.<locals>.<listcomp>)r   r>   r3   r3   r4   cached_filters   rn   zCompressor.cached_filtersc                 C   s   dd |   D S )Nc                 S   s(   g | ]\}}}}|t krtt|qS r3   )SOURCE_FILErH   r	   )ro   kindvaluerM   elemr3   r3   r4   rq      s
    

z%Compressor.mtimes.<locals>.<listcomp>)r?   r>   r3   r3   r4   mtimes   s   zCompressor.mtimesc                 C   s"   t d| jg| j | jdS )Nr   rO   )r   rV   r   rw   encoder$   r>   r3   r3   r4   cachekey   s
   
zCompressor.cachekeyFc                 c   s    t jp|}|  D ]r\}}}}d}| j|}|d| j}	t||||	d}
|tkr7t	|
|d}
| 
||	}| jrE| j|fi |
\}}|rT| j|| jfi |
V  q
|ru| jD ]}|jri| j||gfi |
}qY| 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$   )methodrv   rt   rM   r$   )rX   T)forcedrM   N)r
   COMPRESS_ENABLEDr?   rm   elem_attribsgetr$   METHOD_INPUTrs   r)   rj   r+   
precompilefilterrr   run_with_compression_disabledhandle_outputelem_str)r0   r{   enabledrt   ru   rM   rv   precompiledattribsr$   optionsrp   r3   r3   r4   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.
        )rz   )r   rr   METHOD_OUTPUT)r0   r   r3   r3   r4   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   rS   )r0   r{   r   hunkr3   r3   r4   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 r3|| j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yt   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.
        FtypeNzQCouldn't find any precompiler in COMPRESS_PRECOMPILERS setting for mimetype '%s'.)r   filter_typerX   r$   commandmimetypeTzCould not find "%s".)attrsr   r$   rX   r3   )rm   r}   r~   r+   output_mimetypesr   r   r   ImportError	TypeErrorr   r'   r   r@   rA   r   )r0   r   rt   rv   rX   r$   r2   r   r   filter_or_commandmod_namecls_namemodr   precompiler_classr3   r3   r4   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   r3   )r@   r'   callabler=   )r0   r   r   rz   r2   rp   filter_funcr3   r3   r4   r   2  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   )rV   r   r
   r|   r   r   )r0   rB   r{   rM   r   filtered_outputr3   r3   r4   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   )r0   rB   r   r{   rM   output_funcr3   r3   r4   r   N  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.
        )rM   rL   )
rY   r<   r^   saver   rx   r$   r   rL   render_output)r0   rB   r   r{   rM   new_filepathrL   r3   r3   r4   output_fileW  s
   zCompressor.output_filec                 C   s   |  |d|iS )za
        The output method that directly returns the content for inline
        display.
        r   )r   r0   rB   r   r{   rM   r3   r3   r4   output_inlineb     zCompressor.output_inlinec                 C   s   |  ||||S )z|
        The output method that returns <link> with rel="preload" and
        proper href attribute for given file.
        )r   r   r3   r3   r4   output_preloadi  r   zCompressor.output_preloadc                 C   s   d| j vr
i | j d< | j d |pi  | j d | j t| j d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.
        
compressedflatten)senderr   rB   r&   )r&   )r&   r6   r(   hasattrr   r   sendr7   r'   rD   r   )r0   rB   r&   final_contexttemplate_namer3   r3   r4   r   p  s   


zCompressor.render_output)NNNNNr   rk   )F)NNNN)r   FN)FN)__name__
__module____qualname____doc__r   r5   r9   r   r<   r?   rD   rN   rY   ra   rj   rm   rr   rw   ry   r   r   r   r   r   r   r   r   r   r   r   r3   r3   r3   r4   r      sH    
	

)




'


'


	

r   )&rQ   rc   	importlibr   urllib.requestr   django.core.files.baser   django.utils.safestringr   django.template.loaderr   django.utils.functionalr   compressor.cacher   r	   compressor.confr
   compressor.exceptionsr   r   r   compressor.filtersr   r;   r   compressor.signalsr   compressor.utilsr   r   r   SOURCE_HUNKrs   r   r   r   r3   r3   r3   r4   <module>   s$    