
    h                         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 d dlmZ d	Zd
Zeez  ZdZdZ G d d      Zy)    N)Path)TemporaryDirectory)Dict)parse)datetime)*)RFilei  i  gHzG?100%c                      e Zd ZdZg dZdedefdZdefdZdefdZ	d	edefd
Z
ededefd       Zededefd       Zed        ZdefdZdCdZedDd       Zedefd       Zd ZdDdZed        ZdDdZedDd       ZedDd       Zed	ededefd       Zd	edefdZdedefdZeded eddfd!       Zed"ededdfd#       Zd$ededdfd%Zd&ed$eddfd'Z ded(eddfd)Z!dDd*Z"ed+ed,ed-eddfd.       Z#dEd+ed-ed/edefd0Z$edEd+ed-ed1ed/edef
d2       Z%ed3edefd4       Z&defd5Z'd6 Z(d7 Z)d8 Z*defd9Z+e,d:        Z-edCdefd;       Z.dFd=Z/e e0d>d?d<@      dA               Z1e e0d>d?d<@      dB               Z2y)GCmfPluginConvertMixinuO   
    Используется в классах CmfDocument, CmfAttachment
    )save_to_pdfsave_to_docxexport_to_docxexport_to_pdfexport_obj_list_to_pdfexport_tree_to_pdfcontent	extensionc                 r   ddl m} |j                  | j                  j                   d| j
                          d| }t        j                  t        j                  |      }|j                         5  |j                          ddd       |j                  |d       |j                  S # 1 sw Y   (xY w)	up  
        Метод сохраняет файл директорию объекта и возвращает путь для скачивания
        :param content: Контент в байт
        :param extension: Расширение файла
        :return: file_path: Строка пути с кодированием символов для URL
        r   )cmfutil_.parentnameNF)make_preview)cmf.utilr   translit_stripr   valuecodemodelsCmfAttachmentgcurrent_userdisable_aclsaveupload_fileurl)selfr   r   r   	file_name
attachments         +./common/models/cmf_plugin_convert_mixin.py_save_export_filez'CmfPluginConvertMixin._save_export_file'   s     	%--0A499+.NOPPQR[Q\]	))i)P
  " 	OO	 	wU;~~		 	s   5B--B6returnc                     t        d       | j                         }| j                  t        |d      dd      }| j                  |dd      }| j	                  |d      }|S )	u   
        Сохраняет HTML -> PDF
        Используется преобразование через DOCX, из-за этого нет разрыва страниц.

        :return: Данные pdf в виде строки base64
        !   УСТАРЕВШАЯ ВЕРСИЯutf-8encoding.htmldocx:MS Word 2007 XML.docxpdf:writer_pdf_Exportpdf	cmf_alert_handle_htmlobj_to_formatbytesr-   )r)   argskwargshtml
docx_bytes	pdf_bytesurl_file_paths          r,   r   z!CmfPluginConvertMixin.save_to_pdf9   sd     	56  "''dW(EwPgh
&&z7<ST	..y%@    c                     t        d       | j                         }| j                  t        |d      dd      }| j	                  |d      }|S )uu   
        Сохраняет HTML -> DOCX

        :return: Данные docx в виде строки base64
        r0   r1   r2   r4   r5   docxr9   )r)   r>   r?   r@   rA   rC   s         r,   r   z"CmfPluginConvertMixin.save_to_docxI   sO     	56  "''dW(EwPgh
..z6BrD   	html_textc                 J   ddl m} ddlm}  |       } |       }t	               5 }| j                  ||      }|j                  ||       t        j                         }|j                  |       |j                  d       |j                         cddd       S # 1 sw Y   yxY w)ud   
        Преобразует HTML -> DOCX

        :return: Данные в байтах
        r   )Document)
HtmlToDocxN)rF   rI   htmldocxrJ   r   _handle_view_htmladd_html_to_documentioBytesIOr&   seekgetvalue)	r)   rG   rI   rJ   document
new_parsertmp_dir_namer@   	docx_files	            r,   html_to_docxz"CmfPluginConvertMixin.html_to_docxW   s     	"':\
! 	(\)))\BD++D(;

IMM)$NN1%%'	( 	( 	(s   A*BB"c                 H    t        j                  |       j                         S )up   
        Преобразует байты в строку base64

        :return: Строка base64
        )base64	b64encodedecode)r   s    r,   _get_base64z!CmfPluginConvertMixin._get_base64k   s     (//11rD   r   c                    | j                  d      r5t        dz  t        | j                         j	                  dd            z  }|S | j                  d      r9t        | j                         j	                  dd            t
        z  t        z  }|S | j                  d      r2t        | j                         j	                  dd            t        z  }|S t        d      t
        z  t        z  }|S )u?  
        Метод масштабирует значение ширины под формат А4 и переводит его в пиксели
        :param value: Строка значения ширины в % или пикселях
        :return: pixels: Число с плавающей точкой
        %d    ptpx)endswithA4_PAGE_WIDTH_PXfloatstripreplacePT_TO_PXSCALE_A4)r   pixelss     r,   _get_value_in_pixelsz*CmfPluginConvertMixin._get_value_in_pixelst   s     >>#%+eEKKM4I4I#r4R.SSF  ^^D!EKKM11$;<xG8SF  ^^D!5;;=00r:;hFF  3Z(*X5FrD   c                    | j                   j                  d      r| j                   j                  d      syt        | j                   j                  d      j                         j	                  dd            }t        | j                   j                  d      j                         j	                  dd            }||kD  r2||z  }|dz
  }| d| j                   d<   ||z   d| j                   d<   yy)u   
        Метод масштабирует изображение под ширину ячейки таблицы
        :param img: Тег изображения
        :param cell_width: Ширина ячейки
        widthheightNra   r_   g)\(@)attrsgetrd   re   rf   )img
