B
    fwN                 @   s   d dl Z d dlZd dlmZmZ d dlZd dlmZ d dlT d dlm	Z	 d dl
mZ d dlmZ d dlmZ G d	d
 d
ejeZdS )    N)datetimetimezone)Path)*)CmfModel)cmf_hashlib)CmfPluginConvertMixin)cmf_attachmentc                   s  e Zd Zejjjd Zejj	e
j	 dddddddd	d
dddg Z	edddZedddZdd ZedddZeedddZdd Zdd Z fd d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Z fd,d-Zed.d/ Zd0d1d2d3Zeedd4d5Zd6d7d8e d9d:d;Z!d<d= Z"d]d>d?Z#ee$dd@dAZ%eeddBdCZ&dDdE Z'd7dF fdGdH
Z( fdIdJZ)d^dKdLZ* fdMdNZ+ fdOdPZ, fdQdRZ-dSdT Z.dUdV Z/dWdX Z0 fdYdZZ1 fd[d\Z2  Z3S )_CmfAttachment)file_existsZupsertget_fullviewgen_url_for_webdavget_versionsremove_versionget_url_fileget_local_urlZmark_viewedZ
public_getZpublic_createZpublic_get_rfileZpublic_get_versions)returnc             C   s    |   }|std g S | S )Nu   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)	get_rfile	cmf_alertr   )selfrfile r   (./modules/files/models/cmf_attachment.pyr   !   s
    zCmfAttachment.get_versions)versionc            O   s,   |   }|std d S |j|d|i|S )Nu   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachmentr   )r   r   r   )r   r   argskwargsr   r   r   r   r   )   s
    zCmfAttachment.remove_versionc             O   s*   |   }|std d S |j|f||S )Nu   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)r   r   r   )r   Zeditorr   r   r   r   r   r   r   1   s
    z CmfAttachment.gen_url_for_webdav)os_typec             C   s$   |   }|std d S |j|dS )Nu   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)r   )r   r   r   )r   r   r   r   r   r   r   9   s
    zCmfAttachment.get_url_file)r   r   c             C   s$   |   }|std d S |j|dS )Nu   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)r   )r   r   r   )r   r   r   r   r   r   r   A   s
    zCmfAttachment.get_local_urlc             C   s:   | j jsd S tj| j jd }d}t||kr6|| _d S )N       )name
is_changedospathsplitextvaluelenZ	file_type)r   	extensionZext_max_lengthr   r   r   _calc_file_typeI   s    zCmfAttachment._calc_file_typec             C   s   | j jsd S td| j j}d}t| j jt| t|d  }d}t| j ddkrh| j dd }||krt|d }| j jd |dt|   	  d	t
| j jd
 | _ |r| j  d| | _ d S )Nu   [А-Яа-я]       .r      -   )r   r    refindallr$   r%   splitmathZfloorstripr   Zshort_str_enc)r   Z
rus_simbolZos_max_lengthZfile_name_lengthZextZslice_lengthr   r   r   
_calc_nameS   s     8zCmfAttachment._calc_namec                s   t   ddddg S )Nurlurl_previewurl_preview_imgparent)supersave_preload_fields)r   )	__class__r   r   r;   b   s    z!CmfAttachment.save_preload_fieldsc             C   sD   | j   | j sd S tjtj| j  }tj|s@t	| |S )N)
r9   loadr!   r"   joinconfig
UPLOAD_DIRget_files_direxistsmakedirs)r   
upload_dirr   r   r   rD   e   s    

zCmfAttachment.upload_dirc             C   s4   t jjj }|| j}|jr*|j| _nd| _d S )Nr   )	modelsCmfRFiledpdata_driverget_rdr   
_file_namerB   st_size)r   rdiskr   r   r   r   _calc_st_sizen   s
    
zCmfAttachment._calc_st_sizec             C   s4   t jjj }|| j}|jr0t j	| dd d S )NZ
attachmentZ
after_save)
rE   rF   rG   rH   rI   r   rJ   rB   ZCmfAutomationCrudTriggerZ	crud_hook)r   rL   r   r   r   r   _call_automation_hookv   s    z#CmfAttachment._call_automation_hookc             C   s   | j r| jr| jds| jdstjj}tjj}tj	j
dd| jgdddgdddggd	d
}t| jjtjr|r||krtd| ddd n0t| jjtjr|r||krtd| ddd dS )un  Если установлен лимит на количество вложений, то мы подсчитываем их общее количество,
        и если оно превышает этот предел, то выводим алерт
        Исключаем изображения, которые добавляются в описаниеz	image-mcezcomm-image-mcer9   =r   zNOT LIKEz
