U
    |c<W                     @   sv   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
m
Z
 d dlZd dlZd dlT G dd	 d	ZdS )
    N)Path)TemporaryDirectory)Dict)parse)datetime)*c                   @   s  e Zd ZdZeedddZeedddZeedddZe	eed	d
dZ
eedddZddddZe	ddddZe	ddddZe	eeedddZeedddZeedddZeedddd Zeedd!d"d#Zeedd$d%d&Zeedd'd(d)Zeedd*d+d,Zddd-d.Zeeedd/d0d1Zeeed2d3d4Ze	eeeed5d6d7Ze	eed8d9d:ZdS );CmfPluginConvertMixinuO   
    Используется в классах CmfDocument, CmfAttachment
    )	html_textreturnc                 C   s8   |  |}| t|dddd}| |dd}| |S )u   
        Сохраняет HTML -> PDF
        Используется преобразование через DOCX, из-за этого нет разрыва страниц.

        :return: Данные pdf в виде строки base64
        utf-8encoding.htmldocx:MS Word 2007 XMLz.docxzpdf:writer_pdf_Export_handle_htmlobj_to_formatbytes_get_base64)selfr	   html
docx_bytes	pdf_bytes r   +./common/models/cmf_plugin_convert_mixin.pysave_to_pdf   s    
z!CmfPluginConvertMixin.save_to_pdfc                 C   s*   |  |}| t|dddd}| |S )uu   
        Сохраняет HTML -> DOCX

        :return: Данные docx в виде строки base64
        r   r   r   r   r   )r   r	   r   r   r   r   r   save_to_docx!   s    
z"CmfPluginConvertMixin.save_to_docxc           	   
   C   s~   ddl m} ddlm} | }| }t J}| ||}||| t }|	| |
d | W  5 Q R  S Q R X dS )ud   
        Преобразует HTML -> DOCX

        :return: Данные в байтах
        r   )Document)
HtmlToDocxN)Zdocxr   Zhtmldocxr   r   _handle_view_htmlZadd_html_to_documentioBytesIOsaveseekgetvalue)	r   r	   r   r   ZdocumentZ
new_parsertmp_dir_namer   	docx_filer   r   r   html_to_docx,   s    

z"CmfPluginConvertMixin.html_to_docx)contentr
   c                 C   s   t |  S )up   
        Преобразует байты в строку base64

        :return: Строка base64
        )base64Z	b64encodedecode)r(   r   r   r   r   @   s    z!CmfPluginConvertMixin._get_base64c                 C   sP   ddl m} ||}|d}|r*|  | | | | | | t|S )u   
        Обработка страницы html для сохранения

        :param html_text: Страница html
        :return: Обработанная страница html
        r   BeautifulSouph1)bs4r,   find	decompose_handle_html_img_handle_html_table_handle_html_layoutstr)r   r	   r,   soupr-   r   r   r   r   I   s    



