o
    uvXjóA  ã                   @   sÖ   d 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	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dd„ ZG dd„ deƒ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)Ú
ForeignKeyÚManyToManyFieldÚOneToOneFieldÚRelatedField)ÚGenericRelation)ÚContextÚTemplateÚloader)Ú
force_text)Ú	mark_safe)Úactivatez1.1ÚPython)z'Bas van Oostveen <v.oostveen@gmail.com>)zOAntonio Cavedoni <http://cavedoni.com/>Stefano J. Attardi <http://attardi.org/>z(limodou <http://www.donews.net/limodou/>z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>c                 C   sZ   | sg S t | tttfƒr| S d| vr#tj | ¡r#dd„ t| ƒ ¡ D ƒS dd„ |  	d¡D ƒS )Nú,c                 S   ó   g | ]}|  ¡ ‘qS © ©Ústrip©Ú.0Úer   r   úb/var/www/html/myproject/venv/lib/python3.10/site-packages/django_extensions/management/modelviz.pyÚ
<listcomp>6   ó    z&parse_file_or_list.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r   7   r   )
Ú
isinstanceÚlistÚtupleÚsetÚosÚpathÚisfileÚopenÚ	readlinesÚsplit)Úargr   r   r   Úparse_file_or_list0   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   s  g | _ | dd ¡| _| dd¡| _| dd¡| _t| 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¡| _| jrŠdd„ t ¡ D ƒ| _d S || _d S )NÚcli_optionsÚdisable_fieldsFÚdisable_abstract_fieldsÚinclude_modelsÚ Úall_applicationsÚgroup_modelsÚverbose_namesÚinheritanceTÚrelations_as_fieldsÚsort_fieldsÚlanguageÚexclude_columnsÚexclude_modelsÚhide_edge_labelsÚarrow_shapec                 S   s   g | ]}|j ‘qS r   )Úlabel)r   Úappr   r   r   r   U   s    z'ModelGraph.__init__.<locals>.<listcomp>)ÚgraphsÚgetr'   r(   r)   r%   r*   r,   Úuse_subgraphr.   r/   r0   r1   r2   Úactivate_languager3   r4   r5   r6   r   Úget_app_configsÚ
app_labels)Úselfr>   Úkwargsr   r   r   Ú__init__;   s6   
ÿ


ÿ
ÿ
zModelGraph.__init__c                 C   sx   |   ¡  g }| jD ]}| dd„ |d D ƒ¡ q	| jD ]}|d D ]}|d D ]}|d ur7|d |v r7d|d< q'q!qd S )Nc                 S   s   g | ]}|d  ‘qS )Únamer   r   r   r   r   r   ^   r   z2ModelGraph.generate_graph_data.<locals>.<listcomp>ÚmodelsÚ	relationsÚtargetFÚ
needs_node)Úprocess_appsr9   Úextend)r?   ÚnodesÚgraphÚmodelÚrelationr   r   r   Úgenerate_graph_dataY   s   

€ýÿÿzModelGraph.generate_graph_dataFc                 C   sR   t j  ¡ }| d¡| j| j| j| jdœ}|r"dd„ | jD ƒ|d< |S | j|d< |S )Nz%Y-%m-%d %H:%M)Ú
created_atr'   r(   r)   r;   c                 S   r   r   )Úflatten)r   Úcontextr   r   r   r   r   r   z-ModelGraph.get_graph_data.<locals>.<listcomp>r9   )ÚdatetimeÚnowÚstrftimer'   r(   r)   r;   r9   )r?   Úas_jsonrR   Ú
graph_datar   r   r   Úget_graph_datag   s   
û
þzModelGraph.get_graph_datac                 C   s|   | j r|jrt|jƒ}| ¡ r| ¡ }n|j}t|ƒj}t|t	t
fƒr,|d |jj¡7 }|j|||j||v t|tƒ|jdœS )Nz ({0}))rB   r7   ÚtypeÚblankÚabstractrL   Úprimary_key)r.   Úverbose_namer   ÚislowerÚ
capitalizerB   rW   Ú__name__r   r   r   ÚformatÚremote_fieldÚ
field_namerX   r   rZ   )r?   ÚfieldÚabstract_fieldsr7   Útr   r   r   Úadd_attributesx   s"   
€
ùzModelGraph.add_attributesr+   c           
      C   s  | j r|jrt|jƒ}| ¡ r| ¡ }n|j}t|dƒr7| ¡ }| j r/| ¡ r/| dd¡ ¡ }d 	|t|ƒ¡}| j
