U
    $xh                    @   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                	       s  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dLd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dMd#d$Z!ed%d%dd&edd'd(Z" fd)d*Z#edNd+d,Z$edOd-d.Z%ed/d0 Z&e'e(d%d%d1d2d3 Z)e'e(d%d%d1d4d5 Z*ed6d7 Z+ed8d9 Z,edd:d;d<Z-ed=d> Z.e'eed?d@dAZ/e'eed?dBdCZ0edDdE Z1edFdG Z2e'e(d%d%dHdIdJdK Z3  Z4S )P	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
r|j
jj|_ |j!|_"t|dr |j# r t$|jt%r|jj|_&nt'|j|_&nd|_|j(sg |_(|j(rJt)|j(jdkrJ|j(jdd d d |krJ|S t j*j+rbt j*j+jd ndt j*j,r|t j*j,jd nd }|r|jjnd}t j*j	jt j*jjt j*jjt j*j-j|dt.j/t0j1d2 t./ 3d||d t4  |dd!}|j(5| d|_6|jp
||_|d" |_7|d# |_8|d# rL|
dkrFtj9j:d$d%j	}
|
|_;|d& p\|d' |_<|d( pp|d) |_=|sd
|_|>  |d* s|j?d+krt@d,|||j"jd-|gd. |j?d/kr|jAst@d0| |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-)Br^   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   ra   r   rf   r   loadrc   r	   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   cmf_emit_eventrv   )r<   rJ   personr   r   r>   force_notify_current_personforcer   r   r   rk   r   rl   Zdesk_notifynotifyZfilter_statusr   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_notifyC  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 )N
CmfProject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 |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rd}|d|j  7 }d}d||dgS |d kr|jd!kr<|jd!kr<d"}d#}nDd$}|jj|jj	 }	|d%|	 7 }|jj|jj	 }
|d&|
 7 }d'}d||dgS |d(krd)}|d|jj d*|jjr|jjnd+ 7 }d,}d||dgS |d-kr|jrd.}|d|j  7 }d/}d||dgS |d0kr^d1}|d|jj d*|jjrB|jjnd+ 7 }d2}d||dgS |d3kr|jrd4}|d5|j 7 }d6}d||dgS |d7krd8}|d5|j 7 }d9}d||dgS |d:krd;}d<}d||dgS |d=kr|jrd>}d?}d||dgS |d@kr.dA}dB}d||dgS |dCkrdD}|jj
rZ|dE|jj
j 7 }|jrt|dF|jj 7 }dG}d||dgS |dHkrg }|jjr"dI}|jr|jj}dI}|jr|jj}dJ| }||kr|dK| 7 }|dL7 }|jjr|d5|jj 7 }dM}|dN||d |jjrt|jt|jj
 }|rdOdPdQ |D }dJ| dL}|jjr|d5|jj 7 }dR}|dN||d |S |dSkrdT}dNdU|dgS |dVkrdW}|jjrt|jj}dX}dN||dgS |dYkr&dZ}|jjrt|jj}d[}dN||dgS |d\kr\d]}|jjrJt|jj}d^}dN||dgS |d_krd`}|jjrt|jj}da}dN||dgS |dbkrl|jj
r|jr|jj
j|jjkrg S |jdckrdX}dNdd|dgS dI}|jr|jj}de|jj df| dL}|jjr*|d5|jj 7 }|jj
rZ|jrZdg|jj
j dh|jj di}ndj}dN||dgS |dkkrdl| }dm}dN||dgS |dnkrdo}dp}dN||dgS |dqkrdr| ds}dt}dN||dgS |dukrdv}dw}dN||dgS |dxkrvdy}dz}|jjD ]$}||jj
kr|d{|j 7 }q|jj
D ]$}||jjkrB|d||j 7 }qBdN||dgS d}d~dddg}|dk	rg g g d}|jddD ]j\}}|jsq|j	|j
kr̐q||krڐq| |}|dk rq| }|r|| | qg }d}|d 	r@|dd|d |d |dN 	rf|dNd|dN |d |d 	r|dd|d |d |S | }dNd| d|j |dgS )u  
        Логика:
        - по спец. событиям типа assigned, придет и assigned и updated, поэтому поля спец.событий
            дополнительно нужно отфильтровывать в updated
        updatedu6   Установлена связь с задачей «   »u/   установил связь с задачей   )r   r   message_titlerW   Zdeletedu.   Удалена связь с задачей «u)   удалил связь с задачейcreatedu$   Создана подзадача «u   Созданаu   создал подзадачу)r   r   r   u(   Добавлена подзадача «u   Добавленаu!   добавил подзадачуu$   Удалена подзадача «u   Удаленаu   удалил подзадачу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'   назначил исполнителяr|   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   oldr   	html_diffZperm_policy_anonymousZperm_policy_guestchoicesZcaptionnewrW   r   waiting_forrt   r   	executorsr   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   Znew_executorsr   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_notifyA  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 tjr.d S d}|dkr>d}d }	d }
|jdkr|}	|jj}t|drt|j	 rtd 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}|	r| |	|}n |
r| |
|}n| ||}|jdkr|	s|D ]F}|d|}t & 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sd }tj||j d| }|s tj|d| }|s  d S | |||}|dkrX|	jrX|	jjdrX|	dg |	jjj}||krXi ||< |rt| D ]}||krj||= qjtj j! d|d  d|j" }|r|# D ]n\}}| j$|||	ds̐qt%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 q0qd S )NF)r   r   r   Tr   is_dummyr   CmfAttachmentZCmfTimeTrackerHistoryri   ZCmfGanttTaskr   )r   ZCmfDocumentrW   r   r   )rW   r   r   )r   )r|   r   r   r   r   r   r~   ztree_parent.cmf_author_idr   r   )r   rd   r   )r>   r   r   rJ   r   r   r   r   )*Zdisable_auditZsmart_notifyr^   r   r   rW   ra   rg   r   r   r   r   Ztaskr   r   r   r   Zdisable_aclrh   r   r   Z
project_idr   r   r   Ztree_parent_idr   re   Ztree_parentZcmf_author_idlistkeysr_   r   verbose_namer   r   r   utilr   r   r   )r<   r>   r   r   r   r   r8   rk   r   r   Zdependent_objZmsg_listZmsg_datarW   Ztmp_project_idr   r   r   r   r   Z	email_setr   rY   r2   r2   r3   smart_all_place_notifyk  s    








  



z CmfNotify.smart_all_place_notifyc                    s<   t  j|| td| j  d| jji| j gd d S )Nznotify-person-Z	notify_idr   )superemitr   r   r   r`   ra   )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     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  }n&|j dkr,|g}ntd|j   d S |D ]J}tj|jj	}|d ksD|d sjqDtj
j|||jd|j  dd qDd S )NZCmfPersonGroupri   z,DEV: handle_mention_event unknown obj type: Zemail_if_mentionsu   Вас упомянули в T)r>   r   r   rJ   r   )r   Z
rg_membersr   Z
all_nestedrL   rh   ri   rj   r`   ra   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;   E  s    
zCmfNotify.process_emailc                 O   s   t j }|| | d S )N)rh   CmfPluginSMSGateget_local_smsgater  )rP   r   r8   rk   sms_gater2   r2   r3   rM   K  s    
zCmfNotify.process_smsc                 C   sf   t jj|jdgd}|r`|jr`t|dr`|jdr`|j|j	dds`d|j
 d|j d	|j S |jS )