cell_width	img_width
img_heightproportion_ratios        r,   _auto_size_img_for_cellz-CmfPluginConvertMixin._auto_size_img_for_cell   s     yy}}W%SYY]]8-D#))--0668@@rJK	399==288:BB4LM
z!(:5"T)I$-;b!1CIIg%.1A%A$B""ECIIh	 "rD   c                    | j                         }|j                  d      D ]"  }|j                  |j                  d             $ |j                  d      D ];  }t	        |j
                        dk  s|j                  |j                  d             = | j                  |       | j                  |       | j                  |       | j                  |       | j                  |       | j                  |       | j                  |       |j                  dd      }|j                  d	d
      }d|_        |j                  d|j                  d             |j                   j                  |j                  dd             |j                   j                  |       |j                  |j                  d             |j"                  j                  |       t%        |      S )u   
        Обработка страницы html для сохранения

        :param html_text: Страница html
        :return: Обработанная страница html
        spoiler-iconclass_p   brr@   zru-RU)langstyletext/csstypea  
        @page { size: 21.0cm 29.7cm; margin: 1cm }
        body {
            font-family: Arial, Helvetica, FreeSans, 'Liberation Sans', sans-serif;
            font-size: 10pt;
            line-height: 1.2;
        }
        td { page-break-inside: avoid !important; }
        tr { page-break-after: avoid !important; }
        td p { margin-top: 0.2cm; margin-bottom: 0.2cm }
        r   headmetazUTF-8)charsetbody)handle_include_pagefind_allreplace_withnew_taglencontentsappend_handle_html_card_preview_handle_html_svg_to_png_handle_html_img_handle_html_infopanel_handle_html_layout_handle_html_table_handle_html_cleanstringinsertr   r   str)r)   soupspanrz   r@   r~   s         r,   r;   z"CmfPluginConvertMixin._handle_html   s    '')MMM8 	1Ddll3/0	1
 s# 	-A1::"d+,	- 	&&t,$$T*d###D)  &%% ||F|1W:6
 	At||F+,		fg>?		DLL()		4yrD   Nc                 F   ddl m} |
t               }| j                  dg       | j                  j
                  r| j                  j
                  nd} ||d      }|}|j                  | j                  j
                         |j                  d      D ]  }|j                  j                  d      }|rZ||vrVt        j                  j                  |	      }|r#|j                  |      }	|j                  |	       i|j                          z|j                           |S )
u  
        Подгружает html text из Include страницы
        :param parent_pages: ID родителей страницы для проверки на зацикливание
        :return: bs4.BeautifulSoup soup: Объект библиотеки
        r   BeautifulSouptext_renderr_   html.parserzmacros-include-pagerx   zdata-param-pageid)id)bs4r   setload_fieldsr   r   addr   r   rn   ro   r!   CmfDocumentr   r   	decompose)
r)   parent_pagesr   rG   r   pagesinclude_pagepage_idinclude_documentinclude_htmls
             r,   r   z)CmfPluginConvertMixin.handle_include_page   s     	&5L-).2.>.>.D.DD$$**"	Y6		$''--  MM1FMG 	)L"((,,-@AG7%/#)#5#5#9#9W#9#E ##3#G#G#NL --l; **,&&(	) rD   c                    | j                  d      D ]  }|j                  d      }d|j                  d<   |j                  d      j                  | j	                  d            }|j                  d      j                  | j	                  d            }| j	                  d      }|j                  |       |j                  |       |j                  |       |j                  |        y	)
u  
        Метод парсит DIV вложения и оставляет в нем только нужные теги: изображение, имя файла и дата

        :param bs4.BeautifulSoup soup: Объект библиотеки
        zapp-tinymce-card-previewrx   rp   150pxrl   zapp-tinymce-file-name-viewdivzapp-tinymce-file-create-viewN)r   findrn   wrapr   r   r   )r   previewrp   r*   file_creater   s         r,   r   z/CmfPluginConvertMixin._handle_html_card_preview   s     }},F}G 	&G,,u%C!(CIIg,HINNt||\aObcI!,,.L,MRRSWS_S_`eSfgK,,u%CJJsOJJy!JJ{#  %	&rD   c                     | j                  dd      }|D ]^  }|j                  dd      }|s| j                  d      }|j                  t	        |j
                               |j                  |       ` | S )uq   
        Метод очищает markdown макрос от лишних тегов для libreoffice
        r   zmacros-panel wikimarkdownrx   zbody-previewrz   )r   r   r   extendlistr   r   )r   macros_panelspanelpreview_divnew_ps        r,   _handle_html_markdownz+CmfPluginConvertMixin._handle_html_markdown   su    
 e4OP" 	*E**U>*BKS)T+"6"678""5)	* rD   c           	         ddl }ddlm} |j                  d      D ]8  }	 d}|j	                  d      x}r_|j
                  j                  d      }dd	d
| j                  j                  gdd
| dgg}t        j                  j                  |dg      }|r)|j                  d|j                  j                        }	n|j
                  j                  d      }
|j
                  j                  d      }|j
                  j                  d      }|r4|j                         }|d   |j
                  d<   |d   |j
                  d<   d}|j                  dt        j                  |      i      D ]C  }|j
                  j                  d      }d}t        j!                  |||      |j
                  d<   E |j#                  t%        |            }| j'                  |      }|
r|s3|j)                  t+        j,                  |            }	|	j.                  \  }
}|j                  dd| t%        |
      t%        |            }	|j1                  |	       ; y# t2        $ r' dt%        |       }t4        j7                  |       Y lw xY w)ud  
        Метод заменяет тег SVG тегом IMG с изображением в PNG.
        Конвертирует SVG в PNG, если SVG в диаграммах DrawIO, то сначала пытается найти готовый PNG диаграммы
        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   NImagesvgzdrawio-contentrx   zdata-drawio-titleAND	parent_id==r   z.pngr(   filterfieldsrp   )srcrl   rm   viewbox      z"rgb\((\d+)[\s,]+(\d+)[\s,]+(\d+)\)fillrn   zrgb(\1, \2, \3))
bytestringzdata:image/png;base64,)r   rl   rm   u3   Не удалось заменить SVG на PNG: )cairosvgPILr   r   find_parentrn   ro   r   r   r!   r"   r   r(   splitrecompilesubsvg2pngr   r[   openrN   rO   sizer   	Exceptionlogging	exception)r)   r   r   r   r   r+   drawiodrawio_titler   rp   rl   rm   r   svg_sizepatterntag_with_fillrgbreplimg_byte
img_base64err_msgs                        r,   r   z-CmfPluginConvertMixin._handle_html_svg_to_png  sT    	==' $	+C#+!
 __4D_EE6E#)<<#3#34G#HL#k4%G&RV[gZhhlXmInoF!'!5!5!9!9QVPW!9!XJ,,u*..2F2F,GCIIMM'2E YY]]84F!iimmI6G#*==?-5a[		'*.6qk		(+CG),VRZZPWEX<Y)Z Q+1155f=168ffWdC6P++F3Q
  (//3s8/DH!%!1!1(!;J #jjH)=>(+v,,u4J:,2W-0ZF ' MC  %C$	+D  +OPSTWPXzZ!!'*+s   H4I,J	J	c           
          ddl m} ddl}|j                         5 }|j	                  d      D ]  }|j
                  j                  d      }|j
                  j                  d      }|rit        j                  dd|j                  d	d
            }|j                  d      r&t        dz  t        |j                  dd            z  }nt        |      }|rit        j                  dd|j                  d	d
            }|j                  d      r&t        dz  t        |j                  dd            z  }nt        |      }|j
                  j                  d      }|s/|j                  dt        j                         s#|j                  dt        j                   d      rG|j                  dt        j                   d      }|j                  dt        j                   dd      }|j                  d      s|j                  d      r|j
                  j                  d      }	|j                  dd      }t!        j"                  |      }
