U
    5øi8  ã                   @   sÄ   d dl Z d dlZd dlZ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	 d dl
mZ d dlZd dlmZ d dl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 G d
d„ deƒZdS )é    N)Úimport_module)Úurlretrieve)Úsettings)ÚBaseCommandÚCommandError)Úhandle_extensions)ÚContextÚEngine)Úarchive)Úget_docs_versionc                   @   sn   e Zd ZdZg ZdddgZdZdd„ Zd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dS )ÚTemplateCommandaÛ  
    Copy either a Django application layout template or a Django project
    layout template into the specified directory.

    :param style: A color style object (see django.core.management.color).
    :param app_or_project: The string 'app' or 'project'.
    :param name: The name of the application or project.
    :param directory: The directory to which the template should be copied.
    :param options: The additional variables passed to project or app templates
    ÚhttpÚhttpsÚftp))z.py-tplz.pyc              	   C   sx   |j ddd |j dddd |j dd	d |j d
ddddgdd |j ddddg dd |j dddtjdddd d S )NÚnamez#Name of the application or project.)ÚhelpÚ	directoryú?zOptional destination directory)Únargsr   z
--templatez*The path or URL to load the template from.z--extensionz-eÚ
extensionsÚappendÚpyztThe file extension(s) to render (default: "py"). Separate multiple extensions with commas, or use -e multiple times.)ÚdestÚactionÚdefaultr   z--namez-nÚfilesz_The file name(s) to render. Separate multiple file names with commas, or use -n multiple times.z	--excludez-xÚ zbThe directory name(s) to exclude, in addition to .git and __pycache__. Can be used multiple times.)r   r   r   Úconstr   )Úadd_argumentÚargparseÚSUPPRESS)ÚselfÚparser© r#   úD/tmp/pip-unpacked-wheel-gcyiijx6/django/core/management/templates.pyÚadd_arguments)   s8       ý   ý    üzTemplateCommand.add_argumentsNc           &      K   s²  || _ |dkrdnd| _g | _|d | _|  |¡ |d kr¦tj t ¡ |¡}zt 	|¡ W qî t
k
rz   td| ƒ‚Y qî tk
r¢ } zt|ƒ‚W 5 d }~X Y qîX nHtj tj |¡¡}|dkrÖ|  tj |¡d¡ tj |¡sîtd| ƒ‚tt|d ƒƒ}g }d	d
g}	|d D ] }
| tdd„ |
 d¡ƒ¡ q| d¡ }r^|D ]}|	 | ¡ ¡ qH| jdkrž| j d|d |¡f ¡ | j d|d |¡f ¡ d| }d| }d| }d| }d dd„ | ¡ D ƒ¡}t|||||||dtƒ dtji–dd}t j!st  "¡  t #¡  |  $|d |¡}t%|ƒd  }t &|¡D ]\}}}||d … }| '||¡}|r‚tj ||¡}tj	|d!d" |d d … D ]F}d|kr¾| (d#¡s²|d
krÒ| )|¡ n||	krŽ| )|¡ qŽ|D ]z}| *d$¡rðqÚtj ||¡}tj ||| '||¡¡}| j+D ]2\}} | *|¡r|d t%|ƒ … |  } qPqtj |¡rrtd%|| j|f ƒ‚| *|¡sˆ||krät,|d&d'}!|! -¡ }"W 5 Q R X t.ƒ  /|"¡}#|# 0|¡}"t,|d(d&d'}$|$ |"¡ W 5 Q R X nt1 2||¡ | jdkr| j d)| ¡ zt1 3||¡ |  4|¡ W n, tk
rR   | j5 d*| | j6j7¡ Y nX qÚq<| jr®| jdkr|| j d+¡ | jD ]*}%tj 8|%¡r t )|%¡ n
t1 9|%¡ q‚d S ),NÚappÚanÚaÚ	verbosityz'%s' already existsr   zBDestination directory '%s' does not exist, please create it first.r   z.gitÚ__pycache__r   c                 S   s   |   ¡ S )N)Ústrip)Úxr#   r#   r$   Ú<lambda>`   ó    z(TemplateCommand.handle.<locals>.<lambda>ú,Úexcludeé   z/Rendering %s template files with extensions: %sz, z.Rendering %s template files with filenames: %sz%s_namez%s_templatez%s_directoryzcamel_case_%s_namer   c                 s   s   | ]}|d kr|V  qdS )Ú_Nr#   )Ú.0r,   r#   r#   r$   Ú	<genexpr>q   s      z)TemplateCommand.handle.<locals>.<genexpr>Zdocs_versionZdjango_versionF)Z
autoescapeÚtemplateé   T)Úexist_okÚ.)z.pyoz.pycz	.py.classz_%s already exists. Overlaying %s %s into an existing directory won't replace conflicting files.zutf-8)ÚencodingÚwzCreating %szkNotice: Couldn't set permission bits on %s. You're probably using an uncommon filesystem setup. No problem.zCleaning up temporary files.):Úapp_or_projectÚa_or_anÚpaths_to_remover)   Úvalidate_nameÚosÚpathÚjoinÚgetcwdÚmakedirsÚFileExistsErrorr   ÚOSErrorÚabspathÚ
expanduserÚbasenameÚexistsÚtupler   ÚextendÚmapÚsplitÚgetr   r+   ÚstdoutÚwriteÚtitler   r   ÚdjangoÚ__version__r   Z
configuredÚ	configureÚsetupÚhandle_templateÚlenÚwalkÚreplaceÚ
startswithÚremoveÚendswithÚrewrite_template_suffixesÚopenÚreadr	   Zfrom_stringÚrenderÚshutilÚcopyfileÚcopymodeÚmake_writeableÚstderrÚstyleZNOTICEÚisfileÚrmtree)&r!   r;   r   ÚtargetÚoptionsZtop_dirÚer   Zextra_filesZexcluded_directoriesÚfiler0   r   Ú	base_nameZbase_subdirZbase_directoryZcamel_case_nameZcamel_case_valueÚcontextZtemplate_dirZprefix_lengthÚrootÚdirsr   Ú	path_restZrelative_dirÚ
target_dirÚdirnameÚfilenameÚold_pathÚnew_pathÚ
old_suffixÚ
new_suffixZtemplate_fileÚcontentr5   Znew_fileZpath_to_remover#   r#   r$   ÚhandleC   sþ    

