o
    uvXjð3  ã                   @   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 d dlmZm	Z	 d dl
mZ d dlmZmZ d dlmZ zd dlZdZW n eyI   dZY nw zzd dlZW n ey^   d dlZY nw dZW n eym   dZY nw G d	d
„ d
eƒZdS )é    N)Úsettings)ÚBaseCommandÚCommandError)Úloader)Ú
ModelGraphÚgenerate_dot)ÚsignalcommandTFc                       s\   e Zd ZdZdZ‡ fdd„Zdd„ Zedd„ ƒZdd
d„Z	ddd„Z
dd„ Zdd„ Z‡  ZS )ÚCommandzµCreates a GraphViz dot file for the specified app names. You can pass multiple app names and they will all be combined into a single model. Output is usually directed to a dot file.Tc                    sÄ  i ddddddœ“ddddd	dœ“d
dddddœ“ddddddœ“ddddddœ“ddddddœ“ddddddœ“ddddddœ“ddddd œ“d!dd"dd#d$œ“d%dd&d'd(d$œ“d)ddd*d+dœ“d,dd-d.d œ“d/dd0d1d œ“d2dd3d4d œ“d5dd6d7d œ“d8dd9d:d;dœ“d<dd:d=dœd<d9d>d?dœd<d9d@dAdœdddBdCdœdddDg dE¢dFdGœdHœ¥| _ ttdIdJƒ}|rÕ| j D ]}| dK¡}|dL  dM¡ dMdN¡}||v rÔ|| | j | dO< qµtt| ƒj|i |¤Ž dJS )PaÃ  
        Allow defaults for arguments to be set in settings.GRAPH_MODELS.

        Each argument in self.arguments is a dict where the key is the
        space-separated args and the value is our kwarg dict.

        The default from settings is keyed as the long arg name with '--'
        removed and any '-' replaced by '_'. For example, the default value for
        --disable-fields can be set in settings.GRAPH_MODELS['disable_fields'].
        z--pygraphvizÚ
store_trueFÚ
pygraphvizz,Output graph data as image using PyGraphViz.)ÚactionÚdefaultÚdestÚhelpz--pydotÚpydotz-Output graph data as image using PyDot(Plus).z--dotÚdotzDOutput graph data as raw DOT (graph description language) text data.z--jsonÚjsonzOutput graph data as JSONz--disable-fields -dÚdisable_fieldsz#Do not show the class member fieldsz--disable-abstract-fieldsÚdisable_abstract_fieldsz7Do not show the class member fields that were inheritedz--group-models -gÚgroup_modelsz5Group models together respective to their applicationz--all-applications -aÚall_applicationsz:Automatically include all applications from INSTALLED_APPSz--output -oÚstoreÚ
outputfileziRender output file. Type of output dependend on file extensions. Use png or jpg to render graph to image.)r   r   r   z--layout -lÚlayoutzaLayout to be used by GraphViz for visualization. Layouts: circo dot fdp neato nop nop1 nop2 twopi)r   r   r   r   z
--theme -tÚthemeÚ
django2018z¬Theme to use. Supplied are 'original' and 'django2018'. You can create your own by creating dot templates in 'django_extentions/graph_models/themename/' template directory.z--verbose-names -nÚverbose_namesz%Use verbose_name of models and fieldsz--language -LÚlanguagez3Specify language used for verbose_name localizationz--exclude-columns -xÚexclude_columnszPExclude specific column(s) from the graph. Can also load exclude list from file.z--exclude-models -XÚexclude_modelszjExclude specific model(s) from the graph. Can also load exclude list from file. Wildcards (*) are allowed.z--include-models -IÚinclude_modelszBRestrict the graph to specified models. Wildcards (*) are allowed.z--inheritance -eTÚinheritancez$Include inheritance arrows (default)Ústore_falsez!Do not include inheritance arrowsÚrelations_as_fieldsz-Do not show relations as fields in the graph.Úsort_fieldszDo not sort fieldsÚhide_edge_labelsz)Do not showrelations labels in the graph.Úarrow_shape)ÚboxÚcrowÚcurveÚicurveÚdiamondr   ÚinvÚnoneÚnormalÚteeÚveezˆArrow shape to use for relations. Default is dot. Available shapes: box, crow, curve, icurve, diamond, dot, inv, none, normal, tee, vee.)r   r   r   Úchoicesr   )z--no-inheritance -Ez--hide-relations-from-fields -Rz--disable-sort-fields -Sz--hide-edge-labelsz--arrow-shapeÚGRAPH_MODELSNú r   ú-Ú_r   )	Ú	argumentsÚgetattrr   ÚsplitÚlstripÚreplaceÚsuperr	   Ú__init__)ÚselfÚargsÚkwargsÚdefaultsÚargumentÚ	arg_splitÚsetting_opt©Ú	__class__© úo/var/www/html/myproject/venv/lib/python3.10/site-packages/django_extensions/management/commands/graph_models.pyr<   $   s0  üÿüùüóüíüçüá%üÛ+üÕ1ýÏ6üÊ<üÄBü¾Hý¸Mý³Rý®Wý©\ü¤cüüüüû
† 

