U
    8ÄT_ ;  ã                   @   s€   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mZ d dlmZ d d	lmZ G d
d„ deƒZdS )é    N)Úapps)Úget_finders)Ústaticfiles_storage)ÚTags)ÚFileSystemStorage)ÚBaseCommandÚCommandError)Úno_style)Úcached_propertyc                       s†   e Zd ZdZdZdZ‡ fdd„Zedd„ ƒZdd	„ Z	d
d„ Z
dd„ Zdd„ Zddd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚCommandzc
    Copies or symlinks static files from different locations to the
    settings.STATIC_ROOT.
    z*Collect static files in a single location.Fc                    s8   t ƒ j||Ž g | _g | _g | _g | _t| _tƒ | _	d S ©N)
ÚsuperÚ__init__Úcopied_filesÚsymlinked_filesÚunmodified_filesÚpost_processed_filesr   Ústorager	   Ústyle)ÚselfÚargsÚkwargs©Ú	__class__© ú`/tmp/pip-unpacked-wheel-dv63caxw/django/contrib/staticfiles/management/commands/collectstatic.pyr      s    zCommand.__init__c                 C   s,   z| j  d¡ W n tk
r&   Y dS X dS )NÚ FT)r   ÚpathÚNotImplementedError©r   r   r   r   Úlocal   s
    zCommand.localc              	   C   sš   |j dddd� |j ddddd	d
� |j ddddd
� |j dddg dddd� |j ddddd� |j ddddd� |j ddddd� |j dddd d
� d S )!Nz--skip-checksÚ
store_truezSkip system checks.)ÚactionÚhelpz	--noinputz
--no-inputÚstore_falseÚinteractivez-Do NOT prompt the user for input of any kind.)r"   Údestr#   z--no-post-processÚpost_processz$Do NOT post process collected files.z-iz--ignoreÚappendÚignore_patternsZPATTERNz`Ignore files or directories matching this glob-style pattern. Use multiple times to ignore more.)r"   Údefaultr&   Úmetavarr#   z-nz	--dry-runz+Do everything except modify the filesystem.z-cz--clearz[Clear the existing files using the storage before trying to copy or link the original file.z-lz--linkz7Create a symbolic link to each file instead of copying.z--no-default-ignoreÚuse_default_ignore_patternszWDon't ignore the common private glob-style patterns (defaults to 'CVS', '.*' and '*~').)Úadd_argument)r   Úparserr   r   r   Úadd_arguments&   sf     þ   þ  þ    ý  þ  þ  þ  þzCommand.add_argumentsc                 K   st   |d | _ |d | _|d | _|d | _|d | _|d }|d rR|t d¡j7 }td	d
„ |D ƒƒ| _|d | _	dS )zA
        Set instance variables based on an options dict
        r%   Ú	verbosityÚlinkÚclearÚdry_runr)   r,   Ústaticfilesc                 S   s   h | ]}t j |¡’qS r   )Úosr   Únormpath)Ú.0Úpr   r   r   Ú	<setcomp>W   s     z&Command.set_options.<locals>.<setcomp>r'   N)
r%   r0   Úsymlinkr2   r3   r   Zget_app_configr)   Úlistr'   )r   Úoptionsr)   r   r   r   Úset_optionsK   s    




zCommand.set_optionsc                 C   sf  | j r| jstdƒ‚| jr$|  d¡ | j r2| j}n| j}i }tƒ D ]p}| | j	¡D ]^\}}t
|ddƒrxtj |j|¡}n|}||krž||f||< ||||ƒ qR| jd| dd� qRqB| j�rNt| jdƒ�rN| jj|| jd	�}|D ]l\}}	}
t|
tƒ�r| j d
| ¡ | j ¡  |
‚|
�r>| jd||	f dd� | j |¡ qà|  d| ¡ qà| j| j | j| jdœS )zx
        Perform the bulk of the work of collectstatic.

        Split off from handle() to facilitate testing.
        z&Can't symlink to a remote destination.r   ÚprefixNzÆFound another file with the destination path '%s'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.é   ©Úlevelr'   )r3   zPost-processing '%s' failed!zPost-processed '%s' as '%s'é   zSkipped post-processing '%s')ÚmodifiedÚ
unmodifiedÚpost_processed)r:   r    r   r2   Ú	clear_dirÚ	link_fileÚ	copy_filer   r;   r)   Úgetattrr5   r   Újoinr>   Úlogr'   Úhasattrr   r3   Ú
isinstanceÚ	ExceptionÚstderrÚwriter   r(   r   r   r   )r   ÚhandlerZfound_filesÚfinderr   r   Úprefixed_pathÚ	processorZoriginal_pathZprocessed_pathÚ	processedr   r   r   ÚcollectZ   sV    

ýû
	ÿ
ÿÿ
ýzCommand.collectc           	      K   sˆ  | j f |Ž |d s$| jtjgd� dg}| jr:| d¡ | d¡ |  ¡ rˆ| jjrˆ| jj}| d| ¡ | j 	|¡o„t
| j |¡ƒ}nd }| d¡ d}| jrä|rä| jr¶| d	¡ n
| d
¡ | d¡ td |¡ƒdkrätdƒ‚|  ¡ }| jdk�r„t|d ƒ}t|d ƒ}t|d ƒ}d|d|dk�r0dnd | j�r@dnd|�rPd| nd|d �rdd| nd|d �rzd| �p|ddœ S d S )NZskip_checks)ÚtagsÚ
zGYou have activated the --dry-run option so no files will be modified.

