U
    ƩhW                     @   s`   d dl 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
 G dd de
jeZdS )	    N)Path)*)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dddg Z	 fdd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 fd/d0Zeed1d1d2d3d4 Zed5d6 Z d7d8d9d:Z!eedd;d<Z"d1d=d1d1d>e#d?d@dAZ$dBdC Z%dDdE Z&dkdFdGZ'ee(ddHdIZ)eeddJdKZ*dLdM Z+d=dN fdOdP
Z, fdQdRZ-dldSdTZ. fdUdVZ/ fdWdXZ0 fdYdZZ1d[d\ Z2d]d^ Z3d_d` Z4 fdadbZ5 fdcddZ6e7dmdedfZ8eed1d1dgdhdidj Z9  Z:S )n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_versionsZ
api_createZ
api_updateZ
api_deletec                    s   d | _ t j|| d S N)content_updatedsuper__init__selfargskwargs	__class__ (./modules/files/models/cmf_attachment.pyr   !   s    zCmfAttachment.__init__)returnc                 C   s.   |  ddg |  }|s&td g S | S )Nst_sizeZcmf_modified_at   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)load_fields	get_rfile	cmf_alertr   r   rfiler   r   r   r   %   s    zCmfAttachment.get_versions)versionc                O   s,   |   }|std d S |j|d|i|S )Nr   r#   )r   r    r   )r   r#   r   r   r"   r   r   r   r   /   s
    zCmfAttachment.remove_versionc                 O   s*   |   }|std d S |j|f||S )Nr   )r   r    r
   )r   Zeditorr   r   r"   r   r   r   r
   7   s
    z CmfAttachment.gen_url_for_webdavos_typec                 C   s$   |   }|std d S |j|dS Nr   r$   )r   r    r   r   r%   r"   r   r   r   r   ?   s
    zCmfAttachment.get_url_file)r%   r   c                 C   s$   |   }|std d S |j|dS r&   )r   r    r   r'   r   r   r   r   G   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       )	file_name
is_changedospathsplitextvaluelen	file_type)r   	extensionZext_max_lengthr   r   r   _calc_file_typeO   s    zCmfAttachment._calc_file_typec                 C   s.   t | jjtjr*| dg | jjr*d| _d S )Nzparent.privateT)
isinstanceparentr/   modelsZ
CmfCommentr   privater   r   r   r   _calc_privateX   s    zCmfAttachment._calc_privatec                    s   t   dddddg S )Nurlurl_previewurl_preview_imgr5   Zembedded)r   save_preload_fieldsr8   r   r   r   r=   ^   s    z!CmfAttachment.save_preload_fieldsc                 C   sD   | j   | j sd S tjtj| j  }tj|s@t	| |S r   )
r5   loadr,   r-   joinconfig
UPLOAD_DIRget_files_direxistsmakedirs)r   
upload_dirr   r   r   rE   a   s    

zCmfAttachment.upload_dirc                 C   s4   t jjj }|| j}|jr*|j| _nd| _d S )Nr   )	r6   CmfRFiledpdata_driverget_rdr   
_file_namerC   r   r   rdiskr"   r   r   r   _calc_st_sizej   s
    
zCmfAttachment._calc_st_sizec                 C   s4   t jjj }|| j}|jr0t j	| dd d S )NZ
attachmentZ
after_save)
r6   rF   rG   rH   rI   r   rJ   rC   ZCmfAutomationCrudTriggerZ	crud_hookrK   r   r   r   _call_automation_hookr   s    z#CmfAttachment._call_automation_hookc                 C   s"   | j rt| j}|r|j| _d S r   )is_newAPPget_cache_project
project_idZdefault_attach_full_search_typeZfull_search_typer   projectr   r   r   _calc_full_search_typey   s    z$CmfAttachment._calc_full_search_typec                    sh   |    |   |   |   |   t j||}tj	|  | 
  | jrdttjj| jgd |S )N)r   )	_calc_urlr3   rM   r9   rU   r   saver6   CmfBackbonePeerZobj_after_save_hookrN   rO   Zschedule_deferred_jobr   extract_text_from_attachid)r   r   r   resr   r   r   rW      s    zCmfAttachment.saveT)	only_once
