U
    HaU5                     @   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 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   s^   |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 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.)add_argument)selfparser r   D/tmp/pip-unpacked-wheel-3jxiddxt/django/core/management/templates.pyadd_arguments(   s&          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 nH|dkr| tj|d tjtj|}tj|std| tt|d }g }|d	 D ] }	|td
d |	d q
| jdkrl| 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st  t   | !|d |}t"|d }t#|D ]\}}}||d  }|$|
|}|rPtj||}tj	|dd |d d  D ]&}|%d sv|d!kr\|&| q\|D ]z}|'d"rqtj||}tj|||$|
|}| j(D ]2\}}|'|r|d t"|  | } qqtj|r td#|| j|f |'|s6||krt)|d$d%}|* }W 5 Q R X t+ ,|} | -|}t)|d&d$d%}!|!| W 5 Q R X nt./|| | jdkr| jd'|  zt.0|| | 1| W n, tk
r    | j2d(| | j3j4 Y nX qq
| jr\| jdkr*| jd) | jD ]*}"tj5|"rNt&|" n
t.6|" q0d S )*Nappana	verbosityz'%s' already existsr   zBDestination directory '%s' does not exist, please create it first.r   r   c                 S   s   |   S )N)strip)xr   r   r    <lambda>V       z(TemplateCommand.handle.<locals>.<lambda>,   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_name c                 s   s   | ]}|d kr|V  qdS )_Nr   ).0r'   r   r   r    	<genexpr>d   s      z)TemplateCommand.handle.<locals>.<genexpr>Zdocs_versionZdjango_versionF)Z
autoescapetemplate   T)exist_ok.__pycache__)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.)7app_or_projecta_or_anpaths_to_remover%   validate_nameospathjoingetcwdmakedirsFileExistsErrorr   OSErrorbasenameabspath
expanduserexiststupler   extendmapsplit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   r7   r   targetoptionsZtop_direr   Zextra_filesfile	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contentr0   Znew_fileZpath_to_remover   r   r    handle:   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<   r=   rM   __path__rU   rD   normpathisdiris_urldownloadrC   rE   extractr   r7   )r   r0   subdirZexpanded_templateZabsolute_pathr   r   r    rQ      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   formatr8   r7   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}|rt|\}}|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/)rstriprI   rW   )urltmpro   display_urlr   r   r    cleanup_url   s    


z-TemplateCommand.download.<locals>.cleanup_urldjango_%s_template_Z	_downloadprefixsuffixr+   zDownloading %sz"couldn't download URL %s to %s: %sNr   r   zcontent-dispositionro   r1   zcontent-type)r7   tempfilemkdtempr9   r   r%   rJ   rK   r   r;   r<   r=   rA   r   rI   getcgiparse_headersplitext	mimetypesguess_extensionr\   move)r   r   r   r   tempdirro   r   the_pathinforf   Z	used_namecontent_dispositionr-   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.tarN)	posixpathr   lowerrW   )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   r+   zExtracting %sz"couldn't extract file %s to %s: %sN)r7   r   r   r9   r   r%   rJ   rK   r
   r}   ZArchiveExceptionrA   r   )r   ro   r   r   rf   r   r   r    r}   4  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.:Fr1   r   )rI   r   url_schemes)r   r0   schemer   r   r    r{   E  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   ro   stZnew_permissionsr   r   r    r_   L  s    
zTemplateCommand.make_writeable)N)r   )__name__
__module____qualname____doc__Zrequires_system_checksr   rX   r!   ru   rQ   r:   r|   r   r}   r{   r_   r   r   r   r    r      s   



!6
r   )r   r   r;   r   r\   r   r   	importlibr   urllib.requestr   rM   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    