U
    h-                    @   sV   d dl Z d dlZd dlmZ d dlZd dlZd dlT d dlm	Z	 G dd de	j
Z
dS )    N)urlparse)*)cmf_backbone_peerc                       s  e Zd Zddddddddd	d
dddgZed\ddZed]ddZ fddZdd Zdd Z	 fddZ
 fddZed^ddZed_d d!Zed"d# Zed`d$d%Zedad&d'Zedbd(d)Zedcd*d+Zeddd,d-Zeded.d/Zedfd0d1Zedgd2d3Zedhed4d5d6d7Zedid8d9Zedjd:d;Zedkd<d=Zedld>d?Zedmd@dAZedndBdCZedodDdEZ dpdFdGZ!dqdHdIZ"dJdK Z#drdLdMZ$dNdO Z%G dPdQ dQe&Z'dRdS Z(dsdTdUZ)dtdVdWZ*dudXdYZ+dvdZd[Z,  Z-S )wCmfBackbonePeergetsgetlistslistcountdelete
setup_peer	log_applylog_listlog_mark_doneget_objpeer_project_nclist	full_syncNc                 C   s:   | r6zt | }W n tk
r$   Y nX |jtjkr6dS dS )Neva_apilocal)r   
ValueErrorhostnameconfigZHOSTNAME_FQDN)urlZ
parsed_url r   ../modules/backbone/models/cmf_backbone_peer.pyget_peer_type   s    zCmfBackbonePeer.get_peer_typec                 C   sT   t j  |pddg}t j|} t jj|| ||d}t jjdt jt	||d|dS )Nr   d   )r   typetoken
ssl_verifyr   )slicefilter)kwargspeer)
modelsZCmfAccessListZcheck_admin_moder   r   ZCmfBackboneInstanceZPeer	call_peer
CmfProjectdict)r   r   r   r   r!   r    r#   r   r   r   r   !   s$    
z#CmfBackbonePeer.peer_project_nclistc                    s   t  jf | d S N)superr   selfr"   	__class__r   r   r   8   s    zCmfBackbonePeer.deletec                 C   s(   | j  d| j d| jo| jj | _d S )N@ )backbone_instance_domainbackbone_instance_codepeer_projectcodenamer+   r   r   r   
_calc_name<   s    zCmfBackbonePeer._calc_namec                 C   s<   | j jsd S | j jsd S | j| j jd | j| j jd d S )Ntask_filter)src_task_filter_bql
is_changedoldfull_sync_deletedvaluer   r5   r   r   r   _calc_src_task_filter_bql@   s    z)CmfBackbonePeer._calc_src_task_filter_bqlc                    s   t   ddddg S )Nr0   r1   r2   src_task_filter_ubql)r)   save_preload_fieldsr5   r,   r   r   r@   S   s       z#CmfBackbonePeer.save_preload_fieldsc                    s   |    |   t jf |S r(   )r6   r>   r)   saver*   r,   r   r   rA   W   s    zCmfBackbonePeer.saveFc                 C   s   t jrtd d S tjrd S t|tjr:| j	|||dS t|tj
rV| j|||dS t|tjrr| j|||dS t|tjr| j|||dS t|tjr| ||S t|tjr| |S td d S )Nz_CmfBackbonePeer.obj_after_save_hook(): Skip write changelog due config.MODULE_BACKBONE_DISABLEDr7   zbCmfBackbonePeer.obj_after_save_hook(): Skip write changelog due the model does not support logging)r   MODULE_BACKBONE_DISABLEDloggingwarninggbackbone_sync
isinstancer$   CmfTask_task_after_save_hook
CmfComment_comment_after_save_hookCmfAttachment_attachment_after_save_hookCmfRelationOption _relation_option_after_save_hookCmfDocument_doc_after_save_hookCmfDocumentHistory_doc_history_after_save_hook)clsobjforce_is_newr8   r   r   r   obj_after_save_hook^   s,    
z#CmfBackbonePeer.obj_after_save_hookc           	   
   C   s  t jrtd d S tjrd S t|tjtj	frH| j
