U
    c>\                     @   s   d dl Z 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 d dlmZ G d	d
 d
ZdS )    N)Path)TemporaryDirectory)Dict)parse)datetime)*)RFilec                   @   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edddd Ze	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edd/d0d1Zd<eeeed3d4d5Ze	d=eeeeed6d7d8Ze	eed9d:d;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_docx0   s    

z"CmfPluginConvertMixin.html_to_docx)contentr   c                 C   s   t |  S )up   
        Преобразует байты в строку base64

        :return: Строка base64
        )base64Z	b64encodedecode)r)   r   r   r   r   D   s    z!CmfPluginConvertMixin._get_base64c              	   C   s4  ddl m} ddl}i }ttjdtjd|D ]:}t|	 }|
 }d| d}|||}|||< q0||}	|	d}
|
r|
  | |	 | |	 | |	 t|	}|D ]z}z6|j|| d	}| |}d
| d}|||}W q tk
r,   d||  }t| |||| }Y qX q|S )u   
        Обработка страницы html для сохранения

        :param html_text: Страница html
        :return: Обработанная страница html
        r   BeautifulSoupNz(<svg.*?svg>))flagsz	<div id="z"></div>h1)Z
bytestringz <img src="data:image/png;base64,z">u=   Не удалось конвертировать svg в png: )bs4r-   cairosvgrefindallcompileDOTALLhashlibmd5encodeZ	hexdigestreplacefind	decompose_handle_html_img_handle_html_table_handle_html_layoutstrZsvg2pngr   	Exceptionlogging	exception)r   r
   r-   r1   Zsvg_replaceZsvgr7   Zmd5sumkeysoupr/   Zimg_contentattach_base64img_tagerr_msgr   r   r   r   M   s8    






z"CmfPluginConvertMixin._handle_htmlN)r   c                 C   s  ddl m} ddl}| }|dD ]}|jdd}|jdd}|jd}|s^q*|dtj	 r|
dtj	 d	}|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rHzt|}|jdkr ||dd d }|dkrd}| |j}d| d| |jd< |s t| dt dd| }t|d}||j W 5 Q R X ||}|j\}}W nD tk
rF } z$t !d t"d|  W Y q*W 5 d}~X Y nX 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r|n|}t#|| |jd< q*W 5 Q R X dS )"u   
        Функция заменяет адрес картинки на base64

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   ImageNimgwidthheightsrczhttps:// /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%Szwb+uL   Не удалось скачать изображения документаuN   Не удалось скачать изображения документа:   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 r\   r]   r_   r   r   r   rb      s      )&PILrI   tempfiler   find_allattrsget
startswithconfigZAPP_FQDNr9   r   unquotemodelsCmfAttachmentr   full_path_file
UPLOAD_DIRexistsopenr   readsuffixsizerequestsstatus_coderfindr)   r   Znowwriter@   rA   rB   Z	cmf_alertintjoinr?   )r   rD   rI   rd   tmp_dirrF   rK   rL   rM   url_path
attachmentZattach_pathZattachment_byterE   rJ   resZextension_imgZ	file_pathfpewidth_defaultwidth_value	width_newcoefficientZheight_defaultheight_valuer   r   r   r<   x   sj    

*






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stylerN   ;:rK   100%Zcellpadding1ZcellspacingZborderc                    s   g | ]}t | r|qS r   
isinstancer_   r   r   r   
<listcomp>   s     
 z<CmfPluginConvertMixin._handle_html_table.<locals>.<listcomp>trd   td%T)rK   N)	r0   r   re   rg   splitstriplenr:   children)rD   r   Zstyle_tableparamsnamevalue	nums_colswidth_columnr   Zstyle_tdtagr   r   r   r=      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   r   Zdivzdata-layout-sectiontruer   rK   r   r   c                    s   g | ]}t | r|qS r   r   r_   r   r   r   r      s     
 z=CmfPluginConvertMixin._handle_html_layout.<locals>.<listcomp>r      r   zdata-column-widthr   N)
