U
    5'iou                   @   s  d dl Z d dlZd dlmZmZ d dl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Zd dlmZmZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZ d dlT d dlmZ d dlZd dl Z d dl
Z!d dl"Z"d dl#Z#d dl$m%Z% d dl&Z&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/m0Z0 d dl1Z1d dl2Z2d dl3Z3d dl4Z4d dlmZ d dl5m6Z6 d dl7m8Z8 d dl9m: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Z@G dd dZAG dd dZBG dd dZCG dd  d ZDd!d" ZEd#d$ ZFd%fd&d'ZGd(d) ZHd%fd*d+ZId%fd,d-ZJd.d/ ZKd0d1 ZLd2d3 ZMd4d5 ZNd%d6d7d8ZOd9d: ZPdfd;d<ZQd=d> ZRdfd?d@ZSdAdBd%dCdDfeTeTeTeUeVeVeTdEdFdGZWdAdfeTdHdIdJZXddfeTe.eT e.eT eTdKdLdMZYeTeTdNdOdPZZdQdR Z[dSdT Z\dUdV Z]dWdX Z^dYdZ Z_G d[d\ d\Z`ddd%fd]d^Zad_d` Zbdadb Zcdcdd Zddedf Zedgdh Zfd%fdidjZgdkdl ZheTeTdmdndoZieTeTdmdpdqZjddfeTeTdrdsdtZkdudv Zldwfdxdydzd{Zmd|d} Znd~d Zodd Zpdd ZqG dd dZrdd Zsddddddd%fddZte0dd ZudddddddddddddZve2wdZxe2wdZydd Zzddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd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 d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdXdYdYdZd[d\d]d^d_d`dadbdcdddedfdgdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydz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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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ِ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dddddddddddddddd dddddCdC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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.d.d.d/d/d0d0d1d2d3d3d3d4d4d4d4d5d5d6d6d7d7d7d7d7d8d8d8d9d:d;d;d;d<d=d>d>d>d>d?d@d@d@d@dAdAdAdAdBdBdBdCdCdDdDdDdEdEdEdEdFdFdGdHdIdIdIdIdIdIdIdJdJdJdKdKdLdLdLdLdLdMdMdMdMdNdOdOdOdOdOdOdPdPdPdQdQdQdQdQdQdRdRdRdSdSdSdSdTdTdTdTdUdUdVdVdVdVdVdVdVdVdWdWdXdXdXdXdXdXdYdYdYdYdYdZdZdZdZdZdZ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_d_d_d_d_d_d_d`d`d`d`d`d`d`d`d`d`d`dadadadadadadadadadadadadadadbdbdbdbdbdbdbdbdbdbdbdbdcZ{ddddedfdgdhdidjdkdldmddndodpdqdrdsdtdudvdwdxdydz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dd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d&dd+d+dddÐdĐdŐdƐdǐdȐdɐdʐdːd̐d͐dΐdϐdАdѐdBdҐdӐdԐdՐd֐dאdؐdِdڐdېdܐdݐdސdߐddVdddddddd\dddddddddedddddddddndq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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#d$d%d&d'd'ddd(d)dd*dd+d,d-dd.dd/dd0d0d0dÐd1dƐd2d3d4d5d5dʐd6d͐dϐdϐd7d8d9d:d;d<dԐd=d>d>d?d@d֐d֐dAdאdBdؐdِdCdڐdDdEdFdܐdސdGdߐdHddddIdIddJdddKdLdddMdddNdNdOdPdQdRdRdSdSdTdUdUdUdCdCdVdVdVdWdddXdXdddYd
dZddddddddd[dddd\d\d]ddd^dd d_d_d`d`dadadad%dbdcdcdcd&ddd(d(d)d*d*d*d,d.d.d.d0d1d1dededededfdfd2d3d4d4d4d4d4d4d4d5d5dgdgdgd9d:d:d;d;d<d<d=d=d=d>d>d?d?d?d@dhdhdAdBdidCdCdCdDdDdDdEdFdFdFdFdGdHdHdHdIdIdJdKdKdLdLdMdMdOdOdPdPdPdPdPdPdQdQdQdQdRdSdTdTdTdUdUdUdUdVdVdVdVdVdWdWdXdXdXdXdXdYdYdZdZdZ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`d`d`dadadadadadadadadadbdbdbdbdbdbdjdjdjdjdjdjdjdjdjdjdjdjdDdDdDdDdDdDdDdDdDdDdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdldldldldldldldldldldldldldldldldldldldldldldldldldmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmdmd d d d d d d d d d d d d d d d d d d d d d d d d dnZ|dodp Z}dqZ~drZeee~eZeeee~Zdsdt Zdudv Zd%fdwdxZd%fdydzZd%fd{d|ZddfeTeTeed}d~dZdfddZeTeUdddZeTedddZd%fedddZd%feTdddZd%d%fddZdS (      Nurlparseparse_qs)relativedelta)Union)LockNotOwnedError)datetimedate	timedeltatimezone)Linker)g)Path)timeitProfilerDataCtxprofiler_data_log)*)AES)is_dataclass)OrderedDict)deepcopy)List)contextmanager)SHA256)RSA)get_random_bytes)
PKCS1_v1_5)pad)unpadz******c                   @   s.   e Zd ZdZddddZdd Zdd	 ZdS )
disable_aclt   Отключение проверки прав доступа в ORM для системных частей кодаNreturnc                 C   s
   d | _ d S N)save_acl_flagself r'   ./cmf/util/cmfutil.py__init__1   s    zdisable_acl.__init__c                 C   s   dt krt j| _dt _d S )Ndisable_permissionsT)r   r*   r$   r%   r'   r'   r(   	__enter__4   s    zdisable_acl.__enter__c                 C   s   | j t_d S r#   )r$   r   r*   r&   excvaluetbr'   r'   r(   __exit__9   s    zdisable_acl.__exit____name__
__module____qualname____doc__r)   r+   r0   r'   r'   r'   r(   r   /   s   r   c                   @   s.   e Zd ZdZddddZdd Zdd	 ZdS )

run_systemr    Nr!   c                 C   s   d | _ d | _d S r#   )current_usercurrent_acl_admin_moder%   r'   r'   r(   r)   @   s    zrun_system.__init__c                 C   s(   t j| _tjt j t j| _dt _d S )NT)r   r7   cmfappset_current_personZsystem_useracl_admin_moder8   r%   r'   r'   r(   r+   D   s    zrun_system.__enter__c                 C   s   t j| j | jt_d S r#   )r9   r:   r;   r7   r8   r   r<   r,   r'   r'   r(   r0   L   s    zrun_system.__exit__r1   r'   r'   r'   r(   r6   =   s   r6   c                   @   s.   e Zd ZdZddddZdd Zdd	 ZdS )
disable_notifyu4   Отключение всех уведомленийNr!   c                 C   s
   d | _ d S r#   )save_notify_flagr%   r'   r'   r(   r)   S   s    zdisable_notify.__init__c                 C   s   dt krt j| _dt _d S )Nr=   T)r   r=   r>   r%   r'   r'   r(   r+   V   s    zdisable_notify.__enter__c                 C   s   | j t_d S r#   )r>   r   r=   r,   r'   r'   r(   r0   [   s    zdisable_notify.__exit__r1   r'   r'   r'   r(   r=   Q   s   r=   c                   @   sJ   e Zd ZedZddddZdd Zdd	 Zed
d Z	edd Z
dS )enable_import_modez/tmp/eva_app_import.lockNr!   c                 C   s   d | _ d | _d S r#   )save_import_flagsave_cache_flagr%   r'   r'   r(   r)   b   s    zenable_import_mode.__init__c                 C   sD   dd l }|jdd| _dtkr(tj| _dt_d|jd< |   d S )Nr   NO_CACHE import_modeT1)osenvirongetrA   r   rD   r@   import_heartbeat)r&   rF   r'   r'   r(   r+   f   s    
zenable_import_mode.__enter__c                 C   s4   dd l }| jt_| j|jd< | j r0| j  d S )Nr   rB   )	rF   r@   r   rD   rA   rG   	LOCK_PATHexistsunlink)r&   r-   r.   r/   rF   r'   r'   r(   r0   o   s
    
zenable_import_mode.__exit__c              	   C   s6   t | jd }|tjtjdd W 5 Q R X d S )Nzw+tzz%Y-%m-%d %H:%M:%S %Z%z)openrJ   writer   nowr   utcstrftime)clsfr'   r'   r(   rI   y   s    z#enable_import_mode.import_heartbeatc              	   C   s\   dd l }tj| jsdS t| jd}|j| }W 5 Q R X t	j
tjd|  dk S )Nr   FrrM     )Zdateutil.parserrF   pathrK   rJ   rO   parserparsereadr   rQ   r   rR   total_seconds)rT   ZdateutilrU   	lock_timer'   r'   r(   import_is_running~   s    z$enable_import_mode.import_is_running)r2   r3   r4   r   rJ   r)   r+   r0   classmethodrI   r^   r'   r'   r'   r(   r?   _   s   	

r?   c                 C   s   t tdsd S d|  }|tjkr&d S t }tjjj|dd}|jddd t | }|dkrzt	d|d	d
|  |dkrt
jd|d	d
|  |dkrt tdddkrt
jd|d	d
|  |tj|< t tj|< d S )Nacquired_locksCmfCacheObjLock:   timeoutT)blockingblocking_timeout333333?cache_obj_lock_get long time: 0.3sec    ,DEV: cache_obj_lock_get long time CRITICAL:      #DEV: cache_obj_lock_get long time: )hasattrr   r`   timeAPPREDIS_DBredislockacquiredebugr9   include	cmf_alertr	   todayacquired_lock_timigns)obj_idlock_keyst_timeru   acquire_timer'   r'   r(   cache_obj_lock_get_redis   s$    



r   c                  C   s   t tdsd S t } tj D ]H}z|  W q  tjjk
rf } zt	d|  W 5 d }~X Y q X q t |  }|dkrt	d|ddtj
   i t_d S )Nr`   z*cache_obj_lock_release_all release error: 皙?z%cache_obj_lock_release_all too slow: ri   zsec. Locks:)rp   r   rq   r`   valuesreleasert   
