U
    3MeOb                     @   s  d dl Z d dlmZmZ d dlZd dlZd dlZd dlZd dl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G d
d dZG dd dZG dd dZdd Zdd Z dd Z!dd Z"dd Z#dd Z$ddddZ%d d! Z&dQd"d#Z'd$d% Z(dRd&d'Z)dSd)d*Z*e+e+d+d,d-Z,e+e+d+d.d/Z-d0d1 Z.d2d3 Z/d4d5 Z0d6d7 Z1d8d9 Z2G d:d; d;Z3dTd<d=Z4dUd>d?Z5d@dA Z6e+e+dBdCdDZ7e+e+dBdEdFZ8dVe+e+dGdHdIZ9dJdK Z:dWdMdNdOdPZ;dS )X    N)urlparseparse_qs)datetimetimezonedate)Linker)g)Path)timeitProfilerDataCtxprofiler_data_log)*)AESc                   @   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__   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__   s    zdisable_acl.__enter__c                 C   s   | j t_d S r   )r   r   r   r   excvaluetbr   r   r   __exit__    s    zdisable_acl.__exit____name__
__module____qualname____doc__r   r   r    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 )
disable_notifyr   Nr   c                 C   s
   d | _ d S r   )save_notify_flagr   r   r   r   r   &   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   )   s    zdisable_notify.__enter__c                 C   s   | j t_d S r   )r'   r   r&   r   r   r   r   r    .   s    zdisable_notify.__exit__r!   r   r   r   r   r&   $   s   r&   c                   @   s>   e Zd ZedZddddZdd Z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   5   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getr*   r   r-   r)   import_heartbeat)r   r/   r   r   r   r   9   s    
zenable_import_mode.__enter__c                 C   s@   dd l }| jt_| j|jd< | j r0| j  t	j
j  d S )Nr   r+   )r/   r)   r   r-   r*   r0   	LOCK_PATHexistsunlinkcmfZappZ	CMF_CACHEZflushdb)r   r   r   r   r/   r   r   r   r    B   s    

zenable_import_mode.__exit__c              	   C   s4   t | jd}|tjtjd  W 5 Q R X d S )Nzw+)Ztz)openr3   writer   nowr   utcZ	isoformat)clsfr   r   r   r2   K   s    z#enable_import_mode.import_heartbeat)
r"   r#   r$   r	   r3   r   r   r    classmethodr2   r   r   r   r   r(   2   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_lockszCmfCacheObjLock:   timeoutT)blockingblocking_timeout皙?zcache_obj_lock_get long time: 0.3zsec    z,DEV: cache_obj_lock_get long time CRITICAL:    i  z#DEV: cache_obj_lock_get long time: )hasattrr   r>   timeAPPREDIS_DBredislockacquiredebugr6   include	cmf_alertr   Ztodayacquired_lock_timigns)Zobj_idZlock_keyst_timerM   Zacquire_timer   r   r   cache_obj_lock_getT   s$    



rT   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
   tj D ]6\}}t | }|dkrt	d| d|dd	 qd S )
