
    ntki}`                     z    d dl Z d dlZd dlmZ d dl d dlmZ d dlmZ d dl	m
Z
  G d de
j                  e      Zy)	    N)Path)*)cmf_hashlib)CmfPluginConvertMixin)cmf_attachmentc                       e Zd Zej                  j
                  j                  dz   Zej                  j                  e
j                  z   g dz   Z	 fdZdefdZdefdZd Zd	efd
Zd	edefdZd Zd Z fdZd Zd Zd Zd Z fdZe edd      d               Zed        Z dddZ!edefd       Z"dddddde#fdZ$d  Z%d! Z&d" Z'd9d#Z(ede)fd$       Z*edefd%       Z+d& Z,dd' fd(
Z-d) Z. fd*Z/d:d+Z0 fd,Z1 fd-Z2 fd.Z3d/ Z4d0 Z5d1 Z6d2 Z7 fd3Z8 fd4Z9e:d;d5       Z;e eddd67      d8               Z< xZ=S )<CmfAttachment)file_exists)upsertget_fullviewgen_url_for_webdavget_versionsremove_versionget_url_fileget_local_urlmark_viewed
public_getpublic_createpublic_get_rfilepublic_get_versions
api_create
api_update
api_deletec                 2    d | _         t        |   |i | y N)content_updatedsuper__init__selfargskwargs	__class__s      (./modules/files/models/cmf_attachment.pyr   zCmfAttachment.__init__!   s    #$)&)    returnc                     | j                  ddg       | j                         }|st        d       g S |j                         S )Nst_sizecmf_modified_at   DEV: Не найден Rfile, вероятно не найден файл в хранилище /files для текущего CmfAttachment)load_fields	get_rfile	cmf_alertr   r    rfiles     r$   r   zCmfAttachment.get_versions%   sH    )%678   e  fI!!##r%   versionc                f    | j                         }|st        d       y  |j                  |d|i|S )Nr*   r0   )r,   r-   r   )r    r0   r!   r"   r/   s        r$   r   zCmfAttachment.remove_version/   s@       e  f#u##TE7EfEEr%   c                 j    | j                         }|st        d       y  |j                  |g|i |S )Nr*   )r,   r-   r   )r    editorr!   r"   r/   s        r$   r   z CmfAttachment.gen_url_for_webdav7   s@       e  f'u''@@@@r%   os_typec                 b    | j                         }|st        d       y |j                  |      S Nr*   )r4   )r,   r-   r   r    r4   r/   s      r$   r   zCmfAttachment.get_url_file?   s7       e  f!!'!22r%   c                 b    | j                         }|st        d       y |j                  |      S r6   )r,   r-   r   r7   s      r$   r   zCmfAttachment.get_local_urlG   s7       e  f""7"33r%   c                     | j                   j                  sy t        j                  j	                  | j                   j
                        d   }d}t        |      |k  r|| _        y y )N       )	file_name
is_changedospathsplitextvaluelen	file_type)r    	extensionext_max_lengths      r$   _calc_file_typezCmfAttachment._calc_file_typeO   sR    ~~((GG$$T^^%9%9:1=	y>^+&DN ,r%   c                     t        | j                  j                  t        j                        r1| j                  dg       | j                  j                  rd| _        y y y )Nzparent.privateT)
isinstanceparentrA   models
CmfCommentr+   privater    s    r$   _calc_privatezCmfAttachment._calc_privateX   sL    dkk''):):;./0{{""# # <r%   c                 *    t         |          g dz   S )N)urlurl_previewurl_preview_imgrI   embedded)r   save_preload_fields)r    r#   s    r$   rT   z!CmfAttachment.save_preload_fields^   s    w*,/nnnr%   c                 H   | j                   j                          | j                   sy t        j                  j	                  t
        j                  | j                   j                               }t        j                  j                  |      st        j                  |       |S r   )
rI   loadr>   r?   joinconfig
UPLOAD_DIRget_files_direxistsmakedirs)r    
upload_dirs     r$   r]   zCmfAttachment.upload_dira   se    {{WW\\&"3"3T[[5N5N5PQ
ww~~j)KK
#r%   c                    | j                   rd| _        y t        j                  j                  j
                  j                         }|j                  | j                        }|j                  r|j                  | _        y d| _        y )Nr   )
is_newr(   rJ   CmfRFiledpdata_driverget_rdr,   
_file_namer[   r    rdiskr/   s      r$   _calc_st_sizezCmfAttachment._calc_st_sizej   s\    ;;DL""..5570<< ==DLDLr%   c                    | j                   ry t        j                  j                  j                  j                         }|j                  | j                        }|j                  r"t        j                  j                  | dd       y y )N
attachment
after_save)r_   rJ   r`   ra   rb   rc   r,   rd   r[   CmfAutomationCrudTrigger	crud_hookre   s      r$   _call_automation_hookz#CmfAttachment._call_automation_hookv   s`    ;;""..5570<<++55dL,W r%   c                     | j                   r4t        j                  | j                        }|r|j                  | _        y y y r   )r_   APPget_cache_project
project_iddefault_attach_full_search_typefull_search_type)r    projects     r$   _calc_full_search_typez$CmfAttachment._calc_full_search_type   s8    ;;++DOO<G(/(O(O%  r%   c                    | j                          | j                          | j                          | j                          | j	                          t        |   |i |}t        j                  j                  |        | j                          | j                  r0t        t        j                  j                  | j                  g       |S )N)r!   )	_calc_urlrF   rg   rN   ru   r   saverJ   CmfBackbonePeerobj_after_save_hookrm   r_   schedule_deferred_jobr	   extract_text_from_attachid)r    r!   r"   resr#   s       r$   rx   zCmfAttachment.save   s    ##%glD+F+2248""$;;!&"6"6"O"OW[W^W^V_`
r%   T)	only_once
system_jobc                    dd l }ddlm} t        j                  j                  | g d      }d}d}|j                         }|j                  dv rt        j                  j                  j                  j                         }d}d	}|j                  j                  d
      rBdj                  t         ||j                  j                               j"                  dd        }n ||j                  j                         }|j                  |      }n$|j                  dk(  rd}d	}n|j                  dv rny t%        |j&                  |      5 }	|r|	j)                         }