exceptionsZ	LockErrorrw   keys)r~   ru   eZunlock_timer'   r'   r(    cache_obj_lock_release_all_redis   s    
$r   Fc                 C   s  dd l }ttdsd S d|  }|r4|tjkrBd S n|tjkrBd S |  }d}d}d}d}|rbd}td| d	|  ||k r|d
7 }tjjj	
 |d|i}	t|	d d }
|
rq|| qxtd| d	|  |
stjd||  d |  | }|dkr$td|dd|  |dkrHtjd|dd|  |d
krt tdd
dkrtjd|dd|  |r|  tj|d < dtj|< n|  tj|d < dtj|< d S )Nr   r`   ra   r      zKSELECT pg_try_advisory_xact_lock(('x' || md5(:lock_key))::bit(64)::bigint);zRSELECT pg_try_advisory_xact_lock_shared(('x' || md5(:lock_key))::bit(64)::bigint);zRun pg_try_advisory_xact_lock(z	) shared=rm   r}   zDone pg_try_advisory_xact_lock(ua   DEV: CRITICAL cache_obj_lock_get не смог взять блокировку в течение u   секrg   rh   ri   rj   rk   rl   rn   rb   ro   Z__shTZ__ex)rq   rp   r   acquired_locks_shr`   rw   models	CmfPersondpZ_ddSessionZexecutelistsleepr9   rx   ry   r	   rz   r{   )r|   r[   rq   r}   r~   Z
sleep_timeZ
wait_itersiterZlock_sqlZlock_resZlock_resultr   r'   r'   r(   cache_obj_lock_get_pg   sV    



 


r   c                 C   s    i t _i t _| stjd d S )Nu   DEV: ручной вызов cache_obj_lock_release_all не снимает блокировки! Блокировки будут сняты в конце транзакции)r   r`   r   r9   rx   ry   near_commit_or_rollbackr'   r'   r(   cache_obj_lock_release_all_pg   s
    r   c                 C   s   t tdsd S t| |d}|S )Nr`   )r[   )rp   r   r   )r|   r[   resr'   r'   r(   cache_obj_lock_get   s    
r   c                 C   sd   t tdsd S t| d}tj D ]6\}}t | }|dkr"td| d|dd q"i t_|S )Nr`   r   r   z(cache_obj_lock_release_all lock >100ms:  ri   Zsec)rp   r   r   r{   itemsrq   rw   )r   r   Z	lock_nameZlock_str]   r'   r'   r(   cache_obj_lock_release_all  s    

r   c                  C   s   t tdrtjrt } tjD ]}tjjj|  qt |  }|dkrzttj}t	d| d|  t
d| d|  g t_d S )Ndelayed_redis_eventsr   zPROF emit_delayed_events > 0.1 z, len(g.delayed_redis_events)=)rp   r   r   rq   rr   rs   rt   Zpublishlenrw   print)r~   ZeventZpublish_timecountr'   r'   r(   emit_delayed_events  s    

r   c                 C   s   t t|  S r#   )varsr   )
class_namer'   r'   r(   get_model_by_name"  s    r   c                 C   s   t | }tt| S r#   )get_class_name_by_idr   r   idr   r'   r'   r(   get_model_by_id&  s    r   c                 C   sL   t | tjjr| j} t | tjjr(| jS | dr6dS t	| 
dd }|S )N)zobj//ZCmfRFile:r   )
isinstancer9   fieldsCmfTyper.   r   	BaseModelr   
startswithstrsplit)r|   r   r'   r'   r(   r   +  s    
r   )simplec                O   sH   t | tjjr| j }n|  }t|}|r0|jn|j}||d|i|S )Nr   )r   r9   r   	CmfEntityr   r   sgetrH   )r   r   argskwargsZtuuidmodelrH   r'   r'   r(   get_obj_by_id8  s    
r   c                 C   s   t |trtt| }n|}t | tjjr@t | tjjs@t| } t | tr| |j	 dr`| S |j
| ddgd}|r||jS |j
| ddgd}|r|jS dS t| jS )u  
    Находим id объекта. Функция для использования в API и bzPython ручек, которые используют клиенты.
    Реализуем максимально универсальную логику, чтобы клиент мог получить объект по:
    - id
    - code
    - name
    - передать сам объект
    - передать field модели со ссылкой наобъект
    Если передается id - функция отрабатывает максимально быстро, т.к. используется в кешах
    Если передается code или name - будут доп.запросы в БД.
    Сначала ищем по code и только если не находим - по name
    В class_name можно передать имя модели или саму модель
    r   z--r   )coder   )namer   N)r   r   r   r   r9   r   r   
