B
    f+f                 @   s   d Z ddlZddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlZddlmZ ddlmZ ddlZddlT dd	lmZ eed
 Zed Zed Zdd Zdd Zdd Zdd ZdS )zP
    SPEC: https://bcrm.carbonsoft.ru/project/Document/DOC-011091#spec-011090-b
    N)defaultdictOrderedDict)sha1)chain)Dict)Path)*)isclassZtmpz__autogen_models.pyz__autogen_models_tmp.pyc              c   s   t ddd} t ddd}t df| t dt df| t d	| t d
| t d}x.|D ]&}x ||D ]}|dkrzql|V  qlW q^W d S )N)dir_pathc             s   s4   |   sd S x"t|  D ]}|  r|V  qW d S )N)is_dirsortediterdir)r
   Zsub_path r   ./cmf/make_models.pyget_sub_dirs5   s
    z)iter_models_modules.<locals>.get_sub_dirsc             s   s~   xx| d | d fD ]d}|  s qxTt| D ]D}| r.|jdksFq.|jdrTq.t|j	ddd |j
 V  q.W qW d S )Nfieldsmodels)z.pyz.pyc_/.)r   r   r   is_filesuffixname
startswithstrparentreplaceZstem)r
   Zmodules_dir_pathZmodule_pathr   r   r   get_modules<   s    z(iter_models_modules.<locals>.get_modulescmfzcmf/modulescommonmoduleszcustom/pluginszcustom/modules)zcmf.fields.base_fieldszcmf.models.base_model)r   )r   r   Zbase_dir_pathsZbase_dir_pathmodule_namer   r   r   iter_models_modules,   s    	



r"   c        -         s	  yt   W n tk
r    Y nX yt  W n tk
rB   Y nX dd } i }xbt D ]X}t| tj|d d}x<|j	 D ].\}}t
|r~t|tjjr~| |||| q~W qXW tjG dd d tjG  fddd}t|}tt}i }	t }
x|D ]}|| }|| }td|  d	|_xd
D ]|}xt|| D ]hjddrd|_tdj dj dj dj d	 fdd|jD |_|j q@W q2W xd|jD ]Z}xR| D ]F}|j|jkr
d|_td|j d|j d|j d|j d	 P qW qW |js>td| d |
| qd }x|jD ]}|d krj|jrj|j}x|j	 D ]\}}||jkr |||j|j|< t|tjjr| d}|t |kr||j!kr||j!|< qxt|tjj"rb|j#s|j$st%d| d|j d|& }||	kr|j#rH|j|j'g|	|< n|j$r|j'|jg|	|< nt|tjj(rx|j#s|j$st%d| d|j dd }|j#r|j |j)*  }n4|j$r|j'st+d| d|j' |j,*  }|rx|| ||g qxW qLW |rt }xn|- D ]b}xZ|D ]R}t.|t/rP|| n4x2dD ]*}x"||t0 D ]}|| qjW qVW q4W q*W x"|j	 D ]\}}||k|_1qW qW t 2t j3 dt45  }|6d}|7d |7d |7d xt8|D ]}td|  || }|js4q|7d x"|jD ]} |7d 9| j qFW |7d!9|d":d#d |jD  |7d$ xxt8|jD ]j}|j| }|7d%| d&|j; d|j< d|j= d'|j< d|j= d( |j1d k	r|7d)|j1 d* qW x|j!D ]}!|j!|! }t|tjj>r|7d%|! d+|j? d,tjj@A|j' d-|jB d.|jC d/ |jDr|7d0 njt|tjjEr|7d%|! d+|j? d1|jB d.|jC d2d":d3d4 |jpg D  d5 |jDr|7d0 qW qW xt8|D ]}"||" }#d6d |#D }$t/tt8td7d4 |$D }%t/tt8td8d4 |#D }&|7d d}'x |#D ]}(|(d9 jFrnd	}'P qnW |7d:|" d; |7d$ |7d<|' d* |7d=|& d> |7d? |7d@ |7dA|% d> |7dB |7dC |7dD qW xt8|	D ]}"|	|" }#|#\})}*tjj@A|)}+tjj@A|*},|7d |7d:|" dE |7d$ |7dF|) dG |7dH|+ dI |7d@ |7dJ|* dG |7dK|, dI |7dL |7dM qW |7d* |G  |G  W d Q R X |Ht  d S )NNc             S   s   || krg g g g g d| |< | dr:| | d | n| drX| | d | nh| drv| | d | nJ| dr| | d	 | n,| d
r| | d | ntd|d S )N)r   r   r    pluginscustomzcmf.r   zcommon.r   zmodules.r    zcustom.plugins.r#   zcustom.modules.r$   ub   Неизвестный источник для импорта полей для моделей: {})r   append	Exceptionformat)models_listpathr   objr   r   r   add_to_models_listc   s"    




