o
    ˜¨ÊhèK  ã                   @   sî   d dl Z d dlZd dlZd dlZd dlmZ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 d dlmZ d d	lmZ G d
d„ deƒZG dd„ dƒZG dd„ deƒZG dd„ deeƒZG dd„ deƒZeƒ ZdS )é    N)ÚunquoteÚ	urldefragÚurlsplitÚ
urlunsplit)Úsettings)Úcheck_settingsÚmatches_patterns)ÚImproperlyConfigured)ÚContentFile)ÚFileSystemStorageÚget_storage_class)Úmd5)Ú
LazyObjectc                       s.   e Zd ZdZd‡ fdd„	Z‡ fdd„Z‡  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 u rt j}|d u rt j}t|ƒ tƒ j||g|¢R i |¤Ž |s*d | _d | _d S d S ©N)r   ÚSTATIC_ROOTÚ
STATIC_URLr   ÚsuperÚ__init__Úbase_locationÚlocation)Úselfr   Úbase_urlÚargsÚkwargs©Ú	__class__© úT/var/www/html/env/lib/python3.10/site-packages/django/contrib/staticfiles/storage.pyr      s   
þzStaticFilesStorage.__init__c                    s   | j stdƒ‚tƒ  |¡S )NzaYou're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.)r   r	   r   Úpath©r   Únamer   r   r   r   %   s
   ÿzStaticFilesStorage.path©NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__classcell__r   r   r   r   r      s    r   c                       s”   e Zd Zd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d„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )#ÚHashedFilesMixinzurl("%(url)s")é   ))z*.css)z5(?P<matched>url\(['"]{0,1}\s*(?P<url>.*?)["']{0,1}\)))z.(?P<matched>@import\s*["']\s*(?P<url>.*?)["'])z@import url("%(url)s"))zI(?m)(?P<matched>)^(/\*#[ \t](?-i:sourceMappingURL)=(?P<url>.*)[ \t]*\*/)$z/*# sourceMappingURL=%(url)s */)z*.js))z;(?m)(?P<matched>)^(//# (?-i:sourceMappingURL)=(?P<url>.*))$z//# sourceMappingURL=%(url)sTc                    s€   t ƒ j|i |¤Ž i | _i | _| jD ]+\}}|D ]$}t|ttfƒr&|\}}n| j}t	 
|t	j¡}| j |g ¡ ||f¡ qqd S r   )r   r   Ú	_patternsÚhashed_filesÚpatternsÚ
isinstanceÚtupleÚlistÚdefault_templateÚreÚcompileÚ
IGNORECASEÚ
setdefaultÚappend)r   r   r   Ú	extensionr,   ÚpatternÚtemplateÚcompiledr   r   r   r   P   s   
úÿzHashedFilesMixin.__init__Nc                 C   s>   |du rdS t dd�}| ¡ D ]}| |¡ q| ¡ dd… S )zU
        Return a hash of the file with the given name and optional content.
        NF)Úusedforsecurityé   )r   ÚchunksÚupdateÚ	hexdigest)r   r!   ÚcontentÚhasherÚchunkr   r   r   Ú	file_hash]   s   
zHashedFilesMixin.file_hashc                 C   s*  t t|ƒƒ}|j ¡ }|rt t|ƒƒj ¡ p|}|d u }|r>|  |¡s+td|| f ƒ‚z|  |¡}W n ty=   | Y S w z|  ||¡}W |rL| 	¡  n|rT| 	¡  w w t
j |¡\}}t
j |¡\}	}
|rkd| nd}t
j |d|	||
f ¡}t|ƒ}||d< d|v r‘|d s‘|d  d7  < t|ƒS )	Nz)The file '%s' could not be found with %r.z.%sÚ z%s%s%sé   ú?#é   ú?)r   r   r   ÚstripÚexistsÚ
ValueErrorÚopenÚOSErrorrB   ÚcloseÚosÚsplitÚsplitextÚjoinr/   r   )r   r!   r?   ÚfilenameÚparsed_nameÚ
clean_nameÚopenedrB   r   ÚrootÚextÚhashed_nameÚunparsed_namer   r   r   rX   h   s>   


ÿþ€ÿ
ÿzHashedFilesMixin.hashed_nameFc                    sÀ   t jr|s|d}}n!t|ƒ\}}t|ƒj d¡r|}n|f}|dur(||f7 }||Ž }tƒ  |¡}	d|v }
|s:|
r\tt|	ƒƒ}|rJ|d sJ||d< |
rX|d sX|d  d7  < t	|ƒ}	t
|	ƒS )	ú:
        Return the non-hashed URL in DEBUG mode.
        rC   ú/NrE   é   rF   rD   rG   )r   ÚDEBUGr   r   r   Úendswithr   Úurlr/   r   r   )r   Úhashed_name_funcr!   Úforcer+   rX   ÚfragmentrT   r   Ú	final_urlÚquery_fragmentÚurlpartsr   r   r   Ú_urlŠ   s&   