n7|j+                  |	      }d}
|j,                  D ]  }|
|j/                         z  }
 d d d        
d d |_        |j3                  d       y # 1 sw Y   &xY w)Nr   )unquote)rQ   rC   full_file_pathr/   r}   fieldsTr)z.docz.docxz.dotz.dotxz.docmz.dotmz.rtf.pdfz.xpsz.fdfz.xlsz.xlsxz.xlsmz.pptz.pptxz.odpz.odsFrb/files/   r   )z.txtz.csvz.mdz.html i )	only_data)PyPDF2urllib.parser   rJ   r	   getr,   rC   r`   ra   rb   rc   rQ   
startswithrW   r   rA   partsopentmp_readonly_pathread	PdfReaderpagesextract_texttextrx   )	attach_idr   r   attach
force_readmoder/   rf   r?   filer   readerpages                r$   r|   z&CmfAttachment.extract_text_from_attach   s    	(%%))Y?v)w 
  "  A A OO&&2299;EJD!!,,X6xxWV-?-?-E-E%F G M Mab QRv11778OOD)E'JD!AA %))40 	0Dyy{))$/"LL 0DD--//D0	0 7Fmd#	0 	0s   AF;;Gc                 >    | j                          | j                   S r   )r]   r<   rM   s    r$   	file_pathzCmfAttachment.file_path   s      //#$T^^$455r%   Nr   c                   | j                   j                  s| j                  j                  sy t        j
                  j                  dt        j                  j                  | j                              | _        t        j
                  j                  | j                   dd      | _        t        j
                  j                  | j                   dd      | _        y )Nr   z.metazpreview.pdfzthumbnail.jpg)r<   r=   rP   is_nullr>   r?   rW   urllibparsequoterd   rQ   rR   )r    r   r!   r"   s       r$   rw   zCmfAttachment._calc_url   s    ))TXX-=-=77<<&,,*<*<T__*MN77<<488*E(:MJ!ww||txxj,>Pr%   c                 `    t        t        t        j                  | j                  z               S )u<    Полный фактический путь к файлу )strr   rX   rY   rd   rM   s    r$   full_path_filezCmfAttachment.full_path_file   s#     4))DOO;<==r%   Fbackupsmart_backupmake_preview
