B
    bEfi,                 @   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: разделить приём настроек, приём почты, отправку в Eva
    Частично сделано разделением 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    Здесь не хватает поддержки исправления адреса: старый ящик не удалится. @googlezmail.ruZyandex)z	gmail.comzmail.ruz	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types)r   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midr4   r,   r   r   r   r$   =   s.    
z CmfMailbox._make_channel_messager   )r3   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   )r9   r   list
IndexErrorr(   setup_oauth_credentials)r3   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	   r3   r<   )r:   r'   r3   r<   _update_oauth_secretsr   )r   r3   r;   r<   r   r   r   rA   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/eva-app/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   Не удалили настройки ящика! %srI   )	r'   printr   rH   r   r)   r*   r   delete)r   rI   r   r   mail_dir)r   r   r   rK      s    
zCmfMailbox.deletec          	   C   s   |   }|std| j dS td| j  td}t| }W dQ R X |j| |d}|j	ddd |d d	}|
| W dQ R X dS )
u    Порядок действий продиктован нежеланием писать в файловую систему, пока возможны ошибки уровнем выше u;   Не сможем сохранить настройки! %sNu9   Переписываем конфиг для offlineimap z8/opt/eva-app/modules/mail/templates/offlineimaprc.jinja2)rB   ZlocalfoldersT)parentsexist_okz.offlineimaprcw)rH   r)   r*   r   rJ   openr   readZrendermkdirwrite)r   rL   Ztmplttemplatedatafdr   r   r   r      s    
zCmfMailbox.render_configc          	   C   s~   d}t d| j d}| s"dS |dH}x@| D ]4}||kr8| |dd \}}|| jkr8|S q8W W dQ R X dS )u    Существует чтобы чтобы client_secret = mailbox.get_client_secret() во время рендеринга было попроще =z/opt/eva-app/custom/z_secrets.iniNr   )r   r	   existsrP   	readlinesstripr   r3   )r   sepsecrets_filerV   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B}x:| D ].} |kr8|  dd \}}|||< q8W W dQ R X tt }||	 j
 }	|	dk rtd|| j|kr||| j< |d	"}| fd
d| D  W dQ R X dS )up    Уровень 3: сохранение секрета в конфиг для дальнейшей работы z/opt/eva-app/custom/z_secrets.inirW   rX   NrY   
   uz   WARNING: подозрительно частая попытка сменить авторизационные данныеrO   c             3   s$   | ]\}}|   | d V  qdS )
Nr   ).0r`   ra   )r]   r   r   	<genexpr>   s    z3CmfMailbox._update_oauth_secrets.<locals>.<genexpr>)r   r	   rZ   rP   r[   r\   r   inttimestatst_mtimeOverflowErrorr   r3   
writelinesr5   )
r   r;   Zsecretsr^   rV   r_   r`   ra   ZnowZseconds_since_last_accessr   )r]   r   rD      s"    
z CmfMailbox._update_oauth_secrets)r   )__name__
__module____qualname____doc__r   r   dictr+   r$   staticmethodr7   rC   rA   rH   rK   r   rb   rD   __classcell__r   r   )r   r   r      s   
r   )rh   Zpathlibr   Zshutilr   ZshlexZjinja2r   Zcmf.includeZ
cmf.modelsr   r   r   r   r   r   <module>   s   