U
    h                    @   s^   d dl m Z mZmZ d dlmZ d dlmZ d dlT d dlm	Z	m
Z
mZ G dd de	jZdS )	    )datetime	timedeltatimezone)uuid1)	dataclass)*)
cmf_notifyCmfRelationCmfTypec                	       s6  e Zd ZdZdZdZi Zee	j
ejde	j
ejdgZeed< ejf eZejjddd	g ZeG d
d dZedd Zedd Zedd ZedPddZedd Zedd ZeedddZeeddd Zeedd!d"Z edQd#d$Z!ed%d%dd&edd'd(Z"edRd)d*Z#ed+d, Z$ fd-d.Z%edSd/d0Z&edTd1d2Z'ed3d4 Z(e)e*d%d%d5d6d7 Z+e)e*d%d%d5d8d9 Z,ed:d; Z-ed<d= Z.edd>d?d@Z/edAdB Z0e)eedCdDdEZ1e)eedCdFdGZ2edHdI Z3edJdK Z4e)e*d%d%dLdMdNdO Z5  Z6S )U	CmfNotifyZNotifyZdeskZNTFzcommon/templateszcmf/templatesloaderclose_open_notifiesconfirm_unconfirmed_notifiesplace_notifyc                   @   s*  e Zd ZU dZdZeed< dZeed< dZeed< dZ	e
ed< dZeed	< dZeed
< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZ dS )zCmfNotify.NotifyCtxu1  
        notify_type - тип сообщения
        возможные варианты:
        - просто сообщение (default) -- message
        - редактирование объекта -- obj_edit
        - создание объекта -- obj_create
        - удаление объекта -- obj_delete
        - добавление комментария -- comment_create
        - редактирование комментария -- comment_edit
        - удаление комментария -- comment_delete
        N	person_idnametextr   priorityFstrikethrough
alarm_datemessagenotify_typeobj_hrefobj_codeobj_parent_nameobj_link html_changed_fields
owner_nameowner_initialsperson_phone_mobileperson_phoneperson_nameperson_emailperson_loginmsg_from_idmsg_from_namemsg_from_codemsg_from_login)!__name__
__module____qualname____doc__r   str__annotations__r   r   r   intr   boolr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   comments r2   r2   ./cmf/models/cmf_notify.py	NotifyCtx   s2   
r4   c                 C   sl   |j p
|j}d|j d|j d|j }|  }|r<| }| j|}|j|d}t	| j
|||gd d S )N[z] (z) )ctxargs)r#   r$   r   r   r   Z+get_default_mail_notification_template_name
_jinja_envZget_templateZrenderschedule_deferred_jobprocess_email)cls
notify_ctxobjrcpt_tosubjectZmail_templatetemplate
email_bodyr2   r2   r3   send_email_notify_old@   s    zCmfNotify.send_email_notify_oldc                 C   s   t dd}|jp|j}t|dkr4|d d  d}| d|j d| |j }|jpZ|j}|svtd|j d d S t	| j
||gd d S )	NTZfull_url   z...
4   SMS уведомление пользователю _    не отправлено, не указан номер мобильного телефона.r7   )app_base_hrefr   msglenr   r    r!   	cmf_alertr"   r:   process_sms)r<   r=   urlsubjr   phoner2   r2   r3   send_sms_notify_oldO   s    
zCmfNotify.send_sms_notify_oldc           	      K   s  d|ks|d dkr&t jtjd|d< d|kr:|d}ntj}|jj|d< |j	j|d< |j
j|d< |jj|d< d	|d
< |rd|ks|d dkr|j	|d< d|ks|d dkrt jtjd|d< t|d tr|d j|d< |d |d< |ptj}|j	j|d< |ddg |jr |jjd nd|jr6|jjd nd |d< |rtdd}|j|d< |j
|d< | |d  |d< t|dr|jr|jj	j|d< nd |d< tj|}||d< |d |d< |d |d< |d
 |d < |d! |d"< |d# |d$< | jf |}|S )%Nr   .Ztzmsg_fromr%   r&   r'   r(      Уведомлениеr   r   rJ   r   r   
first_name	last_namer   r   r   TrD   r   r   r   parentr   r   rP   r!   phone_mobiler    r"   emailr#   loginr$   )r   nowr   utcpopgcurrent_personidvaluer   coderZ   
isinstancer
   current_userload_fieldsrU   rV   rI   hrefhasattrrW   models	CmfPersonget_notify_opt_cachedr4   )	r<   r>   r   kwargsrS   Znotify_ownerrN   notify_optsr6   r2   r2   r3   prepare_notify_ctx_old]   sL    