z3make__autogen_models_py.<locals>.add_to_models_list)packagec               @   s6   e Zd ZU dZeed< eed< eed< dZeed< dS )z*make__autogen_models_py.<locals>.FieldDatau$   Данные поля для autogen
field_name
model_namemodel_moduleNui_form_visible)__name__
__module____qualname____doc__r   __annotations__r0   boolr   r   r   r   	FieldData   s
   
r7   c                   sb   e Zd ZU dZdZeed< eje	dZ
e	ed< ejedZeed< ejedZee f ed< dS )z*make__autogen_models_py.<locals>.ModelDatau(   Данные модели для autogenNautogen)default_factory	hierarchy	id_fieldsr   )r1   r2   r3   r4   r8   r6   r5   dataclassesfieldlistr:   r   r;   dictr   r   r   r   )r7   r   r   	ModelData   s
   
r@   zmodel_name T)r$   r#   r    r   r   ZabstractFzSkip model r   z due z is abstract!c                s   g | ]}t  |s|qS r   )
issubclass).0m)modelr   r   
<listcomp>   s    z+make__autogen_models_py.<locals>.<listcomp>!Z_idzfield z of z$ should have left=True or right=Trueu   У поля u-    не указана модель field.model)r   Zcol1Zcol2zw+z+# Autogenerated by manage.py make_models. 
zfrom cmf import fields
zfrom cmf import modelsz


z
import {}
zclass {}({}):
,c             S   s   g | ]}d  |j|jqS )z{}.{})r'   r2   r1   )rB   rC   r   r   r   rE      s    z    abstract = False
z
    class (z):
        """z
 field"""
z        ui_form_visible = 
z&(fields.CmfTUUID):
        caption = "z ID"
        foreign_key = "z.id"
        nullable = z
        unique = z.
        visible = False
        index = True
z        no_acl = True
z ID"
        nullable = z
        foreign_keys = [c             s   s$   | ]}d t jj| dV  qdS )'z.id'N)r   r   
base_modelcamel2snake)rB   rC   r   r   r   	<genexpr>  s    z*make__autogen_models_py.<locals>.<genexpr>z+]
        visible=False
        index=True