system_jobc              	   C   s   dd l }ddlm} tjj| dddgd}d}d}t|j}|jd	krjd
}d}t||j	j
dtj}n|jdkrvnd S t||:}|r| }n&||}	d}|	jD ]}
||
 7 }qW 5 Q R X |d d |_|jdd d S )Nr   )unquoter;   r1   Zfull_file_pathrZ   fieldsTr)z.docz.docxz.dotz.dotxz.docmz.dotmz.rtfz.pdfz.xpsz.fdfz.xlsz.xlsxz.xlsmz.pptz.pptxz.odpz.odsFrbz/files/)z.txtz.csvz.mdz.html i )Z	only_data)PyPDF2urllib.parser^   r6   r   getr   full_path_filer1   r;   r/   replacer@   rA   openreadZ	PdfReaderZpagesZextract_texttextrW   )Z	attach_idrd   r^   attachZ
force_readmode	file_pathfilerk   readerZpager   r   r   rY      s,    





z&CmfAttachment.extract_text_from_attachc                 C   s   |    | j S r   )rE   r*   r8   r   r   r   rn      s    zCmfAttachment.file_pathNr`   c                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thumbnail.jpg)r*   r+   r:   Zis_nullr,   r-   r?   urllibparsequoterJ   r;   r<   )r   r`   r   r   r   r   r   rV      s
    zCmfAttachment._calc_urlc                 C   s   t ttj| j S )u<    Полный фактический путь к файлу )strr   r@   rA   rJ   r8   r   r   r   rg      s    zCmfAttachment.full_path_fileFbackupsmart_backupmake_preview
mark_dirty)contentc          
      O   sV   t jjj }|| j}	|	jdddd |	j|||||d d| _	| 
  d| _	dS )u    Загрузка файла FT)is_direxist_okparentsrv   N)r6   rF   rG   rH   rI   r   rJ   createwriter   rW   )
r   r{   rw   rx   ry   rz   r   r   rL   r"   r   r   r   upload_file   s    zCmfAttachment.upload_filec                 C   s.   |   }|r|  ntd|  ddd dS )u   Делаем отметку в мете что эту версию файла менять нельзя поскольку она опубликована
        uW   При обработке документа обнаружен пустой файл: u   . Возможно, произошла ошибка при загрузке файла. Пожалуйста, загрузите файл повторно.FabortN)r   
do_publishr    r!   r   r   r   r      s    
zCmfAttachment.do_publishc                 O   sP   | j dd}|si }tjj|d< tjj|d< |j|| d| _|   d| _d S )NT)r   task_attachment_max_sizedocument_attachment_max_sizeF)r   gZglobal_settingsr   r   Zstream_writer   rW   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 5 Q R X d S )Nabspathrq   rb   )r   Zget_versionr   r/   ri   )r   r#   r   r"   Zrfile_versionr   ro   r   r   r   get_content   s    

zCmfAttachment.get_contentc                 C   s    t jjj }|| j}|jS r   )r6   rF   rG   rH   rI   r   rJ   rC   rK   r   r   r   r      s    zCmfAttachment.file_existsc                 C   s<   |  ddg | jr,tj| j | jjS tddd dS )uT    Имя файла вложения в зависимости от родителя r5   r*   u   Вложение должно быть привязано к объекту, нельзя сохранять в корень диска.Tr   N)	r   r5   r,   r-   r?   rB   r*   r/   r    r8   r   r   r   rJ     s    zCmfAttachment._file_namec                 O   s   |   }|j||S r   )r   r	   r   r   r   r   r	     s    zCmfAttachment.get_fullview)forcec                   sH   t  j|d|i|}| jr8|  }|r8|j| jjd tj	|  |S )Nr   )prefix)
r   deleterJ   r   Zmove_to_trashcoder/   r6   rX   Zobj_after_delete_hook)r   r   r   r   r[   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_)nameZ
target_dir)	r   restorer6   rF   Zrestore_from_trashr   r/   r*   rJ   )r   r   r[   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   r_   F)r   r|   T)rZ   mkdir)r,   r6   rF   rf   rJ   r*   rZ   r-   dirnamer/   r5   rW   )r   r`   r   _kwargsr,   r[   r   r   r   r   !  s    zCmfAttachment.get_rfilec                    s6   | j r(t| j  }r(|jd| jd n
t   d S )NzPPP-ATT-CREATEobj)rR   rP   rQ   check_project_role_accessr5   r   check_edit_permrS   r   r   r   r   +  s    zCmfAttachment.check_edit_permc                    s   |  dddg | jr|t| j}tj| jkrjz|jd| jd W qz t	k
rf   |jd| jd Y qzX q|jd| jd n
t
   d S )NrR   r5   	cmf_ownerzPPP-ATT-DELETE-ALLr   zPPP-ATT-DELETE-OWN)r   rR   rP   rQ   r   current_userr   r   r5   ZCmfPermissionErrorr   check_delete_permrS   r   r   r   r   2  s    zCmfAttachment.check_delete_permc                    s*   |    |   |   t j|| d S r   )rV   r3   rM   r   _save_importr   r   r   r   r   A  s    zCmfAttachment._save_importc              
   C   s`   ddl m} d}| dddddg ||d	d