4


z CmfNotify.prepare_notify_ctx_oldNr   Fr   c              	   K   s  t jrt d dS t|d}tj|}|dkr8dS d}|t jj	krb|dkrb|d r^d}ndS |r|j
jrv|jjs|ddg d}|rd	}|sd
}| jdd|j	gdd|gdd|gdddgdddggdddddgd}|st }|sd}|jr|jdkr| d|j }|jr(|jr(|r.||_d	|_| jd7  _||_||_d|_|	rb|	|_n
|j  |r$|j|_|j	|_|j|_|j|_t|dr|j
rt|j
j tj!rt"#|j$jj }||_%n|j
jj |_%|j&|_'t|dr*|j( r*t|jt)r|jj|_*nt+|j|_*nd|_|j,s8g |_,|j,rtt-|j,j dkrt|j,j dd d d |krt|S t j.j/rt j.j/j d ndt j.j0rt j.j0j d nd }|r|jj nd}t j.j	j t j.jj t j.jj t j.j1j |dt2j3t4j5d6 t23 7d||d t8  |dd!}|j,9| d|_:|jp4||_|d" |_;|d# |_<|d# rv|
dkrptj=j>d$d%j	}
|
|_?|d& p|d' |_@|d( p|d) |_A|sd
|_|B  |d* s|jCd+krtDd,|||j'j d-|gd. |jCd/kr|jEstDd0| |gd. |S )1u  
        obj: CmfEntity

        :param obj:
        :param msg_from:
        :param person: Идентификатор пользователя которому отправляется сообщение
        :param name: Наименование объекта уведомления
        :param msg: Текст сообщения
        force - форсированная отправка
        :param priority:
        :param strikethrough:
        :param alarm_date: Будильник для уведомлений
        :param force_notify_current_person: отправить сообщение себе
        :param notify_type: Тип сообщения. Описание см в структуре NotifyCtx
        B   Уведомления отключены g.disable_notify = FalseNri   TFemail_if_self_changesrW   rb   openclosedobj_id==r   status	cron_done	confirmed
unread_cntr1   
cron_forcer   filterfieldsrT   r   u
    + еще    r   r   )r`   r   rb   rZ   ZinitialsrR   z%H:%MCmfComment:)	cmf_ownerZcmf_created_atZcmf_created_at_formattedmsg_type_textr   r`   parent_name	log_level
notify_smsnotify_emailsystem:defaultrb   rX   rP   rY   rZ   Z	notify_os1z	notify-os)r   commentr   )Zevent_persons2znotify-important-)Fr^   disable_notifydebugcmfutilZget_obj_id_by_anyrh   ri   rj   r_   r`   rW   
is_definedrb   re   getr   rw   r   rx   rt   Zpriotityr   r   r   Zset_nowr   rr   r   ui_nameZobj_ui_namerg   rc   ra   
CmfProjectZAPPZget_cache_project
project_idr   rf   r   loadr	   Zobj_status_namer-   r1   rK   rd   rU   rV   rZ   r   r[   r   r\   Z	isoformatstrftimer   appendru   person_notify_smsperson_notify_emailCmfEmailTemplatesgetemail_template_idr!   r#   saver   Zcmf_emit_eventrv   )r<   rJ   personr   r   r>   force_notify_current_personforcer   r   r   rk   r   rl   Zdesk_notifynotifyZfilter_statusZproject_namer   r   r   r2   r2   r3   r      s    

	





zCmfNotify.place_notifyc           	      K   s0  t jrt d dS d|kr(|d dk	s0tdd|krD|d dk	sLtd|d t jjkrj|dsjdS d	|kr|d	}|d
dddg nd}|d}t	j
j|dddgd}|st d|  dS |dg }t	j||}| j||f|}|dkrdS | ||}|r,| || | | |S )u  
        obj: CmfEntity

        :param obj:
        :param msg_from:
        :param person_id: Идентификатор пользователя которому отправляется сообщение
        :param recipient_opt: Опции получателя для проверки разрешения получать уведомления пользователем
        :param name: Наименование объекта уведомления
        :param text: Тема сообщения
        :param msg: Текст сообщения
        :param priority:
        :param strikethrough:
        :param alarm_date: Будильник для уведомлений
        :param force_notify_current_person: отправить сообщение себе
        :param notify_type: Тип сообщения. Описание см в структуре NotifyCtx
        rn   NrJ   .u   Укажите msgr   u   Укажите person_idr   r>   rW   rb   r   rf   r   zphone_mobile.numberzphone.numberr`   r{   u   В метод place_notify пришел отсутствующий или удаленный пользователь person_id=recipient_opt)r^   r   r   AssertionErrorr_   r`   r   r]   re   rh   ri   ZCmfPersonNotifyOptZcheck_permission_notify_eventZprepare_notify_ctxZcreate_desk_notifysend_email_notifysend_sms_notify)	r<   rk   r>   r   r   r   Znotify_allowedr=   r   r2   r2   r3   stol_place_notifyG  s8    




zCmfNotify.stol_place_notifyc                 C   s\   |j }|jdkr|jj}t|ds&d }tj||j d| }|sXtj|d| }|S )Nr   logic_prefix.
AllModels.)	parent_id
class_namer`   ra   rg   rh   CmfProjectNotifySchemeget_notify_rule_data_cached)r<   r>   event_type_codeZtmp_parent_id	rule_datar2   r2   r3   get_rule_data  s    

  zCmfNotify.get_rule_data)r   c                 C   sp   g }t |dr.|jdkr.|jr*|jds.g S | ||}|sBdS |d rl|d dD ]}||  qX|S )u   
         email-ы из колонки "Адреса электронной почты" схемы уведомлений
        r   r   CmfProject:Nr   ,)rg   r   r   