c             S   s    g | ]}|d  j r|d  jqS )   )leftr   )rB   vvr   r   r   rE   +  s    c             s   s   | ]}|D ]
}|V  q
qd S )Nr   )rB   sir   r   r   rM   ,  s    c             s   s"   | ]}|d  j r|d  jV  qdS )rN   N)rightrD   )rB   rP   r   r   r   rM   -  s    rN   zclass z(models.CmfGM2MModel):
z    custom = uR       left = fields.Field(fields.CmfGenericRelation, caption="Объект", models=z)
ud       left_id = fields.Field(fields.CmfTUUID, caption="ID Объекта", nullable=True, index=True)
uQ       # TODO: TODO1 сделать update *_cache при обновлении name
uU       right = fields.Field(fields.CmfGenericRelation, caption="Элемент", models=ug       right_id = fields.Field(fields.CmfTUUID, caption="ID Элемента", nullable=True, index=True)
ue       left_name_cache = fields.Field(fields.CmfStr256, caption="Имя объекта", nullable=True)
uh       right_name_cache = fields.Field(fields.CmfStr256, caption="Имя элемента", nullable=True)
z(models.CmfM2MModel):
uV       left = fields.Field(fields.CmfRelation, caption="Левый Объект", model="z")
uc       left_id = fields.Field(fields.CmfTUUID, caption="ID Левого Объекта", foreign_key="z!.id", nullable=True, index=True)
uY       right = fields.Field(fields.CmfRelation, caption="Правый Объект", model="uf       right_id = fields.Field(fields.CmfTUUID, caption="ID Правого Объекта", foreign_key="ur       left_name_cache = fields.Field(fields.CmfStr256, caption="Имя левого объекта", nullable=True)
uu       right_name_cache = fields.Field(fields.CmfStr256, caption="Имя правого объекта", nullable=True)
)Imodels_orig_pathunlinkFileNotFoundErrormodels_tmp_pathr"   print	importlibimport_module__dict__itemsinspectr	   rA   r   r   	BaseModelr<   Z	dataclassr   r>   setr8   getr2   r1   r:   r%   __subclasses__addui_formr   CmfRelationBasedirr;   ZCmfM2MrO   rS   AssertionErrorm2m_model_cls_namerD   ZCmfGenericM2M
class_name
capitalize
ValueErrorbackrefvalues
isinstancer   tupler0   	with_namer   osgetpidopenwriter   r'   joinr/   r.   r-   ZCmfRelationZcaptionrK   rL   nullableuniqueno_aclZCmfGenericRelationr$   flushrename)-r+   Zmodels_dictr!   r/   Zobj_namer*   r@   Zmodels_dataZgm2mZm2mZabstract_modelsr.   Z
model_dataZ
model_listZ
model_typerC   subrc   Z	fieldnamer=   Zid_fieldnamerg   Zgm2m_keyZui_form_fieldsZui_form_groupZui_fieldZlist_keyZui_field_namer-   Z
field_dataZmodels_orig_tmp_pathZ
model_fileZ	imp_modelZid_field_namekvZright_choices_nestedZright_choicesZleft_choicesr$   valZleft_model_nameZright_model_nameZleft_name_snakeZright_name_snaker   )r7   rD   r   make__autogen_models_pyY   sb   	
**




"





6
8D





r~   c                 s  dd l } tt  dd lm} | t i }t	  g }xt
t|D ]t}tt|}t|trHt|tjjrHt|tjjr~qH||  |j x&|jD ]}t|tjjr|||j< qW qHW i }i }x0|D ](}t|dd r|j||j< |j||j< qW t|}	 fdd| D | }ddddd	d
dddddhddhdddddddddddddddhdhd d! fd"d#d8fd$d%	d}
t	 }x>|D ]6}|
t|j7 }
x |j D ]}||j qW qW fd&d'|D }td(t| d)|	 d*|
 d+t|  tjt t!j"#t$j%d,gd-d.}d/d-d0|j&d1< |'d2j(|tj|||ttt)d3}|'d4j(|tj|||ttt)d3}t*d5 }|+|j, d6t!-  }|| t*d7 }|+|j, d6t!-  }|| |.| |.| d S )9Nr   ui_namec                s   g | ]}|j  kr|qS r   )rh   )rB   rD   )concrete_models_namesr   r   rE     s    z+make__autogen_models_ts.<locals>.<listcomp>autorK   Zclass_full_namerh   Zfield_options_list_limitZnested_fieldsZ