r<d}t|jjtjƒro|jjdkrN|j}n%d|jjv r_|jj dd¡\}}n	|jjj}|jj}t ||¡}n|jj}|  ||||¡}	|	|d	 vrŠ|  |	d
 ¡rŒ|	S d S d S )NÚrelated_query_nameÚ_ú z{} ({})r+   r?   Ú.é   rD   rE   )r.   r[   r   r\   r]   rB   Úhasattrrf   Úreplacer_   r5   r   r`   rK   ÚsixÚstring_typesr#   Ú_metaÚ	app_labelr   Ú	get_modelÚget_relation_contextÚ	use_model)
r?   rb   rK   Úextrasr7   rf   Útarget_modelrp   Ú
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 ©ro   )rk   ro   rY   ©r   Úabstract_modelr   r   r   r   ¶   s    þþÿz2ModelGraph.get_abstract_models.<locals>.<listcomp>)Ú	__bases__r   r   )r?   Ú	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_%sri   rg   )rB   Úapp_nameÚcluster_app_namerC   )r   rB   rl   )r?   r8   r   r   r   Úget_app_context½   s   üzModelGraph.get_app_contextc                 C   s2   | j rdd„ |jjD ƒ}|S dd„ |jjD ƒ}|S )Nc                 S   s   g | ]}|‘qS r   r   ©r   rb   r   r   r   r   Ç   s    z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>c                 S   s   g | ]	}t |tƒs|‘qS r   )r   r   r„   r   r   r   r   Ê   s    
ÿ)r0   ro   Úlocal_fields)r?   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 ry   )rk   ro   rY   r^   rz   r   r   r   r   Ï   s    þþÿz5ModelGraph.get_appmodel_abstracts.<locals>.<listcomp>)r|   )r?   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< |S |d |d< |S )Nri   rg   )r�   rB   Ú	abstractsÚfieldsrD   r7   rB   )Ú
__module__rl   r^   r.   ro   r[   r   )r?   r   Úappmodel_abstractsrP   r   r   r   Úget_appmodel_contextÔ   s   ûþzModelGraph.get_appmodel_contextc                 C   sD   g }|j D ]}t|dƒr|jjr| |jj¡ | |  |¡¡ q|S )Nro   )r|   rk   ro   rY   rH   rŠ   Úget_bases_abstract_fields)r?   ÚcÚ_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-tablerY   Úproxyz\ninheritancer+   ri   rg   r/   z+[arrowhead=empty, arrowtail=none, dir=both]T©Ú
target_apprE   rW   rB   r7   ÚarrowsrF   )ro   rY   r‘   r5   r‹   rl   r^   )r?   r   Úparentr7   r   r   r   Úget_inheritance_contextì   s    ùz"ModelGraph.get_inheritance_contextc                 C   s   t | ¡ ƒ}|S ©N)r   Ú
get_models)r?   r8   r}   r   r   r   r˜   ÿ   s   zModelGraph.get_modelsc                 C   s(   |j  dd¡|jt|ƒj|j||ddœS )Nri   rg   Tr’   )r‹   rl   r^   rW   rB   )r?   ru   rb   r7   rt   r   r   r   rr     s   ùzModelGraph.get_relation_contextc                 C   s<   |  ¡ }|  |¡s|r||kr|S |d  |  ||¡¡ |S )NrŠ   )ÚcopyÚ
skip_fieldÚappendre   )r?   rb   rK   Úpkrc   Únewmodelr   r   r   Úprocess_attributes  s
   zModelGraph.process_attributesc              	   C   s^  | j D ]©}t |¡}|sq|  |¡}|  |¡}|  |¡}|| }|D ]}|  |jj¡s,q"|  	|¡}|  
|¡}|  ||¡}	|  |¡}
|jj}|rZ|jjsZ||
v rZ|	d  |  ||¡¡ |
D ]
}|  ||	||¡}	q\| jro|  |	¡}	|jjD ]	}|  ||	|¡}	qs|jjD ]}|  ||	¡}	q�| jrš|jD ]	}|  |||	¡}	q�|d  |	¡ q"|d r¬| j |¡ qd S )NrŠ   rC   )r>   r   Úget_app_configrƒ   r˜   r€   rs   ro   Úobject_namerˆ   rŽ   r�   r‡   rœ   rY   r›   re   rž   r1   Úsort_model_fieldsr…   Úprocess_local_fieldsÚlocal_many_to_manyÚprocess_local_many_to_manyr/   r|   Úprocess_parentr9   )r?   rp   r8   Ú	app_graphÚ
app_modelsr~   r   rŒ   rc   rK   r†   rœ   rb   r•   r   r   r   rG     sD   









€×zModelGraph.process_appsc                 C   s„   |  ¡ }|j d¡s||v s|  |¡r|S t|tƒr"|  ||d¡}nt|tƒr3|  ||d | j	¡¡}nd }|d ur@|d  
|¡ |S )NÚ_ptr_idz*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]rD   )r™   ÚattnameÚendswithrš   r   r   rx   r   r_   r6   r›   )r?   rb   rK   rc   r�   rL   r   r   r   r¢   A  s&   
ÿ
ÿýzModelGraph.process_local_fieldsc                 C   s�   |  ¡ }|  |¡r|S d }t|tƒr-t|jjdƒr,|jjjjr,|  	||d 
| j| j¡¡}nt|tƒr;|  	||tdƒ¡}|d urF|d  |¡ |S )Nro   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]rD   )r™   rš   r   r   rk   r`   Úthroughro   Úauto_createdrx   r_   r6   r   r   r›   )r?   rb   rK   r�   rL   r   r   r   r¤   Y  s&   

