U
    c;                     @   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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mZ d dlmZmZ d dlmZ d d	lmZ d d
lmZ G dd deZdS )    N)import_module)build_opener)settings)BaseCommandCommandError)handle_extensionsrun_formatters)ContextEngine)archive)parse_header_parameters)get_docs_versionc                   @   sv   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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-v4uoe5gc/django/core/management/templates.pyadd_arguments*   sF       
	zTemplateCommand.add_argumentsNc           &      K   s  || _ |dkrdnd| _g | _|d | _| | |d krtjt |}zt	| W q t
k
rz   td| Y q tk
r } zt|W 5 d }~X Y qX nHtjtj|}|dkr| tj|d tj|st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  }|'||}|rt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qtj||}tj|||'||}| j+D ]2\}} |*|r|d t%|  |  } qPqtj|rrtd%|| j|f |*|s||krt,|d&d'}!|!- }"W 5 Q R X t. /|"}#|#0|}"t,|d(d&d'}$|$|" W 5 Q R X nt12|| | jdkr| jd)|  z| 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|%rt)|% n
t19|% qt:|g 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>q       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>   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apply_umaskmake_writeablestderrstyleZNOTICEisfilermtreer   )&r#   r=   r   targetoptionsZtop_direr   Zextra_filesZexcluded_directoriesfiler2   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contentr7   Znew_fileZpath_to_remover%   r%   r&   handleR   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.)rA   rB   rC   rT   __path__r\   rI   normpathisdiris_urldownloadrH   rK   extractr   r=   )r#   r7   subdirZexpanded_templateZabsolute_pathr%   r%   r&   rX      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@      s6    	zTemplateCommand.validate_namec              
   C   s  dd }d| j  }tj|dd}| j| ||\}}| jdkrR| jd|  tj	
||}t }dd	tj fg|_zF||2}	t|d
}
|	 }|
|	  W 5 Q R X W 5 Q R X W n4 tk
r } ztd|||f W 5 d}~X Y nX |dd }|d }|r0t|\}}|dp,|}n|}| |d }|d }|sn|rnt|}|rn||7 }||krt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/)rstriprO   r^   )urltmprv   display_urlr%   r%   r&   cleanup_url%  s    


z-TemplateCommand.download.<locals>.cleanup_urldjango_%s_template_Z	_downloadprefixsuffixr3   zDownloading %sz
User-AgentzDjango/wbz"couldn't download URL %s to %s: %sNr   r   zcontent-dispositionrv   r8   zcontent-type)r=   tempfilemkdtempr?   r   r+   rQ   rR   rA   rB   rC   r   rT   rU   
addheadersr`   infora   rG   r   rO   r   rP   splitext	mimetypesguess_extensionrc   move)r#   r   r   r   tempdirrv   r   the_pathopenersourcerk   headersrm   Z	used_namecontent_dispositionr4   paramsZguessed_filenameextcontent_typeZguessed_pathr%   r%   r&   r      sF    	

&

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.tarN)	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   r3   zExtracting %sz"couldn't extract file %s to %s: %sN)r=   r   r   r?   r   r+   rQ   rR   r   r   ZArchiveExceptionrG   r   )r#   rv   r   r   rm   r%   r%   r&   r   h  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.:Fr8   r   )rO   r   url_schemes)r#   r7   schemer%   r%   r&   r   z  s    zTemplateCommand.is_urlc                 C   s<   t d}t | tt |j}t ||| @  d S )Nr   )rA   umaskstatS_IMODEst_modechmod)r#   rw   rx   current_umaskZcurrent_moder%   r%   r&   re     s    

zTemplateCommand.apply_umaskc                 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)rA   accessW_OKr   r   r   S_IWUSRr   )r#   rv   stZnew_permissionsr%   r%   r&   rf     s    
zTemplateCommand.make_writeable)N)r   )__name__
__module____qualname____doc__Zrequires_system_checksr   r_   r'   r|   rX   r@   r   r   r   r   re   rf   r%   r%   r%   r&   r      s   
(
 
#>
r   )r!   r   rA   r   rc   r   r   	importlibr   urllib.requestr   rT   Zdjango.confr   Zdjango.core.management.baser   r   Zdjango.core.management.utilsr   r   Zdjango.templater	   r
   Zdjango.utilsr   Zdjango.utils.httpr   Zdjango.utils.versionr   r   r%   r%   r%   r&   <module>   s"   