max_lengthstepZscalecommentrw   ru   Zvisibler$   ZlinkablereadonlyZvirtualrk   choicesrO   rS   maxminZplaceholderZoptions_list_paramsZoptions_list_query_allr0   c             S   s  d}t | tjjrd}nt | tjjr,d}nt | tjjr@d}nt | tjjrTd}nt | tjjrhd}nt | tjjr|d}nzt | tjj	tjj
frd}n^t | tjjrd	}nJt | tjjtjjfrd
}n.t | tjjrd}nt | tjjtjjfrd}t| dd pt| dot| dg}|r0|d d kr4|S t | tjjtjjfrb| dd| dS t | tjjtjjtjjfr| dd| dS |S )NZCmfFieldZCmfTextFieldZCmfPhoneFieldZCmfStrFieldZCmfBigIntFieldZCmfIntFieldZCmfBoolFieldZCmfDateTimeFieldZCmfDateTimeRangeFieldZCmfRelationFieldZCmfM2MFieldZCmfBackrefFieldr   rD   r   <z | >z<(z)[]>)rA   r   r   ZCmfTextZCmfPhoneZCmfStrZ	CmfBigIntZCmfIntZCmfBoolZCmfDateZCmfDateTimeZCmfDateRangerd   Z	CmfObjectZ
CmfM2MBaseZCmfBackrefBaseZCmfObjectListgetattrhasattrrt   )	field_clsZts_classZrel_models_listr   r   r   ts_field_class  s@    z/make__autogen_models_ts.<locals>.ts_field_classc                sf   i }x\| j  D ]N\}}|kr$qn2|kr4|r4qn"| krD|sDqn|krV|dkrVq|||< qW |S )ub   Вернём мету без имён и неважных для фронта параметровN)ui_metar\   )r   r   Z
meta_paramZ
meta_value)params_def_falseparams_def_noneparams_def_trueparams_to_stripr   r   
strip_meta  s    z+make__autogen_models_ts.<locals>.strip_metac                sN   |d kr | }|  d\}}}t|}|d t|d d d  S )Nr   :zutf-8   )	partitionr   r   encodeZ	hexdigest)r   r   Z
field_typer   Z_field_type_paramsZhash_key)r   r   r   r   
field_hash  s
    z+make__autogen_models_ts.<locals>.field_hashc                s2   i | ]*}|j  D ]}|jd s| |qqS )Zcf_)r   rl   rh   r   )rB   rD   r   )r   r   r   
<dictcomp>	  s   z+make__autogen_models_ts.<locals>.<dictcomp>zmodels_count: z, concrete_models_count: z
, fields: z, uniq_fields zcmf/templatesT)loaderZkeep_trailing_newlineF)Zensure_asciiZ	sort_keyszjson.dumps_kwargszautogen_models_ts.jinja2)r(   Z
cmf_fieldsmodels_by_ui_nameui_name_by_modelsfields_indexr   r   r   rA   r   r   zautogen_fields_ts.jinja2z__autogen_models.tsr   z__autogen_fields.ts)N)/rY   rW   Z
write_textrT   Z	read_textZtmp.__autogen_models_tmp__autogen_models_tmpreloadr   r_   r   varsr   rm   typerA   r   r^   ZBaseM2MModelr%   rb   rh   __mro__r   lenrl   r   updater   rX   Zjinja2ZEnvironmentZFileSystemLoaderrp   r)   rt   ZconfigPROJECT_DIRZpoliciesZget_templateZrenderr   autogen_pathro   r   rq   ry   )rY   r   Z
all_modelsZautogen_modelsr   rD   baser   r   Zconcrete_models_countZfields_countZfield_ui_meta_setr   r   Z	jinja_envZautogen_models_textZautogen_fields_textZprev_models_fileZtemp_models_fileZprev_fields_fileZtemp_fields_filer   )r   r   r   r   r   r   r   r   r   make__autogen_models_tsy  s    



!"

(




r   c               C   s   t   t  d S )N)r~   r   r   r   r   r   make__autogen_modelsA  s    r   )r4   ZfilecmpZjsonZshutilcollectionsr   r   Zhashlibr   	itertoolsr   r<   typingr   Zpathlibr   Z
cmf.fieldsr   Zcmf.includer]   r	   r   r   rT   rW   r"   r~   r   r   r   r   r   r   <module>   s,   -  " I