ÿÿÿÿÿ     úù

ÿ


  
ÿ
  ÿÿÿ	
þý
zTemplateCommand.handlec                 C   sª   |dkrt j tjd d|¡S | d¡r4|dd… }t j |¡}t j |¡}t j |¡r\|S |  	|¡rr|  
|¡}nt j |¡}t j |¡r”|  |¡S td| j|f ƒ‚dS )z«
        Determine where the app or project templates are.
        Use django.__path__[0] as the default because the Django install
        directory isn't known.
        Nr   Úconfzfile://é   zcouldn't handle %s template %s.)r?   r@   rA   rR   Ú__path__rZ   rG   ÚnormpathÚisdirÚis_urlÚdownloadrF   rI   Úextractr   r;   )r!   r5   ÚsubdirZexpanded_templateZabsolute_pathr#   r#   r$   rV   É   s     


ÿzTemplateCommand.handle_templater   c                 C   s|   |d krt dj| j| jdƒ‚| ¡ s<t dj|| j|dƒ‚zt|ƒ W n tk
r\   Y nX t dj|| j| j|dƒ‚d S )Nz you must provide {an} {app} name)r'   r&   zX'{name}' is not a valid {app} {type}. Please make sure the {type} is a valid identifier.)r   r&   Útypez'{name}' conflicts with the name of an existing Python module and cannot be used as {an} {app} {type}. Please try another {type}.)r   r'   r&   r„   )r   Úformatr<   r;   Úisidentifierr   ÚImportError)r!   r   Zname_or_dirr#   r#   r$   r>   ã   s2    þüÿ	úÿzTemplateCommand.validate_namec              
   C   sJ  dd„ }d| j  }tj|dd}| j |¡ ||ƒ\}}| jdkrR| j d| ¡ zt|t	j
 ||¡ƒ\}}W n4 tk