startswithr   splitr   strip)r<   r>   r   r   
recipientsrY   r2   r2   r3   get_notify_email_members  s     

z"CmfNotify.get_notify_email_membersc                 C   st  t  }t|drL|jdkrL|jr,|jdsL| D ]}dh||jj< q4|S | ||}|s`dS g }|d D ]*}|j	|dd}|dkr|
|t  || d ql|D ]}	tj|	jj}
|
dkrq|	js||	 |
|	jjt  d	}|d
kr|
d rd}nx|dkr"|
d r"d}n^|dkr<|
d r<d}nD|dkrV|
d rVd}n*|dkr|
d rd}||	jj d |r||	jj d qql|jr@|jdr@|r@|jdg |jjs@tjjdd}tjj|j|dgd}|D ]H}t|tjjr|j}|jj|kr|r||d kr||jj= q|d r|jdkr||d  |d D ]}|| s~qltt|| tjjr|| D ]*}|
|jjt  ||jj d qn,|
|| jjt  ||| jj d ql|D ]n}|dr"td| d	d t j!r tjj|dgd }|r |j"r |j"jdr td!| d	d q |S )"uY   
        Рассчитываем набор юзеров и их галочек
        r   r   r   rY   Nnotify_membersT)Zall_nested_personsFz
var:authorZemail_if_authorz	var:ownerZemail_if_owner)zvar:responsiblezvar:executorsZemail_if_responsiblezvar:spectatorsZemail_if_spectatorzvar:current_userro   rd   servicedesk_publicsdesk-client:defaultr   members)r   Zproject_role_idr{   Znotify_custom_fieldCmfTaskzvar:zDEV: Var user in notify! )abortrb   r   z DEV: Var user person in notify! )#dictrg   r   r   r   Zall_relation_personsr`   ra   r   Zextract_var_obj
setdefaultsetaddrh   ri   rj   
user_localr   rW   re   r   ZCmfProjectRoler   ZCmfProjectRoleAssignrc   cmfr{   ZCmfRelationBase
issubclasstypeZ
CmfM2MBaserL   configDEBUGrb   )r<   r>   r   r   r   uZnon_local_personsuser_idZ	var_usersZvar_userrl   rY   Z	proj_roleZproj_role_assignuser
field_nameir2   r2   r3   get_notify_members  s    



"
zCmfNotify.get_notify_membersc                 C   s
  t |tjr|dkrXd|jj d}d|jj d}d}d|||jdd|||jdgS |dkrd|jj d}d|jj d}d	}d|||jdd|||jdgS t |tjr||jjr||d
krd|j d}d}d}d|||jj	dd||dgS |dkr||jr>d|j d}d}d}d|||jj	dd||dgS |jj
r|d|j d}d}d}d|||jj
dd||dgS t |tjr|d
krd}d}d||dgS |dkrd}d}d||dgS |dkrd}d}d||dgS t |tjr8|d
krd}d}d||dgS |dkr8d}d}d||dgS t |tjrf|dkrfd }d!}d||dgS |d"krd#}d$}d||dgS |dkrd%}d&}d||dgS |d
krd'}d(}d||dgS |d)krd*}|d+|j  7 }d,}d||dgS |d-krx|jd.kr&|jd.kr&d/}d0}nDd1}|jj|jj	 }	|d2|	 7 }|jj|jj	 }
|d3|
 7 }d4}d||dgS |d5krd6}|d+|jj d7|jjr|jjnd8 7 }d9}d||dgS |d:kr|jrd;}|d+|j  7 }d<}d||dgS |d=krHd>}|d+|jj d7|jjr,|jjnd8 7 }d?}d||dgS |d@kr|jrdA}|dB|j 7 }dC}d||dgS |dDkrdE}|dB|j 7 }dF}d||dgS |dGkrdH}dI}d||dgS |dJkr|jrdK}dL}d||dgS |dMkrdN}dO}d||dgS |dPkrpdQ}|jj