image-mce%zcomm-image-mce%F)filterZinclude_deleteduQ   Превышено количество добавляемых вложений (ua   ) в задачу.
                          Обратитесь к администраторуT)abortue   ) в документ.
                          Обратитесь к администраторуN)is_newr9   r   
startswithgglobal_settingstask_attachment_max_countdocument_attachment_max_countrE   r
   count
isinstancer$   CmfTaskr   ZCmfDocument)r   rV   rW   Z	att_countr   r   r   _check_count_attachments}   s"    $
z&CmfAttachment._check_count_attachmentsc             C   s   t jjsdS t jjj}ddd |D }|ddd}dd |D }d	| jkrltd
d| dd | jd	d 	 }||krdS td| dd| dd dS )u_   Проверяем расширение у добавляемого файла-вложенияNr*   c             s   s"   | ]}|  s|d kr|V  qdS ));,N)isalnum).0charr   r   r   	<genexpr>   s    z6CmfAttachment._check_file_extension.<locals>.<genexpr>r\   r]   c             S   s   g | ]}|   qS r   )r4   lower)r_   xr   r   r   
<listcomp>   s    z7CmfAttachment._check_file_extension.<locals>.<listcomp>r+   u   Ошибка: выбранный Вами файл не содержит расширения. Пожалуйста, загрузите файл с одним из следующих форматов: T)rQ   r,   uu   Ошибка: выбранный Вами файл имеет неподдерживаемое расширение: ul   . Пожалуйста, загрузите файл с одним из следующих форматов: )
rT   rU   Zallowed_attachment_extensionsr$   r>   replacer2   r   r   rb   )r   Zallowed_extensions_strZcleaned_extensions_strZraw_extensionsZallowed_file_extensionsr&   r   r   r   _check_file_extension   s    

z#CmfAttachment._check_file_extensionc                s   |    |   |   |   |   |   t j||}| jrz| j	rzt
| j	jtjrztj| j	d| j ddd  |   |S )Nu&   Добавлено вложение «   »r)   )r9   text	log_level)rf   r[   r5   	_calc_urlr'   rM   r:   saverR   r9   rY   r$   rE   rZ   
CmfCommentr   rN   )r   r   r   res)r<   r   r   rk      s    zCmfAttachment.savec             C   s   |    | j S )N)rD   r   )r   r   r   r   	file_path   s    zCmfAttachment.file_pathN)fieldsc            O   sb   | j js| jjsd S tjdtj	| j
| _tj| j dd| _tj| j dd| _d S )Nz/filesz.metazpreview.pdfzpreview_img.png)r   r    r6   Zis_nullr!   r"   r>   urllibparseZquoterJ   r7   r8   )r   ro   r   r   r   r   r   rj      s
    zCmfAttachment._calc_urlc             C   s   t ttj| j S )u<    Полный фактический путь к файлу )strr   r?   r@   rJ   )r   r   r   r   full_path_file   s    zCmfAttachment.full_path_fileTF)backupsmart_backup)contentc            O   sF   t jjj }|| j}|jdddd |j|||d | 	  dS )u    Загрузка файла FT)is_direxist_okparents)rt   ru   N)
rE   rF   rG   rH   rI   r   rJ   createwriterk   )r   rv   rt   ru   r   r   rL   r   r   r   r   upload_file   s
    zCmfAttachment.upload_filec             O   sD   | j dd}|si }tjj|d< tjj|d< |j|| |   d S )NT)rz   task_attachment_max_sizedocument_attachment_max_size)r   rT   rU   r}   r~   Zstream_writerk   )r   r   r   r   r   r   r   upload_stream_file   s    z CmfAttachment.upload_stream_filec          	   k   sR   |   }||}|r |d }n| j dgdjj}t|d}|V  W d Q R X d S )Nabspath)ro   rb)r   Zget_versionr   r$   open)r   r   r   r   Zrfile_versionr   filer   r   r   get_content   s    