r0   r   re   r   Znew_tagr   r   roundrg   append)rD   Zlayoutr   columnsr   r   columnr   r   r   r>      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   )rI   UnidentifiedImageErrorr,   azcmf-fileclassrN   file)objtypeZhrefrJ   Zimager   titler   rK   rL   rM   z
data:image,rV   z;base64Zfile_rW   wbrT   rP   rQ   r   rR   r[   c                 s   s   | ]}|  r|V  qd S r\   r]   r_   r   r   r   rb   8  s      z:CmfPluginConvertMixin._handle_view_html.<locals>.<genexpr>rX   zcommon/static/file-outline.png?rY   Zname_rZ   c                 s   s   | ]}|  r|V  qd S r\   r]   r_   r   r   r   rb   T  s      )'rc   rI   r   r0   r-   re   rf   rg   r   dictr;   	enumeraterh   r   r9   r   rp   rw   r*   Z	b64decoder?   r   rj   rk   rl   ri   rn   rm   ro   rs   rx   ry   ZPROJECT_DIRrv   r   rt   ru   Zresolver)   )!r
   r   rI   r   r-   rD   filesr   indexZ_filerK   rL   Zfull_urlZtype_imgZb64dataZ	name_fileZfile_imgr{   r|   Zattachment_pathrJ   r   r   Zpath_defaultZend_nameZfile_extensionZresponserz   filepathr   r   r   r   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NotoSansrN   r   r   rK   r   Z100r   ZcolspanN)Zfpdfr   r   r0   r-   types	new_classospathabspathry   dirname__file__Zcore_fonts_encodingZadd_pageZadd_fontZset_fontZfindAllrf   r   Z
write_htmlr    Zprettifyr   output)r   r
   r   r   r-   r   Z	path_fontZpdfrD   r   r&   r   r   r   html_to_pdfY  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_htmlrU   N)Zmammothr   r   r   ro   rp   r   )r   r   r   r'   resultr   r   r   docx_to_htmlx  s
    z"CmfPluginConvertMixin.docx_to_html)path_imgr   r   c                 C   s   t | | dS u5   
        Конвертирует PDF -> PNG
        N)r   pdf_bytes_to_imgr   r   r   r   r   r     s    z&CmfPluginConvertMixin.pdf_bytes_to_img)path_pdfr   r   c                 C   s   t | | dS r   )r   
pdf_to_img)r   r   r   r   r   r     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   ro   rp   r   rq   r   )r   r   r   	file_htmlr   r   r   r   html_to_img  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   rH   N)rc   rI   rp   r#   )r   r   r   rI   rJ   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   rZ   )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 r\   r   )r`   r   )r   r   r   rb     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_pathrr   r   c                 C   s   t | || dS )u(  
        Конвертация данных в PDF через libreoffice
        :param data: Данные файла в виде байт
        :param output_path: Путь сохранения итогового pdf файла
        :param suffix: Расширение файла
        N)r   
obj_to_pdf)r   r   rr   r   r   r   r     s    z CmfPluginConvertMixin.obj_to_pdfrN   )r   rr   mimetyper   c              
   C   sZ  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}|rR|d}|rR| }|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   rN   headr   T)class_r   rW   {rZ   })rd   r0   r-   r   r   r   rp   rw   get_encoding_typer?   r+   r9   r:   Zget_textre   rg   )r   r   rr   r   rd   r-   Z
bytes_htmlr   Zfull_path_htmlr   r   r
   rD   r   r   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   rr   	to_formatr   r   c                 C   s   t | |||S )u*  
        Конвертация данных в HTML через libreoffice
        :param data: Данные файла в виде байт
        :param suffix: Расширение файла
        :param to_format: Формат файла который хотим получить
        )r   r   )r   rr   r   r   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   )UniversalDetectorrU   r   r   zwindows-1251zwindows-1250zwindows-1252asciiz
iso-8859-1latin1r   r   )Zchardet.universaldetectorr   rp   ZfeedZdoner   rg   closer!   	readlinesr$   UnicodeDecodeError)r   r   Zdetectorr   liner   	encodingsZformat_encodingr   r   r   r     s*    

z'CmfPluginConvertMixin.get_encoding_type)rN   )rN   )__name__
__module____qualname____doc__r?   r   r   r   r(   staticmethodr   r   r<   r=   r>   r    r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	      s>   +G&[		+	(	r	   )r*   r6   r!   pathlibr   rd   r   typingr   Zurllibr   r   r   rt   Zcmf.includeZrdiskr   r	   r   r   r   r   <module>   s   