rD|dR|jj
j 7 }|jr^|dS|jj 7 }dT}d||dgS |dUkrzg }|jjrdV}|jr|jj}dV}|jr|jj}dW| }||kr|dX| 7 }|dY7 }|jjr|dB|jj 7 }dZ}|d||d |jjrv|jjrvd[d\d] |jjD }dW| dY}|jjr`|dB|jj 7 }d^}|d||d |S |d_krd`}dda|dgS |dbkrdc}|jjrt|jj}dd}d||dgS |dekrdf}|jjrt|jj}dg}d||dgS |dhkr8di}|jjr&t|jj}dj}d||dgS |dkkrndl}|jjr\t|jj}dm}d||dgS |dnkrH|jj
r|jr|jj
j|jjkrg S |jdokrdd}ddp|dgS dV}|jr|jj}dq|jj dr| dY}|jjr|dB|jj 7 }|jj
r6|jr6ds|jj
j dt|jj du}ndv}d||dgS |dwkrndx| }dy}d||dgS |dzkrd{}d|}d||dgS |d}krd~| d}d}d||dgS |dkrd}d}d||dgS |dk	rRd}d}|j jD ]$}||j j
kr|d|j 7 }q|j j
D ]$}||j jk	r|d|j 7 }	qd||dgS dddddg}|dk
rlg g g d}|j!ddD ]j\}}|j"	s	q||k	r	q|#|}|dk 	r	q|j	|j
k	rΐ	q| }|	r|| | 	qg }d}|d 
r|dd+|d |d |d 
rB|dd+|d |d |d 
rh|dd+|d |d |S | }dd| d|j |dgS )u  
        Логика:
        - по спец. событиям типа assigned, придет и assigned и updated, поэтому поля спец.событий
            дополнительно нужно отфильтровывать в updated
        updatedu6   Установлена связь с задачей «   »u/   установил связь с задачей   )r   r   message_titlerW   deletedu.   Удалена связь с задачей «u)   удалил связь с задачейcreatedu$   Создана подзадача «u   Созданаu   создал подзадачу)r   r   r   u(   Добавлена подзадача «u   Добавленаu!   добавил подзадачуu$   Удалена подзадача «u   Удаленаu   удалил подзадачуu'   Создан шаг тест-кейсаu'   создал шаг тест-кейсаr|   u'   Удалён шаг тест-кейсаu'   удалил шаг тест-кейсаu)   Изменён шаг тест-кейсаu)   изменил шаг тест-кейсаuE   Добавлена строка значений параметровu?   создал строку значений параметровuA   Удалена строка значений параметровu?   удалил строку значений параметровu4   Изменено значение параметраu2   изменил значение параметраZrestoredu   Восстановленоu   восстановилu   Удаленоu   удалилu   Созданоu   создалZ	publishedu9   Выпущены изменения в документеz<br>u!   выпустил документZshareddefaultu[   Отменен публичный доступ к документу в интернете.u9   отменил публикацию в интернетеui   Документ опубликован для публичного доступа в интернете.u   <br>Анонимные: u"   <br>Авторизованные: u,   опубликовал в интернетеcomment_createdu$   Комментарий создан.: r   u%   написал комментарийZcomment_updatedu&   Комментарий изменен.u%   изменил комментарийZcomment_deletedu#   Комментарий удаленu#   удалил комментарийZattachment_createdu#   Добавлено вложение u   добавил вложениеZattachment_deletedu   Удалено вложениеu   удалил вложениеZworklog_createdu+   Сделана запись о работеu)   сделал запись о работеZworklog_updatedu&   Журнал работ измененu&   изменил журнал работZworklog_deletedu$   Журнал работ удаленu$   удалил журнал работZmovedu   Перемещеноu    из проекта u    в проект u1   переместил в другой проектassignedu   Не установленu%   Задача назначена на u   , ожидает r   u'   назначил исполнителяz, c                 S   s   g | ]}t |jqS r2   )r-   r   ).0er2   r2   r3   
<listcomp>  s     z5CmfNotify._prepare_notify_message.<locals>.<listcomp>u-   назначил соисполнителейZresolvedu   добавил решениеu1   В задаче добавлено решениеrq   u   Задача завершенаu   завершил задачуZwork_startedu   Работа начатаu   начал работуZwork_stoppedu#   Работа остановленаu%   приостановил работуZreopenedu#   Задача переоткрытаu!   переоткрыл задачуchanged_statusZCLOSEDu   Задача закрытаu!   Статус изменен на u   , ожидаем u   изменил статус c "u   " на ""u   изменил статусZapprove_startedu.   Ожидается подтверждение u+   запустил подтверждениеZapprove_rejectedu6   Пользователь отклонил запросu   отклонил запросZapprove_success_fullu   Утверждение u    завершеноu)   утверждение завершеноZapprove_success_oneu:   Пользователь подтвердил запросu!   подтвердил запросZspectators_changedu'   изменены наблюдателиu4   Изменен состав наблюдателейu   <br>добавлен: u   <br>удален: responsiblert   ZviewsZresult_textrW   )r   r|   r   T)
is_changedr   u   изменилu   Пришло событие u    по объекту )$rc   rh   CmfRelationOptionin_linkr   Zout_linkr   Zparent_taskr   ra   oldCmfTestcaseStepCmfTestParamsRowCmfTestParamRowValuer   	html_diffZperm_policy_anonymousZperm_policy_guestchoicesZcaptionnewrW   r   waiting_forrt   r   	executorsZchanges_appendedjoinr-   rb   Zcache_status_typeZ
spectatorsitemsr   Z_get_field_log_level)r<   r>   r   Zin_msgZout_msgr   Zparent_task_msgZtask_msgrJ   Z	anonymousZguestresr   r   r   Z	spectatorZskip_field_namesZtmp_listr   Z	field_objr   r   r2   r2   r3   _prepare_notify_message  s   

















