o
    bD                     @   s   d dl Z 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 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)
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__ a/var/www/secure340b-portal/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("%s")   ))z*.css)z#(url\(['"]{0,1}\s*(.*?)["']{0,1}\)))z(@import\s*["']\s*(.*?)["'])z@import url("%s")Tc                    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   7   s   
zHashedFilesMixin.__init__Nc                 C   s<   |du rdS t  }| D ]}|| q| dd S )zU
        Return a hash of the file with the given name and optional content.
        N   )hashlibmd5chunksupdate	hexdigest)r   r   contentr9   chunkr   r   r   	file_hashD   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OSErrorr?   closeossplitsplitextjoinr,   r   )r   r   r=   filenameparsed_name
clean_nameZopenedr?   r   rootexthashed_nameunparsed_namer   r   r   rT   O   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.
        r@   /NrB      rC   rA   rD   )r   DEBUGr   r   r   endswithr   urlr,   r   r   )r   Zhashed_name_funcr   forcer(   rT   fragmentrQ   r   Z	final_urlZquery_fragmenturlpartsr   r   r   _urlp   s&   

zHashedFilesMixin._urlc                 C   s   |  | j||S )rV   )r_   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  |   \}}td|r|S |dr|tjs|S t|\}}|dr8|tjs.J |ttjd }ntj	dkr?n
tj	d}tt||}jjt|d d}d|ddd |ddd  }|r~|d|v rydnd| 7 }t| 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.
            z^[a-z]+:rW   NT)r\   r(   rB   #)groupsr.   match
startswithr   r   r   lenrK   sepreplace	posixpathrN   dirnamer_   _stored_namer   rL   )	Zmatchobjmatchedr[   Zurl_pathr]   target_nameZsource_nameZ
hashed_urlZtransformed_urlr(   r   r   r5   r   r   	converter   s&   

*z1HashedFilesMixin.url_converter.<locals>.converter)r-   )r   r   r(   r5   ro   r   rn   r   url_converter   s   -zHashedFilesMixin.url_converterc                 +   s    |rdS i }fdd D }  ||D ]\}}}}	|||fV  q fdd|D  tjD ] }
d}  ||D ]\}}}}|||fV  |pL|}q=|sR nq2|r]ddtdfV  j| 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   rq   )pathsr   r   
<dictcomp>   s    z1HashedFilesMixin.post_process.<locals>.<dictcomp>FZAllz!Max post-process passes exceeded.)_post_processrangemax_post_process_passesRuntimeErrorr(   r;   )r   ru   dry_runoptionsr(   adjustable_pathsr   rT   	processed_isubstitutionssubstr   )ru   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rd}d}|s|sd}| ||	}| |}|||< ||||fV  W d    n1 sw   Y  qd S )	Nc                 S   s   t | tjS r   )rf   rL   rK   rg   )r   r   r   r   
path_level   s   z2HashedFilesMixin._post_process.<locals>.path_levelT)keyreverseseekr   Fzutf-8)sortedrH   rQ   hash_keyrT   hasattrr   rF   readdecoder'   itemsr   rp   subrG   deleter
   encodekeep_intermediate_files_save)r   ru   r}   r(   r   r   r   Zstorager   Zoriginal_filecleaned_namer   rT   Zhashed_file_existsr~   Zold_hashed_namer=   r3   r)   r4   r5   ro   exccontent_fileZ
saved_namer   r   r   rw      sh   









zHashedFilesMixin._post_processc                 C   s   | ddS )N\rW   )rh   r   r   r   r   rQ   C  s   zHashedFilesMixin.clean_namec                 C   s   |S r   r   r   r   r   r   r   F  s   zHashedFilesMixin.hash_keyc                 C   sD   t |}| |}| |}||}|d u r | | |}|S r   )ri   normpathrQ   r   getrT   )r   r   r(   r   r   
cache_namer   r   r   rk   I  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=   rO   z*The name '%s' could not be hashed with %r.)rQ   r   r(   r   rx   ry   rT   rG   )r   r   r   r   r   Zintermediate_namer   r   r   r   r`   U  s   


zHashedFilesMixin.stored_namer   r   )FN)F)r    r!   r"   r-   ry   r)   r   r   r?   rT   r_   r[   rp   r   rw   rQ   r   rk   r`   r$   r   r   r   r   r%   ,   s"    

!


60Hr%   c                       sX   e Zd ZdZdZdZdZ 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.jsonTFc                    s    t  j|i | |  | _d S r   )r   r   load_manifestr(   r   r   r   r   r   r   r   s  s   zManifestFilesMixin.__init__c                 C   sV   z |  | j}|  W  d    W S 1 sw   Y  W d S  ty*   Y d S w r   )rH   manifest_namer   r   FileNotFoundError)r   manifestr   r   r   read_manifestw  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   ru   z(Couldn't load manifest '%s' (version %s))r   jsonloadsJSONDecodeErrorr   rG   r   manifest_version)r   r=   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_manifestr   r   r   r   r     s   
zManifestFilesMixin.post_processc                 C   sJ   | j | jd}| | jr| | j t| }| | jt	| d S )N)ru   r   )
r(   r   rF   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'rA   rB   rC   rD   )r   r   r   rE   r   r(   r   manifest_strictrG   rQ   rT   r,   r   )r   r   rP   rQ   r   r   rU   r   r   r   r`     s   

zManifestFilesMixin.stored_name)r    r!   r"   r   r   r   r   r   r   r   r   r   r`   r$   r   r   r   r   r   m  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   ZSTATICFILES_STORAGEZ_wrappedrs   r   r   r   _setup  s   zConfiguredStorage._setupN)r    r!   r"   r   r   r   r   r   r     s    r   )r8   r   rK   ri   r.   urllib.parser   r   r   r   Zdjango.confr   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(      C?