|j|j|d}n,t|tjrt|jtjtj	fkrpd S | j
|j|j|d}nt|tjr
t|jjtjr|jjrt|jjtjtj	fkrd S |jj}n"t|jjtjtj	fr|j}nd S | j
|j||d}njt|tjrf| j
|jj|jj|d}|s:d S | j
|jj|jj|d}t|t|}ntt|||s~d S d|jjd}|D ]H}td|j d t   tj||j |j|d!  W 5 Q R X qd S )NzdCmfBackbonePeer.obj_after_delete_hook(): Skip write changelog due to config.MODULE_BACKBONE_DISABLED
project_idobj_idr8   r   )actionr3   z7CmfBackbonePeer.obj_after_delete_hook(): add record id=z, action=deletebackbone_peer	obj_modelrZ   obj_changes)"r   rB   rC   rD   rE   rF   rG   r$   rH   rP   _get_sync_peersrY   idrJ   cmfutilget_model_by_id	parent_idrL   parentr=   rN   in_linkout_linksetintersection	TypeErrorr   r3   jsoninfodisable_aclCmfBackboneLog
class_namerA   )	rT   rU   r8   peersZtask_idin_link_peersout_link_peersr_   r#   r   r   r   obj_after_delete_hook~   sl    

z%CmfBackbonePeer.obj_after_delete_hookc                 C   s   |d krd S |j |jj|jjd}t|tjrH|jj|d< |jj|d< nt|tj	rb|j
j|d< nnt|tjr||jj|d< nTt|tjr|ddg |jjj|d< |jj|d< nt|tjtjfr|jj|d< |S )N)ro   r4   r3   login
user_localstatus_typera   
logic_typelogic_prefix)ro   r4   rk   r3   rG   r$   	CmfPersonrt   ru   	CmfStatusrv   rH   ra   ZCmfListload_fieldsrw   rx   rJ   rL   )rT   rU   obj_datar   r   r   _serialize_relation_obj   s(    z'CmfBackbonePeer._serialize_relation_objc                    s>  i }ddddddddh}|j |d	d
D ]\}}|jsF|j|f|krFq&|dkrPq&|dkrd|jdkrdq&|drpq&|dr|q&t|tjjrq&i }t|tjj	rd|d< |r܇ fdd|j
D |d<  fdd|jD |d< n fdd|D |d< n<t|tjjrd|d<  |j|d< nd|d< |j|d< |||< q&|S )N)rJ   
cmf_author)rJ   cmf_created_at)rL   r   )rH   r   )rH   Zparent_task)rP   Zorderno)rR   cmf_modified_at)rR   cmf_modified_byT)r:   Z
is_defined>   projectcache_fieldsre   cmf_versionlikesstatus_closed_atstatus_in_progress_endcmf_viewed_atr3   viewsstatus_modified_at)r   r   rR   Z_idZcache_object_listr   c                    s   g | ]}  |qS r   r}   .0Zobj_rT   r   r   
<listcomp>(  s     z4CmfBackbonePeer._get_fields_data.<locals>.<listcomp>appendedc                    s   g | ]}  |qS r   r   r   r   r   r   r   )  s     removedc                    s   g | ]}  |qS r   r   r   r   r   r   r   +  s     r=   object)itemsZvisiblero   endswith
startswithrG   cmffieldsZCmfBackrefBaseZ
CmfM2MBaseZchanges_appendedZchanges_removedZCmfRelationBaser}   r=   rk   )rT   rU   changes_onlyZfields_dataZadd_model_fields
field_namefieldZfield_changesr   r   r   _get_fields_data   sJ    



z CmfBackbonePeer._get_fields_datac           	      C   s   | j dddgdddgdd|ggd}t|}g }|tjkr|D ]H}|jsLq@|d k	rX|n|jj}|r~tjj||t	
|d	s~q@|| q@n@|tjkr|D ]0}|jsqd }tjj|||dd
sq|| q|S )Nr9   
sync_tasks	sync_docsis_src_peer=Tpeer_project_idr   r!   )ra   rd   r!   )ra   rd   r!   include_deleted)r   rb   rc   r$   rH   r   r9   r=   r
   astZliteral_evalappendrP   r   )	rT   rY   rZ   r8   rp   r^   Zresult_peersr#   
