o
    h]9                     @   s   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yE   dZY nw zzd dlZW n eyZ   d dlZY nw dZW n eyi   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 )CommandzCreates 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dd@dAdd<d9dBdCddddDdEddddFg dGdHdIdddJdKdddLdMg dNdOdIdP| _ ttdQdR}|r| j D ]}|dS}|dT dUdUdV}||v r|| | j | dW< qt j|i | dRS )Xa  
        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
django2018zTheme 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.relation_fields_onlyz3Only display fields that are relevant for relationssort_fieldszDo not sort fieldshide_edge_labelsz*Do not show relations labels in the graph.arrow_shape)boxcrowcurveicurvediamondr   invnonenormalteeveezArrow 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   color_code_deletionszColor the relations according to their on_delete setting, where it it applicable. The colors are: red (CASCADE), orange (SET_NULL), green (SET_DEFAULT), yellow (SET), blue (PROTECT), grey (DO_NOTHING) and purple (RESTRICT).TBrankdir)r4   BTLRRLzSet direction of graph layout. Supported directions: "TB", "LR", "BT", "RL", corresponding to directed graphs drawn from top to bottom, from left to right, from bottom to top, and from right to left, respectively. Default is TB.)z--no-inheritance -Ez--hide-relations-from-fields -Rz--relation-fields-onlyz--disable-sort-fields -Sz--hide-edge-labelsz--arrow-shapez--color-code-deletionsz	--rankdirGRAPH_MODELSN r   -_r   )	argumentsgetattrr   splitlstripreplacesuper__init__)selfargskwargsdefaultsargument	arg_splitsetting_opt	__class__ p/var/www/html/ictaz-jobs/venv/lib/python3.10/site-packages/django_extensions/management/commands/graph_models.pyrC   #   sR  %+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*)nargsr:   N)add_argumentr=   r?   )rD   parserrH   rM   rM   rN   add_arguments   s   
zCommand.add_argumentsc                    s  |d }|s|d st tdi d}|r|}ntd|dp"d}tj|\}}| }g d  fd	d
| D }t	|
 }|dkrVtdddd  D  |dkrftdd | D }	n!|skd}	n|dkrrd}	n|dkryd}	ntr~d}	n	trd}	ntd|ddkr|	dvrtd|	dv r|st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)}|	dkr| j|fi |S |	dkr| j|fi |S | || d S )*NrO   r   r9   
app_labelsz&need one or more arguments for appnamer    )r   r   r   r   c                    s   i | ]\}}| v r||qS rM   rM   ).0kvoutput_opts_namesrM   rN   
<dictcomp>   s    z"Command.handle.<locals>.<dictcomp>   zOnly one of %s can be set.z, c                 S   s   g | ]}d | qS )z--%srM   )rW   optrM   rM   rN   
<listcomp>   s    z"Command.handle.<locals>.<listcomp>c                 s   s    | ]	\}}|r|V  qd S NrM   )rW   keyvalrM   rM   rN   	<genexpr>   s    z!Command.handle.<locals>.<genexpr>r   z.dotz.jsonr   r   r   zNeither pygraphviz nor pydotplus could be found to generate the image. To generate text output, use the --json or --dot options.r5   r4   )r   r   r   z7--rankdir is not supported for the chosen output format)r   r   zQAn output file (--output) must be specified when --pydot or --pygraphviz are set.r:      cli_optionsT)as_jsonFr   django_extensionsgraph_modelszdigraph.dot)template)r>   r   getr   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   render_output_pygraphvizrender_output_pydotprint_output)rD   rE   optionsdefault_app_labelsr   r<   outputfile_extoutput_optsoutput_opts_countoutputre   rh   
graph_datar   template_nameri   dotdatarM   rZ   rN   handle   s^   

zCommand.handleNc                 C   s`   t |t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)
isinstancebytesdecodeopenwritestdout)rD   r   output_filedot_output_frM   rM   rN   r~     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)rD   r   r   json_output_frM   rM   rN   rz   &  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 r`   )int)rW   rY   rM   rM   rN   rc   5  s    z3Command.render_output_pygraphviz.<locals>.<genexpr>.)r   $   r   r   )progr   N)rt   r   r   __version__rstriptupler?   tempfileNamedTemporaryFiler   seekname
ValueErrorAGraphr   draw)rD   r   rF   versiontmpfilegraphrM   rM   rN   r|   .  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 errorr]   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)ru   r   r   graph_from_dot_datar   listr   lenrv   stderrr   rfind)rD   r   rF   r   r   formatsextformat_rM   rM   rN   r}   B  s   
zCommand.render_output_pydotr`   )__name__
__module____qualname__r   can_import_settingsrC   rT   r   r   r~   rz   r|   r}   __classcell__rM   rM   rK   rN   r	      s     -

E
r	   )rv   r   rk   r   django.confr   django.core.management.baser   r   django.templater   %django_extensions.management.modelvizr   r   "django_extensions.management.utilsr   r   rt   ImportError	pydotplusr   ru   r	   rM   rM   rM   rN   <module>   s4   