CmfRelBaser   r   r   r   )objr   r   Z
loaded_objr'   r'   r(   get_obj_id_by_anyB  s     

r   c                 c   s^   ddl m} ddlm} t|j D ]2}t||}t||r&|j	rFq&| rR| |r&|V  q&dS )u`   Последовательность моделей, с возможно фильтрацией.r   r   )BaseModelMetaN)
cmf.includer   cmf.models.base_modelr   sorted__dict__r   getattrr   Zabstract)Zmodel_filterr   r   Z
model_namer   r'   r'   r(   iter_modelsh  s    
r   c                 C   s>   ddl m} ddlm} | D ]}|j| kr |j  S q d S )Nr   r   )r   )r   r   r   r   Ziter_subclassesui_namer   )r   r   r   r   r'   r'   r(   get_class_name_by_ui_nameu  s    
r   c                 O   s   |st ddd t|tkr$t|}|j|ddd| gi|}|s| d k	rd| kr| dd }| rt|d	kr|j|ddd
d| gi|}|S )Nu|   TODO: сделать автоматическое обнаружение моделей и объекта как в bzPythonTabortfilterr   =-   ZLIKEz%-)ry   typer   r   rH   r   isdigitr   )r   r   r   r   r   Zcode_numberr'   r'   r(   get_obj_by_code~  s     r   _z[/\0]      )filenamereplacereplace_patternreplace_spaces	max_charshash_lengthr"   c                 C   s$  ddl }ddlm} ddlm} dttttddd	}	|j| \}
}|
}t	
d
|s^| }
d}|d|
}
t	|||
}
|
|k}|rt	d||
}
t|}|rd| nd}|| | }|	|
|}t|t|
k rd}|| d|  }|	|
|}|}
|r|| |}|
 d| | }n|
 | }|S )u  
    Удаляет недопустимые символы из имени файла,
    сокращает имя до максимальной длины
    и добавляет хеш уникальности при необходимости

    Args:
        filename (str): имя файла.
        replace (str, optional): символ замены небезопасных символов. Defaults to "_".
        replace_pattern (str, optional): шаблон для замены символов. Defaults to "[/ ]".
        replace_spaces (str, optional): замена пробела. Defaults to False.
        max_chars (int, optional): максимальное количество символов в имени файла. Defaults to 127.
        hash_length (int, optional): количество символов хеша. Defaults to 4.

    Returns:
        safe_name (str): безопасное имя файла
    r   N)	normalizerm   )short_str_enc   )textr   	max_bytesr"   c                 S   s<   | d| }t |d|kr8t |dkr8|dd }q|S )uh    Обрезает строку до max_chars символов, но не более max_bytes в UTF-8 Nutf-8r   r   )r   encode)r   r   r   Z	truncatedr'   r'   r(   truncate_to_fit  s    z&safe_filename.<locals>.truncate_to_fitz\.[a-zA-Z0-9]{1,10}$rC   NFCz\sTr   )r   )rF   unicodedatar   Zcmf_hashlibr   r   intrX   splitextre	fullmatchsubr   )r   r   r   r   r   r   rF   r   r   r   r   extoriginal_nameZ
needs_hashZ	ext_charsZ
hash_charsZavailable_charsZtruncated_nameZ	name_hashZ	safe_namer'   r'   r(   safe_filename  s8    



r   )r   c              	      s   t j| ddd} d fdd| D  }dd |D } |}|rt||krt|d	kr |d
 ddd |d	d  D gd | S |d
 d | S |S )NruT)Zlanguage_codereversedrC   c                 3   s*   | ]"}|  s|d kr| n V  qdS )r   N)isalnumlower).0csepr'   r(   	<genexpr>  s     z!translit_strip.<locals>.<genexpr>c                 S   s   g | ]}|r|qS r'   r'   r   wr'   r'   r(   
<listcomp>  s      z"translit_strip.<locals>.<listcomp>rm   r   c                 S   s   g | ]}|d  qS r   r'   r   r'   r'   r(   r     s     )transliterateZtranslitjoinr   r   )r   r   lengthwordsr   r'   r   r(   translit_strip  s    
2r   )r   tags_extendprotocols_extendr"   c                 C   s   |r d|kr |  dd dd} tj}dddg|d	< d
g|d< dddg|d< dddg|d< tj}|d	 |d |d |d |d |d |d |d |d |d |r|| tj}|r|| tj| tj||ddS )NZdivz<div>z<p>z</div>z</p>srcwidthZheightZimgr   rq   Zcontrolsr   ZaudioZvideopbrZinsdelZfigureZ
figcaptionT)r   tags
attributes	protocolsstrip)r   bleachZALLOWED_ATTRIBUTESZALLOWED_TAGSappendextendZALLOWED_PROTOCOLSZclean)r   r   r   r  r  r  r'   r'   r(   
html_clean  s0    












r
  )r   r"   c                 C   s    ddd}t |gd}|| S )NFc                 S   s.   |  ds| S t| d }d| d< d| d< | S )N)NZhrefZ_blank)NtargetZexternal)Nclass)rH   r   )Zattrsnewr   r'   r'   r(   
set_target  s    
zlinkify.<locals>.set_target)Z	callbacks)F)r   linkify)r   r  Zlinkerr'   r'   r(   r  
  s    
r  c                    s   i  fdd}|S )Nc                     s4   t | t| f}|kr, | ||< | S r#   )pickledumpsr   r   )r   r   hashfuncZmemoryr'   r(   memo  s    zmemoized.<locals>.memor'   )r  r  r'   r  r(   memoized  s    r  c                 K   s   t jj}d|  }|jddd}| s<tjjddd dS ||sb|	  t
d	 t| d
S t||}t
jj|d kr|	  tjjddd dS ttj|d< ||t| |	  dS )N	obj_lock-obj_lock.lock
   rc   (DEV: FATAL lock(): if not lock.acquire()Tr   FuR   DEV: FATAL Попытка lock_ping() на отсутствующую записьi  	locked_byuJ   DEV: FATAL Попытка lock_ping() на чужую блокировку	ping_time)rr   rs   rt   ru   rv   r9   rx   ry   rK   r   r   rw   r  loadsrH   current_personr   r   rQ   r   rR   setr  )keyr   redis_db_key_lock	lock_infor'   r'   r(   	lock_ping!  s&    



r%  c                 C   sD   | st dtjj}d|  }||r@t||}|r@|S dS )uh   
    Из редиса заберём структуру, где есть данные
    :return:
    uL   Блокировка объектов без key не реализованаr  N)
ValueErrorrr   rs   rt   rK   r  r  rH   )r   r!  r"  r$  r'   r'   r(   r$  :  s    

r$  c                 C   s  t jj}d|  }|jddd}tjjjt	t
jt	t
j|d}| s`tjjddd d	S ||rt||}t	t
j|d
   |k rtjj|d kr|  tjj|d d}tjd|j  d	S tjd |  dS ||t| |  dS )uT   
    Захват объекта на редактирование
    :return:
    r  r  r  rc   )r  Z
lock_startr  lock_timoutr  Tr   Fr  r  )r   u[   Редактирование временно невозможно.
Редактирует u`   DEV: WARNING lock() попытка захватить свою блокировку дважды)rr   rs   rt   ru   r   r  r   r.   r   rQ   r   rR   rv   r9   rx   ry   rK   r  r  rH   r\   r   r   r   r   r  r  )r   Zlock_timeoutr!  r"  ru   r$  personr'   r'   r(   ru   K  s2    



ru   c                 K   s   t jj}d|  }|jddd}| s<tjjddd dS ||s^tjd	 |	  dS t
||}ttj|d
   |d k rtjj|d kr|	  dS || |	  dS n|| |	  dS dS )u2   
    Снятие захвата
    :return:
    r  r  r  rc   z*DEV: FATAL unlock(): if not lock.acquire()Tr   Fus   DEV: WARNING unlock() попытка разблокировать несуществующую блокировкуr  r'  r  )rr   rs   rt   ru   rv   r9   rx   ry   rK   r   r  r  rH   r   rQ   r   rR   r\   r   r  r   delete)r   r   r!  r"  ru   r$  r'   r'   r(   unlockr  s,    

 

r*  c                   @   s0   e Zd ZdZdddddZdd Zd	d
 ZdS )CmfLockuJ   Глобальная блокировка аппа на основе redisrW   Nr!   c                 C   s$   ddl m} |jj|||d| _d S )Nr   )rs   )rd   rf   )r   rs   rt   ru   
redis_lock)r&   r   rd   rf   rs   r'   r'   r(   r)     s    zCmfLock.__init__c                 C   s    | j  std| j j d S )NzCannot lock )r,  rv   ZCmfGetLockErrorr   r%   r'   r'   r(   r+     s    
zCmfLock.__enter__c                 C   s>   z| j   W n* tk
r8   tdd| j j  Y nX d S )Nz%szUnlock CmfLock error: key = )r,  r   r   ZloggingZwarningr   r,   r'   r'   r(   r0     s    zCmfLock.__exit__)rW   Nr1   r'   r'   r'   r(   r+    s   r+  c                 K   s8  t js
dS | s|sdS ttdd }dt_dt_tjd }tjd= |rNt  nt	 }t
|d< tjj|d< ||d< |rxtnt |d< t|d< t|d	< t|d
< t|d< t|d< tjj|d< |r|| zf|rJt|}|dr|dd  }|dr|dd  }td| d}	|	 } W 5 Q R X t| |d}
t|
| |d |}n| rtj| dd}d}|jD ]$}t |tj!rh|j"dkrhd}qh|s|j#tj$tj%ddddddd tj!d|jtj&g tj'ddddgg d g d g dddg d}|g|_t|dd}
t|
| |d |}ntddd W nv t(k
r } zV|t_dt_t |tj)j*r`|dd l+}|, }tjjd| d | d!| dd W 5 d }~X Y nX |t_dt_dtjkr*d"tjkrtjd - D ]@\}}|tjd" krtjd" |  |7  < n|tjd" |< qntjd tjd"< |tjd< |S )#NTdisable_raise_lazyloadZselect_countr   cmfutilr&   r   r	   r
   r   requestsr   ry   z/opt/eva-app/   r   rm   rV   execrun)modeFr   )r.   lineno
col_offset)r4  r5  )Zposonlyargsr   defaultsZvarargZ
kwonlyargsZkwargZkw_defaults)r   bodyr   r4  r5  Zdecorator_listz<string>uC   Попытка вызова несуществующего bzPythonr   uT   Произошла ошибка при выполнении bzPython объекта z: 
Zbzpython_select_count).configZBZPYTHON_ENABLEDr   r   r-  Zrelaxed_bz_python_modeZprofiler_dataglobalscopy_build_safe_bzpython_globalsr   r9   rx   r.  r   _build_safe_datetimer	   r
   r   r/  r   ry   updater   r   rO   r[   compiler1  astrZ   r7  r   ZFunctionDefr   r  ZReturnZConstantZ	argumentsarg	ExceptionZ
base_errorZCmfAbortError	traceback
format_excr   )r   r   Zcode_src_objZeval_file_pathZeval_unsafer   prev_disable_raise_lazyloadZsaved_select_countlrU   Z
code_blockresultZcode_astZhave_fnstfnr   rC  Ztracekvr'   r'   r(   exec_bzpython  s    




 
     

rL  c                  C   s>   d } t jdr4t jdd }|dd  } nt j} | S )NzX-Forwarded-Forr   ,)ZrequestZheadersZgetlistr   r  Zremote_addr)Zext_ipipsr'   r'   r(   get_client_ip  s    rO  c                    s    fdd}|S )Nc                     s   t jjd j ddd d S )Nu   Вызов функции "up   " запрещен, требуется разрешить расширенные возможности BzPythonTr   )r9   rx   ry   r2   )r   r   rU   r'   r(   wrapper'  s    z_restrict_func.<locals>.wrapperr'   )rU   rQ  r'   rP  r(   _restrict_func&  s    rR  c                 O   sP   t | tst| f||S | dr<d| kr<t| f||S tjjddd d S )Nz/tmpz..u   Неверный путь к файлу или несуществующий файл, требуется разрешить расширенные возможности BzPythonTr   )r   r   rO   r   r9   rx   ry   )rU   r   r   r'   r'   r(   _safe_bzpython_open/  s    
rS  c                  C   sN   i } t  }tt|d< tt|d< t|d< tddd}||d< || d< | S )	Nevalr1  rO   )r   c                 _   s@   |  dd }|tjkr0tjjd| ddd t| f||S )N.r   u   Пакет "u)   " нельзя импортироватьTr   )r   r9  ZBZPYTHON_ALLOWED_LIBSr9   rx   ry   
__import__)r   r   r   Zname_to_checkr'   r'   r(   _bzpython_importE  s    
z6_build_safe_bzpython_globals.<locals>._bzpython_importrV  __builtins__)rX  r;  rR  rT  r1  rS  r   )Zbzpython_globalsbuiltinsrW  r'   r'   r(   r<  =  s    	r<  c                     s    t d  G  fdddt} | S )NrV  c                       s   e Zd Z fddZ  ZS )z*_build_safe_datetime.<locals>.SafeDatetimec                    s   t d< t j||S )NrV  )rX  superrS   )r&   r   r   )	__class___original_importr'   r(   rS   [  s    z3_build_safe_datetime.<locals>.SafeDatetime.strftime)r2   r3   r4   rS   __classcell__r'   r\  )r[  r(   SafeDatetimeZ  s   r_  )rX  r   )r_  r'   r^  r(   r=  U  s    r=  c           
      C   s  t | }|jd}|r$|d dkr(d S t|jddgd }|rL|sLd S |d }|s\d S d|krx|jddd	\}}n d