t!        j$                  |
j&                        }|	r#t(        j*                  j                  |	dg      }n7ddd|gdd|
j&                  gg}t(        j*                  j                  |dg      }|rt-        |j.                        }n)t-        |j                  dt        j0                              }|j3                         st-        t        j4                        dz  }	 |j7                  |      }|j8                  \  }}t7        |d      5 }| j;                  |j=                               }|j>                  jA                         }d| d| |j
                  d<   ddd       |j                  d"      r	 tM        j                  |d#$      }|jN                  d%k(  sJ d&|jN                          ||jQ                  d
      d'z   d }|d(vrd)}| j;                  |jR                        }d| d| |j
                  d<   t-        | d*tU        jV                         d+d
|       }t7        |d,      5 }|jY                  |jR                         ddd       |j7                  |      }|j8                  \  }}|j                  d3      r`	 t        j                  d4d|      }ta        jb                  |      }|j7                  te        jf                  |            }|j8                  \  }}|r|s
|z  }|z  }|r|s
|z  }|z  }|s|s}}||z  }|th        z  }||z  }|tj        kD  s|dk  r!|r	tj        |z  nd'}tj        }|tm        |      z  }| d7|j
                  d<   | d7|j
                  d<   |j                  d.      sd8|d.   v s|j[                  d9d:;      }  |jZ                  	 d<i |j
                  }!| jo                  |!       |jE                  |         	 ddd       y# 1 sw Y   xY w# tB        $ r8 |jE                  |jF                         tH        jK                  d | d!       Y ^w xY w# 1 sw Y   xY w# tB        $ r`}|j[                  d-      }d.d/i|_        d0|_.        |jE                  |       tH        jK                  d1       t_        d2|        Y d}~d}~ww xY w# tB        $ r`}|j[                  d-      }d.d/i|_        d0|_.        |jE                  |       tH        jK                  d5       t_        d6|        Y d}~?d}~ww xY w# 1 sw Y   yxY w)=u#  
        Метод заменяет адрес картинки на base64 и масштабирует размер изображения под формат А4 относительно исходного

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   r   Nrp   rl   rm   z[^0-9|%|\.]r_   ,r   r]   r^   r   zhttps://zhttp://z:8080/z	files/objzdata-attach-idz%25r   )r   r   ORr(   r   r   /files/common/static/file-outline.pngrbdata:image/z;base64,u	   Файл u/    не является изображениемhttp)r{      )timeout   u2   Код статуса ответа сервера r{   )pngbmpgiftifftifjpegjpgz/imgz%Y%m%d-%H%M%Szwb+rz   r~   z0color: red; font-style: italic; font-size: 10pt;u?   Не удалось отобразить изображениеuL   Не удалось скачать изображения документаuN   Не удалось скачать изображения документа: 
data:imagez^data:image/.+;base64,uG   Не удалось конвертировать изображениеuI   Не удалось конвертировать изображение: ra   zmargin-left: auto;r   z text-align: center; width: 100%;r~   )rp   )8r   r   tempfiler   r   rn   ro   r   r   rf   rb   WEB_PAGE_WIDTH_PXrd   
startswithconfigAPP_FQDNr   urlparseunquotepathr!   r"   r   full_path_file
UPLOAD_DIRexistsPROJECT_DIRr   r   r[   readformatlowerr   r   r   r   r   requestsstatus_coderfindr   r   nowwriter   r   r:   rX   	b64decoderN   rO   rh   rc   absr   )"r)   r   r   r   tmp_dirimg_tagrl   rm   r   	attach_idr(   url_path_unquoter+   _filterattach_pathrp   width_originalheight_originalattachment_byteattach_base64	mime_typeresextension_img	file_pathfpetag_iimg_base64_dataimg_byte_datascalert   coefficientimg_wrapper	clone_imgs"                                     r,   r   z&CmfPluginConvertMixin._handle_html_img>  s    	((* @	6g==/ 6))'2 **84FF>2u}}S#7NOE~~c* 1C 7%cSU@V:W W %eVVNBsC8PQFs+!2S!85PSUWAX;Y!Y!&vmm''.>>HV__,=">?3>>T[\b\k\k[llqRrCs++0A&BBGC++/@&FKC>>#&#..*E ' 1 12B CI++eS1C..-C',}}SXX'>$ %+%9%9%=%=TWSX%=%Y
#'%7G)H5RVX[X`X`Ja"b%+%9%9%=%=WVYUZ%=%[
!&*:+D+D&E&*+;+C+CIvO`O`+a&b&--/&*6+=+=&>Aa&a!#jj5:=((7!+t4 d,0,<,<_=Q=Q=S,TM(+