ÿý€
z%ModelGraph.process_local_many_to_manyc                 C   sJ   |  ¡ }t|dƒr#|  ||¡}||d vr#|  |d ¡r#|d  |¡ |S )Nro   rD   rE   )r™   rk   r–   rs   r›   )r?   r•   r   rK   r�   rw   r   r   r   r¥   m  s   
zModelGraph.process_parentc                 C   s$   |  ¡ }t|d dd„ d�|d< |S )NrŠ   c                 S   s   | d  | d  | d fS )NrZ   rL   r7   r   )rb   r   r   r   Ú<lambda>x  s    z.ModelGraph.sort_model_fields.<locals>.<lambda>)Úkey)r™   Úsorted)r?   rK   r�   r   r   r   r¡   v  s   zModelGraph.sort_model_fieldsc                 C   sp   | j r| j D ]}d| dd¡ }t ||¡r dS q| jr4| jD ]}d| dd¡ }t ||¡r3 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*   rl   ÚreÚsearchr4   )r?   rv   Úmodel_patternr   r   r   rs   {  s   
ÿ
ÿzModelGraph.use_modelc                 C   s6   | j r| jr|jr|j| j v rdS |j| j v rdS dS )NTF)r3   r.   r[   rB   )r?   rb   r   r   r   rš   �  s   zModelGraph.skip_fieldN)F)r+   )r^   r‹   Ú__qualname__rA   rM   rV   re   rx   r€   rƒ   r‡   rˆ   r�   rŽ   r–   r˜   rr   rž   rG   r¢   r¤   r¥   r¡   rs   rš   r   r   r   r   r&   :   s.    

$
	,	r&   ú*django_extensions/graph_models/digraph.dotc                 C   sX   t |tjƒrt |¡}t |tƒst|dƒrt |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   rm   rn   r
   Úget_templater	   rk   r¶   Ú	Exceptionr   rO   Úrender)rU   r¶   r�   Údotr   r   r   Úgenerate_dot™  s   
 
r»   c                  O   s   t | i |¤Ž}| ¡  | ¡ S r—   )r&   rM   rV   )Úargsr@   Ú	generatorr   r   r   rM   ¨  s   rM   c                 C   s   t g ||d�}| | ¡S )N)r*   r4   )r&   rs   )rK   r*   r4   r½   r   r   r   rs   ®  s   
rs   )rµ   )#Ú__doc__rQ   r   r±   rm   Údjango.appsr   Údjango.db.models.fields.relatedr   r   r   r   Ú"django.contrib.contenttypes.fieldsr   Údjango.templater   r	   r
   Údjango.utils.encodingr   Údjango.utils.safestringr   Údjango.utils.translationr   r<   Ú__version__Ú__license__Ú
__author__Ú__contributors__r%   Úobjectr&   r»   rM   rs   r   r   r   r   Ú<module>   s.   	
  
a