zCmfAttachment.get_contentc             C   s    t jjj }|| j}|jS )N)rE   rF   rG   rH   rI   r   rJ   rB   )r   rL   r   r   r   r   r      s    zCmfAttachment.file_existsc             C   s8   | j   | j r(tj| j  | jjS tddd dS )uT    Имя файла вложения в зависимости от родителя u   Вложение должно быть привязано к объекту, нельзя сохранять в корень диска.T)rQ   N)	r9   r=   r!   r"   r>   rA   r   r$   r   )r   r   r   r   rJ      s    
zCmfAttachment._file_namec             O   s   |   }|j||S )N)r   r   )r   r   r   r   r   r   r   r      s    zCmfAttachment.get_fullview)forcec               sr   t  j|d|i|}| jrLt| jjtjrLtj| jd| j ddd	  | j
rn|  }|rn|j| jjd |S )Nr   u"   Удалено вложение «rg   r)   )r9   rh   ri   )prefix)r:   deleter9   rY   r$   rE   rZ   rl   r   rk   rJ   r   Zmove_to_trashcode)r   r   r   r   rm   r   )r<   r   r   r      s    zCmfAttachment.deletec                s6   t  jf |}tjj| jj d| jj | jd |S )N_)r   Z
target_dir)	r:   restorerE   rF   Zrestore_from_trashr   r$   r   rJ   )r   r   rm   )r<   r   r   r   
  s    $zCmfAttachment.restorec             K   sd   dd l }tjj| j|d}|s`|r`tj| jdd}| j|_tjj|j|jj	dd|_
|  |S )Nr   )idro   F)r   rw   T)r   mkdir)r!   rE   rF   getrJ   r   r   r"   dirnamer$   r9   rk   )r   ro   rz   Z_kwargsr!   rm   r   r   r   r     s    zCmfAttachment.get_rfilec                s6   | j ot| j }|r(|jd| jd n
t   d S )NzPPP-ATT-CREATE)obj)Z
project_idZcmfutilZget_obj_by_idcheck_project_role_accessr9   r:   check_edit_perm)r   project)r<   r   r   r     s    zCmfAttachment.check_edit_permc                s   |  dddg | jrvtj| jkrby| jjd| jd W qt tk
r^   | jjd| jd Y qtX q| jjd| jd n
t 	  d S )Nr   r9   	cmf_ownerzPPP-ATT-DELETE-ALL)r   zPPP-ATT-DELETE-OWN)
load_fieldsr   rT   Zcurrent_userr   r   r9   ZCmfPermissionErrorr:   check_delete_perm)r   )r<   r   r   r   !  s    zCmfAttachment.check_delete_permc                s2   |    |   |   |   t j|| d S )N)r5   rj   r'   rM   r:   _save_import)r   r   r   )r<   r   r   r   /  s
    zCmfAttachment._save_importc          
   C   s^   ddl m} d}| ddddg ||dd	jf | j| j| j| j| j	| j