(8(8(:I5@8TaSb3cGMM%0d >>&)!&ll3?"#5}9klol{l{k|7}}5(+CIIcN1,<,=(>(0\\,1M(,(8(8(E1<]O8TaSb/ce,$(G9D8VVWXeWf)g$h	!)U3 2rHHS[[12#jj3:=((7 >>,/!*,&&1JBPS*T(.(8(8(I#jjM)BC:=((7 !N2E,u4F%"_4E*U2EV*E,F#(6> (!11++uz>C"2U":K,Ec+..F,17"g&-3HB-h';;w',@GGDT,T"&,,v=_,"`K ,!!--!I  &&y1((56@	6 @	6fd d % !,,[-=-=>))Ik]Bq*rs ! 2 2 % ! $S 1'.0b&c'h,,U3)),xz!$rstru"vw !  % ! $S 1'.0b&c'h,,U3))*st!$mnomp"qr !w@	6 @	6s   L]46,Y"AX>1Y9]4B9ZZ (Z]4A\9B]4]4A]4>YY=Z]4Z]4ZZ	\%A\ :]4 \]4	]1A],&]4,]11]44]=c                    | j                  d      D ]8  }| j                  dddd      }|j                  j                  d      }|dk(  rd	|j                  d
<   nh|dk(  rd|j                  d
<   nS|dk(  rd|j                  d
<   n>|dk(  rd|j                  d
<   n)|dk(  rd|j                  d
<   n|dk(  rd|j                  d
<   |j	                  | j                  dd             |j
                  j	                  | j                  ddd             |j                  d      }|o|j                  rcd|j                  j                  d<   d|j                  j                  d<   |j
                  j                  j                  |j                  d g       |j                  d!      }| j                  ddd"      }| j                  d#d$d%&      }|;|j                  r/|j                  |j                  D cg c]
  }|d'k7  s	| c}       |j                  |g       |j
                  j                  |g       |j                  |       ; yc c}w )(u   
        Подменяет инфопанели. Создает панели в виде table вместо div
        :param bs4.BeautifulSoup soup: Объект библиотеки
        :return:
        zak-editor-panelrx   tabler
   0)rl   cellpaddingcellspacingzdata-panel-typenotez/background: #eae6ff; border: none; padding: 0cmr~   infoz/background: #deebff; border: none; padding: 0cmsuccessz/background: #e3fcef; border: none; padding: 0cmalarmz/background: #feece5; border: none; padding: 0cmerrorwarningz/background: #fffae6; border: none; padding: 0cmtrzbackground: transparentr   tdtopz1width: 36px; orphans: 0; widows: 0; margin: 0.2cm)valignr~   zak-editor-panel__iconN	absmiddlealignborder zak-editor-panel__contentz$orphans: 0; widows: 0; margin: 0.2cmfont3zfont-size: 12pt)r   r~   
)r   r   rn   ro   r   r/  r   rp   r0  r   r   r   )	r   r   r%  
panel_typeiconpanel_contenttd_tagtag_fontr   s	            r,   r   z,CmfPluginConvertMixin._handle_html_infopanel  s    ]]*;]< #	&ELLCUXLYE):;JV#'XG$v%'XG$y('XG$w&'XG$w&'XG$y('XG$LLd2KLMHHOODLLe/b ) d e ::%<:=DDHH*5w'+.x(""DHHc?3!JJ.HJIM\\$u<b\cF||F<M|NH(]-C-CM,B,B Pqa4i PQMM8*%HHOOVH%u%G#	&> !Qs   7
I
I
c           	         dd l }	 i dddddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&}|j                  d'      D ]  }i }|j                  d(d)*      }|r|j                  |       |j	                  d+d,      j                  d-      D ]:  }|s|j                  d.      \  }}	|	j                         ||j                         <   < |j	                  d/      r|j	                  d/d,      t        kD  rH|j	                  d/t              }
|j	                  d/t              t        k  r|
|d/<   n
t         |d/<   d,|d+<   |j	                  d0      sd1|d0<   |j	                  d2      sd1|d2<   |j	                  d3      sd4|d3<   |j	                  d5      s|j	                  d5d6      |d5<   i }|j                  g }| j                  |j	                  d/            }
t        |j                  j                  d7            }t        |j                  j                  d89      D ]  \  }}i }t        ||j                  j                         s)|j"                  j	                  d+d,      j                  d-      D ]:  }|s|j                  d.      \  }}	|	j                         ||j                         <   < |j	                  d/      x}	r| j                  |	      }|||<   |
|z  }
d ||<   |j%                  |        t        |      dkD  r|
t        |      z  }|D ]  }|||<   	 |j                  j'                          t)        t+        |j-                                     }|j                  d:      D ]k  }d8}d}| j                  |j	                  d/            }
|j                  d;d<g      D ]  }i }d=|d3<   |j/                  d>      r/|j"                  j	                  d>      }|j	                  |      |d?<   |j	                  d+d,      j                  d-      D ]:  }|s|j                  d.      \  }}	|	j                         ||j                         <   < |t        kD  rd@}n|s8|j	                  d/      xs |j	                  d/      x}r{| j                  |      }ni|j	                  |      }|j	                  dA      }|r@|r>t1        |d8z   t3        |      |z         D ]  }|kD  r n
|||   z  } |t3        |      z  }n|d8z  }|ry|j                         }dB}|D ]+  }|j4                  st7        |j4                        dCk7  s)|} n | dD|d/<   |
|z  }
|j                  dE      D ]  }| j9                  ||        |d8z  } |dkD  s|
|z  }|j                  d;d/d iF      D ]2  }| dD|d/<   |j                  dE      D ]  }| j9                  ||        4 n  y )GNr   zLight greenz#e3fcefz
Light tealz#e6fcffBluez#b3d4ffzLight yellowz#fffae6z	Light redz#feece5zLight purplez#eae6ffz
Light grayz#f4f5f7Tealz#b3f5ffGreenz#abf5d1zDark yellowz#ffc400Yellowz#fff0b3Redz#ffbdadPurplez#c0b6f2Grayz#b3bac5z	Dark Bluez#4c9affz	Dark tealz#79e2f2z
Dark greenz#57d9a3z#ff8f73z#998dd9)zDark redzDark purpler%  r   ztableView-content-wraprx   r~   r_   ;:rl   r'  r&  r(  bordercolorz#eeeeeer5  1colr{   )startr/  r0  thnonezdata-highlight-colorbgcolor   colspan
   z[<br/>]ra   rp   r   )r   r   r   r   ro   r   re   FULL_SCREEN_VALUErc   colgrouprj   r   	enumeratechildren
isinstanceelementTagrn   r   r   roundsumvalueshas_attrrangeintr   r   ru   ) r)   r   r   cell_colorsr%  style_table_dictr   paramsr   r   table_width
cols_widthcol_without_width	col_countcol_numrK  style_col_dictwidth_pxccols_sumr/  	nums_cols
table_celltd_styletable_cell_color_nametd_widthrQ  itable_cell_childrentable_cell_widthtable_cell_childrp   s                                    r,   r   z(CmfPluginConvertMixin._handle_html_table  s   	
9
)
 I
 I	

 
 I
 )
 I
 Y
 9
 i
 9
 i
 I
 
  !