Nr>   z*cache_obj_lock_release_all release error: rD   z%cache_obj_lock_release_all too slow: rE   zsec. Locks:z(cache_obj_lock_release_all lock >100ms:  Zsec)rH   r   rI   r>   valuesreleaserL   
exceptionsZ	LockErrorrO   keysrR   items)rS   rM   eZunlock_timeZ	lock_nameZlock_stZ	lock_timer   r   r   cache_obj_lock_release_alli   s    
$r\   c                  C   s4   t tdr0tjr0tjD ]} tjjj|   qg t_d S )Ndelayed_redis_events)rH   r   r]   rJ   rK   rL   Zpublish)Zeventr   r   r   emit_delayed_events~   s    
r^   c                 C   s   t t|  S r   )varsmodels)
class_namer   r   r   get_model_by_name   s    rb   c                 C   s   t | }tt| S r   )get_class_name_by_idr_   r`   idra   r   r   r   get_model_by_id   s    rf   c                 C   s   t | dd }|S )N:r   )strsplitrd   r   r   r   rc      s    rc   F)simplec                O   sH   t | tjjr| j }n|  }t|}|r0|jn|j}||d|i|S )Nre   )
isinstancer6   r`   	CmfEntityre   rf   sgetr1   )re   rj   argskwargsZtuuidmodelr1   r   r   r   get_obj_by_id   s    
rq   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 можно передать имя модели или саму модель
    rg   z--re   )codefields)namers   N)rk   rh   r_   r`   r6   rs   ZCmfTypeZ
CmfRelBase
startswithra   rm   re   )objra   rp   Z
loaded_objr   r   r   get_obj_id_by_any   s     

rw   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_modelry   sorted__dict__rY   getattrrk   Zabstract)Zmodel_filterr`   ry   Z
model_namerp   r   r   r   iter_models   s    
r   c                 C   s>   ddl m} ddlm} | D ]}|j| kr |j  S q d S )Nr   rx   )rl   )rz   r`   r{   rl   Ziter_subclassesui_namera   )r   r`   rl   rp   r   r   r   get_class_name_by_ui_name   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filterrr   =-   ZLIKEz%-)rQ   typerh   rb   r1   ri   isdigitlen)rr   rp   rn   ro   resZcode_numberr   r   r   get_obj_by_code   s     r   _c                    s(   t j| ddd}d fdd|D S )NruT)Zlanguage_codereversedr,   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>)transliterateZtranslitjoin)textr   r   r   r   r   translit_strip   s    r   )r   r   c                 C   s   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 t j| t j|dS )NsrcwidthZheightZimgr   rI   Zcontrolsrr   ZaudioZvideopbrZinsdelZfigureZ
figcaption)r   tags
attributes)bleachZALLOWED_ATTRIBUTESZALLOWED_TAGSappendZclean)r   r   r   r   r   r   
clean_text   s"    










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)r1   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|   rZ   )rn   ro   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
   r@   (DEV: FATAL lock(): if not lock.acquire()Tr   FuR   DEV: FATAL Попытка lock_ping() на отсутствующую записьi  	locked_byuJ   DEV: FATAL Попытка lock_ping() на чужую блокировку	ping_time)rJ   rK   rL   rM   rN   r6   rP   rQ   r4   rW   r   rO   r   loadsr1   current_personre   r   r9   r   r:   setr   )keyro   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)
ValueErrorrJ   rK   rL   r4   r   r   r1   )r   r   r   r   r   r   r   r   2  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   r@   )r   Z
lock_startr   lock_timoutr   Tr   Fr   r   )re   u[   Редактирование временно невозможно.
Редактирует u`   DEV: WARNING lock() попытка захватить свою блокировку дважды)rJ   rK   rL   rM   r   r   re   r   r   r9   r   r:   rN   r6   rP   rQ   r4   r   r   r1   total_secondsrW   r`   Z	CmfPersonrt   r   r   )r   Zlock_timeoutr   r   rM   r   personr   r   r   rM   C  s2    



rM   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   r@   z*DEV: FATAL unlock(): if not lock.acquire()Tr   Fus   DEV: WARNING unlock() попытка разблокировать несуществующую блокировкуr   r   r   )rJ   rK   rL   rM   rN   r6   rP   rQ   r4   rW   r   r   r1   r   r9   r   r:   r   r   r   re   delete)r   ro   r   r   rM   r   r   r   r   unlockj  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   Глобальная блокировка аппа на основе redis  Nr   c                 C   s$   ddl m} |jj|||d| _d S )Nr   )rK   )rA   rC   )rz   rK   rL   rM   
redis_lock)r   r   rA   rC   rK   r   r   r   r     s    zCmfLock.__init__c                 C   s    | j  std| j j d S )NzCannot lock )r   rN   ZCmfErrorrt   r   r   r   r   r     s    
zCmfLock.__enter__c                 C   s   | j   d S r   )r   rW   r   r   r   r   r      s    zCmfLock.__exit__)r   Nr!   r   r   r   r   r     s   r   c                 K   s  t js
dS | s|sdS ttdd }dt_dt_ddlm}m}m}m	}	 t
t }
||
d< ||
d< ||
d< ||
d< |	|
d	< tjj|
d
< |r|
| zd|rt|}|dr|dd  }|dr|dd  }td| d}| } W 5 Q R X t| |d}t||
 |
