U
    J~Hjú  ã                   @  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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 ee
e	eeef e	edef f  ZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    )ÚannotationsN)ÚAny)ÚIterator)ÚTuple)ÚUnion)Úsettings)ÚManifestStaticFilesStorage)ÚStaticFilesStorage©Ú
Compressorc                   @  s6   e Zd ZdZddddddœdd	„Zdd
dœdd„ZdS )ÚCompressedStaticFilesStoragezC
    StaticFilesStorage subclass that compresses output files.
    Fzdict[str, Any]Úboolr   Ú_PostProcessT)ÚpathsÚdry_runÚoptionsÚreturnc                 k  s|   |rd S t tdd ƒ}| j|dd�}|D ]P}| |¡r&|  |¡}t|ƒt|ƒ }| |¡D ]}	|	|d … }
||
dfV  qXq&d S ©NZ#WHITENOISE_SKIP_COMPRESS_EXTENSIONST)Ú
extensionsÚquiet©Úgetattrr   Úcreate_compressorZshould_compressÚpathÚlenÚcompress)Úselfr   r   r   r   Ú
compressorr   Ú	full_pathÚ
prefix_lenÚcompressed_pathÚcompressed_name© r"   ú6/tmp/pip-unpacked-wheel-dkq0z1h6/whitenoise/storage.pyÚpost_process   s    

z)CompressedStaticFilesStorage.post_processr   )Úkwargsr   c                 K  s
   t f |ŽS ©Nr
   ©r   r%   r"   r"   r#   r   +   s    z.CompressedStaticFilesStorage.create_compressorN)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r$   r   r"   r"   r"   r#   r      s    ÿr   c                   @  s   e Zd ZdS )ÚMissingFileErrorN)r(   r)   r*   r"   r"   r"   r#   r,   /   s   r,   c                      s”   e Zd ZdZdZ‡ fdd„Z‡ fdd„Zdd„ Z‡ fd	d
„Zdd„ Z	dd„ Z
edd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Ze d¡Ze d¡Z‡  ZS )Ú$CompressedManifestStaticFilesStoragezË
    Extends ManifestStaticFilesStorage instance to create compressed versions
    of its output files and, optionally, to delete the non-hashed files (i.e.
    those without the hash in their name)
    Nc                   s,   t tdd ƒ}|d k	r|| _tƒ j||Ž d S )NZWHITENOISE_MANIFEST_STRICT)r   r   Úmanifest_strictÚsuperÚ__init__)r   Úargsr%   r.   ©Ú	__class__r"   r#   r0   <   s    z-CompressedManifestStaticFilesStorage.__init__c                 /  sX   t ƒ j||Ž}| d¡s"|  |¡}|D ],\}}}t|tƒrF|  ||¡}|||fV  q&d S )Nr   )r/   r$   ÚgetÚpost_process_with_compressionÚ
isinstanceÚ	ExceptionÚmake_helpful_exception)r   r1   r%   ÚfilesÚnameÚhashed_nameÚ	processedr2   r"   r#   r$   B   s    


z1CompressedManifestStaticFilesStorage.post_processc                 c  sÀ   i }t ƒ }|  |¡ |D ]2\}}}|r>t|tƒs>|||  |¡< |||fV  q|  ¡  t | ¡ ƒ}t | ¡ ƒ}| jr„||B | }	|}
nt ƒ }	||B }
|  	|	¡ |  
|
¡D ]\}}||dfV  q¦d S )NT)ÚsetÚstart_tracking_new_filesr6   r7   Ú
clean_nameÚstop_tracking_new_filesÚkeysÚvaluesÚkeep_only_hashed_filesÚdelete_filesÚcompress_files)r   r9   Zhashed_namesÚ	new_filesr:   r;   r<   Zoriginal_filesZhashed_filesÚfiles_to_deleteZfiles_to_compressr!   r"   r"   r#   r5   N   s$    

zBCompressedManifestStaticFilesStorage.post_process_with_compressionc                   s.   t ƒ j||Ž}| jd k	r*| j |  |¡¡ |S r&   )r/   r;   Ú
_new_filesÚaddr?   )r   r1   r%   r:   r2   r"   r#   r;   h   s    
z0CompressedManifestStaticFilesStorage.hashed_namec                 C  s
   || _ d S r&   ©rH   )r   rF   r"   r"   r#   r>   n   s    z=CompressedManifestStaticFilesStorage.start_tracking_new_filesc                 C  s
   d | _ d S r&   rJ   ©r   r"   r"   r#   r@   q   s    z<CompressedManifestStaticFilesStorage.stop_tracking_new_filesc                 C  s   t tddƒS )NZ!WHITENOISE_KEEP_ONLY_HASHED_FILESF)r   r   rK   r"   r"   r#   rC   t   s    z;CompressedManifestStaticFilesStorage.keep_only_hashed_filesc                 C  sT   |D ]J}zt  |  |¡¡ W q tk
rL } z|jtjkr<‚ W 5 d }~X Y qX qd S r&   )ÚosÚunlinkr   ÚOSErrorÚerrnoÚENOENT)r   rG   r:   Úer"   r"   r#   rD   x   s    z1CompressedManifestStaticFilesStorage.delete_filesc                 K  s
   t f |ŽS r&   r
   r'   r"   r"   r#   r   €   s    z6CompressedManifestStaticFilesStorage.create_compressorc           	      c  sr   t tdd ƒ}| j|dd�}|D ]N}| |¡r|  |¡}t|ƒt|ƒ }| |¡D ]}||d … }||fV  qPqd S r   r   )	r   Únamesr   r   r:   r   r   r    r!   r"   r"   r#   rE   ƒ   s    

z3CompressedManifestStaticFilesStorage.compress_filesc                 C  sr   t |tƒrnt|jƒr|jd nd}| j |¡}|rntj |¡d  	d¡ 
¡ }| jj||| d¡|d�}t|ƒ}|S )au  
        If a CSS file contains references to images, fonts etc that can't be found
        then Django's `post_process` blows up with a not particularly helpful
        ValueError that leads people to think WhiteNoise is broken.

        Here we attempt to intercept such errors and reformat them to be more
        helpful in revealing the source of the problem.
        r   Ú é   Ú.)Zorig_messageÚfilenameÚmissingÚext)r6   Ú
ValueErrorr   r1   Ú_error_msg_reÚsearchrL   r   ÚsplitextÚlstripÚupperÚ
_error_msgÚformatÚgroupr,   )r   Ú	exceptionr:   ÚmessageÚmatchÚ	extensionr"   r"   r#   r8   Ž   s    	
üz;CompressedManifestStaticFilesStorage.make_helpful_exceptionz#^The file '(.+)' could not be founda          {orig_message}

        The {ext} file '{filename}' references a file which could not be found:
          {missing}

        Please check the URL references in this {ext} file, particularly any
        relative paths which might be pointing to the wrong location.
        )r(   r)   r*   r+   rH   r0   r$   r5   r;   r>   r@   ÚpropertyrC   rD   r   rE   r8   ÚreÚcompilerZ   ÚtextwrapÚdedentr_   Ú__classcell__r"   r"   r2   r#   r-   3   s$   

ÿr-   )Ú
__future__r   rO   rL   rg   ri   Útypingr   r   r   r   Zdjango.confr   Z"django.contrib.staticfiles.storager   r	   Zwhitenoise.compressr   Ústrr   ÚRuntimeErrorr   r   rY   r,   r-   r"   r"   r"   r#   Ú<module>   s    $