a
    ÆZEgÀH  ã                   @   s  d 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m	Z	m
Z
mZmZ ddlmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZ dZdZdZg d¢Z ej!dej"dej#dej$dej%dej&dej'diZ(dd„ Z)G dd„ dƒZ*d"dd„Z+dd„ Z,d d!„ Z-dS )#zÃ
modelviz.py - DOT file generator for Django Models

Based on:
  Django model to DOT (Graphviz) converter
  by Antonio Cavedoni <antonio@cavedoni.org>
  Adapted to be used with django-extensions
é    N)Úapps)Údeletion)Ú
ForeignKeyÚManyToManyFieldÚOneToOneFieldÚRelatedField)ÚOneToOneRelÚManyToOneRel)ÚGenericRelation)ÚContextÚTemplateÚloader)Ú	force_str)Ú	mark_safe)Úactivatez1.1ÚPython)z'Bas van Oostveen <v.oostveen@gmail.com>)zQAntonio Cavedoni <https://cavedoni.com/>Stefano J. Attardi <https://attardi.org/>ZlimodouzCarlo C8E Mironz Andre Campos <cahenan@gmail.com>z#Justin Findlay <jfindlay@gmail.com>z&Alexander Houben <alexander@houben.ch>z Joern Hees <gitdev@joernhees.de>z%Kevin Cherepski <cherepski@gmail.com>z&Jose Tomas Tocino <theom3ga@gmail.com>z#Adam Dobrawy <naczelnik@jawnosc.tk>z6Mikkel Munch Mortensen <https://www.detfalskested.dk/>z+Andrzej Bistram <andrzej.bistram@gmail.com>z%Daniel Lipsitt <danlipsitt@gmail.com>z5Tobias Mitterdorfer <tobias.mitterdorfer97@gmail.com>ZredZblueZorangeZgreenZyellowZgreyZpurplec                 C   sZ   | sg S t | tttfƒr| S d| vrFtj | ¡rFdd„ t| ƒ ¡ D ƒS dd„ |  	d¡D ƒS )Nú,c                 S   s   g | ]}|  ¡ ‘qS © ©Ústrip©Ú.0Úer   r   ú^/var/www/sistema_ama/venv/lib/python3.9/site-packages/django_extensions/management/modelviz.pyÚ
<listcomp>E   ó    z&parse_file_or_list.<locals>.<listcomp>c                 S   s   g | ]}|  ¡ ‘qS r   r   r   r   r   r   r   F   r   )
Ú
isinstanceÚlistÚtupleÚsetÚosÚpathÚisfileÚopenÚ	readlinesÚsplit)Úargr   r   r   Úparse_file_or_list?   s    r'   c                   @   sÀ   e Zd Zdd„ Zdd„ Zd0dd„Zdd	„ Zd1dd„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdS )2Ú
ModelGraphc                 K   sF  g | _ | dd ¡| _| dd¡| _| dd¡| _t| dd¡ƒ| _| dd¡| _| dd¡| _| d	d¡| _	| d
d¡| _
| dd¡| _| dd¡| _| dd¡| _| dd ¡| _| jd urÆt| jƒ t| dd¡ƒ| _t| dd¡ƒ| _| dd¡| _| d¡| _| dd¡| _| j�r0dd„ t ¡ D ƒ| _n|| _| d¡| _d S )NÚcli_optionsÚdisable_fieldsFÚdisable_abstract_fieldsÚinclude_modelsÚ Úall_applicationsZgroup_modelsÚverbose_namesÚinheritanceTÚrelations_as_fieldsÚrelation_fields_onlyÚsort_fieldsÚlanguageÚexclude_columnsÚexclude_modelsÚhide_edge_labelsÚarrow_shapeÚcolor_code_deletionsc                 S   s   g | ]
}|j ‘qS r   )Úlabel)r   Úappr   r   r   r   f   r   z'ModelGraph.__init__.<locals>.<listcomp>Úrankdir)ÚgraphsÚgetr)   r*   r+   r'   r,   r.   Úuse_subgraphr/   r0   r1   r2   r3   r4   Úactivate_languager5   r6   r7   r8   r9   r   Zget_app_configsÚ
app_labelsr<   )ÚselfrA   Úkwargsr   r   r   Ú__init__J   s<    
ÿ


