U
    $-dZ,                     @   s\   d dl Z d dlmZ d dlmZ d dlZd dlmZ d dlT d dl	m
Z
 G dd de
ZdS )	    N)Path)rmtree)Template)*)	CmfEntityc                       s   e Zd ZdZ fddZdd fdd
Zedd	d
ZedddZe	d e
e
e
dddZe
e
e
dddZdd Zdd fdd
Zdd Zdd Ze
dddZ  ZS )!
CmfMailboxu   
    TODO: разделить приём настроек, приём почты, отправку в CRM
    Частично сделано разделением CmfLeadMailbox и CmfMailbox.
    c                    s   t   dddddg S )Nlead_mailboxestypeimap_serverparentz	parent.id)supersave_preload_fields)self	__class__ $./modules/mail/models/cmf_mailbox.pyr      s    zCmfMailbox.save_preload_fieldsr   )depthc                   s   | j jr| jjs| j| _ n$| jjr>| j js>d| j jkr>| j | _| jr| jjr| jdd }dddd}||d| _| jdkrd| _| jr| j	s| 
  t j|d	|i|S )
u    Здесь не хватает поддержки исправления адреса: старый ящик не удалится. @googlemail.ruZyandex)z	gmail.comr   z	yandex.ruZcustomzimap.mail.rur   )nameis_nullemailvaluer	   splitgetr
   Z
is_changedZcmf_deletedrender_configr   save)r   r   argskwargsdomaintypesr   r   r   r      s     

zCmfMailbox.save)message_rawc                 O   s   | d}|stddd d|kr4td| dd | |}|jrRtd dS | d	g t| jd
krtd t	
d dS td| d | jd
 }|| dS )uh    Приём почту и вызываем "коллбэки" подключенных плагинов r   u   Не указан emailT)abortr   u!   Не корректный email: u   Удалось прикрепить сообщение к уже имеющейся сделке ещё на этапе создания!Nr   r   u`   Почтовый ящик не подключен ни к одной воронке продажu   У uf   , не нашлось родителя-сделки, отправим его в лидоловушку)r   Z	cmf_alert_make_channel_messager   gdebugload_fieldslenr   loggingwarningreceive_email)r   r$   r    r!   r   channel_msgZlead_mailboxr   r   r   r-   )   s"    




zCmfMailbox.receive_emailc              	   C   s  | d}|s td|  n\t|tr|t|dkr||dddd}t|dkrttd|t| |dd }||d< | d	 |d
 | d
 |d	 i d|d
  d|d	  }tj	| ||d |d dtj
j |d d|d}|  |dk	std|S )u    Делаем всё что можем с ChannelMessage - создаём и парсим сырые данные для отображения в вебе 
message_idzMESSAGE WITHOUT ID: %s@   < >uh   Динный внешний message_id %s (%d символов), обрежем до 64 символовNZbodyZsubjectTz

r   in)r   )Zchannelr$   r/   	client_idZmessage_flowZperson_fromtextu*   Не создалось сообщение)r   r+   r,   items
isinstancestrr*   replacemodelsZCmfChannelMessageZ	CmfPersonr   AssertionError)r   r$   Zmidr6   r.   r   r   r   r&   =   s:    

 
  	z CmfMailbox._make_channel_messager   )r5   client_secretrefresh_tokenc                 C   s`   t jjdddgdd|gdddggd}|s2tdt|d	krFtd