z"CmfPluginConvertMixin._handle_htmlN)r
   c                 C   s  ddl m} ddl}| `}|dD ]L}|jdd}|jdd}|jd}|s^q*|drt	|}	t
jjd	d
|	gdgd}
|
rt|
j}nt|	dtj}| rt|d4}| | }d|jdd d| |jd< W 5 Q R X |s||}|j\}}|drt|}|jdkr||dd d }|dkr\d}| |j}d| d| |jd< |st| dt dd| }t|d}||j W 5 Q R X ||}|j\}}d}tddd t |D }||ks|dkr|n|}|r*|r&|| nd}||jd< d}tddd t |D }|dkrb|n|}t|| |jd< q*W 5 Q R X dS )u   
        Функция заменяет адрес картинки на base64

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   ImageNimgwidthheightsrc/url==r   filterZfields/files/rbdata:image/. z;base64,http      )ZpngZbmpZgifZtiffZtifZjpegZjpgz/imgz%Y%m%d-%H%M%Swb+  c                 s   s   | ]}|  r|V  qd S Nisdigit.0elr   r   r   	<genexpr>   s      z9CmfPluginConvertMixin._handle_html_img.<locals>.<genexpr>c                 s   s   | ]}|  r|V  qd S rK   rL   rN   r   r   r   rQ      s      )!PILr7   tempfiler   find_allattrsget
startswithr   unquotemodelsCmfAttachmentr   full_path_filereplaceconfig
UPLOAD_DIRexistsopenr   readsuffixsizerequestsstatus_coderfindr(   r   Znowwriteintjoinr4   )r   r5   r7   rS   tmp_dirZimg_tagr9   r:   r;   url_path
attachmentZattach_pathZattachment_byteZattach_base64r8   resZextension_imgZ	file_pathfpwidth_defaultwidth_value	width_newcoefficientZheight_defaultheight_valuer   r   r   r1   ^   s\    

*






z&CmfPluginConvertMixin._handle_html_imgc                    sb  ddl m  | dD ]D}i }|dddD ]&}|r2|d\}}| || < q2|dst|dd	|d< |d
sd|d
< |dsd|d< |ds|dd|d< t fdd|djD }d| }|dD ]x}i }	|dddD ]&}|r|d\}}| |	| < q|	d| d|d< |jddD ]}
|d |
d< qFqqdS )u  
        Функция добавляет стиль для таблиц
        Для конвертирования таблиц в LibreOffice используем inline style

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   TagtablestylerE   ;:r9   100%Zcellpadding1ZcellspacingZborderc                    s   g | ]}t | r|qS r   
isinstancerN   rt   r   r   
<listcomp>   s     
 z<CmfPluginConvertMixin._handle_html_table.<locals>.<listcomp>trd   td%T)r9   N)	r.   ru   rT   rV   splitstriplenr/   children)r5   rv   Zstyle_tableparamsnamevalue	nums_colswidth_columnr   Zstyle_tdtagr   rt   r   r2      s4    



z(CmfPluginConvertMixin._handle_html_tablec                    s   ddl m  | dddiD ]}d|d< d|_| d	} fd
d|jD }t|}td| d}|D ]*}d|_|d| d|d< |	| qf|	| qdS )u   
        Функция добавляет стиль для макета, используем table, так как flex не поддерживается в LibreOffice

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   rt   Zdivzdata-layout-sectiontruerz   r9   rv   r   c                    s   g | ]}t | r|qS r   r|   rN   rt   r   r   r~      s     
 z=CmfPluginConvertMixin._handle_html_layout.<locals>.<listcomp>r      r   zdata-column-widthr   N)
r.   ru   rT   r   Znew_tagr   r   roundrV   append)r5   Zlayoutr   columnsr   r   columnr   rt   r   r3      s    
z)CmfPluginConvertMixin._handle_html_layout)r	   tmp_pathr
   c           !   
   C   s  ddl m}m} ddlm} || }g }|dD ]>}d|jddkrZ|t	|dd	 |jd
s2d|jd
< q2|dD ]}|t	|dd	 q||dD ]}|
  q|dD ]}|
  qt|D ]\}}	|	d }|jdd}
|jdd}|jd}|dr|d\}}|dd}|dd}t|d| d|  }t|d$}|t| t||jd< W 5 Q R X |dr
t|}tjjddtjgdgd}|rt|j}nt|dtj}| r
t||jd< |
s
||}|j\}
}d}tdd d! t|
D }|d"rBttj d# }|!d$d%kr\t"|n|!d$}||!d| }t#|}|j$d&kr4t|}|d'| |  % }t|d}||j& W 5 Q R X z>||}|j\}
}t||jd< |r|n|
r|
n|}W n$ |k
r0   t||jd< Y nX nt||jd< ||krP|n|}|r|| rj|| nd(}||jd< tdd)d! t|D } t| | |jd< qt|S )*u   
        Функция заменяет адрес картинки, файла на фактический

        :return: HTML с фактическими адресами картинок, файлов
        r   )r7   UnidentifiedImageErrorr+   azcmf-fileclassrE   file)objtypeZhrefr8   Zimagerw   titler   r9   r:   r;   z
data:image,rC   z;base64Zfile_rD   wbrA   r=   r>   r   r?   rJ   c                 s   s   | ]}|  r|V  qd S rK   rL   rN   r   r   r   rQ     s      z:CmfPluginConvertMixin._handle_view_html.<locals>.<genexpr>rF   zcommon/static/file-outline.png?rG   Zname_rH   c                 s   s   | ]}|  r|V  qd S rK   rL   rN   r   r   r   rQ   2  s      )'rR   r7   r   r.   r,   rT   rU   rV   r   dictr0   	enumeraterW   r   r\   r   r`   rg   r)   Z	b64decoder4   r   rX   rY   rZ   r]   r^   r[   r_   rc   rh   ri   ZPROJECT_DIRrf   r   rd   re   Zresolver(   )!r	   r   r7   r   r,   r5   filesr   indexZ_filer9   r:   Zfull_urlZtype_imgZb64dataZ	name_fileZfile_imgrk   rl   Zattachment_pathr8   ro   rp   Zpath_defaultZend_nameZfile_extensionZresponserj   filepathr   rq   rr   rs   r   r   r   r      s    





"



z'CmfPluginConvertMixin._handle_view_htmlc              
   C   s  ddl m}m} ddlm} tjd||fd}tj	tj