mark_dirtycontentc                .   t         j                  j                  j                  j	                         }|j                  | j                        }	|	j                  ddd       |	j                  |||||       d| _	        | j                          d| _	        y)u    Загрузка файла FT)is_direxist_okparentsr   N)rJ   r`   ra   rb   rc   r,   rd   createwriter   rx   )
r    r   r   r   r   r   r!   r"   rf   r/   s
             r$   upload_filezCmfAttachment.upload_file   s     ""..5570ED$?%%! 	 	
  $		$r%   c                 l    | j                         }|r|j                          yt        d|  dd       y)u   Делаем отметку в мете что эту версию файла менять нельзя поскольку она опубликована
        uW   При обработке документа обнаружен пустой файл: u   . Возможно, произошла ошибка при загрузке файла. Пожалуйста, загрузите файл повторно.FabortN)r,   
do_publishr-   r.   s     r$   r   zCmfAttachment.do_publish   sE      optou  vQ  R  Z_  `r%   c                 >   |j                  dt        d            }t        j                  j                  dt	                     j                  dt                     j                  d      }|r|dk  r| j                  j                  d      rt        j                  j                  j                  j                         }|j                  | j                        }|j                  s |j                  |i | y  | j                   |i | y  | j                   |i | y )N	file_sizeinfrf   uris3i )z/obj/zobj/)r   floatrX   data_sourcesdictr   r   rd   rJ   r`   ra   rb   rc   r,   r[   stream_writeupload_stream_file2)r    r!   r"   r   is_s3_primaryrf   r/   s          r$   upload_stream_filez CmfAttachment.upload_stream_file   s    JJ{E%L9	++//@DDUCER]]^bcY*49S9STe9fOO&&2299;EOODOO4E<<"""D3F3((($9&9$D$$d5f5r%   c                    | j                  d      }|si }t        j                  j                  |d<   t        j                  j                  |d<    |j
                  |i | d| _        | j                          d| _        y )NT)r   task_attachment_max_sizedocument_attachment_max_sizeF)r,   gglobal_settingsr   r   r   r   rx   r    r!   r"   r/   s       r$   r   z!CmfAttachment.upload_stream_file2  sv    d+F-.->->-W-W)*121B1B1_1_-.D+F+#		$r%   c              +      K   | j                         }|j                  |      }|r|d   }n'| j                  dg      j                  j                  }t	        |d      5 }| d d d        y # 1 sw Y   y xY ww)Nabspathr   r   )r,   get_versionr   rA   r   )r    r0   r"   r/   rfile_versionr   r   s          r$   get_contentzCmfAttachment.get_content  sr      ))'2#I.GnnYKn8@@FFG'4  	DJ	 	 	s   AA9A-$	A9-A62A9c                     t         j                  j                  j                  j	                         }|j                  | j                        }|j                  S r   )rJ   r`   ra   rb   rc   r,   rd   r[   re   s      r$   r
   zCmfAttachment.file_exists  s<    ""..5570||r%   c                     | j                  ddg       | j                  rLt        j                  j	                  | j                  j                         | j                  j                        S t        dd       y)uT    Имя файла вложения в зависимости от родителя rI   r<   u   Вложение должно быть привязано к объекту, нельзя сохранять в корень диска.Tr   N)	r+   rI   r>   r?   rW   rZ   r<   rA   r-   rM   s    r$   rd   zCmfAttachment._file_name!  s`     	(K01;;77<< 9 9 ;T^^=Q=QRR  a  jn  or%   c                 F    | j                         } |j                  |i |S r   )r,   r   r   s       r$   r   zCmfAttachment.get_fullview*  s&     """D3F33r%   )forcec                    t        |   |d|i|}| j                          t        j                  j                  |        |S )Nr   )r   deletedelete_filerJ   ry   obj_after_delete_hook)r    r   r!   r"   r~   r#   s        r$   r   zCmfAttachment.delete.  s@    gnd:%:6:44T:
r%   c                     | j                   r:| j                         }|r'|j                  | j                  j                         y y y )N)prefix)rd   r,   move_to_trashcoderA   r.   s     r$   r   zCmfAttachment.delete_file5  s;    ??NN$E##499??#;  r%   c                     t        |   di |}t        j                  j	                  | j
                  j                   d| j                  j                   | j                         |S )N_)name_before
target_dir )	r   restorerJ   r`   restore_from_trashr   rA   r<   rd   )r    r"   r~   r#   s      r$   r   zCmfAttachment.restore;  sV    go''**$))//9J!DNNL`L`Ka7boso~o~*
r%   c                    dd l }t        j                  j                  | j                  |      }|s|rt        j                  | j
                  d      }| j                  |_        t        j                  j                  |j                  j                  |j                  j                        d      |_
        |j                          |S )Nr   r   F)namer   T)r}   mkdir)r>   rJ   r`   r   rd   r<   r}   r?   dirnamerA   rI   rx   )r    r   r   _kwargsr>   r~   s         r$   r,   zCmfAttachment.get_rfile@  s    oo!!T__V!Dv//t~~e/DC__CF,,0MUY,ZCJHHJ
r%   c                     | j                   r?t        j                  | j                         x}r|j                  d| j                         y t
        |           y )NzPPP-ATT-CREATEobj)rq   ro   rp   check_project_role_accessrI   r   check_edit_permr    rt   r#   s     r$   r   zCmfAttachment.check_edit_permJ  sF    ??3+@+@+Q Q Q--.>DKK-PG#%r%   c                    | j                  g d       | j                  ryt        j                  | j                        }t        j
                  | j                  k(  r	 |j                  d| j                         y |j                  d| j                         y t        | -          y # t        $ r  |j                  d| j                         Y y w xY w)N)rq   rI   	cmf_ownerzPPP-ATT-DELETE-ALLr   zPPP-ATT-DELETE-OWN)r+   rq   ro   rp   r   current_userr   r   rI   CmfPermissionErrorr   check_delete_permr   s     r$   r   zCmfAttachment.check_delete_permQ  s    >???++DOO<G~~/]556JPTP[P[5\ 112FDKK1XG%' * ]556JPTP[P[5\]s   B) )&CCc                     | j                          | j                          | j                          t        |   |i | y r   )rw   rF   rg   r   _save_importr   s      r$   r   zCmfAttachment._save_import`  s7    d-f-r%   c                      y)u^  
            TODO: Сделать data-tag
            <div
                data-need-rebuild="1"
                data-macros="wiki-attachment"
                data-attach-id="CmfAttachment:2c767cfe-dbe6-11f0-965f-0242ac120003"
                data-attach-name="!!! escape"
                data-attach-url=""
                data-attach-url-preview=""
                data-attach-url-preview-img=""
                data-attach-cmf-created-at="2025-12-19T09:18:16.291725+00:00"
            >
                <span>Вложение: <a download=abs_url>Имя файла</a><span>
            </div>
        Nr   rM   s    r$   create_preview_tag_todoz%CmfAttachment.create_preview_tag_todof  s    r%   c                 <   ddl m} d}| j                  g d        | |j                  dd      j                  d	i | 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>
        )rR   rQ   rP   cmf_created_atr<   