*
*




















&













z!CmfNotify._prepare_notify_messagec              
   C   s  |j j}|jj}|jj}|jj}|j}tjj|d}	z&tj	j
|||||dd|	dsXW dS W nP tk
rp   Y dS  tk
r }
 z|
jd |krW Y 
dS  W 5 d}
~
X Y nX |jdkr|jrtjj|j|	dsdS |r|jdkr|jrtjj|j|	dsdS d	S )
u   
        Проверяет, что у получателя notify есть доступ к объекту
        Доп. проверяются права у private-комментариев
        )r`   readF)initial_acl_keyZobject_modelZobject_owner_idZ	object_idZobject_parent_idZaccess_levelZraise_errorchecking_personr|   N
CmfComment)Zcheck_for_userT)Zperm_effective_acl_idra   r   cmf_owner_idr`   r   rh   ri   r   ZCmfAccessListZcheck_accessZCmfACLNotInitializedErrorZCmfACLNotFoundErrorr8   Zprivater   Zcheck_visibility)r<   r>   	member_idobj_commentr   Zobj_parent_idr   Zself_idr   r   r   r2   r2   r3   _check_perm_for_notifyb  s>       

z CmfNotify._check_perm_for_notifyT)r   auditfilter_membersc             
   O   s  |j r
d S |sd S |sd S |js$d S |jr:|jdr:d S tjrDd S d}|dkrTd}d }	d }
|jdkrr|dkrrd S |jdkr|}	|jj	}t
|dr|j rd S |	jd	krd S |jd
kr|}	|jj	}|jdkr|}
|jj	}|jdkr|jsd S |jdkr|}
|jj	}|jdkr"|}
|j j	}|jdkr:|}
|jj	}|jdkrR|}
|jj	}|jdkrr|}
|jj	j j	}|	r| |	|}n |
r| |
|}n| ||}|sd S tj|t|j|	rt|	jnd ||||d d S )Nz-headF)r   r   r   TZCmfAccessRuler   r   is_dummyr   CmfAttachmentZCmfTimeTrackerHistoryri   ZCmfGanttTaskr   r   r   r   )msg_listrr   obj_comment_idr   r   r   r   )Zdisable_auditZsmart_notifyZcmf_verrb   endswithr^   r   r   rW   ra   rg   r   r   r   r   Ztaskr   r   deferred_notify_messagesr   r-   r`   )r<   r>   r   r   r   r   r8   rk   r   r   Zdependent_objr   r2   r2   r3   smart_all_place_notify  s    




z CmfNotify.smart_all_place_notifyc                 C   s.   |rg t _d S t jD ]}| | qg t _d S N)r^   r   _apply_deferred_notify_message)r<   Z
only_cleandeferred_notify_datar2   r2   r3   apply_deferred_notify_messages  s    
z(CmfNotify.apply_deferred_notify_messagesc                 C   s  dddddg}t j|d |dd}d }|d	 rFt j|d	 |d
g d}|d }|d }|d }|d }|d }	|jdkr|s|D ]f}
|
d|}t  H |
d dkrtjj||
d d n tj||
d |
d djdd W 5 Q R X q|sd S |D ]}
|
d dkr
q|j	}t
|ds d }tj||j d| }|s`tj|d| }|s` d S | |||}|dkr|jr|jjdr|d
g |jjj}||kri ||< |	rt| D ]}||	kr||= qtjj d|
d  d|j }|r~| D ]n\}}| j|||d s,qtjj  < tjj||||
d |
d d!|kr`dnd||d" d# W 5 Q R X q|  |||}|D ]F}tjj  . tjj||||
d |
d d||d" d# W 5 Q R X qqd S )$Nr   r   rW   rb   rt   rr   T)r`   r{   include_deletedr   ztree_parent.cmf_author_idr   r   r   r   r   r   )r   ZCmfDocumentZCmfTestcaseZCmfTestcaseRunZCmfTestcycler   r   r   )rW   r   )rW   r   r   F)r   )r|   r   r   r   r   r~   r   r   )r   rd   r   )r>   r   r   rJ   r   r   r   r   )!r   get_obj_by_idr   r   Zdisable_aclrh   r   Zadd_comment_auditr   r   rg   r   r   r   Ztree_parent_idra   r   re   Ztree_parentZcmf_author_idlistkeysr^   r_   r   verbose_namer   r   r   utilr   r   r   )r<   r   _fieldsr>   r   r   r   r   r   r   Zmsg_datarW   Ztmp_project_idr   r   r   r   r   Z	email_setr   rY   r2   r2   r3   r     s    


  



