o
    {,hR                     @   s   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mZm	Z	m
Z
 d dlmZ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 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)md5)unquote	urldefragurlsplit
urlunsplit)STATICFILES_STORAGE_ALIASsettings)check_settingsmatches_patterns)ImproperlyConfigured)ContentFile)FileSystemStoragestorages)
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__ X/var/www/html/rh/venv/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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")   F)*.js))za(?P<matched>import(?s:(?P<import>[\s\{].*?|\*\s*as\s*\w+))\s*from\s*['"](?P<url>[./].*?)["']\s*;)z import%(import)s from "%(url)s";)zT(?P<matched>export(?s:(?P<exports>[\s\{].*?))\s*from\s*["'](?P<url>[./].*?)["']\s*;)z!export%(exports)s from "%(url)s";)z2(?P<matched>import\s*['"](?P<url>[./].*?)["']\s*;)zimport"%(url)s";)z+(?P<matched>import\(["'](?P<url>.*?)["']\))zimport("%(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"))zG(?m)^(?P<matched>/\*#[ \t](?-i:sourceMappingURL)=(?P<url>.*)[ \t]*\*/)$z/*# sourceMappingURL=%(url)s */)r+   ))z9(?m)^(?P<matched>//# (?-i:sourceMappingURL)=(?P<url>.*))$z//# sourceMappingURL=%(url)sTc                    s   | j r|  j| jf7  _t j|i | i | _i | _| jD ]+\}}|D ]$}t|tt	fr2|\}}n| j
}t|tj}| j|g ||f q$qd S r   )$support_js_module_import_aggregationpatterns&_js_module_import_aggregation_patternsr   r   	_patternshashed_files
isinstancetuplelistdefault_templaterecompile
IGNORECASE
setdefaultappend)r   r   r   	extensionr-   patterntemplatecompiledr   r   r   r   m   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OSErrorrF   closeossplitsplitextjoinr3   r   )r   r"   rC   filenameparsed_name
clean_nameopenedrF   r    rootexthashed_nameunparsed_namer   r   r   r\      s>   



zHashedFilesMixin.hashed_namec                    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.
        rG   /NrI      rJ   rH   rK   )r   DEBUGr   r   r    endswithr   urlr3   r   r   )r   hashed_name_funcr"   forcer0   r\   fragmentrX   r   	final_urlquery_fragmenturlpartsr   r   r   _url   s&   

zHashedFilesMixin._urlc                 C   s   |  | j||S )r^   )rj   stored_name)r   r"   re   r   r   r   rc      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|s|dr|S |dr&|tjs&|S t|\}}|s0|S |drD|tjs=J |tj}ntj	dkrKn
tj	d}tt||}jjt|d d}d|ddd	 |dd	d  }	|r|	d
|v rd
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.
            matchedrc   z^[a-z]+:z//r_   T)re   r0   NrI   #)	groupdictr5   match
startswithr   r   r   removeprefixrR   sepreplace	posixpathrU   dirnamerj   _stored_namer   rS   )
matchobjmatchesrl   rc   url_pathrf   target_namesource_name
hashed_urltransformed_urlr0   r"   r   r<   r   r   	converter   s8   
"z1HashedFilesMixin.url_converter.<locals>.converter)r4   )r   r"   r0   r<   r   r   r   r   url_converter   s   8z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  g }tjD ]$}g }  ||D ]\}}}	}|||	f||< |rf|| qR|sk nqG|r}dt|}|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>6  s    z1HashedFilesMixin.post_process.<locals>.<dictcomp>z, z!Max post-process passes exceeded.)_post_processr1   	Exceptionrangemax_post_process_passesr9   rU   sortedRuntimeErrorr0   rA   values)r   r   dry_runoptionsr0   adjustable_pathsprocessed_adjustable_pathsr"   r\   	processed_unresolved_pathsisubstproblem_pathsr   )r   r   r   post_process  sB   