|kr|jd
dd	\}}nd S |dkrtj}n&|dkrtj	}n|dkrtj
}ntj}i }	|r||	d< d
|krtf d|j d| i|	S tf d| i|	S )Nr   rm   )ZshareZdocsr  rC   r   r   r   )maxsplitr   )docZDOCCmfDocument)flZFLZIN_WORK	CmfFolder)CmfListZEPIZsharelink_hashr   r   )r   rX   r   r   queryrH   rsplitr   rb  rd  re  r   r   r   )
Zurl_strZcheck_sharelinkurl
path_partsZ
hash_paramZobj_keyZobj_typeZobj_codeZ	obj_modelZ
get_kwargsr'   r'   r(   get_url_path_objb  s8    
rj  c                  C   s6   t jd\} }}t|}t|}t|tj|S )Nr   )r9  ZEVA_INSTANCE_KEYr   binasciiZ	unhexlifyr   r  ZMODE_CBC)r   Ziv_hexZkey_hexr   ivr'   r'   r(   
get_cipher  s    

rm  )messager"   c                 C   s@   t  }| dtjt| tj    }|| }t|dS )Nr   r   )	rm  r   Z
block_sizer   Zencryptr   base64	b64encodedecode)rn  cipherZpadded_messageZencrypted_messager'   r'   r(   crypt  s    rs  c                 C   s   t  }|t|   S r#   )rm  decryptro  	b64decoderq  r  )rn  rr  r'   r'   r(   rt    s    rt  )rn  r   c              	   C   sZ   t j }|j D ]@}|r:t jj||d| |p0| dd qt jj|d| |pL| dd qd S )Nu   Ошибкаrm   )r   r(  r   msgr   priority)r(  r   rv  r   rw  )r   ZCmfPersonGroupZadmin_groupZ
rg_membersZ
all_nestedZ	CmfNotifyZplace_notify)rn  r   r   Z	admin_grpr(  r'   r'   r(   admin_alert  s$    
rx  c                  C   sl   t  } tjrhd }tj}d|kr.|d\}}d| d| d| _|rh|d\}}t j||| _| S )N@zhttp://)httphttpsr   )r/  r   r9  ZEGRESS_PROXYr   ZproxiesZauthZHTTPProxyAuth)requests_sessionZ
auth_proxyZproxy_settingsusernamepasswordr'   r'   r(   r|    s    r|  rP   zlist|CmfModel|SimpleModelr.   c                 C   sN   ddl m} t| |r| j} t| tr>| D ]}t||d q*nt| d| dS )u   
    Маркируем объект проверенный бизнес логикой политикой по умолчанию.
    Сейчас маркировка проверяется только в api(eva-app)
    r   )r   )policy_acl_policyN)Zcmf.fields.base_fieldsr   r   r.   r   acl_set_policysetattr)r.   r  r   r   r'   r'   r(   r    s    

r  c                 C   s@   ddl m} t| ddd}t| |jjr2|  n|  |jS )Nr   baseT)no_metano_acl)	cmf.data_providersr  CmfResultSplitterr   SimpleMapperSimpleModelsplit_simpler   rG  )r   r  Zsplitterr'   r'   r(   
dumps_dict  s    
r  c                 C   s8   ddl m} t| }t| |jjr*t|S t|S d S )Nr   r  )	r  r  r  r   r  r  	cmf_dumpsujsonr  )r   r  Zres_dictr'   r'   r(   
dumps_json  s
    r  c                 C   s   t | tjrt| S t | tjr(t| S t | tjjrdd | j	
 D }| j	
 D ]&\}}t |tjrT|jrT| ||< qT| j|d< |S t| | jd S )Nc                 S   s0   i | ](\}}t |tjjr|jd k	r||jqS ).)r   r9   r   r   _value)r   attrfieldr'   r'   r(   
<dictcomp>  s
    
 z%cmf_dumps_default.<locals>.<dictcomp>r   )r   	ipaddressIPv4Addressr   decimalDecimalr9   r   r   r   r   ZfieldsCmfTypeZvirtualZvirtual_getterr   	TypeErrorr[  )r   rG  r  r  r'   r'   r(   cmf_dumps_default  s    
r  c              
   C   sV   zt j| tt jdW S  tk
rP } ztd| d|   |W 5 d }~X Y nX d S )N)defaultoptionzorjson.dumps error e=z, obj=)orjsonr  r  ZOPT_NON_STR_KEYSr  r   rw   )r   r   r'   r'   r(   r    s
    r  c                   @   s   e Zd Zd%ddZdd Zdd Zd&d	d
Zd'ddZd(ddZdd Z	ed)e
jjdddZdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ ZdS )*r  NFc                 C   sP   || _ i | _t | _d | _d | _d | _d| _t | _d| _	|| _
i | _|| _d S Nr   )_objmetar  meta_fields_keeprG  startendnumber_of_objectsm2m_id_cachedepthr  3_CmfResultSplitter__project_perm_add_comments_cacher  )r&   r   r  r  r'   r'   r(   r)      s    zCmfResultSplitter.__init__c                    s    fdd}|S )Nc                    sL   |  j d7  _ | j dkrd S  | f||}|  j d8  _ | j dksHt|S )Nrm   r  r   )r  AssertionError)r&   r   r   retrI  r'   r(   wrap/  s    
z,CmfResultSplitter._check_depth.<locals>.wrapr'   )rI  r  r'   r  r(   _check_depth.  s    zCmfResultSplitter._check_depthc                 C   s"   |j | jkrt|j| j|j < d S r#   )r   r  r   Zui_metar&   or'   r'   r(   _add_class_to_meta9  s    z$CmfResultSplitter._add_class_to_metac                 C   s  | d}| d}| d}| d}| d}| d}| d}	tt|}
i }d}d}d}|
jst|D ]}|d	kr|qn||= qnd
|d< |S tjj|||d||||	|d	pt }t|
t	jj
rL|
jrL|rL|dd }tt|d}|j |
j}| d}| d}|r|jsLtjj||||
j|||d|d	}t|t|@ }|dkr|| dr|tj||s|d}t }|dkr| drtj||sd}t }| ddrt|}d|kr|d t|}d|krd|krdnd
}t| }tjds"tjdrBd|
jkrBd|krB|d |D ]0}|tjkrb||= qF|d	krpqF|
j |}|r|jrqF|js||= d
||< qFt|t	jjrt||< d}tjj||||||||	d|d
pt }|dkr|rt }|dkr|rt }|dkr|r|dr|| jkrj| j| sd|krt|}|d nt|}t|d dgdd!}|jj p|j!j }|sd|krt|}|d d| j|< nH|j"d"|dd#dkrd|krt|}|d d| j|< n
d| j|< |d$kr2|d%kr2t|}|#d d|krNd|krJdnd
}|r\|||< |d
krF||krF||= qF|r||d&< |r||d< |S )'u;  
        Чтобы код не дблировать для модели, простой модели и дикта, можно проверять итоговый json
        Правда в таком случае, мы обходим все данные, даже если они не доступны.
        Zperm_effective_acl_idZcmf_owner_idr   	parent_idr   perm_parent_id%perm_security_level_allowed_ids_cacheNr   ZdenyZ_acl_objF)	initial_acl_keyobject_modelobject_owner_idraise_error	object_idobject_parent_idobject_dictperm_security_level_allowed_idschecked_policyr   r   perm_inherit_acl_idperm_parent_owner_id)	r  r  r  object_fieldr  r  r  r  r  