z(CmfNotify._apply_deferred_notify_messagec                    s   t  j|| d S r   )superemit)selfr8   rk   	__class__r2   r3   r
  `  s    zCmfNotify.emitc                 C   sd   |st jjj}dd|gdddgg}|r8|dd|jg | j|dgd}|D ]}d|_|  qLd S )Nr   rs   rt   z!=rq   rr   ry   )r^   r_   r`   ra   r   r  rt   r   )r<   r   r>   Z_filternotifiesr   r2   r2   r3   r   i  s    
zCmfNotify.close_open_notifiesc                 C   sD   |st jj}| jdd|gdddggd}|D ]}d|_|  q,d S )Nr   rs   rv   False)rz   T)r^   r_   r`   r  rv   r   )r<   r   r  r   r2   r2   r3   r   {  s    z&CmfNotify.confirm_unconfirmed_notifiesc                 C   s   |j dkr|j  }nL|j dkr,|g}n:|j dkrR|j jg}d |krfd S ntd|j   d S |D ]J}tj	|j
j}|d ksj|d sqjtjj|||jd|j  dd qjd S )	NZCmfPersonGroupri   ZCmfRolez,DEV: handle_mention_event unknown obj type: Zemail_if_mentionsu   Вас упомянули в T)r>   r   r   rJ   r   )r   Z
rg_membersr   Z
all_nestedr   ra   rL   rh   ri   rj   r`   r   r   r   r  lower)r<   r>   Zevent_personZpersonsr   rl   r2   r2   r3   handle_mention_event  s*    


zCmfNotify.handle_mention_event)	only_once
system_jobc                 O   s   t j }|j| ||d d S )N)r@   )rh   CmfPluginMailBoxget_local_mailboxsend_message)Zrctp_tor@   rB   r8   rk   mail_boxr2   r2   r3   r;     s    
zCmfNotify.process_emailc                 O   s   t j }|| | d S r   )rh   CmfPluginSMSGateget_local_smsgater  )rP   r   r8   rk   sms_gater2   r2   r3   rM     s    
zCmfNotify.process_smsc                 C   sv   t jj|jdgd}|rp|jrpt|drp|jdrp|j|j	ddsT|j|j	ddspd|j
 d	|j d
|j S |jS )Nr   r   r   ztask.sdzsdesk-agent:default)projectZ	role_coder   /z/?obj=:)rh   ri   r   r   r   rg   r   r   Zin_project_rolerW   	ui_moduler   rb   r   )r<   r   r>   r   r2   r2   r3   _calc_notify_obj_link  s    