" )#
$ "$'
* ]]7+ k	HE!&&u5M&NF##E*))GR066s; C"(,,s"3KD%5:[[]$TZZ\2C 99W%7B)?BS)S.227<MN#''1BCGXX%0E'N(8'9E'N!#g99]+'*m$99]+'*m$99]+'0m$99X&"2"6"6x"EhJ~~)$&!"77		'8JK 7 7 >?	$-enn.E.EQ$O :LGS%'N%c3;;??; "%))--"<"B"B3"G I!*0,,s*;KD%;@;;=N4::<8I !/ 2 27 ;;u;#'#<#<U#C.6
7+#x/.2
7+)009: ()A-*S1B-CCH. 1(0
11((*S!2!2!456HnnT* 5H	"77		'8JK"$++tTl"; ('J!H06J}-"++,BC0:0@0@0D0DE[0\-0;@U0V
9-",..""="C"CC"H C!*0,,s*;KD%5:[[]HTZZ\2C !#33#%''/||G'<'W
w@WW8W'+'@'@'JH#->>'#:",..";#%*7Q;Gw8N%O :#$y=$) (JqM 9: $s7|3G#qLG.8.A.A.C++-(0C &,/88SAQAZAZ=[_h=h3; 0 %&
 2B0B".E
7+#x/#-#6#6u#= HC 88hGH "Q	Q('T q=*Y6H&(kk$wok&N H
19
"o
7+#-#6#6u#= HC 88hGHHe5Hmk	HrD   c                    ddl m} | j                  dddi      D ]  }d|d<   d|_        | j	                  d	      }|j
                  D cg c]  }t        ||      s| }}t        |      }t        d
|z  d      }|D ]2  }d|_        |j                  d| d      |d<   |j                  |       4 |j                  |        yc c}w )u   
        Функция добавляет стиль для макета, используем table, так как flex не поддерживается в LibreOffice

        :param bs4.BeautifulSoup soup: Объект библиотеки
        r   )rY  r   zdata-layout-sectiontruer
   rl   r%  r/  r^   r   r0  zdata-column-widthr]   N)r   rY  r   r   r   rV  rW  r   rZ  ro   r   )	r   rY  layoutr/  elcolumnsrl  width_columncolumns	            r,   r   z)CmfPluginConvertMixin._handle_html_layout  s     	mmE,A6+JK 	F$F7O!FKd#B$*OOKbz"c7JrKGKGI y!4L! """(**-@\NRSBT"Uw		&!" MM"	
 Ls   	CCc                 V    | j                  ddg      D ]  }|j                           y)u   
        Метод очищает HTML от лишних тегов

        :param bs4.BeautifulSoup soup: Объект библиотеки
        ztable-context-menuzcell-dropbox-buttonrx   N)r   r   )r   tags     r,   r   z(CmfPluginConvertMixin._handle_html_clean  s.     ==)=?T(U=V 	CMMO	rD   tmp_pathc           	      l
   ddl m}m} ddlm}  ||       }g }|j                  d      D ]g  }d|j                  j                  dd      v r|j                  t        |d	             |j                  j                  d
      rYd|j                  d
<   i |j                  d      D ]  }|j                  t        |d	               |j                  d      D ]  }|j                           |j                  d      D ]  }|j                           t        |      D ]  \  }}	|	d   }|j                  j                  dd      }
|j                  j                  dd      }|j                  j                  d      }|j                  d      r|j                  d      \  }}|j                  dd      }|j                  dd      }t        |      d| d| z  }t!        |d      5 }|j#                  t%        j&                  |             t)        |      |j                  d<   ddd       |j                  d      rt+        j,                  |      }t.        j0                  j                  ddt2        j4                  gdg      }|rt        |j6                        }n)t        |j                  dt2        j4                              }|j9                         r:t)        |      |j                  d<   |
s |j!                  |      }|j:                  \  }
}d }t=        dj?                  d! t)        |
      D                    }|j                  d"      r3t        t2        j@                        d#z  }|jC                  d$      d%k(  rtE        |      n|jC                  d$      }||jC                  d      | }tG        j                  |      }|jH                  d&k(  rt        |      }|d'| | z  jK                         }t!        |d      5 }|j#                  |jL                         ddd       	 |j!                  |      }|j:                  \  }
}t)        |      |j                  d<   |r|n|
r|
n|}nt)        |      |j                  d<   ||kD  r|n|}|so||z  r||z  nd(}||j                  d<   t=        dj?                  d) t)        |      D                    } t=        | |z        |j                  d<    t)        |      S # 1 sw Y   xY w# 1 sw Y   xY w# |$ r t)        |      |j                  d<   Y w xY w)*u   
        Функция заменяет адрес картинки, файла на фактический

        :return: HTML с фактическими адресами картинок, файлов
        r   )r   UnidentifiedImageErrorr   azcmf-fileclassr_   file)objr   hrefrp   imager~   titler  rl   rm   r   r   r   r   z;base64file_r   wbNr   r(   r   r   r   i  c              3   B   K   | ]  }|j                         s|  y wNisdigit.0rx  s     r,   	<genexpr>z:CmfPluginConvertMixin._handle_view_html.<locals>.<genexpr>  s     &Ob"**,r&O   r   r   ?r   name_r{   c              3   B   K   | ]  }|j                         s|  y wr  r  r  s     r,   r  z:CmfPluginConvertMixin._handle_view_html.<locals>.<genexpr>  s     +U2

B+Ur  )'r   r   r  r   r   r   rn   ro   r   dictr   rU  r   r   rf   r   r   r
  rX   r  r   r   r   r!   r"   r   r   r   r  r   r_  joinr  r  r   r  r  resolver   )!rG   r~  r   r  r   r   filesr  index_filerl   rm   full_urltype_imgb64data	name_filefile_imgurl_pathr+   attachment_pathrp   width_defaultwidth_valuepath_defaultend_namefile_extensionresponser  filepathr  	width_newr!  height_values!                                    r,   rL   z'CmfPluginConvertMixin._handle_view_html  s    	6%Y'==% 	'CSYY]]7B77Tc7899==($&		&!	' ==' 	6CLL#G45	6 ==) 	CMMO	 ==) 	CMMO	 &e, <	FLE5,CIIMM'1-EYY]]8Q/Fyy}}U+H""<0$,NN3$7!'#++M2>#++Ir: NuUG1XJ-GG	)T* 6hNN6#3#3G#<='*9~CIIe$6 ""9- ==2#1155eT6K\K\=]gjfk5l