|d }|| || dS )up    Уровень 1: валидация входящих данных и текущего состояния БД r   z!=Nr	   z==r>   )filteru   Не найдены почтовые ящики, для которых была начата, но не закончена настройка   u   Найдено больше одного почтового ящика, с незаконченной настройкой, удалите одинr   )r;   r   list
IndexErrorr*   setup_oauth_credentials)r5   r=   r>   Zmailbox_typeZunconfigured_mailboxesmailboxr   r   r   receive_oauth_credentials[   s    z$CmfMailbox.receive_oauth_credentialsc                 C   sN   |dk	r|dk	r|dk	st | dddg || _|| _| | |   dS )u9    Уровень 2: модификация объекта Nr	   r5   r>   )r<   r)   r5   r>   _update_oauth_secretsr   )r   r5   r=   r>   r   r   r   rC   j   s    
z"CmfMailbox.setup_oauth_credentialsc                 C   s   | j jrtd| j dS d| j jkr<td| j | j dS d| j jkr^td| j | j dS | j dd\}}td| d	| S )
u   
        Формируем из email-адреса путь к его папке с конфигами.
        :return: Path or None
        u(   Не указан email у ящика %sNr   u<   Некорректный email без @: %s у ящика %sz..uD   Некорректный email с двумя ..: %s у ящика %sr@   z/var/lib/acrm/mail//)	r   r   r+   r,   idr   errorr   r   )r   Z	user_nameZserverr   r   r   	_mail_dirt   s    zCmfMailbox._mail_dirF)forcec                   sV   |  dg td| j  |  }|r2t| ntd| j t j|d|i|S )ub    Нельзя тут использовать return, иначе не вызовется super()! r   u   Удаляем ящик u5   Не удалили настройки ящика! %srK   )	r)   printr   rJ   r   r+   r,   r   delete)r   rK   r    r!   mail_dirr   r   r   rM      s    
zCmfMailbox.deletec              	   C   s   |   }|std| j dS td| j  td}t| }W 5 Q R X |j| |d}|j	ddd |d d	}|
| W 5 Q R X dS )
u    Порядок действий продиктован нежеланием писать в файловую систему, пока возможны ошибки уровнем выше u;   Не сможем сохранить настройки! %sNu9   Переписываем конфиг для offlineimap z4/opt/crm/modules/mail/templates/offlineimaprc.jinja2)rD   ZlocalfoldersT)parentsexist_okz.offlineimaprcw)rJ   r+   r,   r   rL   openr   readZrendermkdirwrite)r   rN   Ztmplttemplatedatafdr   r   r   r      s    
zCmfMailbox.render_configc              
   C   s   d}t d| j d}| s"dS |dT}| D ]D}||kr6| |dd \}}|| jkr6|  W  5 Q R  S q6W 5 Q R X dS )u    Существует чтобы чтобы client_secret = mailbox.get_client_secret() во время рендеринга было попроще =/opt/crm/custom/_secrets.iniNr   )r   r	   existsrR   	readlinesstripr   r5   )r   sepsecrets_filerX   line_idsecretr   r   r   get_client_secret   s    
zCmfMailbox.get_client_secret)r=   c           
   	      s   i }t d| j d}d | r|d>}| D ].} |kr6|  dd \}}|||< q6W 5 Q R X tt }||	 j
 }	|	dk rtd|| j|kr||| j< |d	"}| fd
d| D  W 5 Q R X dS )up    Уровень 3: сохранение секрета в конфиг для дальнейшей работы rZ   r[   rY   r\   Nr]   
   uz   WARNING: подозрительно частая попытка сменить авторизационные данныеrQ   c                 3   s$   | ]\}}|   | d V  qdS )
Nr   ).0rd   re   ra   r   r   	<genexpr>   s     z3CmfMailbox._update_oauth_secrets.<locals>.<genexpr>)r   r	   r^   rR   r_   r`   r   inttimestatst_mtimeOverflowErrorr   r5   
writelinesr7   )
r   r=   Zsecretsrb   rX   rc   rd   re   ZnowZseconds_since_last_accessr   rj   r   rF      s"    
z CmfMailbox._update_oauth_secrets)r   )__name__
__module____qualname____doc__r   r   dictr-   r&   staticmethodr9   rE   rC   rJ   rM   r   rf   rF   __classcell__r   r   r   r   r      s   
r   )rm   pathlibr   shutilr   ZshlexZjinja2r   Zcmf.includeZ
cmf.modelsr   r   r   r   r   r   <module>   s   