r   )titler}   urlPreviewImg
urlPreviewrP   
createDatezhtml.parserr   )bs4r   r+   replaceformatr<   r}   rR   rQ   rP   r   json
currentTag)r    r   TAG_TMPLss       r$   create_preview_tagz CmfAttachment.create_preview_tagw  s    %6n 	ab;(**44;; &EIWW484H4H151A1A*.((151D1D1I1I?% & (56 ||r%   c                 f    | j                   r%t        j                  j                  | dg|i | y y )Nattachment_created)r_   rJ   CmfEventdo_eventr    r!   r"   s      r$   _do_event_savezCmfAttachment._do_event_save  s-    ;;OO$$T+?Q$Q&Q r%   c                 L    t        j                  j                  | dg|i | y )Nattachment_deleted)rJ   r  r  r  s      r$   _do_event_deletedzCmfAttachment._do_event_deleted  s!      ';MdMfMr%   c                     t        t        | 	               }| j                  dg       | j                  r0| j                  j                         D ]  }|j                  |        t        |      S )NrI   )setr   
get_ownersr+   rI   addlist)r    r!   r"   ownersparent_ownerr#   s        r$   r  zCmfAttachment.get_owners  s`     UW')*($;; $ 6 6 8 )

<()F|r%   c                     t        |   |i |}t        | j                  d      5 }|j	                  |       d d d        y # 1 sw Y   y xY w)Nr   )r   copyr   r   r   )r    r!   r"   obj_copyfr#   s        r$   r  zCmfAttachment.copy  sK    7<00$%%t, 	+''*	+ 	+ 	+s   AAc                 r   |r|t         j                  k(  rbt         j                  st         j                  ry|rt         j                  j
                  |k(  ryt         j                  }t         j                  }nd}t        j                  |dg d      }|j
                  |j                  k(  ry|j                  syt         j                  dk7  ry|j                  sC|j                  j                  dk(  r*|j                  r|j!                  |j                  d	      ry|j                  D ]  }|j"                  d
