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   ZSTATIC_ROOT
STATIC_URLr	   super__init__Zbase_locationlocation)selfr   base_urlargskwargs	__class__ /home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/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    contentZ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OSErrorrC   closeossplitsplitextjoinr1   r   )r   r    rA   filenameparsed_name
clean_nameZopenedrC   r   rootexthashed_nameunparsed_namer   r   r   rX      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.
        rD   /NrF      rG   rE   rH   )r   DEBUGr   r   r   endswithr   urlr1   r   r   )r   Zhashed_name_funcr    forcer.   rX   fragmentrU   r   Z	final_urlZquery_fragmenturlpartsr   r   r   _url   s&   

zHashedFilesMixin._urlc                 C   s   |  | j||S )rZ   )rc   stored_name)r   r    r`   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|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.
            matchedr_   z^[a-z]+:z//r[   T)r`   r.   NrF   #)	groupdictr3   match
startswithr   r   r   removeprefixrO   sepreplace	posixpathrR   dirnamerc   _stored_namer   rP   )
Zmatchobjmatchesre   r_   Zurl_pathra   target_nameZsource_nameZ
hashed_urlZtransformed_urlr.   r    r   r:   r   r   	converter   s8   
"z1HashedFilesMixin.url_converter.<locals>.converter)r2   )r   r    r.   r:   rt   r   rs   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   rv   )pathsr   r   
<dictcomp>6  s    z1HashedFilesMixin.post_process.<locals>.<dictcomp>z, z!Max post-process passes exceeded.)_post_processr/   	Exceptionrangemax_post_process_passesr7   rR   sortedRuntimeErrorr.   r?   values)r   rz   dry_runoptionsr.   adjustable_pathsZprocessed_adjustable_pathsr    rX   	processed_Zunresolved_pathsisubstZproblem_pathsr   )rz   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   )lenrP   rO   rl   )r    r   r   r   
path_levelQ  s   z2HashedFilesMixin._post_process.<locals>.path_levelT)keyreverseseekr   Fzutf-8)r   rL   rU   hash_keyrX   hasattrr   rJ   readdecodeUnicodeDecodeErrorr-   itemsr
   ru   subrK   deleter   encodekeep_intermediate_files_save)r   rz   r   r.   r   r    ZsubstitutionsZstorager   Zoriginal_filecleaned_namer   rX   Zhashed_file_existsr   Zold_hashed_namerA   excr8   r+   r9   r:   rt   content_fileZ
saved_namer   r   r   r|   O  sv   









zHashedFilesMixin._post_processc                 C   s   | ddS )N\r[   )rm   r   r   r   r   rU     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   )rn   normpathrU   r   getrX   )r   r    r.   r   r   
cache_namer   r   r   rp     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   )rA   rS   z*The name '%s' could not be hashed with %r.)rU   r   r.   r   r~   r   rX   rK   )r   r    r   r   r   Zintermediate_namer   r   r   r   rd     s   


zHashedFilesMixin.stored_namer   r!   )FN)F)r"   r#   r$   r2   r   r*   r,   r+   r   r   rC   rX   rc   r_   ru   r   r|   rU   r   rp   rd   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_manifestr.   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   rL   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 )NrD   version)z1.0r   rz   hashz(Couldn't load manifest '%s' (version %s))r   jsonloadsJSONDecodeErrorr   rK   r   manifest_version)r   rA   Z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   sz   |  d ttt| j  | _| j| j	| jd}| j
| jr*| j
| j t| }| j
| jt| d S )N)rz   r   r   )rC   r   r   dumpsr   r.   r   r   r   r   r   rJ   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'rE   rF   rG   rH   )r   r   r   rI   r   r.   r   manifest_strictrK   rU   rX   r1   r   )r   r    rT   rU   r   r   rY   r   r   r   rd     s   

zManifestFilesMixin.stored_name)r"   r#   r$   r   r   r   r   r   r   r   r   r   rd   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   Z_wrappedrx   r   r   r   _setup  s   zConfiguredStorage._setupN)r"   r#   r$   r   r   r   r   r   r     s    r   ) r   rO   rn   r3   hashlibr   urllib.parser   r   r   r   Zdjango.confr   r   Z django.contrib.staticfiles.utilsr	   r
   Zdjango.core.exceptionsr   Zdjango.core.files.baser   Zdjango.core.files.storager   r   Zdjango.utils.functionalr   r   r'   r   r   r   Zstaticfiles_storager   r   r   r   <module>   s*       M	