r¢ }	 ztd|||	f ƒ‚W 5 d	}	~	X Y nX | d
¡d }
| d¡}|rÞt |¡\}}| d¡pÚ|
}n|
}|  |¡d }| d¡}|s|rt |¡}|r||7 }|
|krFt	j
 ||¡}t ||¡ |S |S )zB
        Download the given URL and return the file name.
        c                 S   s8   |   d¡}| d¡d }|  d¡r,|d }n| }||fS )Nú/éÿÿÿÿ)ÚrstriprM   r\   )ÚurlÚtmprt   Údisplay_urlr#   r#   r$   Úcleanup_url  s    


z-TemplateCommand.download.<locals>.cleanup_urlúdjango_%s_template_Z	_download©ÚprefixÚsuffixr1   zDownloading %sz"couldn't download URL %s to %s: %sNrˆ   r‰   zcontent-dispositionrt   r6   zcontent-type)r;   ÚtempfileÚmkdtempr=   r   r)   rO   rP   r   r?   r@   rA   rE   r   rM   rN   ÚcgiÚparse_headerÚsplitextÚ	mimetypesÚguess_extensionra   Úmove)r!   r‹   rŽ   r‘   Útempdirrt   r   Úthe_pathÚinfork   Z	used_nameÚcontent_dispositionr2   ÚparamsZguessed_filenameÚextÚcontent_typeZguessed_pathr#   r#   r$   r     s<    	

ÿ



zTemplateCommand.downloadc                 C   s@   t  |¡\}}| ¡  d¡r8|dd… | }|dd… }||fS )z@
        Like os.path.splitext, but takes off .tar, too
        z.taréüÿÿÿN)Ú	posixpathr—   Úlowerr\   )r!   rœ   Úbaser    r#   r#   r$   r—   :  s
    zTemplateCommand.splitextc              
   C   s   d| j  }tj|dd}| j |¡ | jdkr>| j d| ¡ zt 	||¡ |W S  tj
tfk
rŠ } ztd|||f ƒ‚W 5 d}~X Y nX dS )zŠ
        Extract the given file to a temporary directory and return
        the path of the directory with the extracted content.
        r   Z_extractr   r1   zExtracting %sz"couldn't extract file %s to %s: %sN)r;   r“   r”   r=   r   r)   rO   rP   r
   r‚   ZArchiveExceptionrE   r   )r!   rt   r‘   r›   rk   r#   r#   r$   r‚   D  s    

ÿzTemplateCommand.extractc                 C   s*   d|krdS |  dd¡d  ¡ }|| jkS )z)Return True if the name looks like a URL.ú:Fr6   r   )rM   r¤   Úurl_schemes)r!   r5   Úschemer#   r#   r$   r€   U  s    zTemplateCommand.is_urlc                 C   s:   t  |t j¡s6t  |¡}t |j¡tjB }t  ||¡ dS )zb
        Make sure that the file is writeable.
        Useful if our source is read-only.
        N)r?   ÚaccessÚW_OKÚstatÚS_IMODEÚst_modeÚS_IWUSRÚchmod)r!   rt   ÚstZnew_permissionsr#   r#   r$   rd   \  s    
zTemplateCommand.make_writeable)N)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zrequires_system_checksr§   r]   r%   rz   rV   r>   r   r—   r‚   r€   rd   r#   r#   r#   r$   r      s   


 
!6
r   )r   r•   r˜   r?   r£   ra   r«   r“   Ú	importlibr   Úurllib.requestr   rR   Zdjango.confr   Zdjango.core.management.baser   r   Zdjango.core.management.utilsr   Zdjango.templater   r	   Zdjango.utilsr
   Zdjango.utils.versionr   r   r#   r#   r#   r$   Ú<module>   s"   