d |}n| rtj| dd}d}|jD ]$}t|tjr4|jdkr4d}q4|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
rn } 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_|S )NTdisable_raise_lazyloadr   )r   r   	timedeltar   r   r   r   r   r   rQ   z/opt/eva-app/   /rG   rexecrun)modeF)r   lineno
col_offset)r   r   )Zposonlyargsrn   defaultsZvarargZ
kwonlyargsZkwargZkw_defaults)rt   bodyrn   r   r   Zdecorator_listz<string>uC   Попытка вызова несуществующего bzPythonr   uT   Произошла ошибка при выполнении bzPython объекта z: 
)&configZBZPYTHON_ENABLEDr~   r   r   Zrelaxed_bz_python_moder   r   r   r   dictglobalsr6   rP   rQ   updaterh   ru   r7   readcompiler   astparser   rk   ZFunctionDefrt   r   ZReturnZConstantZ	argumentsarg	ExceptionZ
base_errorZCmfAbortError	traceback
format_exc)rr   rv   Zcode_src_objZeval_file_pathro   Zprev_disable_raise_lazyloadr   r   r   r   lr<   Z
code_blockresultZcode_astZhave_fnstfnr[   r   Ztracer   r   r   exec_bzpython  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   rG   )ZshareZdocsr   r,   r   r   rg   )maxsplitr   )docZDOCCmfDocument)ZflZFLZIN_WORK	CmfFolder)CmfListZEPIZsharelink_hashre   rr   )r   pathri   r   Zqueryr1   rsplitr`   r   r   r   rq   ra   r   )
Zurl_strZcheck_sharelinkZurl
path_partsZ
hash_paramZobj_keyZobj_typeZobj_codeZ	obj_modelZ
get_kwargsr   r   r   get_url_path_obj  s8    
r   c                  C   s6   t jd\} }}t|}t|}t|tj|S )Nrg   )r   ZEVA_INSTANCE_KEYri   binasciiZ	unhexlifyr   r   ZMODE_CBC)r   Ziv_hexZkey_hexr   Zivr   r   r   
get_cipher1  s    

r   )messager   c                 C   s@   t  }| dtjt| tj    }|| }t|dS )NrU   zutf-8)	r   r   Z
block_sizer   Zencryptencodebase64Z	b64encodedecode)r   cipherZpadded_messageZencrypted_messager   r   r   crypt8  s    r   c                 C   s   t  }|t|   S r   )r   decryptr   Z	b64decoder   strip)r   r   r   r   r   r   ?  s    r   )r   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   ОшибкаrG   )rv   r   rt   msgr   priority)r   rt   r   r   r   )r`   ZCmfPersonGroupZadmin_groupZ
rg_membersZ
all_nestedZ	CmfNotifyZplace_notify)r   rv   r   Z	admin_grpr   r   r   r   admin_alertC  s$    
r   c                  C   st   dd l } |  }tjrpd }tj}d|kr6|d\}}d| d| d|_|rp|d\}}| j|||_|S )Nr   @zhttp://)ZhttpZhttpsrg   )requestsZSessionr   ZEGRESS_PROXYri   ZproxiesZauthZHTTPProxyAuth)r   requests_sessionZ
auth_proxyZproxy_settingsZusernameZpasswordr   r   r   r   V  s    r   r8   zlist|CmfModel|SimpleModel)r   c                 C   s2   t | tr"| D ]}t||d qnt| d| dS )u   
    Маркируем объект проверенный бизнес логикой политикой по умолчанию.
    Сейчас маркировка проверяется только в api(eva-app)
    )policyZ_acl_policyN)rk   listacl_set_policysetattr)r   r  rv   r   r   r   r  i  s    
r  )N)N)r   )NN)F)NN)r8   )<r   Zurllib.parser   r   r   r6   r   r   r   r   r   r   Zflaskr   pathlibr	   Zcmf.cmf_profiler
   r   r   rz   ZCrypto.Cipherr   r   r   Zredis.exceptionsrL   rI   r   r&   r(   rT   r\   r^   rb   rf   rc   rq   rw   r   r   r   r   rh   r   r   r   r   r   rM   r   r   r   r   r   r   r   r   r   r  r   r   r   r   <module>   s^   "
&
	


'#
`
5