Nr   r   r   ztask.sdr   )projectZ	role_code/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_linkQ  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_attachY  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	   Файл r"  u/    не является изображением)ZPILr7  tempfilebase64r#  r  Zemail.mime.imager8  ZTemporaryDirectoryr$  r  r   rh   r   rW   r`   r   r%  r&  r(  r   r)  r   r*  r   r-  r-   )r<   r>   r.  r7  r:  r;  r  r8  r/  Zemail_imagesZtmp_dirZimg_tagr0  r1  r2  r3  r4  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>)r<  r5  extendclean_junk_attr_tags)r<   r.  Zemail_body_cssr>   r   email_attachmentsZemail_attachments2r   r2   r2   r3   prepare_email_text  s    

zCmfNotify.prepare_email_text)htmlr6  c           	      C   s   ddl m} tjrdtj nd}dtj | }|| d}|dD ]F}|d}|jd	d
}|rF|jd| d| d}||_	|
| qFddd |jjD S )Nr   r  r  r   zhttps://r  r   rf   T)r   r  )rf   c                 S   s   g | ]}t |qS r2   r-   r   xr2   r2   r3   r     s     z0CmfNotify.simplify_for_email.<locals>.<listcomp>)r#  r  r   ZEXTERNAL_PORT_HTTPSZAPP_FQDNr$  r   Zget_textr+  stringr,  r   bodychildren)	rA  r  Z	port_specZ	base_hrefr/  linkrf   r   Znew_linkr2   r2   r3   simplify_for_email  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>  s
     
   z2CmfNotify.clean_junk_attr_tags.<locals>.<dictcomp>svgpathr   c                 S   s   g | ]}t |qS r2   rB  rC  r2   r2   r3   r     s     z2CmfNotify.clean_junk_attr_tags.<locals>.<listcomp>)	r#  r  r$  r  r   Z	decomposer   rF  rG  )rA  r  r/  tagrM  r2   r2   r3   r>    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@   r?  )r#   ra   r   rh   r   r   rK   r1   r-   r  rI   r   rI  Zrender_templater   rP  t	   body_сssrQ  r@  r  r  r  )r<   r   r>   r?   _fieldsrA   rJ   rf   Zemail_subjectr.  rB   r?  r	  r2   r2   r3   r     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)Zinclude_deletedr{   u   Отправляем СМСz"models.CmfNotify.send_sms_notify: u   Отправляем emailz$models.CmfNotify.send_email_notify: )rh   r   Zslistr   r   r[   r   printr`   rr   r   Zget_obj_by_idr   r   Zsms_doner-  r%  r&  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_hook3  st                      
"
"zCmfNotify.celery_minutely_hook)Nr   NFFr   NN)N)NN)N)5r)   r*   r+   r   r  Zcode_prefixZ_optionsZjinja2ZFileSystemLoaderosrN  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  staticmethodZcmf_deferred_jobr;   rM   r  r5  r<  r@  rI  r>  r   r   rY  __classcell__r2   r2   r   r3   r   	   s   &


5            0
8
^  5)   




G'

)
r   N)r   r   r   Zuuidr   Zdataclassesr   Zcmf.includeZ
cmf.fieldsr   r	   r
   r   r2   r2   r2   r3   <module>   s
   