k(  r*|j                  r|j!                  |j                  |      c S |j
                  |j
                  k(  r y|du r!t$        j&                  j)                  |d      }|j
                  |v s y y)u  
        !!! Копия метода в CmfComment
        https://bcrm.carbonsoft.ru/project/Document/DOC-014685#spec-014684b
        Проверяем видимость аттача для g.current_person (или check_for_person)
        При использовании check_for_user метод можт выполняться долго! Обязательно перед вызовом
        проверяйте, что аттач имеет флаг private
        T.)
spectatorscmf_owner_idrL   rt   zproject.logic_prefix)simpler   apiFzproject.servicedeskzsdesk-agent:default)rt   	role_codeCmfProjectRole)id_onlyN)r   r   disable_permissionsacl_admin_modecurrent_personr}   current_person__member_ofcmfutilget_obj_by_idr!  rL   	api_scoper   rt   logic_prefix
user_localin_project_role
class_namerJ   CmfAccessListsubject_full_group_list)clsattachment_idowner_idcheck_for_usercheck_for_user__member_ofr   subjects          r$   check_visibilityzCmfAttachment.check_visibility  s~    1>>!A$$(8(8A,,//8;^^N()(C(C% ),%&&$_ ' a  3 33~~ ;;%  NN//3HH"--"226>>Uj2k (( 	G!!%55&..%55fnngNN  GJJ. )C/,2,@,@,X,XYgqu,X,v)zz66	r%   z	@minutely)r   r   schedulec                     t         j                  j                  j                  j	                         } | j
                  j                  t        j                        s,| j
                  j                  t        j                  dd       | j
                  j                  t        j                        D ]  }	 |j                  d      d   }t        j                  |      }|t         j                  t         j                  fv r6|j!                  |       t#                | j
                  j%                  |        y # t&        $ r?}t)                t*        j-                  d| d| t.        j0                         Y d }~d }~ww xY w)NT)r   r   r   u4   Не удалось обработать файлы z: )level)rJ   r`   ra   rb   rc   io	io_existsrX   
DIRTY_PATHio_mkdir
io_iterdirsplitr+  get_model_by_idCmfDocumentCmfTaskprocess_dirty_attach
cmf_commit	io_rmtree	Exceptioncmf_rollbackr   debugloggingERROR)rf   
dirty_pathobj_idmodeles        r$   cron_check_dirtyzCmfAttachment.cron_check_dirty  s+    ""..557xx!!&"3"34HHf//M((--f.?.?@ 
	wJ	w#))#.r2//7V//@@..v6LHH&&z2
	w  wNzlZ\]^\_`hohuhuvvws   5BD99	F5E<<Fr   )NF)NN)>__name__
__module____qualname__cmfrJ   	CmfEntityui_meta_skipr   r	   api_methodsr   r   r  r   intr   r   r   r   r   rF   rN   rT   r]   rg   rm   ru   rx   staticmethodcmf_deferred_jobr|   propertyr   rw   r   bytesr   r   r   r   r   boolr
   rd   r   r   r   r   r,   r   r   r   r   r
  r  r  r  r  classmethodr:  rT  __classcell__)r#   s   @r$   r	   r	      s	   ::''447GGL ..::

+
+,

K(*$d $FS FA3C 34S 4S 4'$o
XP  6+$ 7 +$Z 6 6 '+ Q > > > %%2`6	% T  
 oC o o4 #( <
&(."BHRN+
 5 5l Lw M wr%   r	   )mathr   pathlibr   cmf.includecmf.utilr   &common.models.cmf_plugin_convert_mixinr   modules.files.fieldsr   r	   r   r%   r$   <module>rj     s3          H /OwN002G Owr%   