€zCommand.__init__c                 C   s:   |j ddd� | jD ]}|j | d¡i | j| ¤Ž q
dS )z/Unpack self.arguments for parser.add_arguments.Ú	app_labelÚ*)Únargsr3   N)Úadd_argumentr6   r8   )r=   ÚparserrA   rF   rF   rG   Úadd_arguments½   s   
ÿzCommand.add_argumentsc                    sæ  |d }|s|d st dƒ‚| d¡pd}tj |¡\}}| ¡ }g d¢‰ ‡ fdd„| ¡ D ƒ}t| ¡ ƒ}|d	krHt d
d 	dd„ ˆ D ƒ¡ ƒ‚|d	krXt
dd„ | ¡ D ƒƒ}n!|s]d}n|dkrdd}n|dkrkd}ntrpd}n	trud}nt dƒ‚|dv rƒ|sƒt dƒ‚d 	tjdd … ¡}	t|fd|	i|¤Ž}
|
 ¡  |dkr«|
jdd�}|  ||¡S |
jdd�}|d }tj 	d d!|d"¡}t |¡}t||d#�}tjsÑ| d$¡}|dkrÞ| j|fi |¤ŽS |dkrë| j|fi |¤ŽS |  ||¡ d S )%NrH   r   z&need one or more arguments for appnamer   Ú )r   r   r   r   c                    s   i | ]\}}|ˆ v r||“qS rF   rF   )Ú.0ÚkÚv©Úoutput_opts_namesrF   rG   Ú
<dictcomp>Ï   s    z"Command.handle.<locals>.<dictcomp>é   zOnly one of %s can be set.z, c                 S   s   g | ]}d | ‘qS )z--%srF   )rO   ÚoptrF   rF   rG   Ú
<listcomp>Ò   s    z"Command.handle.<locals>.<listcomp>c                 s   s   � | ]	\}}|r|V  qd S ©NrF   )rO   ÚkeyÚvalrF   rF   rG   Ú	<genexpr>Õ   s   € z!Command.handle.<locals>.<genexpr>r   z.dotz.jsonr   r   r   z€Neither pygraphviz nor pydotplus could be found to generate the image. To generate text output, use the --json or --dot options.)r   r   zQAn output file (--output) must be specified when --pydot or --pygraphviz are set.r3   é   Úcli_optionsT)Úas_jsonFr   Údjango_extensionsÚgraph_modelszdigraph.dot)Útemplatezutf-8)r   ÚgetÚosÚpathÚsplitextÚlowerÚitemsÚsumÚvaluesÚjoinÚnextÚHAS_PYGRAPHVIZÚ	HAS_PYDOTÚsysÚargvr   Úgenerate_graph_dataÚget_graph_dataÚrender_output_jsonr   Úget_templater   ÚsixÚPY3ÚencodeÚrender_output_pygraphvizÚrender_output_pydotÚprint_output)r=   r>   Úoptionsr   r5   Úoutputfile_extÚoutput_optsÚoutput_opts_countÚoutputr]   r`   Ú
graph_datar   Útemplate_namera   ÚdotdatarF   rR   rG   ÚhandleÃ   sX   