zCmfNotify._calc_notify_obj_linkc                 C   sB  ddl m} ddlm} |s$|g fS |ddg |js@|g fS |jjdkrT|g fS tjj	|j
dgd}|jrv|g fS |jjd	kr|g fS |jjd
kr|g fS ||d}g }|jdddddD ]r}	|	j	d}
tjj	|
dddgd}|r|jjdr|j|kr,|jj|kr,td|
d q|jdkrLtd|
d qz| D ]}|jddd }|| |d}|d| || |d }|d! |jd"d#d$| id}|| || |	|  qqVW q tk
r2 } z*td%|j d&| d'|  W Y qW 5 d }~X Y qX qt ||fS )(Nr   BeautifulSoup)MIMEApplicationz,project.servicedesk_email_notify_attach_typezproject.logic_prefixzproject.servicedeskr   r   Z1_AUTH_LINKZ2_SECURE_LINKlxmlZdivzapp-tinymce-card-previewT)classdata-attach-id)attrsr%  full_path_fileparent.parentst_sizer{   r   u@   Не могу прикрепить вложение attach_id = r   i   u=    так как его размер превышает 80Мб r  r|   r}   r   
Content-IDspanu   Вложение: arf   cid:u@   Не удалось приложить файл к письму     вложения из r   )!bs4r!  Zemail.mime.applicationr"  re   r  r   rh   ri   r   r   r   Z$servicedesk_email_notify_attach_typefind_allr&  r   rW   r`   r   logging	exceptionr)  infoget_contentr   rsplitr   
add_headerr   new_tagreplace_with	Exceptionr-   )r<   r>   email_body_htmlr   r!  r"  r   soupZemail_attachesZ
attach_tag	attach_idattachattachment_bytefilename
mime_imageZattach_linkZattach_link_hrefr   r2   r2   r3   _handle_html_attach  sd    







zCmfNotify._handle_html_attach)returnc                 C   s^  ddl m} ddl}ddl}ddlm} ddlm} ||}g }	| }
|	dD ]}|j
d}tjj|dd	gd
}|r|jjdr|j|kr|jj|krtd|d qVzZ| D ]L}|jddd }|| |d}|d| |	| d| |j
d< qW qV tk
rD   td|j d| d Y qVY qVX qVW 5 Q R X t||	fS )uu  
        Заменяет все ссылки на изображения на ссылки вида <img src="cid:%imagename%">
        Возвращает текст письма и словарь заMIMEенкоженных картинок вида {ключ - имя файла картинки: значение - MIMEэнкоженная картинка}
        r   )ImageNr   )	MIMEImageZimgr%  r'  r(  r*  r   uF   Не могу прикрепить изображение attach_id = r   r  r|   r}   r+  r,  r/  srcu	   Файл r0  u/    не является изображением)ZPILrE  tempfilebase64r1  r!  Zemail.mime.imagerF  ZTemporaryDirectoryr2  r&  r   rh   r   rW   r`   r   r3  r4  r6  r   r7  r   r8  r   r;  r-   )r<   r>   r<  rE  rH  rI  r!  rF  r=  Zemail_imagesZtmp_dirZimg_tagr>  r?  r@  rA  rB  r2   r2   r3   _handle_html_img	  s>    

zCmfNotify._handle_html_imgc                 C   sP   |  ||\}}| |||\}}|| | |}d| d| d}||fS )Nz<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
            <html>
                <head>
                    <style>
                        za
                    </style>
                </head>
                <body>
                    z+
                </body>
            <html>)rJ  rC  extendclean_junk_attr_tags)r<   r<  Zemail_body_cssr>   r   email_attachmentsZemail_attachments2r   r2   r2   r3   prepare_email_text1  s    

zCmfNotify.prepare_email_text)htmlrD  c           
      C   s   ddl m} dd l}tjr&dtj nd}dtj | }|| d}|dD ]^}|d}|jd	d
}|rN|	d|rzqN| d|
d }|jd|d}	||	_||	 qNddd |jjD S )Nr   r   r  r   zhttps://r#  r.  rf   T)r   z^(https?:|mailto:|tel:|#)r  )rf   c                 S   s   g | ]}t |qS r2   r-   r   xr2   r2   r3   r   [  s     z0CmfNotify.simplify_for_email.<locals>.<listcomp>)r1  r!  rer   ZEXTERNAL_PORT_HTTPSZAPP_FQDNr2  r   Zget_textmatchlstripr9  stringr:  r   bodychildren)
rO  r!  rS  Z	port_specZ	base_hrefr=  linkrf   r   Znew_linkr2   r2   r3   simplify_for_emailF  s     