doc_filterr   r   r   r`   5  sB    


zCmfBackbonePeer._get_sync_peersc                 C   s  | j |j|j|d}|sd S |p$|j}|r.dnd| j|| dd}|d r|jj|d< |dd	g |jd
kr|j	rd|d kr|d d= |D ]^}t
dd|j d|d  dt|d   t   tj||j|j|d  W 5 Q R X q|s|js|jjrtjj|dddddgdgd}|D ]}	||	_tjj|	d|d q*tjj|ddgd}
|
D ]}||_tjj|d|d qbd S )NrX   createupdater   r[   r   r   r3   epicrx   ztask.sub4CmfBackbonePeer.obj_after_save_hook(): add record %sid=	, action=r[   	, fields=r\   	log_levelis_dummyr~   texttree_parentr   re   r   order_byTrV   r8   r   st_sizere   r   )r`   rd   ra   is_newr   r3   rk   r{   rx   r   rC   rl   r   rb   rm   r$   rn   ro   rA   r   r:   rJ   re   r   rW   rL   )rT   ZtaskrV   r8   rp   r   r_   r#   commentscommentattachments
attachmentr   r   r   rI   `  sJ    


"
   z%CmfBackbonePeer._task_after_save_hookc           
      C   s~  |j dks(|js(t|jtjtjfkr,d S |ddddg t	|j
drV|j
jrVd S | j|j|j|d}|srd S |p|jp|jj}|rdnd	| j|| d
d}|d r(|jj|d< |jj|d< |D ]^}tdd|j d|d  dt|d   t   tj||j|j|d  W 5 Q R X q|js:|jjs@|rztjj|dddgd}|D ]}	||	_
tjj|	d|d qZd S )Nr   zparent.is_dummyr   cmf_owner.namer   r   rX   r   r   r   r   r   r3   rd   r   r   r   r[   r   r\   r   r   r   Tr   )r   r   rb   rc   rd   r$   rH   rP   r{   hasattrre   r`   rY   r   r;   r   r3   rk   rC   rl   ra   r   rm   rn   ro   rA   r:   rL   r   rW   )
rT   r   rV   r8   rp   r   r_   r#   r   r   r   r   r   rK     sR    

"
   z(CmfBackbonePeer._comment_after_save_hookc           	      C   s$  |j j|j jkrd S |jj|jjkr(d S |j j|jjkr<d S |sJ|jsJd S | j|j j|j j|d}|sjd S | j|jj|jj|d}t|t|}|sd S d| 	||j
jd}|d r |D ]^}tdd|j d|d  d	t|d   t   tj||j|j|d
  W 5 Q R X qd S )NrX   r   )r[   r   r3   r   r   r   r   r[   r   r\   )rf   rY   rd   rg   r   r`   ra   rh   ri   r   r3   rk   rC   rl   r   rb   rm   r$   rn   ro   rA   )	rT   Zrelation_optionsrV   r8   rq   rr   rp   r_   r#   r   r   r   rO     sP    

"
  z0CmfBackbonePeer._relation_option_after_save_hookc                 C   s  t |jjtjtjtjfr |js$d S t |jjtjrX|jjrJ|jj	dsNd S |jj}n,t |jjtjtjfrv|j}nt
||jjt|jdr|jj  |jjrd S |js|sd S | j|j||d}|sd S |dg d| ||jjd}|d r|jj|d< |jj|d	< |D ]}|jd
krPtdd|j d|j d|j  qtdd|j d|d  dt|d   t   tj||j|j|d  W 5 Q R X qd S )N)zCmfTask:zCmfDocument:r   rX   r   r   )r[   r   content_pathr   r3   rd   i -1z:CmfBackbonePeer.obj_after_save_hook(): skip attachment: %sr   z, name=z, size=r   r   r[   r   r\   ) rG   re   r=   r$   rJ   rH   rP   rY   rd   r   rj   r   r   loadZcontent_updatedr`   r{   r   r   rk   r3   r   rC   rl   ra   r4   r   rb   rm   rn   ro   rA   )rT   r   rV   r8   rZ   rp   r_   r#   r   r   r   rM     s`     


"
   z+CmfBackbonePeer._attachment_after_save_hookc                 C   s4  | j |j|jd}|sd S |p"|j}|r,dnd| j|| dd}|d r|jj|d< |D ]^}tdd	|j d
|d  dt	|d   t
   tj||j|j|d  W 5 Q R X qZ|r0tjj	|ddddddddgdgd}|D ]}	tjj|	dd qtjj	|dddgd}