zCommand.handleNc                 C   sh   t jrt|t jƒr| ¡ }|r,t|dƒ�}| |¡ W d  ƒ dS 1 s%w   Y  dS | j |¡ dS )z8Write model data to file or stdout in DOT (text) format.ÚwtN)rt   ru   Ú
isinstanceÚbinary_typeÚdecodeÚopenÚwriteÚstdout)r=   r�   Úoutput_fileÚdot_output_frF   rF   rG   ry     s   "ÿzCommand.print_outputc                 C   sV   |r t |dƒ�}t ||¡ W d  ƒ dS 1 sw   Y  dS | j t |¡¡ dS )z2Write model data to file or stdout in JSON format.rƒ   N)r‡   r   Údumpr‰   rˆ   Údumps)r=   r   rŠ   Újson_output_frF   rF   rG   rr     s
   "ÿzCommand.render_output_jsonc                 K   sš   t stdƒ‚tj d¡}z!tdd„ | d¡D ƒƒdk r,t ¡ }| 	|¡ | 
d¡ |j}W n	 ty6   Y nw t |¡}|j|d d	� | |d
 ¡ dS )z,Render model data as image using pygraphviz.z,You need to install pygraphviz python modulez-svnc                 s   s   � | ]}t |ƒV  qd S rX   )Úint)rO   rQ   rF   rF   rG   r[     s   € z3Command.render_output_pygraphviz.<locals>.<genexpr>Ú.)r   é$   r   r   )Úprogr   N)rl   r   r   Ú__version__ÚrstripÚtupler8   ÚtempfileÚNamedTemporaryFilerˆ   ÚseekÚnameÚ
ValueErrorÚAGraphr   Údraw)r=   r�   r?   ÚversionÚtmpfileÚgraphrF   rF   rG   rw     s    

€ÿ
z Command.render_output_pygraphvizc                 K   s˜   t stdƒ‚t |¡}|stdƒ‚t|ttfƒr(t|ƒdkr$tj	 
d¡ |d }|d }g d¢}|| d¡d d	… }||v rA|nd
}|j
||d� d	S )z'Render model data as image using pydot.z'You need to install pydot python modulezpydot returned an errorrU   z9Found more then one graph, rendering only the first one.
r   r   ))ÚbmpÚcanonÚcmapÚcmapxÚcmapx_npr   ÚdiaÚemfÚemÚfplusÚepsÚfigÚgdÚgd2ÚgifÚgvÚimapÚimap_npÚismapÚjpeÚjpegÚjpgÚmetafileÚpdfÚpicÚplainz	plain-extÚpngÚpovÚpsÚps2ÚsvgÚsvgzÚtifÚtiffÚtkÚvmlÚvmlzÚvrmlÚwbmpÚxdotr�   NÚraw)Úformat)rm   r   r   Úgraph_from_dot_datar„   Úlistr•   Úlenrn   Ústderrrˆ   Úrfind)r=   r�   r?   rŸ   rŠ   ÚformatsÚextÚformat_rF   rF   rG   rx   +  s   
zCommand.render_output_pydotrX   )Ú__name__Ú
__module__Ú__qualname__r   Úcan_import_settingsr<   rM   r   r‚   ry   rr   rw   rx   Ú__classcell__rF   rF   rD   rG   r	      s     

@
r	   )rn   r   rc   r–   rt   Údjango.confr   Údjango.core.management.baser   r   Údjango.templater   Ú%django_extensions.management.modelvizr   r   Ú"django_extensions.management.utilsr   r   rl   ÚImportErrorÚ	pydotplusr   rm   r	   rF   rF   rF   rG   Ú<module>   s6   ÿÿÿ