o
    /h	F                     @   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 i fd	d
ZG dd deZdS )    N)settings)BaseCommandCommandError)loader)
ModelGraphgenerate_dot)signalcommandTFc              
   C   s   t |trAtj|r?zt|d}t|}W d    n1 s!w   Y  W n ty> } zt	d|  t|d }~ww | S | d D ] }|D ]}d|v rd|d D ]}|d }||v rc|| |d< qSqIqE| S )NrtzInvalid app style file graphsnamemodelsapp_namestyle)

isinstancestrospathexistsopenjsonload	Exceptionprint)
graph_data	app_stylefegcgmr    r    m/var/www/html/env_mimamsha/lib/python3.10/site-packages/django_extensions/management/commands/graph_models.pyretheme   s.   
r"   c                       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 )Commandz8Creates a GraphViz dot file for the specified app names.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/d0d,d1dd	d2d3dd4dd5d6d(d7dd8d9d(d:dd;d<d(dd=d>d(dd?d@dAddBd	d@dCddBd?dDdEddd	dFdGddBd?dHdIddd	dJdKddddLg dMdNdOdd	dPdQdddRdSg dTdUdOddVdWdXdYgdZdOd[| _ ttd\dV}|r| j D ]}|d]}|d^ d_d_d`}||v r|| | j | da< qt j|i | dVS )ba  
        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--app-stylestorez1Path to style json to configure the style per app	app-stylez.app-style.json)actionhelpdestdefaultz--pygraphviz
store_trueF
pygraphvizz,Output graph data as image using PyGraphViz.)r&   r)   r(   r'   z--pydotpydotz-Output graph data as image using PyDot(Plus).z--dotdotzDOutput graph data as raw DOT (graph description language) text data.z--jsonr   z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--display-field-choicesdisplay_field_choicesz%Display choices instead of field typez--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
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.include_modelszBRestrict the graph to specified models. Wildcards (*) are allowed.T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 is applicable. The colors are: red (CASCADE), orange (SET_NULL), green (SET_DEFAULT), yellow (SET), blue (PROTECT), grey (DO_NOTHING), and purple (RESTRICT).TBrankdir)rO   BTLRRLzSet direction of graph layout. Supported directions: TB, LR, BT and 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.NorderinginoutzControls how the edges are arranged. Supported orderings: "in" (incoming relations first), "out" (outgoing relations first). Default is None.)z--include-models -Iz--inheritance -ez--no-inheritance -Ez--hide-relations-from-fields -Rz--relation-fields-onlyz--disable-sort-fields -Sz--hide-edge-labelsz--arrow-shapez--color-code-deletionsz	--rankdirz
--orderingGRAPH_MODELS r   -_r)   )	argumentsgetattrr   splitlstripreplacesuper__init__)selfargskwargsdefaultsargument	arg_splitsetting_opt	__class__r    r!   ra   <   sr  "(.4:@HOW]bho
 
 L

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*)nargsrX   N)add_argumentr[   r]   )rb   parserrf   r    r    r!   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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,}t||d-}|	dkr	| j|fi |S |	dkr| j|fi |S | || d S ).Nrk   r2   rW   
app_labelsz&need one or more arguments for appnamer3    )r,   r+   r   r-   c                    s   i | ]\}}| v r||qS r    r    ).0kvoutput_opts_namesr    r!   
<dictcomp>3  s    z"Command.handle.<locals>.<dictcomp>   zOnly one of %s can be set.z, c                 S   s   g | ]}d | qS )z--%sr    )rs   optr    r    r!   
<listcomp>8  s    z"Command.handle.<locals>.<listcomp>c                 s   s    | ]	\}}|r|V  qd S Nr    )rs   keyvalr    r    r!   	<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.rP   rO   )r,   r+   r-   z7--rankdir is not supported for the chosen output formatrT   z8--ordering is not supported for the chosen output format)r,   r+   zQAn output file (--output) must be specified when --pydot or --pygraphviz are set.rX      cli_optionsT)as_jsonFr5   django_extensionsgraph_modelszdigraph.dotr%   )r   )template)r\   r   getr   r   r   splitextloweritemssumvaluesjoinnextHAS_PYGRAPHVIZ	HAS_PYDOTsysargvr   generate_graph_dataget_graph_datarender_output_jsonr   get_templater"   r   render_output_pygraphvizrender_output_pydotprint_output)rb   rc   optionsdefault_app_labelsr3   rZ   outputfile_extoutput_optsoutput_opts_countoutputr   r   r   r5   template_namer   dotdatar    rv   r!   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)r   bytesdecoder   writestdout)rb   r   output_filedot_output_fr    r    r!   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)rb   r   r   json_output_fr    r    r!   r     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)rs   ru   r    r    r!   r     s    z3Command.render_output_pygraphviz.<locals>.<genexpr>.)r   $   r   r4   )progr3   N)r   r   r+   __version__rstriptupler]   tempfileNamedTemporaryFiler   seekr   
ValueErrorAGraphr4   draw)rb   r   rd   versiontmpfilegraphr    r    r!   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 errorry   z9Found more then one graph, rendering only the first one.
r   r3   )*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webpxdotr   Nraw)format)r   r   r,   graph_from_dot_datar   listr   lenr   stderrr   rfind)rb   r   rd   r   r   formatsextformat_r    r    r!   r     s    
,zCommand.render_output_pydotr|   )__name__
__module____qualname__r'   can_import_settingsra   rp   r   r   r   r   r   r   __classcell__r    r    ri   r!   r#   5   s     b

\
r#   )r   r   r   r   django.confr   django.core.management.baser   r   django.templater   %django_extensions.management.modelvizr   r   "django_extensions.management.utilsr   r+   r   ImportError	pydotplusr,   r   r"   r#   r    r    r    r!   <module>   s6   