|
D ]}tjj|dd qd S )NrY   rZ   r   r   r   r   r   r3   r   r   r   r[   r   r\   r   r   r~   r   r   re   Zinline	cmf_ownerr   r   TrV   r   r   r   )r`   rd   ra   r   r   r3   rk   rC   rl   r   rb   rm   r$   rn   ro   rA   rJ   r   rW   rL   )rT   docrV   r   rp   r   r_   r#   r   r   r   r   r   r   r   rQ   +  s@    

"
   z$CmfBackbonePeer._doc_after_save_hookc                 C   s   | j |j|jd}|sd S |dg d| |d}|d r|jj|d< |jj|d< |D ]^}tdd	|j	 d
|d  dt
|d   t   tj||j|j	|d  W 5 Q R X qZd S )Nr   r   r   r   r   r3   rd   r   r   r   r[   r   r\   )r`   rY   rd   r{   r   r3   rk   rC   rl   ra   r   rb   rm   r$   rn   ro   rA   )rT   Zdoc_historyr   rp   r_   r#   r   r   r   rS   Y  s,    "
z,CmfBackbonePeer._doc_history_after_save_hookzcmf.models.BaseModel | None)methodmodelc           
      C   s   |s| }|j dkrt||}d}t|ttfsPt|d }|f|dd }t||}||pbg |phi }	|r|j	r|
  n>|j dkr| j|j d| |||j|j|jd}	n
t|j |	S )u   
        !!! Локально работаем в той же транзакции
        :param method:
        :param model:
        :param args:
        :param kwargs:
        :param peer:
        :return:
        r   Nr      r   .)r   argsr"   r   r   r   )r   inspectZgetattr_staticrG   classmethodstaticmethodrb   get_obj_by_idgetattrr:   rA   _eva_api_callro   r   r   r   r   )
rT   r   r   r   r"   r#   Zmethod_attrZself_Zmethod_funcresultr   r   r   r%   }  s.    




    
zCmfBackbonePeer.call_peerc              
   C   s   dd l }|jdkr>tjj|dgd}| D ]}|   S nf|jdkrz| j||j|j	|j
dW S  |jk
r } ztd||| W 5 d }~X Y qX n
t|jd S )Nr   r   re   ra   r   r   )r   r   r   zFCmfBackbonePeer.peer_get_attachment_content(%s, %s): download error %s)requestsr   r$   rL   r   Zget_contentread_eva_http_getr   r   r   RequestExceptionrC   errorr   )rT   attachment_idr   r#   r   r   fileer   r   r   peer_get_attachment_content  s*    

     z+CmfBackbonePeer.peer_get_attachment_contentc              
   C   s   dd l }|jdkr0tjj|dgd}|| nl|jdkrz | j|d|i|j|j|j	dW S  |j
k
r } ztd||| W 5 d }~X Y qX n
t|jd S )	Nr   r   re   r   r   r   )filesr   r   r   zDCmfBackbonePeer.peer_put_attachment_content(%s, %s): upload error %s)r   r   r$   rL   r   Zupload_file_eva_http_postr   r   r   r   rC   r   r   )rT   r   r   contentr#   r   r   r   r   r   r   peer_put_attachment_content  s*    

  z+CmfBackbonePeer.peer_put_attachment_contentc                 C   s@   dd l }i }| |kr*| }||_||| < ||  }|j  |S )Nr   )r   ZSessionZverifyZcookiesclear)r   r   r   Zhttp_sessionsZsession_r   r   r   _get_eva_http_session  s    
z%CmfBackbonePeer._get_eva_http_sessionc                 C   sJ   | dsd| }| j||dj| | dd| id}|  |jS )N/r   r   AuthorizationBearer )headers)r   r   r   raise_for_statusr   )rT   pathr   r   r   responser   r   r   r     s    

 zCmfBackbonePeer._eva_http_getc           	      C   sj   | dsd| }t| | dd| id}|r<||d< |rH||d< | j||djf |}|  d S )Nr   r   r   )r   r   datar   r   )r   r'   r   postr   )	rT   r   r   r   r   r   r   Zpost_kwargsr   r   r   r   r     s    

zCmfBackbonePeer._eva_http_postc              
   C   s   |pi }d|d< dt t d||p&g |p,i d|d}z2| j||dj| d| |dd	| id
}	W n4 tk
r }
 ztd||t |