&*:+D+D&EO&*8+;+;IvGXGX+Y&ZO"))+'*?';CIIe$ #jj9(+vMbgg&OCJ&OPQK""6*#F$6$67:ZZ,4NN3,?2,E3x=8>>Z]K^!)(..*=h!G#<<1''3."8nG 'E%8H*I IRRTHh- 5

8#3#345=#jj2(+v+.x=		%(5@kPUu[h (+<'8CIIe$)4})D+I9B[9Pi+5VW%.		'""277+UV+U#VW&),*D&E		(#y<	F| 4yg6 6<5 5 2 =+.|+<		%(=s+   %=S:?T$AT:T	T	T32T3c           	      n   ddl m}m} ddlm} t        j                  d||f      }t        j                  j                  t        j                  j                  t        j                  j                  t              dd            }t        j                  j                  |ddd	d
dd      } |       }d|_        |j                          |j                  dd|       |j!                  d        ||      }|j#                  d      D ]  }	d|	j$                  d<    |j#                  d      D ]   }	d|	j$                  d<   d|	j$                  d<   " t'               5 }
|j)                  | j+                  |j-                         |
             t/        |j1                               cddd       S # 1 sw Y   yxY w)uw   
        Конвертирует HTML -> PDF

        :return: Возвращает байты PDF файла
        r   )FPDF	HTMLMixinr   	_HTML2PDF)basesz..modulesappassetsfontsz	noto-sanszNotoSans-Regular.ttfr1   NotoSansr_   r%  r
   rl   r0  100rJ  rQ  N)fpdfr  r  r   r   types	new_classosr   abspathr  dirname__file__core_fonts_encodingadd_pageadd_fontset_fontfindAllrn   r   
write_htmlrL   prettifyr=   output)r)   rG   r  r  r   r  	path_fontr8   r   r  rT   s              r,   html_to_pdfz!CmfPluginConvertMixin.html_to_pdf  sT    	)%OOKi7HI	GGOOBGGLL1JDRV$WX	GGLLIuhQ\^tu	k")ZY/Z Y'<<( 	(C!'CIIg	(<<% 	'C!&CIIg#&CIIi 	'  ! 	'\NN411$--/<PQ&	' 	' 	's   AF++F4	path_docxc                     ddl m} t        j                  j	                  |      r*t        |d      5 } ||      }|j                  cddd       S y# 1 sw Y   yxY w)u7   
        Конвертирует DOCX -> HTML
        r   )convert_to_htmlr   N)mammothr  r  r   r  r   r   )r)   r  r  rU   results        r,   docx_to_htmlz"CmfPluginConvertMixin.docx_to_html  sS    
 	,77>>)$i& $)(3||$ $ %$ $s   AApath_imgrB   c                 0    t        j                  | |       yu5   
        Конвертирует PDF -> PNG
        N)r	   pdf_bytes_to_imgr  rB   s     r,   r  z&CmfPluginConvertMixin.pdf_bytes_to_img&  s    
 	x3rD   path_pdfc                      yr   )r  r  s     r,   
pdf_to_imgz CmfPluginConvertMixin.pdf_to_img-  s     	rD   	path_htmlc                     t         j                  j                  |      rHt        |d      5 }| j	                  |j                               }| j                  ||       ddd       yy# 1 sw Y   yxY w)u6   
        Конвертирует HTML -> PNG
        rr  N)r  r   r  r   r  r  r  )r)   r  r  	file_htmlrB   s        r,   html_to_imgz!CmfPluginConvertMixin.html_to_img5  sn     77>>)$i% N ,,Y^^-=>	%%x9%MN N %N Ns   3A))A2	path_xlsxc                 "    ddl m }  |||       y)u7   
        Конвертирует XLSX -> HTML
        r   	xlsx2htmlNr  )r)   r  r  r  s       r,   xlsx_to_htmlz"CmfPluginConvertMixin.xlsx_to_html>  s    
 	()Y'rD   path_pngc                 T    ddl m} |j                  |      }|j                  |       y)u<   
        Сохранение в формате PNG
        r   r   N)r   r   r   r&   )r)   r  r  r   rp   s        r,   save_imgzCmfPluginConvertMixin.save_imgF  s!    
 	jj"rD   c                    ddl m} ddlm} ddlm ddlm  ||dd      }|j                         }|j                         }t        t        |            D ]  }|j                  ||         }	|dk(  r|j                  }
||   |
_        n|j                  ||         }
|	j                  D ]$  }|\  }}}}|
j                  |d	z   ||d	z   |
       & fdt        |	j                         D ]<  }|
j#                  fd|	j%                  ||	j'                  |            D               >  |j)                  |       y)u6   
        Конвертирует XLS -> XLSX
        r   )workbook)open_workbook)XL_CELL_DATE)xldate_as_tupleT)formatting_inforagged_rows)r  r{   )	start_rowend_rowstart_column