jf | j| j| j| j| j	| j
jdd}|jS )Nr   )BeautifulSoupa  
        <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"
                cmf_converted="true"
                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>
        r<   r;   r:   cmf_created_atr*   
rc   )titlerZ   ZurlPreviewImgZ
urlPreviewr:   Z
createDatezhtml.parser)Zbs4r   r   rh   formatr*   rZ   r<   r;   r:   r   ZjsonZ
currentTag)r   r   ZTAG_TMPLsr   r   r   create_preview_tagG  s    7z CmfAttachment.create_preview_tagc                 O   s    | j rtjj| df|| d S )NZattachment_created)rO   r6   CmfEventdo_eventr   r   r   r   _do_event_save  s    zCmfAttachment._do_event_savec                 O   s   t jj| df|| d S )NZattachment_deleted)r6   r   r   r   r   r   r   _do_event_deleted  s    zCmfAttachment._do_event_deletedc                    sB   t t  }| dg | jr:| j D ]}|| q*t|S )Nr5   )setr   
get_ownersr   r5   addlist)r   r   r   ZownersZparent_ownerr   r   r   r     s    zCmfAttachment.get_ownersc              	      s4   t  j||}t| jd}|| W 5 Q R X d S )Nrb   )r   copyri   rg   r   )r   r   r   Zobj_copyfr   r   r   r     s    zCmfAttachment.copyc                 C   s  |r|t jkr@t jst jrdS |r2t jj|kr2dS t j}t j}nd}tj|ddddddgd}|j	rrt j
d	krrd
S |js|jjdkr|jrdS |j	sdS |j|jkrdS |jD ]`}|jdkr|jr||j|  S |j|jkr dS |dkrtjj|dd}|j|kr dS qdS )u  
        https://bcrm.carbonsoft.ru/project/Document/DOC-014685#spec-014684b
        Проверяем видимость аттача для g.current_person (или check_for_person)
        При использовании check_for_user метод можт выполняться долго! Обязательно перед вызовом
        проверяйте, что аттач имеет флаг private
        T.
spectatorscmf_owner_idr7   rT   zproject.logic_prefix)Zsimpler`   ZapiFzproject.servicedeskZCmfProjectRole)Zid_onlyN)r   r   Zdisable_permissionsZacl_admin_modeZcurrent_personrZ   Zcurrent_person__member_ofcmfutilZget_obj_by_idr7   Z	api_scoper   rT   Zlogic_prefixZ
user_localr   
class_nameZin_project_roler6   ZCmfAccessListZsubject_full_group_list)clsZattachment_idZowner_idZcheck_for_userZcheck_for_user__member_ofrl   Zsubjectr   r   r   check_visibility  s8    

zCmfAttachment.check_visibilityz	@minutely)r\   r]   Zschedulec                  C   s   t jjj } | jtjs0| jj	tjddd | j
tjD ]}z8|dd }t|}|| t  | j| W q> tk
r } z&t  tjd| d| tjd W 5 d }~X Y q>X q>d S )NT)r~   r}   /u4   Не удалось обработать файлы z: )level)r6   rF   rG   rH   rI   ioZ	io_existsr@   Z
DIRTY_PATHZio_mkdirZ
io_iterdirsplitr   Zget_model_by_idZprocess_dirty_attachZ
cmf_commitZ	io_rmtree	ExceptionZcmf_rollbackr   debugZloggingZERROR)rL   Z
dirty_pathZobj_idZmodeler   r   r   cron_check_dirty  s    

zCmfAttachment.cron_check_dirty)N)NF)NN);__name__
__module____qualname__Zcmfr6   Z	CmfEntityZui_meta_skipr   r   Zapi_methodsr   r   r   r   intr   r
   ru   r   r   r3   r9   r=   rE   rM   rN   rU   rW   staticmethodZcmf_deferred_jobrY   propertyrn   rV   rg   bytesr   r   r   r   boolr   rJ   r	   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   __classcell__r   r   r   r   r      s   
		
$
	

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

C
)r   )Zmathrr   pathlibr   Zcmf.includeZcmf.utilr   Z&common.models.cmf_plugin_convert_mixinr   Zmodules.files.fieldsr   r   r   r   r   r   <module>   s   