CmfCommentZprivateTCmfAttachmentZcmf_deletedrP   r[   readonlyz.getz.ui_getZcomments)
r  r  r  r  r  r  r  r  r  r  zCmfProject:
project_id)r   Zinclude_deletedzPPP-COM-ADD)r   r  r   Z
CmfProjectZ_acl_fields)$rH   r   r   Z	api_allowr   ZCmfAccessListZcheck_accessr  
issubclassr9   r   Zacl_parent_field	partitionr   r  r  Zcheck_visibilityr  removetupler   r   Z
api_methodendswithr  Zapi_hack_fieldsZCmfPassword_PASSWORD_MASKr   r  r   r  r.   r  Zcheck_project_role_accessadd)r&   Zobj_dict
acl_policyr  Zobj_owner_idr|   Zobj_parent_idr   r  r  r   Z
acl_fieldsZacl_objZcomment_denyZattachment_deny
field_nameZaccess_levelsZparent_class_nameZparent_modelZparent_fieldr  r  Zparent_access_levelsZ_tmpZobj_keysr  Z	acl_fieldZfield_access_levelsZproject_Zobj_Zproject_id_r'   r'   r(   _acl_obj_dict=  s   







     

     





     







zCmfResultSplitter._acl_obj_dictr   c                 C   s   |  j d7  _ | js| | d|ji}|jddD ]$}|js@q4| j||d d||j< q4| js|jdkr| j	|t
|dd d}|S )	Nrm   r   T)
is_definedr  Zpublic_readr  r  )r  r  r  r   r   r  _process_cmf_typer  Zacl_typer  r   )r&   r  r  rG  rK  r'   r'   r(   _process_cmf_model  s    

z$CmfResultSplitter._process_cmf_modelc                 C   s   |  j d7  _ | js*tt|j}| | i }|j D ].\}}| jsX| j	|j|f | 
|||< q8| js| j|t|dd d}|S )Nrm   r  r  )r  r  r   r   r   r  r   r   r  r  _processr  r  )r&   r   r  r   rG  r  r.   r'   r'   r(   _process_simple_model  s    
z'CmfResultSplitter._process_simple_modelc                    s    fdd  |S )Nc                    s   t | tr fdd| D S t | tr| d} fdd|  D }t |trd|krĈ jd7  _tjj	
|}js| | D ]}j|j|f q|j|d< jsĈj|| d	d
}|S | S )Nc                    s   g | ]} |qS r'   r'   )r   elproccess_jsonr'   r(   r     s     zSCmfResultSplitter._process_json_as_model.<locals>.proccess_json.<locals>.<listcomp>r   c                    s   i | ]\}}| |qS r'   r'   )r   rJ  rK  r  r'   r(   r    s      zSCmfResultSplitter._process_json_as_model.<locals>.proccess_json.<locals>.<dictcomp>r   rm   r   r  r  )r   r   dictrH   r   r   r  r9   r   ZCmfTUUIDZget_cls_by_tuuid_strr  r  r  r  r   r  r  )r   r|   datar   r  r  r&   r'   r(   r    s"    