end_columnc                     | j                   }| j                  k(  r0 |d      }|dd dk(  rt        j                  |dd   }|S t        | }|S )Nr   r   )r   r   r   )r   ctyper   time)cellr   datetime_tupr  r  s      r,   _get_xlrd_cell_valuez?CmfPluginConvertMixin.xls_to_xlsx.<locals>._get_xlrd_cell_valuei  s`    

::-#25!#<L#Aa(I5 (|AB/? @  !), 7rD   c              3   .   K   | ]  } |        y wr  r  )r  r  r  s     r,   r  z4CmfPluginConvertMixin.xls_to_xlsx.<locals>.<genexpr>t  s      # ).#s   )end_colxN)openpyxlr  xlrdr  r  r  Workbooksheet_namesr^  r   sheet_by_nameactiver  create_sheetmerged_cellsmerge_cellsnrowsr   	row_slicerow_lenr&   )r)   path_xlsr  r  r  book_xls	book_xlsxr  sheet_index	sheet_xls
sheet_xlsxcrangerlorhiclochirowr  r  r  s                    @@@r,   xls_to_xlsxz!CmfPluginConvertMixin.xls_to_xlsxO  sO   
 	&&%( 4TR%%'	**, [!12 	K ..{;/GHIa&--
#.{#;
 &33+k:R3S
#00 O%+"S#s&&q#47!G ' OO
 Y__- !! # ) 3 3C)BSBSTWBX 3 Y# -	6 	y!rD   dataoutput_pathsuffixc                      y)u(  
        Конвертация данных в PDF через libreoffice
        :param data: Данные файла в виде байт
        :param output_path: Путь сохранения итогового pdf файла
        :param suffix: Расширение файла
        Nr  )r  r  r  s      r,   
obj_to_pdfz CmfPluginConvertMixin.obj_to_pdfz  s     	rD   mimetypec                 R   ddl }ddlm} | j                  ||d|      }|j	                         5 }t        |      dz  }t        |d      5 }	|	j                  |       | j                  t        |            }
ddd       ddd       |j                  
d      j                  d	d
      }|j                  dd      } ||      }|j                  d      }|r|j                  d      }|r|j                         }|j                  d      D ]v  }|j                  dd      }d}|d   D ]O  }|j                  d|       }|||d j                  d      z   dz   }|||d j                  d      z   }|||| z  }Q || z   |d<   x t        |      S # 1 sw Y   xY w# 1 sw Y    xY w)u  
        Конвертация данных в HTML через libreoffice

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

        :return: Строка HTML
        r   Nr   r@   z	file.htmlr  ignore)errors u   �u   r_   r   r~   Trx   r  r   {r{   })r   r   r   r<   r   r   r   r
  get_encoding_typer   rZ   rf   r   get_textr   ro   )r)   r  r  r  r   r   
bytes_htmlr~  full_path_htmlr  r3   rG   r   r   r~   
style_textr}  	style_tagstyle_class	class_tagstart_pos_classstyle_start	style_ends                          r,   obj_to_htmlz!CmfPluginConvertMixin.obj_to_html  s    	%''ffhG
((* 	Gh!(^k9Nnd+ Gy
+11#n2EFG	G %%hx%@HHQYZ	%%h3	Y'yy IIg&E"^^-
===5 @C # 4I"$K%(\ I	*4//Ai[/*J&5
?CS8T8Y8YZ]8^&^ab&b$3jAQ6R6W6WX[6\$\	#z+i'HH	I
 $-+#?CL@ 4y/G G	G 	Gs#   F
,F6FF	FF&	to_formatc                     	 t        j                  | |||      }|S # t        $ r}t        j	                  |        d}~ww xY w)u*  
        Конвертация данных в HTML через libreoffice
        :param data: Данные файла в виде байт
        :param suffix: Расширение файла
        :param to_format: Формат файла который хотим получить
        N)r	   r<   r   r#   debug)r  r  r(  r  converted_dataerrs         r,   r<   z#CmfPluginConvertMixin.obj_to_format  sE    	"00vy(SN
 	  	GGCL	s    	A ;A 	path_filec                 "   ddl m}  |       }t        | d      5 }|D ]=  }|j                  |       |j                  s!|j
                  j                  d      s= n |j                          ddd       |j
                  j                  d      }|sSg d}|D ]J  }	 t        j                  | d|      5 }|j                          |j                  d       |}	 ddd        |S  |S # 1 sw Y   {xY w# 1 sw Y   nxY wh# t        $ r d	}Y uw xY w)
u   
        Определяем кодировку файла

        :param path_file: Путь к файлу
        :return: Кодировка файла
        r   )UniversalDetectorr   r3   N)r1   zwindows-1251zwindows-1250zwindows-1252asciiz
iso-8859-1latin1r  r2   r1   )chardet.universaldetectorr/  r   feeddoner  ro   closerN   	readlinesrP   UnicodeDecodeError)r-  r/  detectorr  liner3   	encodingsformat_encodings           r,   r  z'CmfPluginConvertMixin.get_encoding_type  s    	@$&)T" 	d d#==X__%8%8%D NN	 ??&&z2rI#, 	''C/J d(		!#2	  	' +	 	  
 * '&H's@   #C'C'C'D 4%C3D 'C03C<	8D  DDc                 |   ddl m} | j                  dg        || j                  j                  xs d      }|j                  d      }|j                  dd      }d	|_        |j                  j                  d|       |j                  j                  j                  |       |j                  d
      D ]"  }|j                  |j                  d             $ |j                  d      D ];  }t        |j                        dk  s|j                  |j                  d             = | j                  |       | j!                  |       | j#                  |       | j%                  |       | j'                  |       | j)                  |       | j+                  |       | j-                  |       t/        |      S )Nr   r   r   <p></p>r   r~   r   r   zg@page { size: 21.0cm 29.7cm } td,th { padding: 0.45cm; } td p,th p { margin: 0;word-break: break-all; }rw   rx   rz   r{   r|   )r   r   r   r   r   r   r   r@   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r)   r   r   head_tagr!  r   rz   s          r,   prepare_document_to_docxz.CmfPluginConvertMixin.prepare_document_to_docx  ss   %-)T--33@yA <<'LLzL:	 E			H%		i(MMM8 	1Ddll3/0	1 s# 	-A1::"d+,	- 	&&t,""4($$T*d###D)  &%%4yrD   c                 \    | j                  dg       | j                  rt        dd       y y )Nperm_encryptu`   Зашифрованный документ не может быть экспортирован.T)abort)r   rA  r:   )r)   s    r,   check_encryptz#CmfPluginConvertMixin.check_encrypt  s4    .)*x  AE  F rD   c                     | j                          | j                         }| j                  t        |d      dd      }| j                  |dd      }| j	                  |d      }|S )Nr1   r2   r4   r5   r6   r7   r8   rC  r?  r<   r=   r-   )r)   prepared_htmlrA   rB   rC   s        r,   r   z#CmfPluginConvertMixin.export_to_pdf  sf    557''mg(NPWYpq