ÿ
ÿzModelGraph.__init__c                 C   sx   |   ¡  g }| jD ]}| dd„ |d D ƒ¡ q| jD ]<}|d D ].}|d D ] }|d urN|d |v rNd|d< qNqBq6d S )Nc                 S   s   g | ]}|d  ‘qS )Únamer   r   r   r   r   r   p   r   z2ModelGraph.generate_graph_data.<locals>.<listcomp>ÚmodelsÚ	relationsÚtargetFÚ
needs_node)Úprocess_appsr=   Úextend)rB   ÚnodesÚgraphÚmodelÚrelationr   r   r   Úgenerate_graph_datak   s    

zModelGraph.generate_graph_dataFc                 C   s’   t j  ¡ }| d¡| j| j| j| j| jdœ}|r„dd„ | jD ƒ}|D ]4}|d D ]&}| 	d¡ |d D ]}| 	d¡ qfqPqD||d	< n
| j|d	< |S )
Nz%Y-%m-%d %H:%M)Z
created_atr)   r*   r+   r?   r<   c                 S   s   g | ]}|  ¡ ‘qS r   )Úflatten)r   Úcontextr   r   r   r   †   r   z-ModelGraph.get_graph_data.<locals>.<listcomp>rF   rN   ÚfieldsÚfieldr=   )
ÚdatetimeÚnowÚstrftimer)   r*   r+   r?   r<   r=   Úpop)rB   Zas_jsonrV   Ú
graph_datar=   rR   Z
model_dataZ
field_datar   r   r   Úget_graph_datay   s$    
ú	


zModelGraph.get_graph_datac              	      sŒ   | j r(ˆ jr(tˆ jƒ}| ¡ r.| ¡ }nˆ j}tˆ ƒj}tˆ t	t
fƒrX|d ˆ jj¡7 }ˆ ˆ j||ˆ jt‡ fdd„|D ƒƒtˆ tƒˆ jdœS )Nz ({0})c                 3   s   | ]}ˆ j |j kV  qd S ©N)Zcreation_counter)r   Zabstract_field©rT   r   r   Ú	<genexpr>¥   s   ÿz,ModelGraph.add_attributes.<locals>.<genexpr>)rT   rE   r:   ÚtypeÚblankÚabstractrO   Úprimary_key)r/   Úverbose_namer   ÚislowerÚ
capitalizerE   r^   Ú__name__r   r   r   ÚformatÚremote_fieldÚ
field_namer_   Úanyr   ra   )rB   rT   Úabstract_fieldsr:   Útr   r\   r   Úadd_attributes’   s&    


þõzModelGraph.add_attributesr-   Nc                 C   s2  | j r(|jr(t|jƒ}| ¡ r.| ¡ }n|j}t|dƒrn| ¡ }| j r^| ¡ r^| dd¡ ¡ }d 	|t|ƒ¡}| j
rxd}t|jjtƒrÜ|jjdkrš|j}qäd|jjv r¼|jj dd¡\}}	n|jjj}|jj}	t ||	¡}n|jj}|rüd	 	|dd
… |¡}|  ||||¡}
|
|d v�r.|  |
d ¡�r.|
S d S )NÚrelated_query_nameÚ_ú z{} ({})r-   rB   Ú.é   z[{}, color={}]éÿÿÿÿrG   rH   )r/   rb   r   rc   rd   rE   Úhasattrrm   Úreplacerf   r7   r   rg   rN   Ústrr%   Ú_metaÚ	app_labelr   Z	get_modelÚget_relation_contextÚ	use_model)rB   rT   rN   ÚextrasÚcolorr:   rm   Útarget_modelrw   Ú
model_nameÚ_relr   r   r   Úadd_relation­   s4    



