U
    zg                     @   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dGd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dHd#d$Z!ed%d%d&edd'd(Z" fd)d*Z#edId+d,Z$edJd-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d?d@ Z/edAdB Z0e'e(d%d%dCdDdEdF Z1  Z2S )K	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gd}|st }|sd}|jr|jdkr| d|j }|jr$|jr$|r*||_d	|_| jd7  _||_||_d|_|	r^|	|_n
|j  |r|j|_|j	|_|j|_|j|_t|dr|j
r|j
jj|_ |j!|_"t|dr|j# rt$|jt%r|jj|_&nt'|j|_&nd|_|j(s
g |_(|j(rFt)|j(jdkrF|j(jdd d d |krF|S t j*j+r^t j*j+jd ndt j*j,rxt 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" r.|
|_9|d# p>|d$ |_:|d% pR|d& |_;|sbd
|_|<  |d' s|j=d(krt>d)|||j"jd*|gd+ |j=d,kr|j?st>d-| |gd+ |S ).u  
        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_forcefilterfieldsrT   r   u
    + еще    r   r   )r`   r   rb   rZ   ZinitialsrR   z%H:%MzCmfComment:)	cmf_ownerZcmf_created_atZcmf_created_at_formattedmsg_type_textr   r`   parent_name	log_level
notify_smsnotify_emailrX   rP   rY   rZ   Z	notify_os1z	notify-os)r   commentr   Zevent_persons2znotify-important-)@r^   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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_notifyA  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_dataz  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:default)rb   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_personsZ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)   удалил связь с задачейZ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,   опубликовал в интернетеZ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_notify?  s>       

z CmfNotify._check_perm_for_notifyT)r   auditc                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 q8|sd S |
D ]r}|d dkrq|j}t|dsd }tj||j d| }|stj|d| }|s d S | |||}tjj d|d  d|j }|r| D ]n\}}| j|||dsTq6tjj < tj j!||||d |d d|krdnd||d d W 5 Q R X q6| "|||}|D ]F}tjj . tj j!||||d |d d||d d W 5 Q R X qqd S )NF)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   )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   r_   r   verbose_namer   r   r   utilr   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   Z	email_setr   rY   r2   r2   r3   smart_all_place_notifyi  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   listrt   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 ]H}tj|jj	}|d ksD|d sjqDtj
j|||jd|j  d qDd S )NZCmfPersonGroupri   z,DEV: handle_mention_event unknown obj type: Zemail_if_mentionsu   Вас упомянули в )r>   r   r   rJ   )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;   7  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   =  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_linkC  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_LINKZ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   Znew_tagZ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_attachK  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 )uy  
        Заменяет все ссылки на изображения на ссылки вида <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PILr*  tempfilebase64r  r	  Zemail.mime.imager+  ZTemporaryDirectoryr  r  r   rh   r   rW   r`   r   r  r  r  r   r  r   r  r   r   r-   )r<   r>   r!  r*  r-  r.  r	  r+  r"  Zemail_imagesZtmp_dirZimg_tagr#  r$  r%  r&  r'  r2   r2   r3   _handle_html_img  s>    

zCmfNotify._handle_html_imgc                 C   sF   |  ||\}}| |||\}}|| 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/  r(  extend)r<   r!  Zemail_body_cssr>   r   email_attachmentsZemail_attachments2r   r2   r2   r3   prepare_email_text  s    
zCmfNotify.prepare_email_textc                 C   s   |j s
d S |j j}tjj|jdddgd}t|jr>|jd nt }| j	||d}t
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}   )r   r>   TrD   r   )r@   r1  )r#   ra   rh   ZCmfEmailTemplater   r   rK   r1   r-   r  rI   r   Zrender_templater   r3  t	   body_сssr4  r2  r   r   r   )r<   r   r>   r?   rA   rJ   rf   Zemail_subjectr!  rB   r1  r   r2   r2   r3   r     s4    		
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_hook  st                      
"
"zCmfNotify.celery_minutely_hook)Nr   NFFr   NN)N)NN)N)3r)   r*   r+   r   r  Zcode_prefixZ_optionsZjinja2ZFileSystemLoaderospathr   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  r(  r/  r2  r   r   r;  __classcell__r2   r2   r   r3   r   	   s   &


5            .
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
   