W 5 d}
~
X Y nX |	jstd|	j|	j	|	j
|	|	 }|drtd||||d rtd||||d }|S )u\   Адаптированный код, из нагрузочного тестирования.TZ
admin_modez2.2N)ZjsonrpcZcallidZjsverr   r   r"   Zno_metaflagsr   z/api/?m=r   r   )rk   r   z&CmfBackbonePeer._eva_api_call(): errorzAPI call error r   abortz&CmfBackbonePeer._eva_api_call(): abortr   )struuidZuuid1r   r   	ExceptionZCmfErrorokZstatus_codereasonr   rk   r   )rT   r   r   r"   r   r   r   r   r   r   r   Zjson_resultr   r   r   r   r     s8    

$
zCmfBackbonePeer._eva_api_callc              	   K   s   | j ||ddddddgd}	|	sPtjj |d}
|
sDtd	| d
d | ||
d}	||	_||	_||	_||	_||	_|	j	r||	
  |	jj|	jjj|	jjjdS )Nr2   r1   backbone_instance_namer0   r   r?   )backbone_instance_idr   r   ra   u   Проект не найден T)r   )r   r2   )ra   Zproject_codeZproject_name)r   r$   r&   Z	cmf_alertr1   r   r0   r   r?   r:   rA   ra   rk   r2   r3   r4   )rT   r   r1   r   r0   r   r   r?   _kwargsr#   r2   r   r   r   r   "  s6         zCmfBackbonePeer.setup_peerc                    s  dd g }d k	rn
j  jj   fdd}dddg d|tjrD ] }tjj|dd	 || q`t	  qRd
g d|tjr4D ]}j
|j|jd}|s d S dj|ddd}|jj|d< |D ]@}tdd|j dt|d   tj||j|j|d  qqt	  qtjjdd|gdd|ggdddgdD ]}tjj|dd	 qZ~ddddg d|tjrD ]}	tjj|	dd qt	  qd
g d|tjrjD ]}	j
|	j|	jd}|s d S dj|	ddd}|	jj|d< |D ]B}tdd|	j dt|d   tj||	j|	j|d  qqt	  qdd d!g d|tjrD ]}
tj|
 qt	  qxd S )"N  c                    sP   | t jkr}n| t jt jfkr$d }| jj|  gdgd7 S )Nr   )rY   r!   r   r    r   )r$   rH   rP   rR   r   r   )r   r!   r   r   r+   
slice_sizestartr8   r   r   get_dataG  s    

z+CmfBackbonePeer.full_sync.<locals>.get_datar   r   workflowr   Tr   ***r   r   Fr   r   r3   z*CmfBackbonePeer.full_sync(): add record %sr   z, action=update, fields=r   r\   rf   INrg   Zrelation_type)r!   r   r   tree_parent_idztree_parent.namer   r   zcmf_modified_by.namezstatus.name)r9   r   r=   r   r$   rH   r   rW   r   
cmf_commitr`   rd   ra   r   r3   rk   rC   rl   r   rn   ro   rA   rN   rP   rR   )r+   r8   Zobjsr   trp   r_   r#   Zrelationddhr   r   r   r   >  s    


   

   

zCmfBackbonePeer.full_syncc                    sN  dg g  |d k	r|n
j  j}ddg d fdd	}d|tj|dr|D ]}tjj||d	 q^t  qLdd
g |tj	rD ]}tjj||d	 qt  qd|tj
rD ]}tjj||d	 qt  qdd tjjdgjdD }dddg |tjdd|gddrJD ]}tjj||d	 q(t  qd S )Nr   r   r   Tc                    sD   t |  gdgddd}|r,j|d< | jf |7 S )Nr   T)r!   r   r    r   Zcmf_deletedr   rY   )r'   r   r   )r   r!   by_project_idr"   r   r   r+   r   r   r   r   r     s    

z3CmfBackbonePeer.full_sync_deleted.<locals>.get_datar   )r!   r7   re   c                 S   s   g | ]}|j jqS r   )
src_obj_idr=   )r   Zrlor   r   r   r     s     z5CmfBackbonePeer.full_sync_deleted.<locals>.<listcomp>r  )r   r   rf   rg   ra   r   F)r!   r  )NT)r9   r   r=   r{   r$   rH   r   rs   r   rJ   rL   ZCmfBackboneObjMappingr   r   rN   )r+   r8   r   r  caZrelations_idsrr   r  r   r<     s@    