zHashedFilesMixin._urlc                 C   s   |   | j||¡S )rZ   )rf   Ústored_name)r   r!   ra   r   r   r   r_   ©   s   zHashedFilesMixin.urlc                    s$   ˆdu rˆj ‰‡ ‡‡‡fdd„}|S )zJ
        Return the custom URL converter for the given file name.
        Nc           
         s  |   ¡ }|d }|d }t d|¡r|S | d¡r!| tj¡s!|S t|ƒ\}}| d¡r>| tj¡s4J ‚|ttjƒd… }ntj	dkrEˆnˆ 
tj	d¡}t t |¡|¡}ˆjˆjt|ƒdˆ d�}d | d¡dd… | d¡dd…  ¡}	|r„|	d	|v rd	nd
| 7 }	t|	ƒ|d< ˆ| S )zÚ
            Convert the matched URL to a normalized and hashed URL.

            This requires figuring out which files the matched URL resolves
            to and calling the url() method of the storage.
            Úmatchedr_   z^[a-z]+:r[   NT)ra   r+   éÿÿÿÿrE   ú#)Ú	groupdictr1   ÚmatchÚ
startswithr   r   r   ÚlenrN   ÚsepÚreplaceÚ	posixpathrQ   Údirnamerf   Ú_stored_namer   rO   )
ÚmatchobjÚmatchesrh   r_   Úurl_pathrb   Útarget_nameÚsource_nameÚ
hashed_urlÚtransformed_url©r+   r!   r   r8   r   r   Ú	converter¶   s4   
ü"ÿz1HashedFilesMixin.url_converter.<locals>.converter)r0   )r   r!   r+   r8   r|   r   r{   r   Úurl_converter¯   s   4zHashedFilesMixin.url_converterc                 +   s  � |rdS i }‡fdd„ˆ D ƒ}i }ˆ  ˆ ||¡D ]\}}}	}
||vs(t|	tƒr/|||	fV  q|||	f||< q‡ fdd„|D ƒ‰ d}tˆjƒD ]!}d}ˆ  ˆ ||¡D ]\}}}	}|||	f||< |pb|}qR|sh nqG|rsddtdƒfV  ˆj |¡ | ¡ E dH  dS )	a  
        Post process the given dictionary 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   g | ]
}t |ˆ jƒr|‘qS r   )r   r*   ©Ú.0r   ©r   r   r   Ú
<listcomp>  s
    ÿÿz1HashedFilesMixin.post_process.<locals>.<listcomp>c                    s   i | ]}|ˆ | “qS r   r   r~   )Úpathsr   r   Ú
<dictcomp>  s    z1HashedFilesMixin.post_process.<locals>.<dictcomp>FÚAllz!Max post-process passes exceeded.)	Ú_post_processr-   Ú	ExceptionÚrangeÚmax_post_process_passesÚRuntimeErrorr+   r=   Úvalues)r   r‚   Údry_runÚoptionsr+   Úadjustable_pathsÚprocessed_adjustable_pathsr!   rX   Ú	processedÚ_ÚsubstitutionsÚiÚsubstr   )r‚   r   r   Úpost_processì   s<   €
ÿÿÿ
ÿzHashedFilesMixin.post_processc                 c   sò  � dd„ }t ||dd�D ]ê}d}|| \}}| |¡�Ó}	|  |¡}
|  |
¡}||vr1|  ||	¡}n|| }t|	dƒr?|	 d¡ |  |¡}d}||v rË|}|	 ¡  	d¡}| j
 ¡ D ]9\}}t||fƒr‘|D ],\}}|  |||¡}z| ||¡}W qd ty� } z|d |dfV  W Y d }~qdd }~ww qX|r™|  |¡ t| ¡ ƒ}| jr¨|  ||¡ |  ||¡}|  |¡r¸|  |¡ |  ||¡}|  |¡}||krÉd}d}|sÜ|sÜd}|  ||	¡}|  |¡}|||< ||||fV  W d   ƒ n1 sñw   Y  qd S )	Nc                 S   s   t |  tj¡ƒS r   )rn   rO   rN   ro   )r!   r   r   r   Ú
path_level-  s   z2HashedFilesMixin._post_process.<locals>.path_levelT)ÚkeyÚreverseÚseekr   Fzutf-8)ÚsortedrK   rT   Úhash_keyrX   Úhasattrr˜   rI   ÚreadÚdecoder*   Úitemsr   r}   ÚsubrJ   Údeleter
   ÚencodeÚkeep_intermediate_filesÚ_save)r   r‚   r�   r+   r•   r!   r‘   Ústorager   Úoriginal_fileÚcleaned_namerš   rX   Úhashed_file_existsr�   Úold_hashed_namer?   r6   r,   r7   r8   r|   ÚexcÚcontent_fileÚ
saved_namer   r   r   r…   +  sl   €




ÿ€ÿ€