&&z7<ST	..y%@rD   c                     | j                          | j                         }| j                  t        |d      dd      }| j	                  |d      }|S )Nr1   r2   r4   r5   rF   rE  )r)   rF  rA   rC   s       r,   r   z$CmfPluginConvertMixin.export_to_docx  sQ    557''mg(NPWYpq
..z6BrD   c                 v   | j                  ddg       ddlm}  || j                  j                  xs dd      }|j                  d      }| j                  j                  |_        |j                  d|       | j                  |       |j                  dd	d
i      }|j                  |       t        |      S )Nr   projectr   r   r=  r   h1r   r~   zpage-break-after: always;r   )r   r   r   r   r   r   r   r   r   r   r   r   )r)   r   r   name_tag	break_tags        r,   prepare_document_to_exportz0CmfPluginConvertMixin.prepare_document_to_export  s    -34%T--33@y-P<<%))//Ax d#LLw8S.TLU	I4yrD   c                    dg}|D ]  }t        |      }|j                         D cg c](  }t        |      j                  d      st        |      * }}|D ]d  }t	        |d      5 }|j                         }|j                  d      }	||	_        |j                  j                  j                  |	       d d d        f  |S c c}w # 1 sw Y   yxY w)Nz&/opt/eva-app/dist/cmf-angular/tinymce/z.cssr  r~   )r   iterdirr   rb   r   r  r   r   r@   r   r   )
clsr   foldersfolder_namefoldercss_filecss_listr  csscss_tags
             r,   _append_css_tagsz&CmfPluginConvertMixin._append_css_tags'  s    ;>" 
	3K+&F6<nn6Fi(#h-J`J`agJhHiHi$ 3(C( 3D))+C"ll73G%(GNIINN))'23 33	
	3  j3 3s   CC&ACCc           
      H   ddl m} dd l}t        j	                         5  t
        j                  j                  d       t
        j                  j                  j                          d d d         || xs dd      }|j                  d      }|j                  j                  d|       |j                  ddd	i
      }|j                  j                  j                  |       t
        j                  j!                  |      }d|j                  j"                  j$                  d<   t'               5 }|sd}| d}| d| d}	t)        |d      5 }
|
j+                  t-        |             d d d        |j/                  dddddd|	 | gd      }t
        j1                  t2        j4                  | d      }t)        |	d      5 }|j7                  |dd       |j9                          d d d        t        j	                         5  t
        j                  j;                  |       d d d        t
        j<                  j?                  t2        j4                  d|dd        d d d        y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   jxY w# 1 sw Y   y xY w)!Nr   r   i,  r=  lxmlr   r   r   r1   r   z%mce-content-body mce-content-readonlyr  exportz/export.htmlr   z.pdfwchromiumz
--headlessz--disable-gpuz--no-pdf-header-footerz--no-sandboxz--print-to-pdf=T)checkr   r   F)backupr   u&   Закончен экспорт в PDFuf   Файл доступен для скачивания в разделе "Фоновые задачи".)personr   r  force_notify_current_personmsg) r   r   
subprocessr   r%   r!   CmfDeferredJobset_estimate_durationdpcommitr   r@   r   r   r   r   rX  r   rn   r   r   r
  r   runr"   r#   r$   upload_stream_filer&   set_result_attachment	CmfNotifyplace_notify)r@   r*   r   rc  r   r>  charset_tagr  html_file_namepdf_file_namer  proc
new_attachfs                 r,   _export_html_to_pdfz)CmfPluginConvertMixin._export_html_to_pdf8  sl   %   " 	.!!77<!!$$++-	. T.Y7<<' 			H%ll6)W1ElF		k*!!2248(O		W%! #	W$	 'y5N&iq48Mnc* &d

3t9%& >> #,"%m_5%& " " #D  --Q^^YKW[J\-]JmT* "a--aE-R!" $$& H%%;;JGH ))~~=,0| * ;#	 #	%	. 	.2& &" "H H5#	 #	sa   AI&/JI3(AJ%J 'J J#:J&I03I=	8J J		JJ	JJ!Fc                 v   d}|
t               }|r| g| j                  j                         z   }n| j                  j                         }t        |d       }t	        |      D ]  \  }}|j
                  j                  d      s|j
                  j                  d      r|j
                  j                  d      rX||vr|j                  |       no|j
                  j                  d      r&	 |j                  d       ||j                         z  }||j                  |	      z  } |S # t        $ r Y $w xY w)
Nr_   c                 6    | j                   j                         S r  )ordernoload)xs    r,   <lambda>z;CmfPluginConvertMixin.collect_html_nested.<locals>.<lambda>  s    !))..2B rD   )keyCmfDocument:z
CmfFolder:zCmfProject:TTEXKOM_skip_failread_audit)	processed)r   
tree_nodesrw  sortedrU  r   r   r   _acl_check_readrM  CmfPermissionErrorcollect_html_nested)r)   export_selfr~  	html_bodynodessorted_nodesrq  nodes           r,   r  z)CmfPluginConvertMixin.collect_html_nestedu  s)   	IFT__1133EOO((*Ee)BC . 	GGAtGG&&~6$'':L:L\:Zww))-89$d#ww!!.1((D(I!@!@!BBI
 11I1FFI%	G(  * s   .%D,,	D87D8u   Экспорт PDF-файлаT)descriptionshow_bg_progressbar
system_jobc                     t         j                  |       }|j                  d      }t        j                  j                  ||j                         y)u\   
        Выгружает объект и всех его потомков в pdf
        T)r  )r*   N)r   get_obj_by_idr  r!   r   rs  r   )obj_idr  html_nesteds      r,   r   z(CmfPluginConvertMixin.export_tree_to_pdf  sD     ##F+--$-?..{chh.OrD   c                    d}| D ]R  }|j                  d      st        j                  |      }|s-	 |j                  d       ||j	                         z  }T t        j                  j                  |       y# t
        $ r Y w xY w)u   
        Выгружает все объекты из списка в pdf
        obj_list -- список id выгружаемых объектов
        r_   r{  Tr|  N)	r   r   r  r  rM  r  r!   r   rs  )obj_listr@   r  r  s       r,   r   z,CmfPluginConvertMixin.export_obj_list_to_pdf  s      
	F$$^4''/C''4'HC::<<D
	 	..t4 * s   %A::	BBr  )r.   N)r_   )FN)3__name__
__module____qualname____doc__api_methodsr=   r   r-   r   r   rV   staticmethodr[   rd   rj   ru   r;   r   r   r   r   r   r   r   r   r   rL   r  r  r  r  r  r  r  r  r  r'  r<   r  r?  rC  r   r   rM  classmethodrX  rs  r  cmf_deferred_jobr   r   r  rD   r,   r   r      s   
K 3 $c  s (c (e (( 2U 2s 2 2 C E  " F F"0c 0dB & && s  -+^I6V )& )&VHHT  ,   YS YC YC Y Yv'S 'U '>	$c 	$c 	$ 43 45 4T 4 4 S C D  NS NC ND N(c (c (d (   )"V  S # $  & &s &c &3 &P E 3 3 # W\   S S  B!# !FF
# $    :S : :x D "AW[hmnP o P "AW[hmn5 o 5rD   r   )rX   hashlibrN   pathlibr   r   r   typingr   urllibr   r   r  r  cmf.includerdiskr	   r   rc   rh   rg   rS  r   r  rD   r,   <module>r     s[      	  '          // \5 \5rD   