z!CmfBackbonePeer.full_sync_deletedc                 K   s   t d| jd| | jdgd tj|dgdd| jgd}|sFd	S d
|jj| |d}t	|t
jt
jfrz|jj|d< td	|j|jj|jj|d}t d| j| |S )u9  
        Получаем объект целиком.
        {
            id: log.id,  # CmfBackboneLog:...
            obj_model: obj.class_name,  # CmfTask
            obj_id: obj.id,  # CmfTask:...
            datetime: log.cmf_created_at.isoformat(),  # 2025-01-01T01:02:03Z
            obj_changes: {
                action: create/update/remove,
                code: obj.code,
                fields: {
                    name: {
                        type: 'value',  # value/object/object_list
                        value: 'New Name'
                    },
                    executors: {
                        type: 'object_list',
                        value: [
                            {
                                class_name: CmfPerson,
                                name: 'Joe',
                                login: 'joe@eva.com',
                                user_local: true,
                            },
                            ...
                        ]
                    }
                },
            },
        }
        zCmfBackbonePeer.get_obj(%s): %szobj_id=r   r   r   r   r   r   Nr   )r[   r3   r   rd   ra   r^   rZ   Zdatetimer_   z&CmfBackbonePeer.get_obj(%s): result %s)rC   rl   r3   r{   rb   r   r   rk   r   rG   r$   rJ   rL   rd   r'   ro   ra   r   debug)r+   rZ   r   rU   r|   r   r   r   r   r     s8         zCmfBackbonePeer.get_objc                 K   s@   dd t jjdd| gdd|pg gdddgg|d	d
ddgdD S )u(  
        Получаем список изменений по точке синхронизации
        [
            {
                id: log.id,  # CmfBackboneLog:...
                obj_model: obj.class_name,  # CmfTask
                obj_id: obj.id,  # CmfTask:...
                datetime: log.cmf_created_at.isoformat(),  # 2025-01-01T01:02:03Z
                obj_changes: {
                    action: create/update/remove,
                    code: obj.code,
                    fields: {
                        name: {
                            type: 'value',  # value/object/object_list
                            value: 'New Name'
                        },
                        executors: {
                            type: 'object_list',
                            # for update
                            appended: [
                                {
                                    class_name: CmfPerson,
                                    name: 'Joe',
                                    login: 'joe@eva.com',
                                    user_local: true,
                                },
                                ...
                            ]
                            removed: [
                                ...
                            ],
                            # on full obj sync
                            value: [
                                ...
                            ]
                        }
                    },
                },
            },
            ...
        ]
        c              	   S   s,   g | ]$}t |j|j|j|j |jd qS )r  )r'   ra   r^   rZ   r   Z	isoformatr_   )r   itemr   r   r   r   V  s   z,CmfBackbonePeer.log_list.<locals>.<listcomp>r]   r   rZ   zNOT INstatusZqueuedr   r^   r_   )r!   r    r   )r$   rn   r	   )r+   r    Zskip_idsr   r   r   r   r   *  s    ,
zCmfBackbonePeer.log_listc                 K   s   |D ]}t d| jd|dd|d |d }tjj|dgd}|d }|dkrjd	|_|  q|d
krd|_| jd7  _|d|_	|
  qd|_| jd7  _d| |_	|
  t d|| qdS )u1  
        Отмечаем записи лога как обработанные
        [
            {
                id: log.id,  # CmfBackboneLog:...
                status: success,  # success|fail|skip
                [error_text: 'some backtrace',]
            },
            ...
        ]
        z5CmfBackbonePeer.log_mark_done(%s): changes applied %szlog_mark.get("id")=ra   z, log_mark.get("status")=r  error_countr   )successskipZsynced)failZfailedr   
error_textzUnknown apply status: zBCmfBackbonePeer.log_mark_done(): unknown apply status %s for id %sN)rC   r  r3   r   r$   rn   r  r   r  r  rA   rD   )r+   Zlog_mark_listr   Zlog_markZlog_idlogr  r   r   r   r   g  s,     

zCmfBackbonePeer.log_mark_donec                   @   s   e Zd ZdZdS )zCmfBackbonePeer._ApplySkipErroru<   Пропускаем применение измененийN)__name__
__module____qualname____doc__r   r   r   r   _ApplySkipError  s   r  c                 K   sX  | j ddddgd tj}g }|D ].}td| jd|dd	|d
d|dd|di ddt|di dg 
 td| j| d}d}d}d}	zzdt_|d }|d
 }|d }t	