jd
d}|jS )Nr   )BeautifulSoupap  
        <div contenteditable="false" class="app-tinymce-card-preview app-tinymce-is-preview"
            data-attach-id="{id}" data-mce-contenteditable="false"
            bis_skin_checked="1"><a class="app-tinymce-href-preview app-tinymce-is-preview"
                title="{title}"
                rel="{urlPreview}"
                download="{url}">
                <span class="app-tinymce-img-preview-block app-tinymce-is-preview"> <span
                        class="app-tinymce-img-preview-size app-tinymce-is-preview"> <img
                            class="app-tinymce-img-preview app-tinymce-is-preview"
                            src="{urlPreviewImg}"
                            alt="attachment"
                            data-mce-src="{urlPreviewImg}">
                    </span> </span> <span class="app-tinymce-file-preview-block app-tinymce-is-preview"> <span
                        class="app-tinymce-file-name-block app-tinymce-is-preview"> <span
                            class="app-tinymce-file-name-view app-tinymce-is-preview">{title}</span>
                        </span> <span
                        class="app-tinymce-file-create-view app-tinymce-is-preview display-contents">{createDate}</span> <svg class="remove-file-icon" style="width: 24px; height: 24px;" viewBox="0 0 24 24"
                        data-mce-style="width: 24px; height: 24px;">
                        <path style="pointer-events: none;" fill="#e8e8e8"
                            d="M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M19,19H5V5H19V19M17,8.4L13.4,12L17,15.6L15.6,17L12,13.4L8.4,17L7,15.6L10.6,12L7,8.4L8.4,7L12,10.6L15.6,7L17,8.4Z"
                            data-mce-style="pointer-events: none;"></path>
                    </svg> </span> </a>
            <div contenteditable="false" class="app-tinymce-preview-actions" data-mce-contenteditable="false"
                bis_skin_checked="1">
                <div data-obj-id="{id}" bis_skin_checked="1"><svg
                        class="preview-action edit-preview" viewBox="0 0 24 24"
                        style="width: 18px; height: 18px; color: #444444;"
                        data-mce-style="width: 18px; height: 18px; color: #444444;">
                        <path _ngcontent-mjc-c10="" fill="#444"
                            d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z">
                        </path>
                    </svg><br></div>
                <div bis_skin_checked="1"><svg class="preview-action show-preview" viewBox="0 0 24 24"
                        style="width: 18px; height: 18px; color: #202020;"
                        data-mce-style="width: 18px; height: 18px; color: #202020;">
                        <path _ngcontent-chu-c10="" fill="#202020"
                            d="M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9M12,4.5C17,4.5 21.27,7.61 23,12C21.27,16.39 17,19.5 12,19.5C7,19.5 2.73,16.39 1,12C2.73,7.61 7,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C15.76,17.5 19.17,15.36 20.82,12C19.17,8.64 15.76,6.5 12,6.5C8.24,6.5 4.83,8.64 3.18,12Z">
                        </path>
                        <defs _ngcontent-chu-c10="">
                            <linearGradient _ngcontent-chu-c10="" id="MyGradient" x1="0" x2="0" y1="0" y2="1">
                                <stop _ngcontent-chu-c10="" offset="20%" stop-color="#ffd19e"></stop>
                                <stop _ngcontent-chu-c10="" offset="80%" stop-color="#ffeec2"></stop>
                            </linearGradient>
                        </defs>
                    </svg><br></div>
                <div bis_skin_checked="1"><svg class="preview-action download-preview" viewBox="0 0 24 24"
                        style="width: 18px; height: 18px; color: #202020;"
                        data-mce-style="width: 18px; height: 18px; color: #202020;">
                        <path _ngcontent-chu-c10="" fill="#202020" d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z"></path>
                    </svg><br></div>
            </div>
        </div>
        r8   r7   r6   cmf_created_at
r*   )titler   ZurlPreviewImgZ
urlPreviewr6   Z
createDatezhtml.parser)Zbs4r   r   re   formatr   r   r8   r7   r6   r   ZjsonZ
currentTag)r   r   ZTAG_TMPLsr   r   r   create_preview_tag6  s    6z CmfAttachment.create_preview_tagc             O   s    | j rtjj| df|| d S )NZattachment_created)rR   rE   CmfEventdo_event)r   r   r   r   r   r   _do_event_savex  s    zCmfAttachment._do_event_savec             O   s   t jj| df|| d S )NZattachment_deleted)rE   r   r   )r   r   r   r   r   r   _do_event_deleted|  s    zCmfAttachment._do_event_deletedc                sF   t t  }| dg | jr>x| j D ]}|| q,W t|S )Nr9   )setr:   
get_ownersr   r9   addlist)r   r   r   ZownersZparent_owner)r<   r   r   r     s    zCmfAttachment.get_ownersc          	      s4   t  j||}t| jd}|| W d Q R X d S )Nr   )r:   copyr   rs   r   )r   r   r   Zobj_copyf)r<   r   r   r     s    zCmfAttachment.copy)N)NF)4__name__
__module____qualname__ZcmfrE   Z	CmfEntityZui_meta_skipr	   r
   Zapi_methodsr   r   r   intr   r   rr   r   r   r'   r5   r;   rD   rM   rN   r[   rf   rk   propertyrn   rj   rs   bytesr|   r   r   boolr   rJ   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   )r<   r   r
      sf   
		



B
r
   )r3   rp   r   r   ZshutilZpathlibr   Zcmf.includeZ
cmf.modelsr   Zcmf.utilr   Z&common.models.cmf_plugin_convert_mixinr   Zmodules.files.fieldsr	   r
   r   r   r   r   <module>   s   