zdYou have requested to collect static files at the destination
location as specified in your settingsz:

    %s

z.

Tz-This will DELETE ALL FILES in this location!
z$This will overwrite existing files!
zNAre you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: r   Úyesz"Collecting static files cancelled.r?   rC   rD   rE   z]
%(modified_count)s %(identifier)s %(action)s%(destination)s%(unmodified)s%(post_processed)s.zstatic fileÚsZ	symlinkedÚcopiedz to '%s'z, %s unmodifiedz, %s post-processed)Úmodified_countÚ
identifierr"   ZdestinationrD   rE   )r=   Úcheckr   r4   r3   r(   Úis_local_storager   ÚlocationÚexistsÚanyÚlistdirr%   r2   ÚinputrJ   r   rV   r0   Úlenr:   )	r   r<   ÚmessageZdestination_pathZshould_warn_userZ	collectedr\   Zunmodified_countZpost_processed_countr   r   r   Úhandle˜   s`    ÿÿþ


ÿ
ÿÿøýzCommand.handlerB   c                 C   s   | j |kr| j |¡ dS )z"
        Small log helper
        N)r0   ÚstdoutrP   )r   ÚmsgrA   r   r   r   rK   Ö   s    
zCommand.logc                 C   s   t | jtƒS r   )rM   r   r   r   r   r   r   r_   Ý   s    zCommand.is_local_storagec              	   C   sè   | j  |¡sdS | j  |¡\}}|D ] }tj ||¡}| jrP| jd| dd� q$| jd| dd� z| j  |¡}W n  tk
r’   | j  	|¡ Y q$X tj |¡s¸tj 
|¡r¸t |¡ q$| j  	|¡ q$|D ]}|  tj ||¡¡ qÊdS )zW
        Delete the given relative path using the destination storage backend.
        NúPretending to delete '%s'r?   r@   úDeleting '%s')r   ra   rc   r5   r   rJ   r3   rK   r   ÚdeleteÚlexistsÚunlinkrF   )r   r   ÚdirsÚfilesÚfZfpathÚ	full_pathÚdr   r   r   rF   à   s"    zCommand.clear_dirc           	   
   C   s  | j  |¡�rz| j  |¡}W n tttfk
r8   Y n X z| |¡}W n tttfk
rb   Y nvX | jrŒ| j  |¡}| jt	j 
|¡A  }nd}|jdd�|jdd�k}|rØ|rØ|| jkrÆ| j |¡ |  d| ¡ dS | jrî|  d| ¡ n|  d| ¡ | j  |¡ dS )zR
        Check if the target file should be deleted if it already exists.
        Tr   )ÚmicrosecondzSkipping '%s' (not modified)Frj   rk   )r   ra   Zget_modified_timeÚOSErrorr   ÚAttributeErrorr    r   r:   r5   ÚislinkÚreplacer   r(   rK   r3   rl   )	r   r   rS   Úsource_storageZtarget_last_modifiedZsource_last_modifiedrr   Zcan_skip_unmodified_filesZfile_is_unmodifiedr   r   r   Údelete_fileû   s6    

ÿÿ
zCommand.delete_filec              
   C   sF  || j kr|  d| ¡S |  |||¡s*dS | |¡}| jrN| jd| dd� nÜ| jd| dd� | j |¡}tjtj |¡dd	� z&tj 	|¡ršt 
|¡ t ||¡ W n€ tk
rÔ   d
dl}td| ¡  ƒ‚Y nV tk
rþ   d
dl}td| ¡  ƒ‚Y n, tk
�r( } zt|ƒ‚W 5 d}~X Y nX || j k�rB| j  |¡ dS )z*
        Attempt to link ``path``
        z&Skipping '%s' (already linked earlier)NzPretending to link '%s'r?   r@   zLinking '%s'rB   T)Úexist_okr   z)Symlinking is not supported by Python %s.z2Symlinking is not supported in this platform (%s).)r   rK   rz   r   r3   r   r5   ÚmakedirsÚdirnamerm   rn   r:   rv   Úplatformr   Úpython_versionr   ru   r(   )r   r   rS   ry   Úsource_pathrr   r~   Úer   r   r   rG   -  s8    


ÿ
ÿ
zCommand.link_filec              	   C   s”   || j kr|  d| ¡S |  |||¡s*dS | |¡}| jrN| jd| dd� n6| jd| dd� | |¡�}| j ||¡ W 5 Q R X | j  |¡ dS )z7
        Attempt to copy ``path`` with storage
        z&Skipping '%s' (already copied earlier)NzPretending to copy '%s'r?   r@   zCopying '%s'rB   )	r   rK   rz   r   r3   Úopenr   Úsaver(   )r   r   rS   ry   r€   Zsource_filer   r   r   rH   Q  s    

zCommand.copy_file)rB   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   Zrequires_system_checksr   r
   r    r/   r=   rV   rg   rK   r_   rF   rz   rG   rH   Ú__classcell__r   r   r   r   r      s    	
%>>
2$r   )r5   Zdjango.appsr   Z"django.contrib.staticfiles.findersr   Z"django.contrib.staticfiles.storager   Zdjango.core.checksr   Zdjango.core.files.storager   Zdjango.core.management.baser   r   Zdjango.core.management.colorr	   Zdjango.utils.functionalr
   r   r   r   r   r   Ú<module>   s   