|}
|o|
j|dd| jgd}	|	rP|	  |d d dkr |	  n(|d d dkr8|
tjkoLd|d d k}|rj|d d dd }| j|	|d d |d d d |	  d|d d kr|d d d d |	_t|	tjr|	jrtjj|	jtjd}|D ]}|  qd|	_|	|	j_|	j|	j_|	j  |r&||	_|	jrH|	  nt d|j!d d}n |d d d kr@|d!kr|d d" }t	j"|| jd#}|s| #d$| d%n| j}|
|d&}	| j|	|d d |d d d |d'kr*|	j$r*t	%|	j$tj&kr*tjj|	j$|	j'd(D ]}|j' d)|_'|  q|	  |	j(j)}d}n| #d*| t*||||	od|	jj)|d+}t|	tj+r|	j,j)|d,< |-| W n | j#k
r } z6|-t*||||	o|	jj)d-d+ t.d.||| W 5 d}~X Y nV t/k
r>   t0d/|d |-t*|d|d
|dd0t12 d1 Y nX W 5 |t_X t3  q"|S )2u  
        Применяем список изменений на точке синхронизации
        [
            {
                id: log.id,  # CmfBackboneLog:...
                obj_model: obj.class_name,  # CmfTask
                obj_id: obj.id,  # CmfTask:...
                datetime: log.cmf_created_at.isoformat(),  # 2025-01-01T01:02:03Z
                obj_changes: {
                    action: create/update/remove,
                    code: obj.code,
                    fields: {
                        name: {
                            type: 'value',  # value/object/object_list
                            value: 'New Name'
                        },
                        executors: {
                            type: 'object_list',
                            # for update
                            appended: [
                                {
                                    class_name: CmfPerson,
                                    name: 'Joe',
                                    login: 'joe@eva.com',
                                    user_local: true,
                                },
                                ...
                            ]
                            removed: [
                                ...
                            ],
                            # on full obj sync
                            value: [
                                ...
                            ]
                        }
                    },
                },
            },
            ...
        ]
        return:
        [
            {
                id: log.id,  # CmfBackboneLog:...
                obj_model: obj.class_name,  # CmfTask
                obj_id: obj.id,  # CmfTask:...
                obj_code: obj.code,  # TSK-1
                status: success,  # success|fail|skip
                [error_text: 'some backtrace',]
            },
            ...
        ]
        r2   Zdst_create_listsZdst_create_usersZdst_create_users_as_guestr
  z/CmfBackbonePeer.log_apply(%s): apply changes %szchange change.get("id")=ra   z, change.get("obj_model")=r^   z, change.get("obj_id")=rZ   z., change.get("obj_changes", {}).get("action")=r_   r[   z7,list(change.get("obj_changes", {}).get("fields", []))=r   NTr   r   )ra   r!   r   )r   r   r   r=   r[   r   )rd   r   zInvalid actionr  r   )rJ   rL   rR   rd   )r   zparent z absent)re   rP   )r   r4   u    (старый)zobj not found )ra   r^   rZ   obj_coder  r   r  z7CmfBackbonePeer.log_apply(): skip record %s, obj %s: %sz2CmfBackbonePeer.log_apply(): apply record %s errorr  )ra   r^   rZ   r  r  )4r{   rE   rF   rC   rl   r3   r   r   r  rb   get_model_by_namer2   Zsave_preparer   r$   rP   pop_apply_obj_changesrA   r   rG   rR   Zhas_publishedrd   Zsystem_personZcur_workflowre   Zcur_published_versionZdoc_versionZ	save_datar   r:   r   r_   r   r  r   rc   r&   r4   ra   rk   r'   rL   r   r   rD   r   	exception	traceback
format_excr   )r+   Zchanges_listr   Zg_backbone_sync_bkr   ZchangeZ	change_idr^   rZ   rU   r   Zis_doc_text_changedZchanged_textZunpublished_in_work_by_systemr  Zsync_statusrd   re   r   Zresult_datar   r   r   r   r     s    9

 T
 
 





 
 