tjtdd}tj
|ddd	d
dd}| }d|_|  |dd| |d ||}|dD ]}	d|	jd< q|dD ]}	d|	jd< d|	jd< qt 0}
|| | |
 t| W  5 Q R  S Q R X dS )uw   
        Конвертирует HTML -> PDF

        :return: Возвращает байты PDF файла
        r   )FPDF	HTMLMixinr+   	_HTML2PDF)basesz..modulesZappZassetsZfontsz	noto-sanszNotoSans-Regular.ttfr   ZNotoSansrE   rv   rz   r9   r   Z100r{   ZcolspanN)Zfpdfr   r   r.   r,   types	new_classospathabspathri   dirname__file__Zcore_fonts_encodingZadd_pageZadd_fontZset_fontZfindAllrU   r   Z
write_htmlr   Zprettifyr   output)r   r	   r   r   r,   r   Z	path_fontpdfr5   r   r%   r   r   r   html_to_pdf7  s&     

z!CmfPluginConvertMixin.html_to_pdf)	path_docxr
   c              
   C   sH   ddl m} tj|rDt|d}||}|jW  5 Q R  S Q R X dS )u7   
        Конвертирует DOCX -> HTML
        r   )convert_to_htmlrB   N)Zmammothr   r   r   r_   r`   r   )r   r   r   r&   resultr   r   r   docx_to_htmlV  s
    z"CmfPluginConvertMixin.docx_to_html)path_imgr   r
   c                 C   s4   ddl }|d|}|d}| }|| dS )5   
        Конвертирует PDF -> PNG
        r   Nr   )fitzr`   ZloadPageZ
get_pixmapr"   )r   r   r   r   r   ZpageZimagesr   r   r   pdf_bytes_to_imga  s
    
z&CmfPluginConvertMixin.pdf_bytes_to_img)path_pdfr   r
   c              	   C   s8   t j|r4t|d}| j|| d W 5 Q R X dS )r   rB   r   r   N)r   r   r_   r`   r   ra   )r   r   r   Zfile_pdfr   r   r   
pdf_to_imgl  s    z CmfPluginConvertMixin.pdf_to_img)	path_htmlr   r
   c              	   C   sB   t j|r>t|d"}| | }| j||d W 5 Q R X dS )u6   
        Конвертирует HTML -> PNG
        rr   N)r   r   r_   r`   r   ra   r   )r   r   r   	file_htmlr   r   r   r   html_to_imgt  s    z!CmfPluginConvertMixin.html_to_img)	path_xlsxr   r
   c                 C   s   ddl m } ||| dS )u7   
        Конвертирует XLSX -> HTML
        r   	xlsx2htmlNr   )r   r   r   r   r   r   r   xlsx_to_html}  s    z"CmfPluginConvertMixin.xlsx_to_html)r   path_pngr
   c                 C   s$   ddl m} ||}|| dS )u<   
        Сохранение в формате PNG
        r   r6   N)rR   r7   r`   r"   )r   r   r   r7   r8   r   r   r   save_img  s    
zCmfPluginConvertMixin.save_imgc              
      s  ddl m} ddlm} ddlm  ddlm ||ddd}| }| }tt	|D ]}|
|| }	|dkr|j}
|| |
_n|j|| d}
|	jD ]*}|\}}}}|
j|d	 ||d	 |d
 q fddt|	jD ],}|
fdd|	j||	|dD  qqZ|| dS )u6   
        Конвертирует XLS -> XLSX
        r   )workbook)open_workbook)XL_CELL_DATE)xldate_as_tupleT)Zformatting_infoZragged_rows)r   rH   )Z	start_rowZend_rowZstart_columnZ
end_columnc                    sJ   | j }| j krF|d}|dd dkr>tj|dd   }nt| }|S )Nr      )r   r   r   )r   Zctyper   time)cellr   Zdatetime_tup)r   r   r   r   _get_xlrd_cell_value  s    

z?CmfPluginConvertMixin.xls_to_xlsx.<locals>._get_xlrd_cell_valuec                 3   s   | ]} |V  qd S rK   r   )rO   r   )r   r   r   rQ     s   z4CmfPluginConvertMixin.xls_to_xlsx.<locals>.<genexpr>)Zend_colxN)Zopenpyxlr   Zxlrdr   r   r   ZWorkbooksheet_namesranger   Zsheet_by_nameZactiver   Zcreate_sheetZmerged_cellsZmerge_cellsZnrowsr   Z	row_sliceZrow_lenr"   )r   Zpath_xlsr   r   r   Zbook_xlsZ	book_xlsxr   Zsheet_indexZ	sheet_xlsZ
sheet_xlsxZcrangeZrloZrhiZcloZchirowr   )r   r   r   r   xls_to_xlsx  s2    
 
z!CmfPluginConvertMixin.xls_to_xlsx)dataoutput_pathrb   r
   c              	   C   s.   t |d}|| ||d W 5 Q R X dS )u(  
        Конвертация данных в PDF через libreoffice
        :param data: Данные файла в виде байт
        :param output_path: Путь сохранения итогового pdf файла
        :param suffix: Расширение файла
        rI   r   N)r`   rg   r   )r   r   r   rb   fr   r   r   