z?CmfResultSplitter._process_json_as_model.<locals>.proccess_jsonr'   r  r'   r  r(   _process_json_as_model  s    z(CmfResultSplitter._process_json_as_model)r  c                 C   sb  |  j d7  _ | js*| j|jj|jf t|tjj	rD| 
|jS t|tjjr^| |jS t|tjjrx| |jS t|tjjrt|| jkrd S | jt| |jrd S | j|j|d d}| jt| |S t|tjjrFt|| jkrg S | jt| g }|jD ]}| |}|| q| jt| |S |j}|dkr\|jS |jS )Nrm   r  .)r  r  r  r  instancer   r   r9   r   ZCmfObjectJsonr  r.   ZCmfObjectList_process_listZ	CmfObjectr  ZCmfRelationBaser   r  Zis_nullr  r   r  jsonr  )r&   r  r  r   rG  ir   r'   r'   r(   r    s@    


z#CmfResultSplitter._process_cmf_typec                    s$     j d7  _  fdd|D }|S )Nrm   c                    s   g | ]}  |qS r'   )r  )r   r   r%   r'   r(   r   M  s     z3CmfResultSplitter._process_list.<locals>.<listcomp>)r  )r&   r  rG  r'   r%   r(   r  K  s    zCmfResultSplitter._process_listc                 C   s   |  j d7  _ t }| D ]v\}}| |||< | js|dkr|rt|trtt|	dd d }|r| 
| | D ]}| j|j|f qzq|dr|dr| js| j||dd}|S )Nrm   r   r   r   r   r  r  )r  r   r   r  r  r   r   r   r   r   r  r   r  r  r   rH   r  r  )r&   r  rG  rJ  rK  mr  r'   r'   r(   _process_dictP  s    
zCmfResultSplitter._process_dictc                 C   s   |  j d7  _ t|tr"| |S t|tjjr:| |S t|tjj	rR| 
|S t|rd| |S t|trx| |S t|tjtjfrt|S t|ttfr| S |S )Nrm   )r  r   r   r  r9   r   r   r  r   r   r  r   r  r  r  r  r  r  r  r   r   r	   Z	isoformat)r&   r   r'   r'   r(   r  `  s     






zCmfResultSplitter._processc                 C   sB   | j  D ]2\}}t|d D ]}||f| jkr|d |= qq
d S )Nr   )r  r   r   r  r&   r   Zclass_valuer  r'   r'   r(   _process_metas  s    zCmfResultSplitter._process_metac                    s\   d fdd	  j  j D ]2\}}t|d D ]}||fjkr8|d |= q8q$d S )Nr   c           	         s   j d7  _ t| rdtt| j}| | j D ](\}}j	|j|f  ||d  q6n t
| tjjrtt| j}| | j D ]>\}}t
|tr|jdk	rj	|j|f  |j|d  qnt
| tr| D ]} ||d  qnt
| trd }| d}|rJt
|trJtt|dd d  }rJ| |  D ]0\}}|rrj	|j|f  ||d  qRd S )Nrm   .r   r   r   )r  r   r   r   r   r  r   r   r  r  r   r9   r   r   r  r   r  rH   r   r  )	r   r  r   Zsub_attrZ	sub_valueZ	sub_fieldr   r|   Zsub_keyprocess_jsonr&   r'   r(   r  {  s6    




z<CmfResultSplitter._process_simple_meta.<locals>.process_jsonr   )r   )r  r  r   r   r  r  r'   r  r(   _process_simple_metaz  s    
z&CmfResultSplitter._process_simple_metac                 C   s$   | j r| jsd S t| j| j  d S )Ni  )r  r  r   r%   r'   r'   r(   ms  s    zCmfResultSplitter.msc                 C   s4   t   | _| | j| _| js&|   t   | _d S r#   )rq   r  r  r  rG  r  r  r  r%   r'   r'   r(   r     s
    
zCmfResultSplitter.splitc                 C   s4   t   | _| | j| _| js&|   t   | _d S r#   )rq   r  r  r  rG  r  r  r  r%   r'   r'   r(   r    s
    
zCmfResultSplitter.split_simple)NF)N)r   )r   )r   )r2   r3   r4   r)   r  r  r  r  r  r  r9   r   r   r  r  r  r  r  r  r  r   r  r'   r'   r'   r(   r    s$   

 ,

0&r  c                 C   s:   dd l }z|| }| W S  |jk
r4   Y dS X d S )Nr   F)psutilZProcessZ
is_runningZNoSuchProcess)pidr  Zprocessr'   r'   r(   check_process_running  s    

r  r   c                 C   s  ddl m}m}	 tjj}
|
s.tjddd dS |
D ]d}z|t|}|jdkrptjd| d	d
d W  dS |j	}|j
r|j
nd}|jr|jdnd}|stjd| dd
d W  dS |jr|	|jni }|ddgd }|dk	r| dk}|ddgd }|r|}|ddgd }|dk	r<| dk}tjd| d| d| d| dd ddt| dt|dt|d|d g
}|r|d! |r|d" || |r|d# |r|d$ || |r|d% |t| n|d& |t| tjd'd(| dd tj|dd)ddd*}d+|jkrrtjd,| d| d| dd W q2n\d-| d| d| d.|p| d/| d0|d1|j }tj|d
d |rt||W  dS W q2 tjk
r, } z:d2| d/| }tj|d3d |rt||W Y  dS d}~X Y q2 tjk
r } zJd4| d/| d5|j d6|j }tj|d3d |r~t||W Y  dS d}~X Y q2X q2tjd7|  d8dd dS )9u#  
    Проверка файла на ICAP сервере(ах) с использованием c-icap-client.
    
    Поддержка множественных ICAP серверов с настраиваемыми параметрами через URL.
    
    Формат URL: icap://host[:port]/service[?tls=true&tls_method=TLSv1_2&tls_no_verify=true]
    
    TLS параметры могут быть указаны в URL (query параметры) или как параметры функции.
    Приоритет: параметры из URL > параметры функции (fallback).
    
    Примеры использования:
        # TLS через URL
        icap_check(file_path, icap_url="icap://host/service?tls=true&tls_method=TLSv1_2")
        
        # TLS через параметры функции (старый способ, для обратной совместимости)
        icap_check(file_path, tls=True, tls_method='TLSv1_2')
        
        # Комбинированный (URL имеет приоритет)
        icap_check(file_path, icap_url="icap://host/service?tls=true", tls=False)  # tls=true из URL
    
    Query параметры URL:
        - tls: true - включить TLS
        - tls_method: строка - метод TLS (например, TLSv1_2, TLSv1_3)
        - tls_no_verify: true - отключить проверку сертификата
    
    !!! import icapclient - похоже ломает gevent
        Либа читает файл только с диска (


    Используем cli клиент:
    /usr/bin/c-icap-client [-V ] [-VV ]
     [-i icap_servername] [-p port] [-s service] [-tls ] [-tls-method tls_method] [-tls-no-verify ]
     [-f filename] [-o filename] [-method method] [-req url] [-resp url]
     [-d level] [-noreshdr ] [-nopreview ] [-no204 ] [-206 ]
     [-x xheader] [-hx xheader] [-rhx xheader] [-w preview] [-v ]

    -V                      : Print version and exits
    -VV                     : Print version and build informations and exits
    -i icap_servername              : The icap server name
    -p port         : The server port
    -s service              : The service name
    -tls                    : Use TLS
    -tls-method tls_method          : Use TLS method
    -tls-no-verify                  : Disable server certificate verify
    -f filename             : Send this file to the icap server.
    Default is to send an options request
    -o filename             : Save output to this file.
    Default is to send to stdout
    -method method          : Use 'method' as method of the request modification
    -req url                : Send a request modification instead of response modification
    -resp url               : Send a responce modification request with request url the 'url'
    -d level                : debug level info to stdout
    -noreshdr                       : Do not send reshdr headers
    -nopreview                      : Do not send preview data
    -no204                  : Do not allow204 outside preview
    -206                    : Support allow206
    -x xheader              : Include xheader in icap request headers
    -hx xheader             : Include xheader in http request headers
    -rhx xheader            : Include xheader in http response headers
    -w preview              : Sets the maximum preview data size
    -v                      : Print response headers

    Valid:
    root@crm:/opt/eva-app# c-icap-client -f uwsgi.ini -req / -i 10.50.17.68 -s avscan -method POST -v >/dev/null
    ICAP server:10.50.17.68, ip:192.168.0.33, port:1344

    No modification needed (Allow 204 response)

    ICAP HEADERS:
            ICAP/1.0 204 Unmodified
            Server: C-ICAP/0.5.6
            Connection: keep-alive
            ISTag: CI0001-B5sZ3i1I3+P4H3at/XZ4mQAA

    REQMOD HEADERS:
            POST / HTTP/1.0
            Last-Modified: Tue Apr  9 10:46:16 2024
            Content-Length: 1426
            Content-Length: 1426
            User-Agent: C-ICAP-Client/x.xx

    Virus:
    root@crm:/opt/eva-app# c-icap-client -f xf-mccs6.exe -req / -i 10.50.17.68 -s avscan -method POST -v >/dev/null
    ICAP server:10.50.17.68, ip:192.168.0.33, port:1344


    ICAP HEADERS:
            ICAP/1.0 200 OK
            Server: C-ICAP/0.5.6
            Connection: keep-alive
            ISTag: CI0001-B5sZ3i1I3+P4H3at/XZ4mQAA
            X-Infection-Found: Type=0; Resolution=2; Threat=Win.Tool.Genkryptik-9939783-0;
            X-Violations-Found: 1
            -
            Win.Tool.Genkryptik-9939783-0
            0
            0
            Encapsulated: res-hdr=0, res-body=108

    RESPMOD HEADERS:
            HTTP/1.0 403 Forbidden
            Server: C-ICAP
            Connection: close
            Content-Type: text/html
            Content-Language: en

    r   r   z8icap_check(): no ICAP servers configured, check disabledDEBUG)levelTZicapz$icap_check(): invalid scheme in URL z, expected "icap://"ZWARNINGFi@  r   Zavscanzicap_check(): invalid URL z, missing hosttlsNtrue
tls_methodtls_no_verifyz&icap_check(): checking file on server r   z
, service=z, tls=INFOz/usr/bin/c-icap-clientz-fz-iz-pz-sz-vz-tlsz-tls-methodz-tls-no-verifyz-methodz-reqz-respz!icap_check(): executing command: r      )Zcapture_outputrd   checkr   zNo modification neededz#icap_check(): file passed check on zicap_check(): failed on server z, url=z, file_path=z	, method=z
, result:
z icap_check(): timeout on server ZERRORzicap_check(): error on server z, returncode=z	, stderr=zicap_check(): file z passed all checks)urllib.parser   r   r   Zglobal_settingsZicap_serverrw   r   schemehostnameportrX   lstriprf  rH   r   r  r   
subprocessr2  stderrZCmfIcapCheckErrorZTimeoutExpiredZCalledProcessError
returncode)Z	file_pathZresp_urlZreq_urlmethodr  r  r  r  r   r   Zicap_serversZicap_urlparsedhostr  ZserviceZquery_paramsZurl_tlsZurl_tls_methodZurl_tls_no_verifyr   procrn  r   r'   r'   r(   
icap_check  s    p


&         







    6

 
r  c                  c   s*   t tdd} zdt_d V  W 5 | t_X d S )Nr-  FT)r   r   r-  )rE  r'   r'   r(   allow_lazyload  s
    
r   u   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)rm      r   r   rk            	   r        en_USru_RUc                 C   s.   | d t jkrt|  S t|  S d S r  )stringascii_lettersdictionary_enr  
capitalizedictionary_ru)wordr'   r'   r(   dictionary_check  s    r  i'  i$  i#  iH   ib  iC  i  i  i}  i  i+  i  i  is  iC  i  i  i  ip  i  i  i  i  i  i  ia  i  i  iy  iC  i  i  i  i  i  i  i  i  i  i[  i?  i  i  i  i  i  i:  i  i  iO  i>  i  i  i  i  iZ  i  i  i  i  i9  i
  i
  i
  in
  im
  iU
  iJ
  i/
  i$
  i
  i	  i	  i	  i	  i[	  i?	  i0	  i  i  iD  i/  i$  i  i  i  i  i  i  i  iM  i?  i8  i2  i  i  iu  iR  iM  iC  i8  i6  i4  i   i  i  i  i  i  i  i  i  i  i  i  i  iw  ih  if  iY  iL  i<  i2  i#  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  iy  ig  ie  iV  iP  iL  iA  i6  i0  i.  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  iv  ij  ic  i^  i[  iZ  iU  iR  iJ  iH  iF  iC  i=  i9  i%  i!  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  iw  in  ic  i^  i]  iZ  iN  iI  iF  iE  i8  i0  i)  i  i  i  i  i  i  i
  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i}  ix  is  iq  ip  io  im  il  if  id  ic  i\  i[  iX  iT  iO  iN  iL  iD  i?  i>  i9  i8  i6  i3  i2  i0  i.  i*  i'  i$  i"  i   i  i  i  i  i  i
  i  i  i  i  i     r                                                                                                                                                                  ~   {   z   y   v   u   s   q   p   o   m   l   k   j   i   g   f   e   c   a   `   _   ^   \   [   Z   Y   W   V   U   R   Q   N   M   J   I   G   F   D   C   B   A   @   ?   >   =   :   9   8   7   6   3   2   1   0   /   .   -   ,   +   *   (   '   %   $   #   "   !          r                                            rb      r0  r  r  r  r  r  r  r  (  u   стu   тоu   ноu   наu   поu   енu   ниu   коu   раu   овu   неu   роu   прu   алu   гоu   реu   осu   лиu   каu   воu   ерu   таu   отu   ваu   орu   олu   етu   теu   омu   анu   елu   одu   тьu   лаu   онu   леu   лоu   есu   атu   риu   льu   деu   огu   веu   ныu   тиu   заu   итu   скu   даu   акu   ойu   инu   меu   емu   илu   чеu   обu   асu   доu   моu   киu   трu   сяu   едu   соu   миu   ннu   сеu   амu   исu   авu   жеu   азu   маu   имu   твu   арu   виu   иеu   руu   боu   слu   изu   выu   диu   быu   ияu   икu   егu   пеu   ивu   чтu   всu   ейu   сьu   окu   ьнu   оеu   нуu   сиu   ихu   этu   хоu   адu   чаu   ожu   аяu   спu   ляu   евu   ичu   муu   чиu   шеu   тсu   днu   куu   удu   ыхu   саu   екu   беu   очu   ийu   паu   циu   крu   знu   опu   аеu   дуu   ииu   щеu   туu   ыеu   ыйu   ирu   тыu   озu   внu   ылu   рыu   ятu   утu   тнu   жиu   нтu   усu   ссu   шиu   идu   ымu   няu   гаu   свu   езu   луu   ктu   мыu   мнu   ееu   ужu   уюu   влu   улu   грu   пиu   ажu   брu   абu   учu   дрu   цеu   аюu   ечu   снu   ачu   гиu   чнu   суu   глu   люu   жнu   ахu   ебu   буu   рнu   урu   ьсu   ывu   щиu   ньu   звu   плu   апu   жаu   гдu   ряu   нсu   ькu   угu   блu   оиu   лсu   ждu   ашu   баu   биu   умu   ицu   епu   ртu   здu   ютu   зоu   ежu   врu   длu   укu   упu   клu   шаu   ешu   ошu   пуu   смu   агu   двu   вуu   кеu   ткu   ацu   йсu   ояu   айu   зиu   иоu   дыu   убu   нкu   ысu   ытu   игu   ехu   ющu   ещu   хаu   ндu   дсu   рмu   ялu   геu   янu   гуu   июu   лыu   ушu   рсu   фиu   тяu   цаu   зыu   вшu   охu   ишu   змu   фоu   ьшu   иаu   нцu   ксu   ямu   шкu   увu   рьu   зуu   ргu   ибu   рвu   ядu   срu   зеu   чуu   шлu   феu   мяu   явu   унu   шьu   лнu   ьюu   ркu   ьеu   чкu   дьu   ущu   щаu   ышu   ооu   еоu   ухu   бяu   вкu   сыu   ясu   втu   йнu   зрu   ецu   юдu   язu   бнu   лкu   бщu   узu   ржu   вяu   мпu   кнu   ллu   дяu   уеu   квu   счu   шнu   взu   юбu   оцu   ижu   ипu   яеu   ьяu   пыu   ащu   дкu   рдu   лжu   офu   аиu   хиu   ящu   яхu   хнu   ощu   злu   фаu   ырu   экu   вдu   шоu   бсu   ынu   зяu   шуu   згu   тлu   ьмu   впu   хрu   млu   ьтu   йтu   жуu   гнu   еаu   пяu   ыкu   ршu   нгu   бъu   еяu   ммu   оюu   яюu   ьзu   ыбu   цыu   ъеu   кцu   схu   сдu   ыпu   афu   чьu   якu   ауu   ючu   ищu   дпu   рхu   нчu   мсu   уаu   фрu   вьu   цоu   дцu   ычu   йчu   ефu   тдu   збu   хуu   зкu   лгu   хвu   пнu   ифu   вмu   нюu   джu   нфu   оэu   йдu   яжu   ппu   ыдu   еиu   штu   жкu   юсu   еюu   мкu   цуu   ячu   юрu   рбu   элu   дмu   йкu   сшu   рюu   сюu   дтu   рпu   щуu   хлu   тчu   ярu   ъяu   ррu   чшu   ьбu   ыгu   бкu   йшu   птu   мьu   рчu   тмu   гкu   зьu   пкu   рлu   еуu   ьцu   нщu   ягu   ьгu   кжu   псu   бхu   уйu   сбu   цкu   фуu   мбu   ьиu   пьu   лчu   яяu   сцu   оуu   тпu   цвu   яцu   ттu   энu   лтu   ызu   щнu   хеu   тюu   ябu   ддu   зжu   сфu   нрu   яйu   нвu   дшu   ввu   йоu   рцu   юнu   флu   аоu   жоu   хсu   рфu   дчu   ьчu   чоu   эрu   ффu   вчu   юзu   лдu   сёu   эфu   ьдu   бюu   бвu   жбu   уяu   тцu   нзu   фтu   вгu   хмu   члu   юмu   дхu   ймu   дгu   тбu   йцu   эмu   эпu   щьu   вхu   ётu   юкu   япu   жчu   оаu   ыжu   бмu   рзu   мрu   эсu   юлu   ёнu   йлu   ккu   юцu   вцu   ыяu   съu   щёu   чрu   дзu   хтu   кзu   дъu   швu   иуu   бьu   ёмu   дбu   юшu   чёu   жьu   мвu   южu   мчu   мцu   мгu   уцu   жсu   лбu   лпu   уиu   ююu   нжu   гчu   сгu   ьвu   еёu   зсu   пцu   лёu   яиu   ёлu   яшu   уфu   гсu   аэu   фсu   дюu   лмu   югu   рщu   вщu   ёрu   эдu   лзu   гмu   гвu   дёu   мфu   зъu   шпu   мэu   эвu   пчu   кмu   ьфu   бжu   тхu   ншu   эйu   кпu   уэu   гтu   нбu   ьоu   бдu   шмu   кгu   зчu   шёu   юхu   сжu   ббu   нёu   кшu   ззu   тщu   фыu   зцu   ггu   лхu   йеu   ааu   тёu   ьщu   ыиu   тфu   нхu   тгu   рэu   лвu   бшu   рёu   вёu   ьпu   лрu   зтu   ххu   йзu   эзu   чвu   шрu   ыщu   оёu   вбu   нпu   кдu   сэu   йбu   жлu   тъu   жмu   бзu   уоu   жрu   сзu   жгu   тзu   жёu   жжu   фьu   йфu   пшu   зюu   иэu   эхu   тэu   лшu   бэu   йрu   хгu   бтu   хшu   гбu   мтu   йгu   фнu   нэu   тшu   фгu   аёi!  iF  i  iL  iW  i  i  i	  i  i[  i  il  if  iD  iw  iR  i$  i  i  i  i  i  ix  i  i
  i
  ic
  i2
  i%
  i
  i	  i	  i	  i:	  i.	  i 	  i	  i	  i  i  i  i  i:  i  i  i  i  i  iJ  i=  i+  i*  i  i  i  i	  i  i  i  i  i  iw  iQ  iO  i-  i  i  i  i  i  i  i  i  iZ  iU  iH  iC  i>  i5  i3  i  i  i  i  i  i  i  i  i  i  i  i  im  ia  iS  iN  i-  i  i  i  i  i  i  i  i  i  i  i  i  i  i~  i{  il  if  ie  iY  iW  iL  iG  i@  i/  i"  i  i
  i	  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  it  ik  ih  i_  i\  iU  iT  iQ  iG  i>  i,  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  iw  it  ih  i`  i_  iY  iV  iJ  iH  iF  iE  iC  iB  iA  i<  i:  i4  i/  i,  i+  i&  i!  i  i  i  i  i  i  i                                                                             r                  }   |   x   t   r   h   d   b   X   T   P   O   L   K   H   <   ;   4   )   &   rk   r   r  rm   (  thheinZerZanr   esZonrH  ntenZatZedZndtoorZeaZtiarteZngZalitasisZhaetZseZouZofleZsaveroZraZrihinemedecotaZecsiZllZsoZnaZliZlar  ZmaZdiZicZrtnsZrsioZomZchZotcaZceZhobettfotsssnoeeZemZacZildaZniurwashZeiamtrZdtusloZpeZunZncZwiutZadZewZowgeZepZaiZlyZolZftrF   eoZefZprZweZdomor   ZiemipafiZpoZctZwhZirZaygaZscZkeZevspZimopZdsZldZulZooZsuiaZghplZebZigvirl  ZwoZyordZtwZbaZagZryabZlsswZapZfeZtuZcifaZhtfravZegZgoZboZbutyZmpocZodZehZysZeyZrmZovgtZyaZckZgiZrnZgrrcZblltZytZoaZyeobZdbZffZsfZrrZduZkiZucifafZdrZclexZsmZpiZsbZcrtlZoir   ZupZbyZtcnnZakslZnfZueZdwZauppZugZrlZrgr  ZcuZuaZdhZrkyiZluZumZbinyZnwZquZogZsnZmbvaZdfddr  ZgsZawZnhZpuhrsdr/   ptZnmZdcZguZtmZmuZnuZmmnleuZwnnbZrpZdmsrZudZuiZrfokZywZtfiprwrbZohksr   ZfuZyctpmtZdlZnkccZubZrhZnpZjurc  ZdnkaphhuZjoZlfZybrvZoeZibZikZypglZlpZymZlbZhsZdgZgnZeknrZpsZtdZlcskZyfZyhZvoZahZdyZlmZsynvZydZfsZsgZyrZylwsZmyZoyknZizZxpZlwtnkoZaajaZzeZfcZgwtgZxtZfhZlrZjeZynZggZgfeqZhyZktZhcbsZhwZhncsZhmZnjZhhZwtgcZlhZejZfmZdvlvwrZgpfpZgbZgmZhlZlkcyZmcZygZxiZhbfwZgyZhpZmwZpmZzaZlgiwZxaZfbsvgdZixZajklZhfZhdZaesqZdjZfyazZlnZaofdkwZmfZmhZsjZufZtvZxcZyuZbbZwwZojZaxmrZwlZxeZkhZoxZuoZziZfgZihZtkiiiuZtjZmnZwykyZkfrI  ZuyZpwZdkZrjukZkrZkuZwmZkmZmdmlZezZkbZwcZwdZhgZbtZzoZkcZpfZyvZpcpywbZykZcpZyjZkpZpbZcdZjiZuwZuhZwfZyyZwpZbcZaqcbZiqcmZmgZdqZbjrN   ZkdpdZfjcfZnzZcwZfvZvyZfkZozZzzZijZljZnqZuvZxoZpgZhkZkgZvsZhvZbmZhjZcngvZcgZwuZgjxhZgkZtqZcqZrqZbhZxsuzZwkZxuZuxZbdZbwZwgmvZmjZpnZxmZoqZbvZxwZkkZbpzuZrzZxfmkzhZbnZzyZhqZwjZiyZdzZvrZzsZxyZcvxbZxrZujZyqZvdZpkZvuZjrZzlZszZyzZlqZkjZbfZnxZqaZqiZkvZzwZwvuuZvtZvpZxdZgqZxlZvcczZlzZztZwzZsxZzbZvlZpvZfqZpjZzmZvwZcjZzcbgZjsZxgrxhzZxxZvmZxnZqwZjpZvnZzdZzrZfzZxvZzpZvhZvbzfgzZtxZvfZdxZqbZbkZzgZvgZjcZzkZznZuqZjmZvvZjdZmqZjhqsZjtZjbZfxZpqZmzZyxZqtZwqZjjZjwZlxZgxZjnZzvZmxZjkZkqZxkZjfZqmZqhZjlZjgZvkZvjZkzZqcZxjZpzZqlZqoZjvZqfZqdZbzhxZzjZpxZqpZqeZqrZzqZjyZbqZxqZcxZkxZwxZqyZqvZqnZvxZbxZjzZvzZqgZqqZzxxzZqkZvqZqjZqxZjxZjqZqzc                    sZ   t dd| | krdS  fddt| | dd  D }t|dkrFdS t|t| d S )N
[\[\];',.]rC   gHz>c                    s    g | ]\}}  || d qS r   rH   )r   abstatr'   r(   r     s     z$bigram_text_rank.<locals>.<listcomp>rm   r   )r   r   zipr   sum)r   rm  Zstatsr'   rl  r(   bigram_text_rank  s     rp  u   йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮz@qwertyuiop[]asdfghjkl;'zxcvbnm,.QWERTYUIOP[]ASDFGHJKL;'ZXCVBNM,.c                    s\    t kr| d tjkr|  S  tkr<| d tjkr<|  S d fdd| D }| S )Nr   rC   c                 3   s   | ]}  ||V  qd S r#   ri  )r   xdict_r'   r(   r     s     z'ninja_translate_text.<locals>.<genexpr>)rus2engr
  	printabler   eng2rusr   )r   rs  r  r'   rr  r(   ninja_translate_text  s    rw  c                 C   sB   | d t jkrt| t}n
t| t}tdd||kr:|S | S d S )Nr   rh  rC   )r
  ru  rw  rv  rt  r   r   )r  r  r'   r'   r(   ninja_revers  s    
rx  c                 C   s   t | dk r| S t| t}t| t}t|t}t|t}|rpt|  d| dd||   d| dd||   	 t|rt|s|S t|rt|s|S d||  dkr|S d||  dkr|S | S d S )Nr  z
 rank_ru: r   rm   z rank_eng: g?)	r   rw  rt  rv  rp  bigram_stat_rubigram_stat_engr   r  )r  rw   Z	trans_engZ	trans_rusZrank_ruZrank_engr'   r'   r(   
ninja_once  s"    



4r{  c                 C   s4   d| kr| S t | |}|| kr,|  d| S | S d S )Nry  |)r{  )r  rw   Z
ninja_wordr'   r'   r(   	ninja_add  s    
r}  c                    s   d  fdd| dD S )Nr   c                    s   g | ]}t | qS r'   )r}  r   rw   r'   r(   r   %  s     zninja.<locals>.<listcomp>)r   r   )r   rw   r'   r~  r(   ninja$  s    r  )subjectcontentr*  bccc                 C   sJ   dd }ddl m} || } ||}||}|tjj| ||||gd dS )u=  Метод для отправки почты из bzpython

    Args:
        to (list|str): Куда
        subject (str): Тема
        content (str): Содержание
        cc (list, optional): Копия. Defaults to None.
        bcc (list, optional): Скрытая копия. Defaults to None.
    c                 S   s    t | trdd | D S t| S )Nc                 S   s   g | ]}t |qS r'   )r   )r   r   r'   r'   r(   r   3  s     z5send_email.<locals>.convert_value.<locals>.<listcomp>)r   r   r   r  r'   r'   r(   convert_value1  s    
z!send_email.<locals>.convert_valuer   )schedule_deferred_job)r   N)r   r  r   ZCmfPluginMailBoxZsend_email_job)r  r  r  r*  r  r  r  r'   r'   r(   
send_email'  s    
r  zCmf[a-zA-Z]*c                 C   s   t d| dt| dkS )u  Определяет, является ли value идентификатором объекта:
        * определённого класса, если указан class_name
        * любого Cmf-класса, если class_name не указан
    ^z:[0-9a-z-]*$N)r   matchr   )r.   r   r'   r'   r(   is_tuuid=  s    r  )rh  r"   c                 C   sf   dd l }|j| }tjd}|js6|jdr6dS |j	dkrDdS |j
}||kpd|od|d| S )Nr   rU  r   T>   rz  r{  F)urllibrZ   r   r9  ZAUTH_SESSION_COOKIE_DOMAINr  netlocrX   r   r  r  r  )rh  r  r  Zparent_domainr  r'   r'   r(   is_safe_next_urlD  s    
r  )	delta_strr"   c                 C   s   | pd  }|st S td|}|s4td| t }|D ]\}}t|}|dkrf|t|d7 }q>|dkr~|t|d7 }q>|dkr|t|d	7 }q>|d
kr|t|d7 }q>|dkr|t|d7 }q>|dkr|t|d7 }q>|dkr>|t|d7 }q>|S )NrC   z([+-]?\d+)(y|M|[wdhms])u0   Неверный формат смещения: y)ZyearsM)Zmonthsr   )Zweeksd)Zdaysh)Zhoursr  )Zminutess)Zseconds)r  r   r   findallr&  r   )r  r  r  r  nurK  r'   r'   r(   str_to_timedeltaR  s0           r  )jwtc                 C   s^   |r
t jnt j}|t| d   d}|t| d   d}| d| S )uX   Создает JWT строку с urlsafe base64 для передачи через URLheaderr   payloadrU  )ro  urlsafe_b64encoderp  r  r  r   rq  rstrip)r  urlsafeencoderr  r  r'   r'   r(   
jwt_to_stre  s      r  c                 C   s\   t tj}t }||   ||}|r6tj	ntj
}|| d}|  d| S )uS   Подписывает JWT с urlsafe base64 для передачи через URLr   rU  )r   r  rr   Zrsa_private_keyr   r>  r   signro  r  rp  rq  r  )r  r  Zsignerdigestr  r  r'   r'   r(   rsa_sign_pack_jwtl  s    
r  c                 C   sB  |  d\}}}|ddt|d   7 }|ddt|d   7 }|ddt|d   7 }t }|  dd  d|  dd  }||  |rtjntj}||}	t	t
j}
|
||	}|sdS || }|| }t|}t|}|r8d|kr8tt t|d kr8tdt |d  dS ||d	S )
ug   Проверяет и декодирует JWT с urlsafe base64 для передачи через URLrU  r   r   r   rm   NZexpu9   Время жизни токена закончилось)r  r  )r   r   r   r  r>  r   ro  Zurlsafe_b64decoderu  r   rr   Zrsa_public_keyZverifyrq  r  r  r   rq   r   rw   )ZrjwtZ	check_expr  Z
header_b64Zpayload_b64Zsignature_b64r  Zjwt_unsigneddecoderZ	signatureZverifierZverifiedr  r  r'   r'   r(   rsa_verify_unpack_jwtv  s*    "

*r  )r  r  r  r   r   r@  Zdateutil.relativedeltar   typingr   Zredis.exceptionsr   r9   r  r   r   r	   r
   r   r   Zflaskr   pathlibr   Zcmf.cmf_profiler   r   r   r   ZCrypto.Cipherr   rk  ro  rt   rq   ZrandomZdataclassesr   r  r  r  r  collectionsr   r;  r   r   
contextlibr   r/  Zenchantr
  r   ZCrypto.Hashr   ZCrypto.PublicKeyr   ZCrypto.Randomr   ZCrypto.Signaturer   ZCrypto.Util.Paddingr   r   r  r   r6   r=   r?   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   boolr   r   r   r
  r  r  r%  r$  ru   r*  r+  rL  rO  rR  rS  r<  r=  rj  rm  rs  rt  rx  r|  r  r  r  r  r  r  r  r  r   Z	RU_MONTHSZDictr  r  r  ry  rz  rp  Zrus_keyZeng_keyr  rn  rt  rv  rw  rx  r{  r}  r  r   r  r  r  r  r  r  r  r'   r'   r'   r(   <module>   sV   /9

&	N"!
'#r
	5$	   
    
 |



          "          T	 