& zCmfBackbonePeer.log_applyc           
   	   C   s  |d krd S |d }t |}|sDtd|  d| d| d d S t|tjjsrtd|  d| d|  d S |d}|d}d }|d	kr|d
}|r|j|d}|s|r|j|d}n
|dkr|r|j|d}|s|r|j|d}n|dkr,|rtj	j|d}|s|rtj	j|d}n|dkrD|j|d}n|dkrjd|kr|j|d d}nd|dkr|| j
}nRg }	t|tjtjtjtjfsd|jkr|	dd| j
g |r|j||	d}|std|  d| d |S )Nro   %sz%._map_object_value(): cannot map obj(z	): model z - not foundz): invalid model r4   r3   ry   rt   )rt   )r4   ZCmfRelationType)r3   CmfLogicTypeZCmfWorkflowrJ   ra   r   r&   r   r   )r4   r!   z): not mapped)rb   r  rC   rD   
issubclassr   r$   ZCmfModelr   r#  r2   rz   ZCmfActivityZCmfPersonGroupZCmfTagr   r   )
r+   r|   	obj_fieldZobj_class_namer^   Zobj_namer  rU   rt   Z
obj_filterr   r   r   _map_object_valueI  sx    
  








z!CmfBackbonePeer._map_object_valuec           	      C   s   d|kr$|  |d d }|r$||_|  d|krP|  |d d }|rP||_d|krt|  |d d }|rt||_|  d|krd}t|tjr|  |d d }|s|d d }|rtj	|
d|
d|
d	d
nd}||_|  dS ) activityr=   rw   r   r  Nr4   r3   rv   )r4   r3   rv   )r&  r(  Z_calc_scheme_wfrw   r   Z_calc_workflowrG   r$   rP   rz   r   r  Z_calc_status)	r+   rU   fields_changesr[   r(  rw   r   r  Zstatus_datar   r   r   _apply_wf_logic  s<      zCmfBackbonePeer._apply_wf_logicc                 C   sN   |dkrJ|j sJ|di d}|rJd|d d|d d|j |_d S )	Nr   r~   r=   u   <p>Автор: r4   z &lt;rt   z&gt;</p><br>)r~   r   r   )r+   rU   r)  r[   Zcmf_author_datar   r   r   _add_comment_meta  s
    "z!CmfBackbonePeer._add_comment_metac              
   C   sV  d}|  D ]\}}t|tjtjfr6|dkr6d}q|j|}|shtd|  d| d|j	 d qt
||}|d }	|	d	krt|||d	  q|	d
kr^d }
|d	d k	rd|d	 krt|d	 d }
|j	dkr|dkr|
r|
tjk	r|
j|d	 d | jd}n| j|d	 |d}|sP|jsP| d| d| d|d	  t||| q|	dkrd	|krg }|d	 D ]$}| j||d}|r||| q|t||| d|kr|d D ]$}| j||d}|r|| qd|kr|d D ]$}| j||d}|r|| qq|r4| j|||d t|tjrR| j|||d d S )NF>   r  rw   r   	scheme_wfr(  Tr"  z._apply_obj_changes(): field z not found in z. Field changes lost.r   r=   r   ro   rP   r   r4   )r4   r   )r%  zskip apply z', object not mapped for required field z, r   r   r   r  )r   rG   r$   rH   rP   r   r   rC   rD   ro   r   setattrrb   r  r&   r2   r&  Znullabler  r   remover*  rJ   r+  )r+   rU   r)  r[   Zhas_wf_changesr   Z
field_datar   r%  Zfield_data_typeZvalue_modelZ	value_objr=   r|   Z
mapped_objr   r   r   r    sj    

(


z"CmfBackbonePeer._apply_obj_changes)N)NNNNN)FN)N)F)N)N)N)N)N)N)N)NNNN)N)N)NF)NNF)NNNNF)NNNNNF)NNNNNNN)N)N)NN)N)N)N)N).r  r  r  Zapi_methodsr   r   r   r   r6   r>   r@   rA   r   rW   rs   r}   r   r`   rI   rK   rO   rM   rQ   rS   r   r%   r   r   r   r   r   r   r   r   r<   r   r   r   r   r  r   r&  r*  r+  r  __classcell__r   r   r,   r   r      s             E
"M*1.,<-#"-            
o
>?
=$ <
J
/
	r   )r   r   urllib.parser   r   Z
cmf.modelsr   Zcmf.includeZmodules.backbone.fieldsr   r   r   r   r   r   <module>   s   