zCmfNotify.simplify_for_emailc                 C   sp   ddl m} || d}|dD ]}dd |j D |_q |ddgD ]}|  qJd	d
d |jjD S )Nr   r   r#  Tc                 S   s(   i | ] \}}| d s|dks||qS )zdata-Zcontenteditable)r   )r   kvr2   r2   r3   
<dictcomp>e  s
     
   z2CmfNotify.clean_junk_attr_tags.<locals>.<dictcomp>svgpathr   c                 S   s   g | ]}t |qS r2   rP  rQ  r2   r2   r3   r   k  s     z2CmfNotify.clean_junk_attr_tags.<locals>.<listcomp>)	r1  r!  r2  r&  r   Z	decomposer   rW  rX  )rO  r!  r=  tagr^  r2   r2   r3   rL  ]  s    

zCmfNotify.clean_junk_attr_tagsc                 C   s  |j s
d S |j j}dddg}|jr6tjj|j|d}ntjjd|d}t|jrZ|jd nt }| j	||d}t
d	d
 | |_| |d |d< tj|||d |jj|jj|jj}tj|||d |jj|jj|jj}	| |	|j||\}
}tj }|j||
||d d S )Ntmplt_subjecttmplt_body_htmlu	   body_сssr*  r   )rb   r{   r}   )r   r>   TrD   r   )r@   rM  )r#   ra   r   rh   r   r   rK   r1   r-   r  rI   r   rZ  Zrender_templater   ra  t	   body_сssrb  rN  r  r  r  )r<   r   r>   r?   r  rA   rJ   rf   Zemail_subjectr<  rB   rM  r  r2   r2   r3   r   m  s<    
		
zCmfNotify.send_email_notifyc                 C   sf   |j std|j d d S tdd |j }|j}| d| }|j j}tj	 }|
|| d S )NrG   rH   TrD   rF   )r!   rL   r   rI   r   r   ra   rh   r  r  r  )r<   r   r>   rN   rO   r   rP   r  r2   r2   r3   r     s    
zCmfNotify.send_sms_notifyz	@minutely)r  r  Zschedulec                  O   s  t jjddgdddgdddggd}d	d
 |D }t jjdddgdddt tdd gdddgdd|gggdgdgd}|sqtd|j d|  dddddddddddd d!d"d#d$d%d&dg}d }|j	rt
j|j	d|d'}|jr<z td( t j|| d|_W n4 tk
r: } ztd)|  W 5 d }~X Y nX |jrz td* t j|| d|_W n4 tk
r } ztd+|  W 5 d }~X Y nX d|_|  |j  q2d S ),Nz--rr   ru   rs   Frx   T)r{   rz   c                 S   s   h | ]
}|j qS r2   )rr   )r   r>   r2   r2   r3   	<setcomp>  s     z1CmfNotify.celery_minutely_hook.<locals>.<setcomp>ORZcmf_modified_at<   )ZminutesINr   )rz   r{   Zorder_byuB   Обработка отправки уведомлений для r   r`   rb   r   r   r  rt   r   rW   zparent.logic_prefixZ
cmf_authorZ
logic_typeZdeadliner   r   ZlistsZreleasesZaffected_versionsZstory_point)r  r{   u   Отправляем СМСz"models.CmfNotify.send_sms_notify: u   Отправляем emailz$models.CmfNotify.send_email_notify: )rh   r   Zslistr   r   r[   r   printr`   rr   r   r  r   r   Zsms_doner;  r3  r4  r   r   Z
email_doneru   r   ZdpZcommit)r8   rk   Zforce_objectsZforce_object_idsr   r{   r>   r   r2   r2   r3   celery_minutely_hook  st                      
"
"zCmfNotify.celery_minutely_hook)Nr   NFFr   NN)N)F)NN)N)7r)   r*   r+   r   r  Zcode_prefixZ_optionsZjinja2ZFileSystemLoaderosr_  r   r   ZPROJECT_DIRZ_loaderZEnvironmentr9   r   r   Zapi_methodsr   r4   classmethodrC   rQ   rm   r   r   r   r-   r   r   r   r   r   r  r   r
  r   r   r  staticmethodZcmf_deferred_jobr;   rM   r  rC  rJ  rN  rZ  rL  r   r   ri  __classcell__r2   r2   r  r3   r   	   s   &


5            4
8
^  R)  `
f	




G'

)
r   N)r   r   r   Zuuidr   Zdataclassesr   Zcmf.includeZ
cmf.fieldsr   r	   r
   r   r2   r2   r2   r3   <module>   s
   