zHashedFilesMixin.post_processc                 c   s.   dd }t ||ddD ]}d}|| \}}||}	| |}
| |
}||vr2| ||	}n|| }t|	dr@|	d | |}d}||v r|}z	|	 	d}W n t
yo } z|d |dfV  W Y d }~nd }~ww | j D ]9\}}t||fr|D ],\}}| |||}z|||}W q ty } z|d |dfV  W Y d }~qd }~ww qu|r| | t| }| jr| || | ||}| |r| | | ||}| |}||krd}d}|s|sd}| ||	}| |}|||< ||||fV  W d    n	1 sw   Y  qd S )	Nc                 S   s   t | tjS r   )lenrS   rR   rs   )r"   r   r   r   
path_levelQ  s   z2HashedFilesMixin._post_process.<locals>.path_levelT)keyreverseseekr   Fzutf-8)r   rO   rX   hash_keyr\   hasattrr   rM   readdecodeUnicodeDecodeErrorr/   itemsr
   r   subrN   deleter   encodekeep_intermediate_files_save)r   r   r   r0   r   r"   substitutionsstorager    original_filecleaned_namer   r\   hashed_file_existsr   old_hashed_namerC   excr:   r-   r;   r<   r   content_file
saved_namer   r   r   r   O  sv   









zHashedFilesMixin._post_processc                 C   s   | ddS )N\r_   )rt   r!   r   r   r   rX     s   zHashedFilesMixin.clean_namec                 C   s   |S r   r   r!   r   r   r   r     s   zHashedFilesMixin.hash_keyc                 C   sD   t |}| |}| |}||}|d u r | | |}|S r   )ru   normpathrX   r   getr\   )r   r"   r0   r   r   
cache_namer   r   r   rw     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   )rC   rV   z*The name '%s' could not be hashed with %r.)rX   r   r0   r   r   r   r\   rN   )r   r"   r   r   r   intermediate_namer   r   r   r   rk     s   


zHashedFilesMixin.stored_namer   r#   )FN)F)r$   r%   r&   r4   r   r,   r.   r-   r   r   rF   r\   rj   rc   r   r   r   rX   r   rw   rk   r(   r   r   r   r   r)   /   s&    

"


A@M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.1zstaticfiles.jsonTFN)manifest_storagec                   s8   t  j|i | |d u r| }|| _|  \| _| _d S r   )r   r   r   load_manifestr0   manifest_hash)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   rO   manifest_namer   r   FileNotFoundError)r   manifestr   r   r   read_manifest  s   
(z ManifestFilesMixin.read_manifestc                 C   sz   |   }|d u ri dfS zt|}W n
 tjy   Y nw |d}|dv r3|di |ddfS td| j| jf )NrG   version)z1.0r   r   hashz(Couldn't load manifest '%s' (version %s))r   jsonloadsJSONDecodeErrorr   rN   r   manifest_version)r   rC   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   )r0   r   r   r   save_manifest)r   r   r   r   r   r   r     s   
zManifestFilesMixin.post_processc              	   C   sz   |  d ttt| j  | _| j| j	| jd}| j
| jr*| j
| j t| }| j
| jt| d S )N)r   r   r   )rF   r   r   dumpsr   r0   r   r   r   r   r   rM   r   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'rH   rI   rJ   rK   )r   r   r    rL   r   r0   r   manifest_strictrN   rX   r\   r3   r   )r   r"   rW   rX   r   r   r]   r   r   r   rk     s   

zManifestFilesMixin.stored_name)r$   r%   r&   r   r   r   r   r   r   r   r   r   rk   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 | _d S r   )r   r   _wrappedr   r   r   r   _setup  s   zConfiguredStorage._setupN)r$   r%   r&   r   r   r   r   r   r     s    r   ) r   rR   ru   r5   hashlibr   urllib.parser   r   r   r   django.confr   r    django.contrib.staticfiles.utilsr	   r
   django.core.exceptionsr   django.core.files.baser   django.core.files.storager   r   django.utils.functionalr   r   r)   r   r   r   staticfiles_storager   r   r   r   <module>   s*       M	