zModelGraph.add_relationc                 C   s2   g }|D ]}|dd„ |j D ƒ7 }qtt|ƒƒ}|S )Nc                 S   s"   g | ]}t |d ƒr|jjr|‘qS ©rv   )rs   rv   r`   ©r   Zabstract_modelr   r   r   r   ×   s   ÿz2ModelGraph.get_abstract_models.<locals>.<listcomp>)Ú	__bases__r   r   )rB   Ú	appmodelsÚabstract_modelsÚappmodelr   r   r   Úget_abstract_modelsÔ   s    ÿ
zModelGraph.get_abstract_modelsc                 C   s,   t d|j d|j d|j dd¡ g dœƒS )Nz"%s"z%sz
cluster_%srp   rn   )rE   Úapp_nameZcluster_app_namerF   )r   rE   rt   )rB   r;   r   r   r   Úget_app_contextÞ   s    üzModelGraph.get_app_contextc                 C   s0   | j rdd„ |jjD ƒ}ndd„ |jjD ƒ}|S )Nc                 S   s   g | ]}|‘qS r   r   ©r   rT   r   r   r   r   è   r   z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>c                 S   s   g | ]}t |tƒs|‘qS r   )r   r   r‰   r   r   r   r   ë   s   
ÿ)r1   rv   Úlocal_fields)rB   r…   Ú
attributesr   r   r   Úget_appmodel_attributesæ   s    z"ModelGraph.get_appmodel_attributesc                 C   s   dd„ |j D ƒS )Nc                 S   s$   g | ]}t |d ƒr|jjr|j‘qS r€   )rs   rv   r`   re   r�   r   r   r   r   ð   s   ÿz5ModelGraph.get_appmodel_abstracts.<locals>.<listcomp>)r‚   )rB   r…   r   r   r   Úget_appmodel_abstractsï   s    ÿz!ModelGraph.get_appmodel_abstractsc                 C   sN   ||j  dd¡|j|g g dœ}| jr>|jjr>t|jjƒ|d< n|d |d< |S )Nrp   rn   )rN   r‡   rE   Z	abstractsrS   rG   r:   rE   )Ú
__module__rt   re   r/   rv   rb   r   )rB   r…   Úappmodel_abstractsrR   r   r   r   Úget_appmodel_contextõ   s    ú	zModelGraph.get_appmodel_contextc                 C   sD   g }|j D ]4}t|dƒr
|jjr
| |jj¡ | |  |¡¡ q
|S )Nrv   )r‚   rs   rv   r`   rK   rS   Úget_bases_abstract_fields)rB   ÚcZ_abstract_fieldsr   r   r   r   r‘     s    
z$ModelGraph.get_bases_abstract_fieldsc                 C   sN   d}|j jrd}|j jrd}|d7 }| jr.d}|j dd¡|jdd|d	d
dœS )Nzmulti-tabler`   Úproxyz\ninheritancer-   rp   rn   r0   z+[arrowhead=empty, arrowtail=none, dir=both]T©Z
target_apprH   r^   rE   r:   ZarrowsrI   )rv   r`   r“   r7   rŽ   rt   re   )rB   r…   Úparentr:   r   r   r   Úget_inheritance_context  s     ùz"ModelGraph.get_inheritance_contextc                 C   s   t | ¡ ƒ}|S r[   )r   Ú
get_models)rB   r;   rƒ   r   r   r   r—   !  s    zModelGraph.get_modelsc                 C   s(   |j  dd¡|jt|ƒj|j||ddœS )Nrp   rn   Tr”   )rŽ   rt   re   r^   rE   )rB   r|   rT   r:   rz   r   r   r   rx   %  s    ùzModelGraph.get_relation_contextc                 C   s<   |  ¡ }|  |¡s|r"||kr"|S |d  |  ||¡¡ |S )NrS   )ÚcopyÚ
skip_fieldÚappendrl   )rB   rT   rN   Úpkrj   Únewmodelr   r   r   Úprocess_attributes0  s
    zModelGraph.process_attributesc              	   C   sh  | j D �]Z}t |¡}|sq|  |¡}|  |¡}|  |¡}|| }|D �]}|  |jj¡s\qF|  	|¡}|  
|¡}|  ||¡}	|  |¡}
|jj}|r¸|jjs¸||
v r¸|	d  |  ||¡¡ |
D ]}|  ||	||¡}	q¼| jrâ|  |	¡}	|jjD ]}|  ||	|¡}	qê|jjD ]}|  ||	¡}	�q| j�r>|jD ]}|  |||	¡}	�q(|d  |	¡ qF|d r| j |¡ qd S )NrS   rF   )rA   r   Zget_app_configrˆ   r—   r†   ry   rv   Zobject_namer�   r‘   r�   rŒ   r›   r`   rš   rl   r�   r3   Úsort_model_fieldsrŠ   Úprocess_local_fieldsZlocal_many_to_manyÚprocess_local_many_to_manyr0   r‚   Úprocess_parentr=   )rB   rw   r;   Z	app_graphZ
app_modelsr„   r…   r�   rj   rN   r‹   r›   rT   r•   r   r   r   rJ   7  s@    