obj_to_pdf  s    z CmfPluginConvertMixin.obj_to_pdf)r   rb   r
   c              
   C   sX  ddl }ddlm} | ||d}| @}t|d }t|d}|| | t	|}	W 5 Q R X W 5 Q R X |j
|	ddd	d
}
|
dd}
||
}|d}|rP|d}|rP| }|jddD ]}|dd}d}|d D ]T}|d| }|||d d d }|||d d }|||| 7 }q||  |d< qt	|S )u  
        Конвертация данных в HTML через libreoffice

        :param data: Данные файла источника в виде байт
        :param suffix: Расширение файла источника

        :return: Строка HTML
        r   Nr+   r   z	file.htmlr   ignore)errors u   �u   rE   headrw   T)class_r   rD   {rH   })rS   r.   r,   r   r   r   r`   rg   get_encoding_typer4   r*   r\   r/   Zget_textrT   rV   )r   r   rb   rS   r,   Z
bytes_htmlr   Zfull_path_htmlr   r   r	   r5   r   rw   Z
style_textr   Z	style_tagZstyle_classZ	class_tagZstart_pos_classZstyle_startZ	style_endr   r   r   obj_to_html  s4    	

"

z!CmfPluginConvertMixin.obj_to_html)r   rb   	to_formatr
   c                 C   sH   t jtjd| i||dd}|jdkr>td| d|j n|jS dS )u*  
        Конвертация данных в HTML через libreoffice
        :param data: Данные файла в виде байт
        :param suffix: Расширение файла
        :param to_format: Формат файла который хотим получить
        r   )rb   format)r   r   rG   u4   Не удалось конвертировать в z: N)rd   Zpostr]   ZCONVERTER_URLre   	Exceptionr(   )r   rb   r   rm   r   r   r   r     s    
z#CmfPluginConvertMixin.obj_to_format)	path_filer
   c              
   C   s   ddl m} | }t| d8}|D ]$}|| |jr"|jdr" qHq"|  W 5 Q R X |jd}|sddddd	d
dg}|D ]d}zFtj| d|d,}|	  |
d |}W 5 Q R  W  qW 5 Q R X W q tk
r   d}Y qX q|S )u   
        Определяем кодировку файла

        :param path_file: Путь к файлу
        :return: Кодировка файла
        r   )UniversalDetectorrB   r   r   zwindows-1251zwindows-1250zwindows-1252asciiz
iso-8859-1latin1r   r   )Zchardet.universaldetectorr   r`   ZfeedZdoner   rV   closer    	readlinesr#   UnicodeDecodeError)r   r   Zdetectorr   liner   	encodingsZformat_encodingr   r   r   r     s*    

z'CmfPluginConvertMixin.get_encoding_type)__name__
__module____qualname____doc__r4   r   r   r   r'   staticmethodr   r   r1   r2   r3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s8   ?&[		+
(r   )r)   r    pathlibr   rS   r   typingr   Zurllibr   r   r   rd   Zcmf.includer   r   r   r   r   <module>   s   