Â€ûzHashedFilesMixin._post_processc                 C   s   |  dd¡S )Nú\r[   )rp   r    r   r   r   rT   u  s   zHashedFilesMixin.clean_namec                 C   s   |S r   r   r    r   r   r   rš   x  s   zHashedFilesMixin.hash_keyc                 C   sD   t  |¡}|  |¡}|  |¡}| |¡}|d u r |  |  |¡¡}|S r   )rq   ÚnormpathrT   rš   ÚgetrX   )r   r!   r+   r¦   rš   Ú
cache_namer   r   r   rs   {  s   



zHashedFilesMixin._stored_namec                 C   s„   |   |¡}|  |¡}| j |¡}|r|S |}t| jd ƒD ]}|   | j|d |d�¡}||kr7|| j|< |  S |}qtd|| f ƒ‚)Né   )r?   rR   z*The name '%s' could not be hashed with %r.)rT   rš   r+   r®   r‡   rˆ   rX   rJ   )r   r!   r¦   rš   r¯   Úintermediate_namer’   r   r   r   rg   ‡  s   

ÿ
zHashedFilesMixin.stored_namer   r"   )FN)F)r#   r$   r%   r0   rˆ   r,   r¢   r   rB   rX   rf   r_   r}   r”   r…   rT   rš   rs   rg   r'   r   r   r   r   r(   /   s"    

"


=?Jr(   c                       s^   e Zd ZdZdZdZdZddœ‡ fdd„
Zd	d
„ Zdd„ Z	‡ fdd„Z
dd„ Zdd„ Z‡  ZS )ÚManifestFilesMixinú1.0zstaticfiles.jsonTFN)Úmanifest_storagec                   s2   t ƒ j|i |¤Ž |d u r| }|| _|  ¡ | _d S r   )r   r   r´   Úload_manifestr+   )r   r´   r   r   r   r   r   r   ¥  s
   zManifestFilesMixin.__init__c                 C   sX   z!| j  | j¡�}| ¡  ¡ W  d   ƒ W S 1 sw   Y  W d S  ty+   Y d S w r   )r´   rK   Úmanifest_namerœ   r�   ÚFileNotFoundError)r   Úmanifestr   r   r   Úread_manifest¬  s   
(ÿÿz ManifestFilesMixin.read_manifestc                 C   sj   |   ¡ }|d u r
i S zt |¡}W n
 tjy   Y nw | d¡}|dkr+| di ¡S td| j| jf ƒ‚)NÚversionr³   r‚   z(Couldn't load manifest '%s' (version %s))r¹   ÚjsonÚloadsÚJSONDecodeErrorr®   rJ   r¶   Úmanifest_version)r   r?   Ústoredrº   r   r   r   rµ   ³  s    ÿ

ÿÿz ManifestFilesMixin.load_manifestc                 /   s:   � i | _ tƒ j|i |¤ŽE d H  | d¡s|  ¡  d S d S )Nr‹   )r+   r   r”   r®   Úsave_manifest)r   r   r   r   r   r   r”   Ä  s   €
ÿzManifestFilesMixin.post_processc                 C   sP   | j | jdœ}| j | j¡r| j | j¡ t |¡ ¡ }| j 	| jt
|ƒ¡ d S )N)r‚   rº   )r+   r¾   r´   rI   r¶   r    r»   Údumpsr¡   r£   r
   )r   ÚpayloadÚcontentsr   r   r   rÀ   Ê  s
   z ManifestFilesMixin.save_manifestc                 C   sŽ   t t|ƒƒ}|j ¡ }|  |¡}| j |¡}|d u r+| jr#td| ƒ‚|  	|  
|¡¡}t|ƒ}||d< d|v rC|d sC|d  d7  < t|ƒS )Nz+Missing staticfiles manifest entry for '%s'rD   rE   rF   rG   )r   r   r   rH   rš   r+   r®   Úmanifest_strictrJ   rT   rX   r/   r   )r   r!   rS   rT   rš   r¯   rY   r   r   r   rg   Ñ  s   

ÿzManifestFilesMixin.stored_name)r#   r$   r%   r¾   r¶   rÄ   r¢   r   r¹   rµ   r”   rÀ   rg   r'   r   r   r   r   r²   Ÿ  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 r   )r   r   ÚSTATICFILES_STORAGEÚ_wrappedr€   r   r   r   Ú_setupï  s   zConfiguredStorage._setupN)r#   r$   r%   rÉ   r   r   r   r   rÆ   î  s    rÆ   )r»   rN   rq   r1   Úurllib.parser   r   r   r   Údjango.confr   Ú django.contrib.staticfiles.utilsr   r   Údjango.core.exceptionsr	   Údjango.core.files.baser
   Údjango.core.files.storager   r   Údjango.utils.cryptor   Údjango.utils.functionalr   r   r(   r²   rÅ   rÆ   Ústaticfiles_storager   r   r   r   Ú<module>   s(      rF	