zModelGraph.process_appsc                 C   s¸   |  ¡ }|j d¡s&||v s&|  |¡r*|S d }| jrZt|ttfƒrZt|j	dd ƒ}t
 |¡}t|tƒrv|  ||d|¡}n(t|tƒrš|  ||d | j¡|¡}nd }|d ur´|d  |¡ |S )NZ_ptr_idZ	on_deletez*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]rG   )r˜   ZattnameÚendswithr™   r9   r   r   r   Úgetattrrg   ÚON_DELETE_COLORSr>   r   rf   r8   rš   )rB   rT   rN   rj   rœ   r{   Zfield_on_deleterO   r   r   r   rŸ   c  s0    

ÿ
ÿú	zModelGraph.process_local_fieldsc                 C   s�   |  ¡ }|  |¡r|S d }t|tƒrZt|jjdƒrv|jjjjrv|  	||d 
| j| j¡¡}nt|tƒrv|  	||tdƒ¡}|d urŒ|d  |¡ |S )Nrv   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]rG   )r˜   r™   r   r   rs   rg   Zthroughrv   Zauto_createdr   rf   r8   r
   r   rš   )rB   rT   rN   rœ   rO   r   r   r   r    ‚  s$    

ÿý
z%ModelGraph.process_local_many_to_manyc                 C   sJ   |  ¡ }t|dƒrF|  ||¡}||d vrF|  |d ¡rF|d  |¡ |S )Nrv   rG   rH   )r˜   rs   r–   ry   rš   )rB   r•   r…   rN   rœ   r~   r   r   r   r¡   –  s    
zModelGraph.process_parentc                 C   s$   |  ¡ }t|d dd„ d�|d< |S )NrS   c                 S   s   | d  | d  | d fS )Nra   rO   r:   r   r\   r   r   r   Ú<lambda>¡  r   z.ModelGraph.sort_model_fields.<locals>.<lambda>)Úkey)r˜   Úsorted)rB   rN   rœ   r   r   r   rž   Ÿ  s    zModelGraph.sort_model_fieldsc                 C   sp   | j r4| j D ]&}d| dd¡ }t ||¡r dS q| jrh| jD ]&}d| dd¡ }t ||¡r@ dS q@| j  S )z€
        Decide whether to use a model, based on the model name and the lists of
        models to exclude and include.
        z^%s$Ú*z.*TF)r,   rt   ÚreÚsearchr6   )rB   r}   Zmodel_patternr   r   r   ry   ¤  s    

zModelGraph.use_modelc                 C   sV   | j r2| jr"|jr"|j| j v r"dS |j| j v r2dS | jrRt|tttt	t
tfƒsRdS dS )NTF)r5   r/   rb   rE   r2   r   r   r   r   r   r   r	   )rB   rT   r   r   r   r™   ¸  s    þzModelGraph.skip_field)F)r-   N)re   rŽ   Ú__qualname__rD   rP   rZ   rl   r   r†   rˆ   rŒ   r�   r�   r‘   r–   r—   rx   r�   rJ   rŸ   r    r¡   rž   ry   r™   r   r   r   r   r(   I   s,   !

'
	,	r(   ú*django_extensions/graph_models/digraph.dotc                 C   sV   t |tƒrt |¡}t |tƒs<t|dƒr4t |jtƒs<tdƒ‚t| ƒ 	¡ }| 
|¡}|S )NÚtemplatezyDefault Django template loader isn't used. This can lead to the incorrect template rendering. Please, check the settings.)r   ru   r   Zget_templater   rs   r­   Ú	Exceptionr   rQ   Úrender)rY   r­   r’   Údotr   r   r   Úgenerate_dotÈ  s    

 
r±   c                  O   s   t | i |¤Ž}| ¡  | ¡ S r[   )r(   rP   rZ   )ÚargsrC   Ú	generatorr   r   r   rP   ×  s    rP   c                 C   s   t g ||d�}| | ¡S )N)r,   r6   )r(   ry   )rN   r,   r6   r³   r   r   r   ry   Ý  s    ry   )r¬   ).Ú__doc__rU   r    r©   Zdjango.appsr   Zdjango.db.modelsr   Zdjango.db.models.fields.relatedr   r   r   r   Z'django.db.models.fields.reverse_relatedr   r	   Z"django.contrib.contenttypes.fieldsr
   Zdjango.templater   r   r   Zdjango.utils.encodingr   Zdjango.utils.safestringr   Zdjango.utils.translationr   r@   Ú__version__Ú__license__Ú
__author__Z__contributors__ZCASCADEZPROTECTZSET_NULLZSET_DEFAULTZSETZ
DO_NOTHINGZRESTRICTr¤   r'   r(   r±   rP   ry   r   r   r   r   Ú<module>   s@   	ù
   
