U
    OEh.                    @   sn  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl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mZ d dlmZ d dlmZmZmZmZ d dlm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!m"Z" d d	l#m$Z$ d d
l%m&Z& d dl'm(Z( d dl)T d dl*m+Z, d dl-Z'd dl.Z.e./dZ0G dd de1Z1dd Z2G dd de3Z4G dd de$Z5e1e6de7j8dZ9e5e9e9_:de9_;de9_<g e9_=de9_>d e9j7d< i e9_?de9_@i e9_Ade9_Bde9_Cde9_DeE e9_Fi e9_Ge7jHe9_Id dlJmKZKmLZL d dlMmNZN d dlMmOZO d dlPZPeQddd ZRi e9_SeRe9_Rdd"d#ZTG d$d% d%ZUeU ZVeWe7d&re7jXd' d( d)kre7jXd' Y ZZeZ[d( d*eZkreZ[d* ePj\f eZeV_Pe]j^_d+reVjPdkre`d,e9d-e7jadd.ZbeWe7d&re7jXd' d( d)kre7jXd' d/ Zce7jXd' _d0rPd1e7jXd' d0  d2ec ZdeNedd3dd4Zeeeebd5< nd6Zfd7e7jXd' krvefe7jXd' d7 7 Zfd8e7jXd' krefd9e7jXd' d8  d:7 Zfefe7jXd' d; 7 Zfefd9e7jXd' _d<d= 7 Zfefd>ec 7 Zfefebd?< d d@lgmhZh dAeh_ieKf ebZMeOe7jadBZjeOe7jadBZke]jlme7j8dC rTene7j8dC Zoeop q e7_rW 5 Q R X eWe7d&re7jXd' d( d)kre4eVjPdDZsn(e7jXd' d( dEkre4ddFZsne`dGne4 ZseVe9_Vde9_td e9_ue9ve`dHdI Zwe9xe`ew ee7j8dJ Zyee7j8dK Zzd dLl{m|Z| eym r$e|}ey~ e9_ezm r>e|}ez~ e9_dMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjge9_dkdl Z;dmdn Zdodp Zdqdr Zdsdt Z<de9_de9_de9_dudv Zdwdx Zdydz Zee;ee_;ee;ee_eeee_eeee_eeee_eeee_eeee_ee<ee_<d{d| Zeeee_d}d~ Zeeee_dddZdddZdddddZdd Ze9jdd ZdddZdddZdd Zdd Zdd Zdd Zdd ZdddZdd Zdd Zdd Zdd Ze9jdd Zdd Zdd Zdd Ze9jdddZdddZdddZd>ddg dddZdddZdd Zdd Zdd Zdd ZdddZdddÄZG ddń dŃZddǄ ZddɄ Zddd˄Zdd̈́ Zddτ Zddф ZeQdҜddԄZeQed՜ddׄZi e9_i e9_i e9_i e9_i e9_dZdadadddڄZdd܄ Zddd߄Zdd ZdddZdddZdS )    N)OrderedDictdefaultdict)Path)urlparseparse_qs	urlencodequote)	safe_join)SHA256)
PKCS1_v1_5)Responseflash)DefaultJSONProvider)HTTPExceptionfields)*)basez^.*\.(png|jpeg|ico)|^(/plugins/|/sso/|/drawio/|/pub/|/docs/|/share/|/files/|/tinymce/|/app/assets/|/socket.io/).*|^.*/forms/CmfForm:.*|^.*(styles|vendor|runtime|polyfills|main).*\.js$|/styles.*\.css$c                       s$   e Zd Z fddZdd Z  ZS )Flaskc                    s   t  j|| d S N)super__init__selfargskwargs	__class__ ./cmf/app.pyr   )   s    zFlask.__init__c                    s    fdd}|S )Nc                    sn     dd }| j}|dd }|dkr6d|  }n}|d krP|d | j }j||| f  t| | S )Nendpoint.index/)pop
__module__split__name__add_url_ruleprint)fr    module_pathZmodule_nameurloptionsruler   r   r   	decorator-   s    zFlask.route.<locals>.decoratorr   )r   r0   r/   r1   r   r.   r   route,   s    zFlask.route)r(   r&   __qualname__r   r2   __classcell__r   r   r   r   r   (   s   r   c                 O   s$   | r t dddd |D  d S )N%s c                 s   s   | ]}t |V  qd S r   str).0argr   r   r   	<genexpr>@   s     zprint_debug.<locals>.<genexpr>)loggingdebugjoin)Zcondr   _kwargsr   r   r   print_debug>   s    r@   c                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
deddddZdd Zdd	 Zd
d Zdd ZdfddZdd Zdd Zdd Zdd ZeeedddZeedddZedgddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Z dhd.d/Z!d0d1 Z"d2d3 Z#d4d5 Z$did6d7Z%djd8d9Z&d:d; Z'd<d= Z(d>d? Z)d@dA Z*dBdC Z+dDdE Z,dFdG Z-dkdHdIZ.dJdK Z/dldMdNZ0dOdP Z1dmdQdRZ2dSdT Z3e4dUdV Z5e4dWdX Z6e4dndYdZZ7ee8d[d\d]d^ Z9e4d_d` Z:e4dadb Z;e4dcdd Z<dS )oCmfCacheNFreturnc                 C   sN   t  | _t  | _|| _|| _i | _| jrD| jdd | jdd d| _d S )Nstat_hitr   	stat_missF)dict	cache_objcache_invalidateredis_dbmemoryZtexcom_growcache_hack_cacheincrbyjob_daemon_mode)r   rI   rJ   r   r   r   r   P   s    zCmfCache.__init__c                 C   sj   t tjp| jdtjd | jr*| j  nt | _t | _	| j
dtd  | j
dtddi d S )NzCmfCache.flushdb!!!filezCmfCache:flushdbCmfCache:inmemory_delkeysALL)r@   configDEBUGsysstderrrI   flushdbrF   rG   rH   publishjsondumpsr   r   r   r   rV   \   s    zCmfCache.flushdbc                 C   s   t tjp| jdtjd tt}| j }| jj	dddD ]p}t | jd| dtjd |dd	 
 }| j|}|d	kr~q:t|}|d
 }|d || |< || q:|  | | d	S )u)   Инвалидируем весь jscachezCmfCache.flush_jscache!!!rM   zobj:jshash:*  countz"CmfCache.flush_jscache invalidate z!!!   Ncurrent_person_idjsver)r@   rR   rS   rT   rU   r   rF   rI   pipeline	scan_iterdecodegetpickleloadsdeleteexecuteemit)r   emit_msgpipekeyjshashjsresjspersonr   r   r   flush_jscachef   s    

zCmfCache.flush_jscachec                 C   s   t tjp| jdtjd d}| j }| jjdddD ]"}|drFq6|d7 }|	| q6|
  t tjpn| jd	| d
tjd dS )u+   Инвалидируем весь obj cachezCmfCache.flush_all_obj!!!rM   r   zobj:*r[   r\   s
   obj:jshash   zCmfCache.flush_all_obj: z recordsN)r@   rR   rS   rT   rU   rI   ra   rb   
startswithrg   rh   )r   r]   rk   rl   r   r   r   flush_all_objx   s    

zCmfCache.flush_all_objc           	         s  dd l dd l}dd lddlm ddlm  |} fddtjr	t
tjj tjdd dd   d d	 d
kr| }|dkrtjrtjtjkrtjj S |D ]}|d | }qd|kr|d t
|d  }t| D ],\}}|dkrq|d | d | }q| jrrd|dd  d 	|   }|dd}|dd}n| d	|   }t| jd| |S )Nr   )timezone)ImmutableDictc              
      s  t | }t|tjjr4| jr,| j} t | }nd} t}d}|ttt	fkr|tkr| dd dkrz8j
| }|j}|jddd}|} td|  W n" tk
r } zW 5 d }~X Y nX t| }n|tkr| D ]}|| d }qn|tks| kr:|  D ]4\}}|| }|r,| d	| }n|d }qn^| d krJd
}nN|tkr^t| }n:t| drvt| j}n"d|j d	 t|   }|S )Nz... r      Z20)secondZmicrosecondz!!!!! Date:,:Noneidz
todo2:obj:)type
issubclasscmfr   CmfType
is_definedvaluer8   intfloatparserparseZ
astimezoneutcreplacer*   	ExceptionlistrF   itemsboolhasattrr|   r(   md5re   rY   	hexdigest)valtresZval1evkru   _all2strdateutilhashlibrt   r   r   r      sH    




"zCmfCache.hash.<locals>._all2strZ   )Zdaysr^      )Zc92a103Zd860eddgUUUUUU?|r|   z|id:rz   zHASH:i  z|md5:
r6   _zDEBUG_CACHE HASH:)r   randomZdateutil.parserdatetimert   Zwerkzeug.datastructuresru   APPcache_optimizer   r8   r   r   CmfDatenowZ	timedeltaencoder   gcurrent_usersystem_usersortedr   rS   r   r@   )	r   prefixr   r   r   srr   rl   r   r   r   hash   s4    2D
&zCmfCache.hashc                 C   s2  |d krt  }|s|S tt|j}t  }|j D ]}|j|d }|sJq2|drh|	|d d  n
|	| t
|tjjrt||jd }|r| j||d q2t
|tjjtjjfr2t||jd }|r|D ]}| j||d q| D ]"}	d|j d|	j }
|	|
 qq2|	|jd dt|  |S )N_idr"   )r   ref_r   r6   ry   )setgetattrmodels
class_name__dict__rP   r   rd   endswithaddr~   r   CmfRelationBasesimple_objects_id_recursive
CmfM2MBaseCmfBackrefBaserelated_modelsr|   r>   r   )r   objr   modelfields_str_set
field_nameZ	field_clsZfield_valuerel_obj	rel_modelrefr   r   r   r      s6    

z$CmfCache.simple_objects_id_recursivec                 C   s  |sg S g }t  }|jddD ]}|jdrD||jdd  n||j t|tjjrp|	| 
|j t|tjjtjjfr|jr|jD ]}|	| 
| q| D ]"}d|j d|j }|| qq||jjd d	t|  tt |}|S )
u   
        Собираем ид связанных обьектов 2 уровня для настройки инвалидации
        :param obj:
        :return:
        Tr   r   Nr"   r   r   r6   ry   )r   valuesr   r   r   
isinstancer   r   r   extendobjects_id_recursiver   r   r   r   r|   appendr>   r   r   )r   r   r   r   fieldr   r   r   r   r   r   r      s(    
 zCmfCache.objects_id_recursivec                 C   sT   t |tjkrtddd dS | jr<| jd| | dS | jrP|| j|< dS d S )NuU   DEV: Слишком большой объект для кэширования — keyT)
debug_onlyFobj:)lenrR   ZCACHE_MAX_OBJ_SIZE	cmf_alertrI   r   rJ   rG   )r   rl   Zstr_valr   r   r   _obj_dict_set  s    
zCmfCache._obj_dict_setc                 G   sr   t  }|D ]}|d|  q
| jrD| jj| t|kr>dS dS n*| jrj|D ]}| j|sN dS qNdS d S d S )Nr   TF)r   r   rI   existsr   rJ   rG   rd   )r   rP   Zhkeysrl   r   r   r   _obj_dict_exists-  s    zCmfCache._obj_dict_existsc                 C   sX   | j r>| j d| }|d k	r.| j d n| j d |S | jrP| j|S d S d S )Nr   rD   rE   )rI   rd   rK   rJ   rG   )r   rl   r   r   r   r   _obj_dict_get?  s    zCmfCache._obj_dict_getrm   inv_payloadc                 C   s   |  d| S )N::r   r   r   r   r   %_jshash_invalidate_confirm_member_keyL  s    z.CmfCache._jshash_invalidate_confirm_member_keyZ
member_keyc                 C   s   | j dddS )Nr   rq   )maxsplitr'   r   r   r   r   +_jshash_invalidate_confirm_member_key_splitP  s    z4CmfCache._jshash_invalidate_confirm_member_key_splitc                 C   s    | r| n| dd }d| S )Nrz   zjscache-invalidate-confirm-set:r   )cache_idrm   set_keyr   r   r   "_jshash_invalidate_confirm_set_keyT  s    z+CmfCache._jshash_invalidate_confirm_set_keyc           	      C   s   t t}| D ]Z\}}td| |d |gd | D ]0\}}|dr8|| j|d | || q8q| jr| D ]\}}| jj	|f|  qzd S )Nzinvalidate-)roomevent_personsjshash:rm   )
r   r   r   cmf_emit_eventrr   r   r   r   rI   sadd)	r   ZmsgsZconfirmationsZ	person_idinv_dictrm   r   r   confirm_listr   r   r   ri   [  s    

zCmfCache.emitc                 C   sb   | j r^|r^|d d }| j|d}t }|D ]}|| |d |d  q,| j j|f|  d S )Nr   r   rq   )rI   r   r   r   r   srem)r   Zconfirm_dictZsample_jshashZkey_cache_idr   Zconfirmr   r   r   jshash_invalidate_confirmj  s    
z"CmfCache.jshash_invalidate_confirmc                    s<   t jrt   jr8 |} fdd j|D S d S )Nc                    s   g | ]}  | qS r   )r   rc   )r9   memberrZ   r   r   
<listcomp>  s   z;CmfCache.jshash_invalidate_confirm_list.<locals>.<listcomp>)r   invalidated_keys	CMF_CACHE_do_invalidate_defferrI   r   smembers)r   r   r   r   rZ   r   jshash_invalidate_confirm_listv  s    


z'CmfCache.jshash_invalidate_confirm_listc              	   C   s0  |sd S | j r| j jdd |D   t| | | i }|D ]x}| jrdd|krdtd|  t| jd|  | j jd| dd }rBt| jd	|  | jrtd
|  | j 	 }|D ]0}	|
d|	d  |d|	d  q| }
t||
dd d D ]\}	}|	d}	|d kr2qt|}|r|d }||kr^t ||< |dkr|rdtdd |D }nd}|d  d| d| d| }||| |	< qqvqBt }| | t }|| dkr,td||  d n.| jr(|D ]}|| jkr
| j|= q
nd S d S )Nc                 S   s   g | ]}d | qS )r   r   r9   rl   r   r   r   r     s     z+CmfCache._obj_dict_mdel.<locals>.<listcomp>r]   z#DEBUG_CACHE JSHASH: try invalidate z*DEBUG_CACHE JSHASH: try invalidate:jshash:invalidate:jshash:d   r\   z*DEBUG_CACHE JSHASH: got invalidate:jshash:z#DEBUG_CACHE JSHASH: got invalidate r   utf-8r   rw   r_   updater   c                 S   s   g | ]}|d kr|qS ))Zcache_fieldsZcmf_modified_atcmf_viewed_atZcmf_modified_by_idr   r9   r   r   r   r   r     s    ONLYFORUPDATESr`         ?z_obj_dict_mdel emit got sec)rI   rg   r   inmemory_delprofiler_invalidaterS   r   r@   Zspopra   rd   rc   rh   zipre   rf   rF   r>   r   timeri   r   r=   rJ   rG   )r   rP   obj_changed_fieldsobj_idactionrj   rl   Zinvjsrk   rm   Zjshash_listrn   ro   changed_fieldsr   Z
emit_startZemit_endr   r   r   _obj_dict_mdel  s\    








	
zCmfCache._obj_dict_mdelc              	   C   s   | j rN| j  6}| D ]\}}|jd| f|  q|  W 5 Q R X nD| jr|D ]2}|| jkr|| j| ||  qX|| | j|< qXnd S d S Ninvalidate:)rI   ra   r   r   rh   rJ   rH   r   )r   r   rk   rl   r   r   r   r   _invalidate_dict_mset  s    
zCmfCache._invalidate_dict_msetc                 C   sH   | j r.| j d| }|r*dd |D S |S | jr@| j|S d S d S )Nr  c                 S   s   g | ]}| d qS )r   rc   r   r   r   r   r     s     z1CmfCache._invalidate_dict_get.<locals>.<listcomp>)rI   r   rJ   rH   rd   )r   namer   r   r   r   _invalidate_dict_get  s    zCmfCache._invalidate_dict_getc              	   C   s   | j rT| j  <}| D ]$\}}|r| j jd| f|  q|  W 5 Q R X nJ| jr| D ]4\}}|D ]&}|| j|g krn| j| | qnqbnd S d S r  )	rI   ra   r   r   rh   rJ   rH   rd   remove)r   r   rk   r  r   Zkey_listrl   r   r   r   _invalidate_dict_mdel  s    zCmfCache._invalidate_dict_mdelc                    s:  t jdrdt_d S tjr*|s*jr*d S tjkrDj	dd d S t
|rpdt_tjdt
|  d S |}tj|tj}||k rdt_tjdtj d|  d S i tjj|}fdd	  fd
d}	|rFt|tsFt|dd rF|	| d}
t|jtjkrtd|j dtj  d S n|rxt|trxt|d dd rxd}
|	| nN|d k	rd}
t|tkrt|tkrttkrn|sd}
d}nt dd}|rL|d rLtjd| |
dkrP|j!|d krP|d D ]D}||j! d|j! dfkr
d}|j krFt"d  qPq
|sLg }d,|j#D ] }||d krd|d | }qd|sdg}t|tj$d< |D ]}|d krd!}|d D ]h}|%d"d }||kr d#|   d#| d$ n* d%| d&|   d%| d&| d$ qq|d D ]} d#| d$ q4|r\|d sl d#| d$ jrD ]}tjd'| d(  qxt&'|}(|sdt_)|rt
*|t+| d)tkr,tj,r,tjd* dtj,  jrt-d* tj, .d+ tj,fi . d S )-NNO_CACHETr   r}   z%DEBUG_CACHE ADD SKIP CACHE LOCKED_BY z#DEBUG_CACHE ADD SKIP too old trans r6   c                    sT   |  d\}}}| kr"t  |< |r@ |  d|  n |   d S )Nr6   )	partitionr   r   )Zbind_and_fieldsbindr   r   )r   rl   r   r   bind_add  s    
zCmfCache.add.<locals>.bind_addc                    sd   t | tr| }n| g}g }|D ]@}t |jtjjr>|}nt|}|D ]} | qPqdS )u   
            Собираем списки ключей инвалидации
            :param val:
            :param invalidate_dict:
            :return:
            N)r   r   r|   r   r   r   r   r   )r   Zobj_listr   itemr  )r  r   r   r   bind_add_recursive#  s    
z(CmfCache.add.<locals>.bind_add_recursiver|   r   zSkip add to cache z  g.skipcache_select_for_update: r   r   ZcustomemptyZEmptyuG   Невозможный объект для хранения в кешеFr   zDEBUG_CACHE WHERE: r   z.idz.codezDEV: Obj in not in inv_dictparentZcache_clustersZScopeAll)ZNullZNULLZnullr{   ZnoneNr{   r!   where_ScopeAll__insdelwhere_r   zDEBUG_CACHE BIND: z = rm   #DEBUG_CACHE JSHASH: add invalidate r   )r  )/osenvironrd   r   no_jscache_forcerR   ZJOB_DAEMON_DISABLE_CACHErL   r   $profiler_redis_invalidated_keys_skipr   cache_is_lockedr@   rS   cache_locked_byget_last_invalidatecache_lockscache_transaction_startr   utilcmfutilget_model_by_namer   r   r   r8   r|   skipcache_select_for_updater*   r}   r   r   r   r   r   cache_cluster_fieldsprofiler_datar'   re   rY   r   Zcache_store_errorinmemory_addr   rm   r   r  )r   rl   r   obj_typeZquery_paramscache_inmemoryZlir  	obj_modelr  Zobj_caseZwhere_pkr   Zscopesc_fieldZscope
model_nameZbindidZstr_objr   )r  r   rl   r   r   r     s    


  $

&



zCmfCache.addc              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrXt|t jd< nt jd  t|7  < tjrdt jkrg t jd< t jd | d S )Nr%  rH   Zcache_invalidate_keys)r   rF   r%  r   r   rA   DEBUG_PROFILE_VERBOSEr   )r   rP   r   r   r   r   r     s    


zCmfCache.profiler_invalidatec              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrTdt jd< nt jd  d7  < dt jkrzdt jd< tjrdt jkrg t jd< t jd | d S )Nr%  redis_cache_hitrq   redis_cache_missr   Zredis_cache_hit_keysr   rF   r%  r   rA   r,  r   r   rl   r   r   r   r   profiler_redis_data_hit  s    




z CmfCache.profiler_redis_data_hitc              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrTdt jd< nt jd  d7  < dt jkrzdt jd< |t jd< tjrdt jkrg t jd< t jd | d S )Nr%  r.  rq   r-  r   Zredis_cache_miss_lastZredis_cache_miss_keysr/  r0  r   r   r   profiler_redis_data_miss  s    





z!CmfCache.profiler_redis_data_missc              
   C   st   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX d| }|t jkr^dt j|< nt j|  d7  < d S )Nr%  Zinvalidated_keys_skip_rq   )r   rF   r%  r   )r   r}   r   r   r   r   r   r    s    

z-CmfCache.profiler_redis_invalidated_keys_skipc                 C   sJ  t jdstjrd S |tjkr0| jdd d S d}|rDt|}nd}t	| j
d |dkrd}| |}|rt|}t|}|dk	r*dtkrtjr| d	| tjfi t	| j
d
| dtj  | j
rtd| tj t	| j
d|  t	| j
d| |s&|r&| | t||| |S | | t	| j
d|  d S )Nr
  rd   r  T.ZCACHEFrm   r   z*DEBUG_CACHE JSHASH: add invalidate jshash:r6   r  zDEBUG_CACHE HIT: zDEBUG_CACHE GET:zDEBUG_CACHE MISS: )r  r  rd   r   TECHCOM_HACK3441r   r  r   inmemory_getr@   rS   r   re   rf   r   rm   r  r   r1  r&  r2  )r   rl   r(  Zfrom_inmemoryr   r   obj_sizer   r   r   rd     s>    





zCmfCache.getc                 C   s   dS S )Nr   z%DEBUG_CACHE TRANS get_last_invalidatecache_last_invalidate_r@   rS   r   rI   rd   r   r+  r   r   r   r  5  s     zCmfCache.get_last_invalidatec                 C   s   t | jd |  t_d S )Nz)DEBUG_CACHE TRANS cache_transaction_start)r@   rS   gen_time_usr   r  rZ   r   r   r   r  :  s    z CmfCache.cache_transaction_startc                 C   s   t tjtjjdS )Nz%Y%m%d%H%M%S%f)r   r   r   rt   r   strftimerZ   r   r   r   r9  >  s    zCmfCache.gen_time_usc                 C   s   d S d S )NzDEBUG_CACHE TRANS cache_lockr6  cache_lock_)	r@   rS   r  r9  rI   r   r   r  r  )r   r+  lr   r   r   
cache_lockA  s          zCmfCache.cache_lockc                 C   s\   d S t j D ]H\}}| |}||ks6t j|d krt| jd | jd| d qd S )Nr   zDEBUG_CACHE TRANS cache_unlockr;  0)	r   r  r   r  r  r@   rS   rI   r   )r   r+  Ztr_startZlock_trr   r   r   cache_unlockR  s      
zCmfCache.cache_unlockc                 C   s   dS S )Nr   z%DEBUG_CACHE TRANS get cache_locked_byr;  r7  r8  r   r   r   r  b  s     zCmfCache.cache_locked_byc                 C   s   dS dS dS )NFr   r>  z/DEBUG_CACHE TRANS cache_is_locked drop deadlockr;  r?  T)	r  r   r  rd   r  r@   rS   rI   r   )r   r+  Z_cache_locked_byr  r   r   r   r  g  s           zCmfCache.cache_is_lockedc                 C   s   t   }tj}tj}tj}t }	|d kr.|j}|D ]f}
|
|krPt||
 ||
< n||
 ||
  ||
 D ],}d|kr|	|	dd  qj|	| qjq2||	 |
|dd |jddD ||	d t   }|| dkrtd	||  d
 d S )Nr6   r   c                 S   s   g | ]}|qS r   r   r   r   r   r   r     s     z+CmfCache._do_invalidate.<locals>.<listcomp>T)
is_changed)r   r   r   inv_listr   zPROF _do_invalidate got r   )r   r   r   rB  r   r   r|   r   r   r'   r   rP   r=   )r   r   r   r   r   stglob_inv_dictglob_inv_listr   rB  r   Zinv_valendr   r   r   _do_invalidatev  s2    
zCmfCache._do_invalidatec                 C   s   t js
d S t }t j}t j}|D ]$}| |d |d |d |d  q"t }| | t }|| dkrt d||  d t d||  d	tt j  t d
||  d	t|  t	 t _i t _g t _d S )NrB  r   r   r   r   z_do_invalidate_deffer got r   z)_do_invalidate_deffer _obj_dict_mdel got zsec len=z0_do_invalidate_deffer _invalidate_dict_mdel got )
r   r   r   r   rB  r  r	  r=   r   r   )r   rC  rD  rE  rB  Zst_invalidate_dict_mdelrF  r   r   r   r     s"    "
 zCmfCache._do_invalidate_defferr   c              	   C   s  t jdrd S |d kr$| dh}|s,d S | | t| jd| d| dt|  t }t }t }i }i }t|dkr|D ]j}	| jj	d|	 ddd	}
|
D ]>}| j
|}|r|D ]$}|d
d }|| |	||< qq||
 qntd t| jj	ddd	}
tdt|
  tdd| d }td}td |
D ]p}| }||snqR| j
|}|r|D ]0}|d
d }|| ||d ||< q|| qR|D ]}| j
d|  }||}	|r|D ]}|d
d }|| | jd|  }|s2qt|}|d }||krXt ||< d}|d  d| d|	 d| }||| | < qq|dd |D dd |D dd |D }|rtd| d| d|  | jj|  ntd| d| d  | | d S )!Nr
  rz   z!DEBUG_CACHE start invalidate_ids r6   x   zinvalidate:*r   r[   )matchr]       r   zscan get all keysz
scan over z.*(r   z).*zK[A-Za-z]+:[0-9a-z-]{8}-[0-9a-z-]{4}-[0-9a-z-]{4}-[0-9a-z-]{4}-[0-9a-z-]{12}zre compile doner   r   r_   r   r`   r   c                 s   s   | ]}d |   V  qdS r   Nr  r9   	query_keyr   r   r   r;     s     z*CmfCache.invalidate_ids.<locals>.<genexpr>c                 s   s   | ]}d |   V  qdS )r   Nr  rL  r   r   r   r;     s     c                 s   s   | ]}d |   V  qdS rK  r  )r9   rm   r   r   r   r;     s     zinvalidate_ids(, ): z): no keys found.)r  r  rd   r=  r@   rS   r   r   rI   rb   r   r'   r   r   r   r=   r   recompiler>   rc   rI  findallre   rf   rF   rg   ri   )r   r+  idsr   Zinvalidate_keysZ
query_keysZjshashesrj   Zobj_id_by_query_keyid_rP   rl   Zinv_membersZ
inv_memberZid_reZtuuid_reZkey_decodedrM  Zquery_jshashesrm   rn   ro   r   r   Z	keys_listr   r   r   invalidate_ids  s    
"









zCmfCache.invalidate_idsc                    s   d fdd	}t jdr"d S |s*d S | tjd  d|  i |D ]6}|d| d| d	 ||d
 jd  |d qTd S )Nrv   c                    s6    | }|r2|| < tjd  d| |   d S )NDEBUG_CACHE INVAL: r6   )r  r@   rS   )invalr=   invdr   r   r   r   r   _check_inval  s    
z8CmfCache.invalidate_ids_as_wrapper.<locals>._check_invalr
  DEBUG_CACHE start invalidate r6   r   r   ref=obj.id=)r   )rv   )r  r  rd   r=  r@   rS   rG  )r   r+  rS  r   rZ  rT  r   rY  r   invalidate_ids_as_wrapper  s    

z"CmfCache.invalidate_ids_as_wrapperc              
      s  t d d|d|d| t }d8 fdd	}dd	lm} tjd
rXd S |j	 t
jd  d|j	  |j	}i jrdd l}	|	  |j	dkr||j d  dkrv|d|j d|j	 d |std ||j d|gd |d|j	 dd |d|j d|j	 dd t }
|  t }|| dkrrt d  d||  d d S t }|jddD ]x\}}d }|j	|krqt|tjjrlt|d!r|jjr|jsl d"kr|r|jr|d|j d|j	 d  d#krl|jrl|j|jkrl|d|jj d|j	 d$ |d|jj d|j	 d% || qt|tjj r d#kr|jr|| q|jrt|tjj!r|| q|jr|j|jkr|| |"d&r||d d'  qt#|dkr8 d#kr8t
jd(  d)|j d S d*g}|j$D ]}|| qDt%t&|d+d rr|'|  d"kr||j d  d#kr||j d|d  d#kr|D ]
}d9|j$D ]}t||sؐqt(t&|| tjj r || D ]$}|d|j d| d-| d qnt(t&|| tjjr^|d||d&   d| d-| d nFt(t&|| tjj)r|d||  d| d-| d ntd.dd/ q|d| d-| d qd0}d:|j$D ]8}t||r|| jr|| j|| jkrd}qЈ d"ks|r t|d!r8|jjr8|js d;|j$D ]}t||sXqBt(t&|| tjj r|| D ] }|d|j d| dd1 qx|| jr|| jr|| jD ] }|d|j d| dd2 qnt(t&|| tjjrR|d||d&   d| dd || jr|| jr|d|| jj d| dd3 nzt(t&|| tjj)r|d||  d| dd || jr|| jr|d|| jj d| dd3 ntd.dd/ qBt|d!r|jjr|jsR|d| d nRt*j+rR d"ks|rRt|d!rR|jjsR|j,  |jrRtd4t j- d5 t.j/rtt j0d6g g t j0d6< t }
|  t }|| dkrt d7||  d d S )<NzRUN INVALIDATE: action=z obj=z item=z m2m_field_name=rv   c                    s   | }g }|r|rt|}g }|D ]}d|kr@|| q(|d^}}}|rtd|  d|  td|  d| d| dd || q(t|d}	||	@ r(|| q(|| < n|| < tjd  d| |   i }
||
| < t	j
rtjdg |
g tjd< d S )	Nr6   z=cmfCache.invalidate(): ValueError: too many values to unpack(rO  Tabortry   rV  rX  )r  r   r   r'   r   r=   r   r@   rS   rA   r,  r%  rd   )rW  r=   change_fieldsrX  Zinvd_affectedir   Zi_fieldstailZi_set_fieldsZtmprY  r   r   rZ  >  s4    



z)CmfCache.invalidate.<locals>._check_invalr   )r   r
  r[  r6   ZRelationCachezRelationCache.parent.id=)r   r  r   r   r\  uY   DEV: FATAL в инвалидацию м2м поля не передали имя поляr]  )ra  r  r  zwhere=r  r   zinvalidate (action=z) got zjsec. _check_inval {_check_inval_done - st}sec, _do_invalidate {_do_invalidate_done - _check_inval_done}secTr   )r   Zcmf_viewed_byZcmf_versionrv   is_dummy)createrg   r   zref_new=zref_old=r   r"   zDEBUG_CACHE ivalidate: z not fields_have_changesz--Zlogical_deleter  r!   u   Ошибка конфигурации моделей: cache_cluseter_fields может быть только по m2m и relation полямr_  Fz
where_m2m=zwhere_m2m_old=z
where_old=u   DEV: в методе ux    не загружается is_dummy, что приводит к лишним инвалидациям кластераr   zinvalidate got )rv   N)r  )r  )r  )1r   r=   r   collectionsr   r  r  rd   r=  r   r@   rS   TRACEpdbZ	set_traceZ	parent_idr|   r   rG  r   r   r   r   r   r   r   rd  r   rA  oldnewr   r   r   r   r   r$  r   r}   load_fieldsr~   ZCmfTUUIDrR   ZRAISE_LAZYLOADload
api_methodrA   r,  r%  )r   r   r   r  Zm2m_field_namerC  rZ  r   r'  rh  Z_check_inval_doneZ_do_invalidate_donera  r   r   Zno_caching_fieldsZcluster_load_fieldsr*  Zcc_field_nameZ
cc_clusterZcluster_field_is_changedr   rY  r   
invalidate;  s   "% 


 
"








$&"
  ""

zCmfCache.invalidatec                 C   s<   | j D ]\}}td| q| j D ]\}}td| q$d S )NzDEBUG CmfCache.dumps)rG   r*   rH   r   )r   rl   r   r   r   r   rY   P  s    zCmfCache.dumpsc                 C   s   | dd }tjr"| dd }ztjj|}W n tk
rJ   Y dS X tj	st|j
rf|jtjkrfn| | dS |j
stddd d S |tjkr| | dS tj| }||d}|dkr| | |S || | | |S d S )	Nr!   r   rz   rq   .S   DEV: inmemory_get вызван для модели без флага cache_inmemoryTr_  )r'   rA   rS   r   r   r!  r"  KeyErrorr   in_memory_cacher(  r   in_memory_cache_skip_modelsprofiler_inmemory_data_skipr   r   INMEM_CACHEprofiler_inmemory_data_missrd   move_to_endprofiler_inmemory_data_hit)clsrl   r+  r   model_cacheretr   r   r   r4  _  s4    




	

zCmfCache.inmemory_getc                 C   s  |dkrt |tjjs t|r,d| }nJ|rvt |trvt |d tjjsZt|d rvd|d j dt| d}t	| j
d| d|  d S t	| j
d|  |d	d }tj
r|d
d }ztjj|}W n tk
r   Y d S X tjs|jsd S |jstddd d S |jr(d}|tjkr@t tj|< tj| }||kr|| |krtd| d| d||   d S |||< t||kr|jdd\}	}
t	| j
d|	  d S )Ni  rN  r   []u/   DEV: skip inmemory_cache obj_size > 128000 — u	    байтzCmfCache:inmemory_add add key r!   rz   rq   ro  Tr_    zInmemory cache error! key:z	 try_add:z exists:F)lastz"CmfCache:inmemory_add evicted key )r   r   r   	BaseModeldataclassesZis_dataclassr   r   r   r@   rS   r'   rA   r   r!  r"  rp  r   rq  r(  r   r   rt  r   r*   popitem)rx  rl   r   r5  Zdetailr+  r   Z	LRU_LIMITry  Zevicted_keyr   r   r   r   r&    sJ    

zCmfCache.inmemory_addc              	   C   s   g }|dkr"t | jd i t_d S |D ]}|dd }tjrL|dd }ztjj	|}W n t
k
rv   Y q&Y nX |jsq&|| |tjkrq&tj| }|D ]}||d  qq&|s|rtjdt|t dg d S )	NrQ   uS   CmfCache:inmemory_del Полный сброс inmemory_cache при REDISDB.flushdbr!   r   rz   rq   rO   )rP   Zskip_app_id)r@   rS   r   rt  r'   rA   r   r   r!  r"  rp  r(  r   r%   r   delayed_redis_eventsrX   rY   r  getpid)rx  rP   
from_eventZ
event_keysrl   r+  r   ry  r   r   r   r     s.    



zCmfCache.inmemory_delrO   )channelc                    s6   | sd S | d   fdd}t tjd t| d S )NrP   c                      s    t tjd  tj dd d S )Nz*CmfCache:on_inmemory_del event with keys: T)r  )r@   rA   rS   r   r   r   rP   r   r   handler  s    z)CmfCache.on_inmemory_del.<locals>.handlerz&CmfCache:on_inmemory_del spawn handler)r@   rA   rS   geventspawn)datar?   r  r   r  r   on_inmemory_del  s    zCmfCache.on_inmemory_delc              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrTdt jd< nt jd  d7  < dt jkrzdt jd< tjrdt jkrg t jd< t jd | d S )Nr%  inmemory_cache_hitrq   inmemory_cache_missr   Zinmemory_cache_hit_keysr/  rx  rl   r   r   r   r   rw    s    




z#CmfCache.profiler_inmemory_data_hitc              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrTdt jd< nt jd  d7  < tjrdt jkrg t jd< t jd | d S )Nr%  Zinmemory_cache_skiprq   Zinmemory_cache_skip_keysr/  r  r   r   r   rs    s    


z$CmfCache.profiler_inmemory_data_skipc              
   C   s   zdt krt t _W n( tk
r< } z
W Y d S d }~X Y nX dt jkrTdt jd< nt jd  d7  < dt jkrzdt jd< tjrdt jkrg t jd< t jd | d S )Nr%  r  rq   r  r   Zinmemory_cache_miss_keysr/  r  r   r   r   ru    s    




z$CmfCache.profiler_inmemory_data_miss)NF)N)NN)NF)N)F)N)r   )NN)F)=r(   r&   r3   rG   rH   rI   rJ   rS   r,  rg  ZPROCESS_EVICTED_FLUSHr   rV   rp   rs   r   r   r   r   r   r   staticmethodr8   r   r   r   ri   r   r   r  r  r  r	  r   r   r1  r2  r  rd   r  r  r9  r=  r@  r  r  rG  r   rU  r^  rn  rY   classmethodr4  r&  r   Zon_server_eventr  rw  rs  ru  r   r   r   r   rA   F   s   
S
#I
 T

&

m 
  
.
0!

rA   c                   @   s   e Zd Zdd ZdS )CustomJSONProviderc              
   C   s   znt |tjtjfr|j}t |tjs2t |tjrP|jsF| d W S | W S t |tj	rd|jW S t
|}W n" tk
r } zW 5 d }~X Y n
X t|S t| |S )NZ)r   r   ZCmfDateTimer   r   r   dateZtzinfoZ	isoformatr   iter	TypeErrorr   r   default)r   r   iterabler   r   r   r   r  .  s    
zCustomJSONProvider.defaultN)r(   r&   r3   r  r   r   r   r   r  -  s   r  )Zstatic_folderZ	root_pathTZSEND_FILE_MAX_AGE_DEFAULTF)SocketIO	Namespace)RedisManager)Client)
project_idc                 C   s6   t j| }|s2tjj| ddddgd}|t j| < |S )NZui_form_scheme
logic_typeZlogic_prefixZcust_field_conf_schemer|   r   )r   cache_projectsrd   r   Z
CmfProject)r  Zprojectr   r   r   get_cache_project`  s
    
r  rv   c              
   C   s   |rd| dg}nddddg}dd |D D ]r}t || }tj|sVtj||}ztj|shW q.W n" ttfk
r   tj	
 Y nX tj	j|d	d
  S tjD ]$}|| }|rtj	j|d	d
  S qtj	dS )Nzcustom/plugins/z/staticzcustom/static/zcommon/static/zcmf/static/zdist/cmf-angular/c                 S   s   g | ]}t jtj|qS r   )r  pathr>   rR   PROJECT_DIR)r9   dr   r   r   r   u  s     zsend_static.<locals>.<listcomp>T)Zconditionalzdist/cmf-angular/index.html)r	   r  r  isabsr>   isfiler  
ValueErrorflaskZhelpersZ
BadRequestZ	send_filer   HOOK_STATIC_NOTFOUND)Zreq_filenameZpluginsearch_dirsZ	directoryfilenamehookr   r   r   send_staticl  s,    

r  c                   @   s   e Zd ZdZdejdddZdd Zedd	 Zed
d	 Zedd Z	edd Z
edd ZedddZedd ZedddZedd Zedd ZdS ) CmfRedisMemoryWrapperut    Если есть self.redis - используется он
        Если нет - нужен фолбэк
    N)redisc                 C   s   || _ i | _d S r   )r  
memstorage)r   r  r   r   r   r     s    zCmfRedisMemoryWrapper.__init__c                    s    fdd}|S )Nc                    s6   | j rt| j  j||S td | f||S d S )Nu&   Redis memory wrapper запрещен!)r  r   r(   CmfAbortErrorr   r+   r   r   wrapper  s    z/CmfRedisMemoryWrapper.fallback.<locals>.wrapperr   )r+   r  r   r  r   fallback  s    zCmfRedisMemoryWrapper.fallbackc                 O   s   t d S r   NotImplementedErrorr   r   r   r   r     s    zCmfRedisMemoryWrapper.smembersc                 O   s   t d S r   r  r   r   r   r   r     s    c                 C   s   | j |S r   r  rd   r   rl   r   r   r   rd     s    zCmfRedisMemoryWrapper.getc                 C   s   | j   d S r   )r  clearrZ   r   r   r   rV     s    zCmfRedisMemoryWrapper.flushdbc                 C   s   | j |S r   )r  ttlr  r   r   r   r    s    zCmfRedisMemoryWrapper.ttlFc                 C   s   | j j||||||dS )N)nxxxgtlt)r  expire)r   rl   r   r  r  r  r  r   r   r   r    s    zCmfRedisMemoryWrapper.expirec                 C   s$   | j |d}||7 }|| j |< |S )Nr   r  )r   rl   amountr   r   r   r   rK     s    
zCmfRedisMemoryWrapper.incrbyrq   c                 C   s   |  ||S r   )rK   )r   rl   r  r   r   r   incr  s    zCmfRedisMemoryWrapper.incrc                 G   s$   d}|D ]}|| j kr|d7 }q|S )Nr   rq   r  )r   namesr   nr   r   r   r     s
    

zCmfRedisMemoryWrapper.existsc                 C   s   || j |< d S r   r  )r   rl   r   r   r   r   r     s    zCmfRedisMemoryWrapper.set)N)FFFF)rq   )r(   r&   r3   __doc__r  Redisr   r  r   rd   rV   r  r  rK   r  r   r   r   r   r   r   r    s.   







r  cache_settingsr  r}   r  Z	celery_dbZ	run_uwsgiu?   При работе через uwsgi обязателен Redisr   )ZappZcors_allowed_originsloggerZengineio_loggerdbZunix_socket_pathzunix://z?db=zflask-socketio)r  Z
write_onlyclient_managerzredis://usernamepasswordrz   @hostportZ6379r$   message_queue)Payloadr   )r  z/custom/org_name)rI   rJ   )rJ   u&   Неизвестный тип кешаc                 C   s   t |  t t  tj }t| trn|  }| j	| j
d}|rZt |d< | j|d< t||_d|_n4ddd}|rt |d< t| |d< t|}d|_dtj |jd< d	|jd
< d|jd< |S )N)coder  	tracebackdescriptionapplication/jsonr}  zUnknown errorhttps://Access-Control-Allow-Origintrue Access-Control-Allow-CredentialsContent-Type, x-ijtAccess-Control-Allow-Headers)r   r=   r  
format_excrR   
PRODUCTIONr   r   Zget_responser  r  r  rX   rY   r  content_typer8   Zjsonifystatus_codeAPP_FQDNheaders)r   Z
show_traceZresponseZresponse_datar   r   r   handle_exception  s2    




r  Zjwt_rsazjwt_rsa.pub)RSAZcmf_deletedrg_member_ofZdefault_projectZemailZphone
user_localZphone_internalZprimary_roleZonline_statusZvacation_startZvacation_endZon_vacationactivitydoes_not_workauth_inactive_blockZis_admin
is_supportservicedesk_allowZ
first_name	last_nameztwo_factor.two_factor_optztwo_factor.application_verifiedztwo_factor.applicationZlic_evaprojectZlic_evawikiZlic_evaservicedeskZ
lic_evagitZlic_evatestZlic_evacicdZ
lic_evarmsc                 C   sP   t js
d S ztjs&tjjdtjdt_W n  tk
rH   t	
d  Y nX tjS )Nz.CmfPerson:00000000-0000-0000-0000-000000000001r  zapp.system_person() error)rR   AUTH_ENABLEDr   system_personr   	CmfPersonrd   current_person_fieldsr   r<   	exceptionrZ   r   r   r   r  Y  s     
r  c            
      C   s  t jdrt jd} n^t js$dS ztt j}W n  tk
rT   t	
d Y dS X |dkrbdS t|tov|dd} | sdS t| }|jdsdS dt_t|jd	dgd
 }|rt|dkrdS |jdd }|sdS td| }r| \}}ndS |dks$|dks$|dkr,tj}nR|dksT|dksT|dksT|dkr\tj}n"|dksp|dkrxtj}ntj}t|tjjsdS d|kr|j|j d| ddgd}	n|j|ddgd}	|	sdS |t|	j krdt_!|	t_"dS )u  
    Проверяем, что пользователь пришел из share-ссылки
    Если идёт обращение к /files, то проверяем Referer
    Т.к. jsurl передаётся только в апи для других ендпоинтов не смысла путаться парсить body
      Вообще, для API тоже лучше использовать реферер, тогда не придётся по два раза парсить json
    Выставляем:
     - g.sharelink_access_request = True, если пользователь пришел по /share ссылке
     - g.sharelink_access_granted = True, если проверка hash прошла
     - g.sharelink_access_obj = объект, по которому проверяли ключ. Используется в API для доп.фильтрации
    /filesRefererNu{   _check_sharelink_access не смогли распарсить request.data для проверки прав доступаjsurlrv   /share/Tr   r      r$   r   z*^(?P<obj_type>[^:-]*)[:-](?P<obj_code>.*)$docZDOCCmfDocumentZflZFLZIN_WORK	CmfFolderCmfListZEPI-rz   r|   sharelink_hashr  )r  r   )#requestr  rr   r  rd   r  ujsonrf   r   r<   r  r   rF   r   r   sharelink_access_requestr   queryr   r'   rP  rI  groupsr   r  r  r  r~   r   Z	CmfEntityr   r8   r  sharelink_access_grantedsharelink_access_obj)
r  Zjson_resr-   Z
hash_paramZobj_keyrI  r'  Zobj_coder)  r   r   r   r   _check_sharelink_accessj  s^    
(
r  c                 C   s(   | t _| r"| t jkt _| t jkt _t jS )uh   !!! Эта функция не меняет контекст, только инициализирует.)r   _current_personanonymous_usercurrent_user_is_anonymoussharelink_anonymous_user#current_user_is_sharelink_anonymous)personr   r   r   set_current_person  s
    r	  c                 C   sJ   t | dd }|dkr| jS tjs$d S |d k	r0|S td tjtjd d S )Nr  ZFAIL_recursionz#Warning!!! Lazy Calc Current PersonrM   )	r   r  rR   r  r*   r  print_stackrT   stdout)r   Zcpr   r   r   current_person  s    r  c              	      s   zt jstjjdgd}|jsztjj J dd l	}dd l
|j|j  d fddtdD |_|  W 5 Q R X |jt _W n  tk
r   td  Y nX t jS )	Napp_keyr   r   rv   c                 3   s   | ]}  V  qd S r   )choice)r9   r   Zalphabetsecretsr   r   r;     s     zapp_key.<locals>.<genexpr>    zapp.app_key() error)r   r  r   CmfGlobalSettingsrd   r   r   r!  disable_aclstringr  ascii_lettersdigitsr>   rangesaver   r<   r  )r   Zsettingsr  r   r  r   r    s     
r  c              	   C   s   t | dd d k	r| jS ztjs4tjjddtjdt_tj| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W 5 Q R X t  W 5 |  X | jW S  tk
r   td  Y nX d S )	N_anonymous_userzanonymous@evateam.ruTr  Zinclude_deletedr   zcreate-anonymous-user-lock   timeoutzapp._anonymous_user() error)r   r  r   r   r  rd   r  REDIS_DBr  lockacquirereleaser   r   r!  r  system_dataZcreate_anonymous_userr  ddcommit_all_dsr   r<   r  r   Z
redis_lockr   r   r   r    s8      

r  c              	   C   s   t | dd d k	r| jS ztjs4tjjddtjdt_tj| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W 5 Q R X t  W 5 |  X | jW S  tk
r   td  Y nX d S )	N_sharelink_anonymous_userzsharelink-anonymous@evateam.ruTr  z$create-sharelink-anonymous-user-lockr  r  z%app._sharelink_anonymous_user() error)r   r&  r   r   r  rd   r  r  r  r  r   r!  r   r   r!  r  r"  Zcreate_sharelink_anonymous_userr  r#  r$  r   r<   r  r%  r   r   r   r    s<      

r  c              	   C   s   t | dd d k	r| jS ztjjddtjd| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W 5 Q R X t  W 5 |  X | jW S  tk
r   td  Y nX d S )	N_test_guest_userztest-guest@evateam.ruTr  zcreate-test-guest-user-lockr  r  zapp._test_guest_user() error)r   r'  r   r  rd   r   r  r  r  r  r   r!  r   r   r!  r  r"  Zcreate_test_guest_userr  r#  r$  r   r<   r  r%  r   r   r   test_guest_user?  s4      

r(  c                 C   s
   t j S r   )r   r  Zget_settingsrZ   r   r   r   global_settingsh  s    r)  c                 C   s:   t | dr t| dd d k	r | jS tjjddgd| _| jS )N_global_varZaccount_sync_statusZaccount_sync_lastr   )r   r   r*  r   ZCmfGlobalVarrd   rZ   r   r   r   
global_varo  s    r+  lineno   c                 C   s6  |  tddtddf} | j|dd}td|  t|d | dD ]\}}|jd }tj	|j
tjd	d  }td
|||j|jd f  t|j
|j }|rtd|  |j D ]}	t|	 qqJ||d  }
|
rtdd |
D }tdt|
|d f  tdd |D }td|d   d S )NFz<frozen importlib._bootstrap>z	<unknown>T)Z
cumulativezTop %s linesrq   r   z#%s: %s:%s: %.1f KiBi   z    %sc                 s   s   | ]}|j V  qd S r   sizer9   statr   r   r   r;     s     zdisplay_top.<locals>.<genexpr>z%s other: %.1f KiBc                 s   s   | ]}|j V  qd S r   r/  r1  r   r   r   r;     s     zTotal allocated size: %.1f KiB)Zfilter_tracestracemallocZFilterZ
statisticsr*   	enumerater  r  sepr>   r  r'   r,  r0  	linecachegetlinestripformatsumr   )ZsnapshotZkey_typelimitZ	top_statsr#   r2  framer  lineZllotherr0  totalr   r   r   display_topy  s.    


r@  c              
   C   s  t jjjddd tjj| jtj	d}|sdd | j
ddD }tj|d	< tj|d
< tj|d< tjf |}|rd|_|jtj  d|_|jtj  |rd|_|jtjjdd t jj  |jdd W 5 Q R X t  |W  5 Q R  S Q R X d S )Nzcreate-current_person-lock
   r  )loginr   c                 S   s(   i | ] \}}| d s|dkr||qS )Zcmf_r|   )rr   )r9   r   r   r   r   r   
<dictcomp>  s
   
  z+create_person_from_auth.<locals>.<dictcomp>Tr   	cmf_owner
cmf_authorcmf_modified_byZServiceDeskClient)r  )Z	only_data)r   r   r!  ZCmfLockr   r  rd   rB  r   r  r   r   r   r  r  r   ZCmfPersonGroupZsupport_groupr  Z
user_groupr  r  r  r#  r$  )authr  is_servicedeskr  Zperson_valuesr   r   r   create_person_from_auth  s,    



rI  )forcelevelc                 G   sr  t   }ttdd s| s|rn|d k	r<t|trNtt|}n| rHtj}ntj}t   }tt|t	j
 d d}tt|t	j d d}t	di dt }|dd}|dd}	|d	d}
tjd
}t	jd|d| d| dd| d|	 d|
 d||	 |
  ddf|}t|dddd |D  t   t	_tt   | d }|dkrnt|dd| d d S )NrS   r[   rw   r%  Zselect_countZselectr   r   insertmr$   z(+z)mszs zu zi r   r5   r6   c                 s   s   | ]}t |V  qd S r   r7   )r9   partr   r   r   r;     s     zdebug.<locals>.<genexpr>zPROF debug funcion got ms)r   r   rR   r   r8   r<   INFOrS   roundr   debug_start	debug_nowrd   rF   r  r   
request_idlogr>   r   )rJ  rK  messagesZdebug_str   r   r  ZscZscsZscuZscirM  partsZ	debug_endr   r   r   r=     s@    
   "

r=   c                  C   s   t jd} t jdrZ| rZtt| j}|t  dr@dS |dsT|drdS ntt jdrjdS t jd	st jdrd
S t jdst jdst jdrdS t jdrdS t jdrdS dS )Nr  /files/Zservicedesksd_api/docs/r  Zpub_api/servicedesk/api/Zapi/pub//auth/rG  /with-contextsystemZdeny)r  r  rd   r  rr   r8   r   app_base_href)ZrefererZreferer_pathr   r   r   set_api_scope  s$    $rb  c               	   C   s
  t jdkrdS t  t  t  dt_i t_	i t_
g t_tjddkt_ddlm}  ddlm} |  t_tjt_d	|d
ddt_dt_g t_g t_dt_dt_dt_dt_dt_dt_dt_ dt_!dt_"dt_#dt_$dt_%dt_&dt_'dt_(dt_)dt_*dt_+t, t_-dt_.dt_/t0j01t0j2j3t_4dd t_1tj45 t_6dd t_5dt_7i t_8i t_9g t_:g t_;i t_<dt_=dt_>t? t_@i t_Ag t_Bdt_Cdt_Ddt_Eg t_Fi t_Gi t_Hi t_It? t_Ji t_Kg t_Li t_Mi t_Ng t_Og t_PtQt_Qdt_Rdt_Sdt_Tdt_Ut? t_Vdt_WtXjYZ  tXj[Z  t\j]s<t^d dS t j_`drNdS tajbstajcstQdtd  d taje tQdtd  d tajbstQdtd  d tf  tg  t\jhrti  t\jjrtk  dta_btQdtd  d ntQdtd  d W 5 Q R X t\jlr2d	tmddt_Wd}d}t j_`dsVt j_`drt jnd}|st jnd}|r|`dr|todd }nd}|st jpd }|rtXjqr|}tXjqj|dtajsd!}tQd"|dd  d#| d$|  |sttud%t jnt jp tvd&d'd(d)S t j_d*kr:tXjwjxtajsd+}t j_`ty  d,rd-}d.t jzkrjt jzd. }t{|}|st|d.|i}t}ty  d/| }d0t\j~ |jnd1< d2|jnd3< d4|jnd5< |S d6}	|  }
|s2t jd7}t jd8}|rtXj|\t_t_/n|rtXj|t_tjrRt\jo<tXjjtjjjd9}t\jrR|sRdt_tjr2tjjjt_d:d;tjjgg}tXjqj|tajsd<}d=tj d>}	|r|jrtQd=|j d? d}n$|jr2d=|j d@}	tQ|	 d}nN|rt|tjjdA}n6tjjrttjtjjdA}ntjjr2ttjddB}|  |
 dCkrXtQdD|  |
   t j_`dEp~t j_`dFp~t j_`dG}dHdI }|r|jjt_tjrtjjt_tjj t_ndt_|j t_dt_t^| nN|s| rtj}t  tj(r tj}dt_dt_t^| ndt_t^tj tjpt j_`dJpt j_`dKpt j_dLkpt j_`dMpt j_`dNpt j_`dOpt j_`dPpt j_dQkpt j_`dRpt j_`drt jzdSdTkrt jdUkpt j_`dVpt j_dWkpt j_`dXpt j_`dYrt jdUkpt j_`dZr0t jdUkp| rRt j_`d[rRtXj p| rtt j_`d\rttXj pt j_`d]rtjptt j_pt j_`d^otj}tj}tj}|  }
tXj[  |  |
 dCkrtQd_|  |
   |s| 	r dS tj-d`k	rB|	s*tj	r"t|	S t|	S |j
s*|j
s*t S ntj	rX|	sXt|	S t j_d-k	r|	r|j	s|j	rt}daS t}dbS |	stdcS |j	st\j	stddS tj	rt S tj
s*ttXded
r*|
r*|j
r*|  }
tXj 
st}t  dfS |  |
 dCk
r*tQdg|  |
   taj
sjdta_|  }
t  |  |
 dCk
rjtQdh|  |
   tj/
r|  }
tj/ }|  |
 dCk
rtQdi|  |
   |
r|S dS )juJ  
    Должны вернуть Response or None
    Особенности поведения:
      В случае web запроса:
        - response - view не выполняется, сразу отправляем response
        - None - выполняем view
        - Exception(в т.ч. и abort) - обработчик выводит трейс клиенту
      Системный контекст(shell, celery, socket, other with cmf_context):
        - None, Response - нет разницы
        - Exception - прерывает выполнение.
    ZOPTIONSNFZ
run_pytest1r   r   )choicesrv   Z0123456789abcdef   )r   c                   S   s   t jS r   )r   _nowr   r   r   r   <lambda>'	      z before_request.<locals>.<lambda>c                   S   s   t jS r   )r   _dater   r   r   r   rh  )	  ri  Tz/memZOKz"Wait first_request_init lock (pid=)z!Got lock first_request_init (pid=zStart first_request_init (pid=zDone first_request_init (pid=z%Already done first_request_init (pid=Z>qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789   r\  rX  zX-Eva-TokenZAuthorizationzBearer token)api_token_hashr  r   zAuth API Token(z...): hash=z	, person=z6Invalid API token: request.headers=%s, request.args=%szInvalid API token  
text/plainr  /pub/webhookr   zauth/not_authorizedr$   next_urlauth/signin?r  r  r  r  r  r  uU   Требуется авторизация. Введите логин и пароль.session_tokenaccess_token)rB  rB  ==filterr   u   Учётная запись uQ    заблокирована. Обратитесь к администраторуu    заблокирована.uo    заблокирована за неактивность, обратитесь к администратору)r  )rH  g?z-PROF before_request get auth and session got z/pub/pub_apiz/docsz/sharec                   S   s   t jdpt jdS )Nr  /socket.io/)r  r  rr   r   r   r   r   is_allow_public
  s    
z'before_request.<locals>.is_allow_publicz/health_check/z
/auth/sync)z/auth/invitez/auth/restore_passwordz
/auth/signz/servicedesk/auth/signz/servicedesk/auth/invitez/servicedesk/auth/two-factorz"/servicedesk/auth/restore_passwordz/auth/two-factormoderootz	127.0.0.1z/crm/forms/z/manifest.webmanifestz/app/assets/z/forms/z/js/r]  z/sso/z	/helpdeskz/nolicense.htmlz6PROF before_request CmfAccessList.setup_context() got rY  r[  rZ  u)   Требуется авторизацияu-   Доступ в раздел запрещен
CmfLicenseznolicense.htmlz,PROF before_request license_ui_access() got z-PROF before_request prepare_plan_cache() got z/PROF before_request tfa_check_two_factor() got )r  methodcheck_db_lockr   r  r#  before_requestr   r  r  flagsremove_filesr  r  rd   Ztestr   r   re  rS  rR  r>   rT  Zsave_only_data_hackalertnoterG  rB  Zis_guest_userZis_anonymousr  Zis_system_contextr  r  Zdisable_notifyZimport_modesession_tab_idZcomponent_idZinteractive_shellr  r   rm  Zapi_argsZ
api_kwargsrb  	api_scoper  sessionr   r   rt   r   rg  r  rj  Zrelaxed_bz_python_mode	emit_listsocket_eventsserver_eventsZdeferred_audit_listZdeferred_fullsearch_dirty_listr  Zjscache_timelifer   r   r   rB  ZTEXCOM_ENABLE_GROWCACHE_HACKr3  rq  rr  Zacquired_locksZacquired_locks_shZacquired_lock_timignsr#  Zfulltext_search_headlinesr  Zproject_perm_browse_cacheZ%project_perm_timetrackerhistory_cacheZshow_bg_progressbarZapi_hack_fieldsr=   Z
new_acl_idZapi_license_requiredZ license_disable_user_count_hooksZbackbone_syncZcurrent_save_objects	csp_noncer   ZCmfDeferredJobZinit_contextCmfAccessListrR   r  r	  r  rr   r   first_request_init_donefirst_request_init_skipr  first_request_init_lockapp_init_aclapp_init_project_permissionWHATSAPP_MESSENGER_URLspawn_messenger_socketio_clientWHATSAPP_WEB_SOCKETspawn_whatsapp_socketio_clientCSP_ENABLEDZsampler  r   r   r  Z
hash_tokenr  r<   warningr   Z
CmfWebhookZget_token_personauth_base_hrefr   check_sso_redirectr   redirectr  ZcookiesZ
CmfSessionZ
from_tokenCmfAuthZfrom_jwtZIS_AUTHORIZATORr   r  r  rI  Zjwt_is_supportr)  Zservicedesk_allow_auth_guestsZjwt_is_match_orgr  r  r  r  r   Zremote_addrZ	CmfPluginZcheck_secretSTATIC_URL_RErI  r  Zsetup_contextreject_responser  r   r~  Zlicense_ui_accessra  prepare_plan_cache_doneprepare_plan_cacheZtfa_check_two_factor)r   re  Zauth_personZ	real_authZ	api_tokenrn  rs  r   qserr_msgprof_stru  rv  _filterZis_force_publicr{  Zanon_personZis_allow_without_authr   r   r   r   r    s8   





   $




















	

 


#	
$
r  c                 C   sF   dddgg}t jdkr&|dddg tjj|d}|rB|| S d S )NZdisabledrw  FrY  Zservicedesk_supportT)ry  )r   r  r   r   ZCmfAuthOpenIdPluginrd   Zlogin_redirect)rs  r  Zopenidr   r   r   r  
  s    
r  c                 C   s  t jdkstjdkr2tdt jtjtjtjtj t j	dsTt j	dsTt jdkrft
| p\ddd	d
S tt j}d|i}| rt| d | |d< t|}d }|st|}|stjdkrtt  d| }ntt  d| }dtj |jd< d|jd< d|jd< |S d S )Nr_  r`  zJRequest reject access: path=%s, auth=%s, login=%s, api_scope=%s, person=%srz  r\  rr  znot authorizedro  rp  rq  rs  Z
auth_errormessagerY  zservicedesk/auth/signin?rt  r  r  r  r  r  r  )r  r  r   r  r<   r  rG  rB  r  rr   r   r   r-   r   r   r  r  r  rR   r  r  )r  Zskip_ssors  paramsr  r   r   r   r   r  
  sB        






r  c                   C   s   t   t  t  d S r   )r#  r$  emit_eventsemit_server_eventsr   r   r   r   commit_with_event
  s    r  c               	   C   sN   t dsd S t j D ]*\} }td|d  |d|ddd qi t _d S )Nr  is_changed-r   r$   r   private)	namespacer   )r   rd   r  r   r   )r   r   r   r   r   emit_list_apply
  s
    
$r  c                 C   s  |   D ]\}}|D ]}|d }|d= t|d }|d= |d  }z"t| t| t| W nJ tk
r } z,td| d| d| d|  W Y qW 5 d }~X Y nX t|ts|j	|f|d |d	|d	 i q|d
 r,|d
 dks,|d
 |d
< |j	|f|d |d	|d	 i q|
dr|d rd|d d krj||d d d  d|d d kr|d d d D ]}|| q|D ]r}	t|	tjjrtd|	 d| d| d|  |	jj}
nt|	}
|
|d
< |j	|f|d |d	|d	 i qqqd S )Nsocket_clientr   r   uP   DEV: FATAL emit пришел с несериализуемыми данными z! socket_client:z; event_persons:z; event_param:r   r  r   r  rA  event_current_personr   Zrelation_personsuY   DEV: INFO Кривой евент, в event_person попал объект, а не str: r6   )r   r   copyrX   rY   r   r*   r   r  ri   rr   r   r   r   r  r|   r   r8   )Z
event_dictmsgZevent_param_listZevent_paramr  r   Zemit_kwargsr   Zuser_idevent_personevent_persons_strr   r   r   emit_events_dict
  sF    


 
""
 
r  c                   C   s   t dd d S )Nr   delay)emit_events_with_delayr   r   r   r   r    s    r  c                  C   sX   dd l } tdsd S i }|  tjD ]$}|dr&tj| ||< tj|= q&t| d S )Nr   r  Zproject_notify)r  r   rd   r  rr   r  )r  r  r  r   r   r   emit_project_events  s    


r  c                    sL   t   tdpi i t_r< r< fdd}t| nrHt dS )u   Запускаемся в контексте, но отправляем в отдельном таске вне контекста, после паузы, чтобы не держать запрос.r  c                      s   t   t d S r   )r  sleepr  r   r  r  r   r   emitter,  s    
z'emit_events_with_delay.<locals>.emitterN)r  r   rd   r  r  r  r  )r  r  r   r  r   r  %  s    r  c                  C   sP   t dpg } g t _| D ]2\}}t d| d|  tj|t| qd S )Nr  zemit_server_events: rN  )	r   rd   r  r=   r  r  rW   rX   rY   )r  r  r  r   r   r   r  7  s
    r  c                   C   s   t   i t_d S r   )r#  Zrollback_all_dsr   r  r   r   r   r   rollback_purge_event?  s    r  c                  C   s2   t dg D ]} tj| rt|  qg t _d S )Nr  )r   rd   r  r  r   r  r  r  r   r   r   apply_deferred_remove_filesE  s    r  c                 C   s   t jrtjt j|  dS )u   Сессия может быть продлена через SSO, надо продлить куку

    Args:
        r (response): ответ браузеру в котором обновляем куки
    N)r   r  r   r  Zset_session_tokenr   r   r   r   update_cookiesM  s    r  c                 C   s   t ddd t|  tjrZtjds2tjdrPdtj dtj d| j	d	< n
d
| j	d	< dtj
 | j	d< d| j	d< d| j	d< d| j	d< | S )uk   
    Запускается только если небыло ошибок
    :param r:
    :return:
    Trw   )after_hooksevent_delayz/servicedesk/auth/r^  z-default-src 'self'; script-src 'self' 'nonce-z'; style-src 'self' 'nonce-z?'; base-uri 'self'; form-action 'self'; frame-ancestors 'self';zContent-Security-Policyzdefault-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 'unsafe-eval'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; img-src 'self' data: blob:;r  r  r  r  r  r  byteszAccept-ranges)
cmf_commitr  rR   r  r  r  rr   r   r  r  r  r  r   r   r   acaoX  s    
		


r  c               	   C   sN   ddl m}  tjsd S tjt_tjj	
  tjjj  W 5 Q R X |   d S )Nr   spawn_server_event_listener)Zcmf.cmf_server_event_listenerr  rR   r  ZDISABLE_PERMISSIONSr   disable_permissionsr   r   r!  r  includer   r  Zload_acl_datar  r   r   r   r    s    r  c                	   C   s<   t tjjdsd S tjj  tjjj  W 5 Q R X d S )NCmfProjectPermScheme)	r   r   r  r   r   r!  r  r  Zload_project_permission_datar   r   r   r   r    s    r  c                  C   sX  t tddkrd S tjj * tj } tjj	| d d}|
  W 5 Q R X tj	 }|r"|  |  |ddddg |d	d
ddddg |ddddddddg |ddg |dddddddddd d!d"d#g |d$g |dddd%ddd&d'd(d)g
 |dd*d+d,g |d+d,g |d-d.d$g |d/g |d-d0d1g |d2d3d4ddd+d,d5g |d6d7dd8g |d9dg |dd:g |ddd;g |d<d=d>dddd?d@dAdBdCdDg |dEdFdGdHdIdJdKg |dddddLdddddd d!dMd"d#dNdOg |dPg dQdRdSgdTdQdRdSgdQdRdUggfD ].}|dVdRdWgg}tjj|dXdYdZd[d\gd] qBtj	 }|r|  |  |ddddg |dd^ddd_d`g |d6dd^dadbdcddg tj	 }|r4|  |  |dedg |dfdgdhdg |d	d3ddidjdeddkdldmdndog tj	 }|rT|  |  d S )pNr  z/opt/eva-appr|   )r|   r  r  r  Z	scheme_wfrE  ZdealZordernozparent.project_idr  rD  z
perm_acl.*zperm_acl.cmf_ownerz!perm_acl.object_ownerperm_inheritZperm_effective_acl_idZperm_has_aclZperm_inherit_acl_idZperm_parentZparent_logic_prefixz0parent.sl_allow_executor_change_nofatal_deadlinezparent.sl_deadline_shiftzparent.sl_deny_no_approvezparent.sl_only_owner_approvezparent.sl_task_need_approvezparent.sl_task_only_owner_closezworkflow.enable_sl_controlz2workflow.sl_allow_executor_change_nofatal_deadlinezworkflow.sl_deadline_shiftzworkflow.sl_deny_no_approvezworkflow.sl_only_owner_approvezworkflow.sl_task_need_approvez!workflow.sl_task_only_owner_closez'project.task_code_use_logic_type_prefixZperm_inheritZperm_policyZperm_policy_anonymousZperm_policy_guestZperm_policy_sharelinkZcmf_owner_assistantszparent.cmf_ownerzparent.cmf_owner_assistantszlogic_type.obj_code_prefixzproject.task_code_prefixz!parent.default_agile_story_pointszparent.task_code_prefixz&parent.task_code_use_logic_type_prefixZcache_status_typeZcmf_created_atrF  Zwaiting_forr  ZhrefZui_nameZop_gantt_taskZtree_parent_idzparent.ui_form_schemeZagile_story_pointsZ	executorsZlistspriorityZresponsiblezresponsible.namestatuszstatus.status_codezstatus.status_typezcmf_author.user_localzcmf_owner.user_localzexecutors.user_localzparent.cmf_owner.user_localzresponsible.user_localzspectators.user_localzwaiting_for.user_localzparent.sl_readonly_closed_taskz workflow.sl_readonly_closed_taskz5workflow.sl_deny_closing_task_before_closing_subtasksu.   workflow.sl_сlose_task_after_closing_subtasksz9project.security_level_scheme.default_task_security_levelZcache_action=r  ORre  Z	cmf_modelCmfTaskZjson_filterZjson_entry_pointZjson_actionZ	func_nameZ	json_datarx  r  zparent.logic_prefixZsys_typezparent.codez	parent.idzparent.logic_type.namezparent.nameZ	log_levelzparent.activityzparent.logic_type_idzparent.scheme_wfZ	importantZlikeszperson_views.personr  Z
spectatorstextZtree_parent)r   rR   r   r   r!  r  r   r  Zcreate_dummy_taskrd   Zdelete_dummy_taskZsave_prepareZ_load_perm_fieldsrk  Z
CmfTriggerr   r  Z
CmfCommentZ	CmfNotify)Zdummy_task_dataZ
dummy_taskr   Z_fr<  cr  r   r   r   r    sh    

$",$

"
r  c                 C   s   t | d d S Nr  )cmf_rollbackr  r   r   r   teardown_request  s    r  c              	   C   s   |rt jsdS |dkr&|r tjntj}tjd| d|d|d||d |dk	rd|t j krddS |rdt	
 }td|  t| | tjkrtj|  dS )	   
    Глобальная функция для оповещения фронта о предупреждениях
    :param msg:
    :return:
    Nzcmf_alert: msg=z abort= debug_only= devel_only=rK  r   zcmf_alert Stack:
)rR   rS   r<   ZWARNINGrP  r   r=   r  r>   r  format_stackr  r  r   )r  r`  r   
devel_onlyrK  Z	stack_strr   r   r   r     s    
&
r   c                 C   sn   |rt jsdS |dkrtj}tjd| d|d||d |dk	rT|t j krTdS | tjkrjtj|  dS )r  Nzcmf_note: msg=r  r  r  )	rR   rS   r<   rP  r   r=   r  r  r   )r  r   r  rK  r   r   r   cmf_note  s    
 
r  r  )r  r  r   r   c             
   O   s  |st }zdtkrt t_W n( tk
rD } z
W Y d S d }~X Y nX t|dkrldtjrdtjjjpfd ig}t	|d tkrdtkrtj
|d d< nd|d d< tjrtjjjpd |d d< t||||d}t| ||d< d	}	d
D ]}
| |
rd}	 q q|	rtdt   |s:tjg}|	s:tdt   g }|D ]4}t|tjjrf||jj n|t| qB||d< t|d  tj| g }||kr|| d S )Nr  r   r_   r  rv   r  )r   r   r  r   r  F)
zevent-zinvaldebug-ztask-comment-zaudit-task-comment-znotify-person-r  zcomment-z	notify-osznotify-important-ZDEBUG_TuC   DEV: WARNING в cmf_emit_event не указали cmf_emit_event: u   DEV: FATAL!!!!!!!!!!!!!! Добавьте меня в спинт Баги реактивности. 10.10.2022 в cmf_emit_event не указали cmf_emit_event: r   )socketior   rF   r  r   r   r  r|   r   r}   r  rX   rY   rr   r*   localsr   r   r   r   r  r   r8   
setdefault)r  r  r  r   r   r   r   r   Zevent_paramsZmutedZ
muted_debtr  r  Z
event_listr   r   r   r     sL    


r   c                 C   s  |rd |nd}|rdnd}	|r&dnd}
d |	|| |
g}|rRddlm} | }tj|dtjtjd	}|r| \}}|r| }| }|j}|r|rt	d
| t	d| t	d| t
d| |g}|r|| || n||p| |r|| |  |S dS )u  
    :param command: собственно, команда которую необходимо выполнить
    :param sudo: необходимо ли команду выполнять от рута
    :param timeout: секунд на выполнение. Дальше команда получит SIGTERM.
    :param wait: True дождаться окончания выполнения команды, False запустить и забыть, вернёт (None, None)
    :param separate_out_and_err: отдельно stdout, отдельно stderr, иначе не ясно как это всё парсить
        False по умолчанию, чтобы никому ничего не сломать.
    :param do_decode: возвращать декодированные строки вместо байт
    :param do_raise: выбрасывать исключение в случае, если код возврата != 0 (удобно для логирования трэйсбэков)
    TODO: почему u''? Наследие python2 и биллинга или реальная необходимость?
    TODO: Можно перейти на f'{sudo}bash -c export BLA=BLA;{timeout}{cmd}{redirect}', читается лучше
    ztimeout -v {0} rv   zsudo z 2>&1z0{0} bash -c "export BOOTUP="noncolor";{1}{2}{3}"r   rd  T)shellr  rU   u6   Произошла ошибка при вызове %sz
STDOUT: %sz
STDERR: %su4   Произошла ошибка при вызове )NN)r9  r   
subprocessPopenPIPEZcommunicaterc   
returncoder<   errorRuntimeErrorr   )ZcommandZsudor  waitZseparate_out_and_errZ	do_decodeZdo_raiseZmeasure_runtimeZtimeout_cmdZ_sudoZ	_redirectcmdr   Zpopen_startZprocessouterrZerrcoderz  r   r   r   run_bash_commandF  sH    
r  c                 C   sL   t tj}t }||   ||}t	|
 }|  d| }|S )ua   
    Подписываем токен сертификатом
    :param jwt:
    :return:
    r!   )r   rj  r   rsa_private_keyr
   r   r   signbase64	b64encoderc   )jwtZsignerZdigestr  r   r   r   r   rsa_sign_pack_jwt{  s    
r  c                 C   sH   ddd}t t|  }t t|   } | d|  S )uD   
    Создаем токен
    :param payload:
    :return:
    ZRS256ZJWT)Zalgtypr!   )r  r  rX   rY   r   rc   )payloadheaderr   r   r   
create_jwt  s    
r  c                   C   s   t jS )u2   
    Текущая версия
    :return:
    )rR   ZCMF_VERSIONr   r   r   r   cmf_get_version  s    r  c                 C   s   | t jkrt j|  dS )ux   
    Удаления файлов после коммита транзакции
    :param filename:
    :return:
    N)r   r  r   r  r   r   r   cmf_remove_file  s    
r  c                 C   s   t j| d d S r  )r#  r$  r  r   r   r   r    s    r  c                 C   s   t   | rt }ddlm} t  |j  |j	
  t  t|d t  t  t   t | dkrtdt |   d S )Nr   )r   r  g{Gz?z PROF cmf_commit after_hooks got )r#  r$  r   cmf.includer   r   r   ZCmfAuditZapply_deferred_auditZCmfFullSearchZapply_deferred_dirtyr  r  r  r  r   r=   )r  r  r  r   r   r   r   r    s    


r  c                   @   s,   e Zd ZdddddZdd Zd	d
 ZdS )cmf_contextFTNrB   c                 C   s   t d| _|| _|| _d S )Nr_  )r   Ztest_request_contextctxinit_views_and_dspreprocess_request)r   r  r  r   r   r   r     s    zcmf_context.__init__c                 C   sJ   ddl m} | rtd| j  | jr8t  t  | j	rFt
	  d S )Nr   )has_app_contextu;   Контекст нельзя включать дважды)r  r  r   r  	__enter__r  start_viewsr#  Zinit_dsr  r   )r   r  r   r   r   r    s    
zcmf_context.__enter__c                 C   s6   z|rt|d n
tdd W 5 | j ||| X d S )Nr  T)r  )r  __exit__r  r  )r   excr   r  r   r   r   r     s
    zcmf_context.__exit__)FT)r(   r&   r3   r   r  r   r   r   r   r   r    s   r  c                  C   s   ddddddg} t jdd | D  }|D ]\}}}|tjd	}|d
r(|D ]\}|dsf|drN|dsNddd |dD }t	j
|d |dd  d d qNq(tjddtd tjddtd tjddtd tjddtd t  d S )Nz	cmf/viewszcmf/modulescommonmoduleszcustom/commonzcustom/modulesc                 S   s&   g | ]}t jtj d | ddqS )r$   T)followlinks)r  walkrR   r  )r9   Z
search_dirr   r   r   r     s   zstart_views.<locals>.<listcomp>rv   z/viewsz.pyz.pycz__init__.pyr!   c                 s   s   | ]}|r|V  qd S r   r   )r9   r   r   r   r   r;     s      zstart_views.<locals>.<genexpr>r$   r   )packager}  )r    Z	view_funcz/<path:req_filename>Zdistz/static/<path:req_filename>Zstaticz,/plugins/<plugin>/static/<path:req_filename>Zplugins_static)	itertoolschainr   rR   r  r   rr   r>   r'   	importlibimport_moduler   r)   r  app_before_run)r  Zsearch_iterdirnamedirnames	filenamesr  r,   r   r   r   r    s(    

$  r  c                   C   s   d S r   r   r   r   r   r   r    s    r  c                 K   s,   | dd ||d< ||d< | jf | d S )NZ	countdownrw   r   r   )r  Zapply_async)Zjobr   r   r/   r   r   r   schedule_deferred_job  s    r  c                  C   s"   dd } t jrtj| dgd d S )Nc                 S   s2   i }t jdd rdtji}tjtj| |d d S )NZSOCKETIOr   
namespacesr  )r  r  rd   rR   ORG_NAMEwhatsapp_sioconnectr  r  r   r   r   messenger_connect  s    
 z:spawn_messenger_socketio_client.<locals>.messenger_connectz	/whatsapp)r  )rR   r  r  r  )r  r   r   r   r    s    r  c                   C   s   t tjtj d S r   )r  r  whatsapp_go_sior  rR   r  r   r   r   r   r    s    r  c                  C   s@   dd l } tddtj dtj  | jtjtjdddd d S )Nr   r5   uY   Подключаемся к удаленной отладке config.REMOTE_DEBUG_SERVER=z config.REMOTE_DEBUG_PORT=TF)r  ZstdoutToServerZstderrToServerZsuspend)pydevd_pycharmr<   inforR   ZREMOTE_DEBUG_SERVERZREMOTE_DEBUG_PORTsettrace)r  r   r   r   cmf_pycharm_debug  s     r  rB   c                  C   sH   t tjtjttt ttt d tjj	dd} t
| }t|S )N<   Zguid)ZissZorg_nameZiatZexpr  Zjti)rF   rR   r  r  r8   r   r   r   r  r   r  r  )r  r  r   r   r   gen_eva_app_token  s    r  )urir  c           
      C   s   ddl m} tjrtjdkrPttj|d }|dg }|di }|||}n| }ddd	d
|_t	  |  }t
 |d< |j|t|d}	|	jdkrtd| d|	j d|	j |	 }|rd|krtd| t| |S )Nr   )r  Falser  r   r   r  rp  r   )zContent-typeZAcceptzContent-EncodingZeva_app_token)r     u9   Не удалось отправить запрос, url=z, status_code=z, res=r  u(   Сервер вернул ошибку: )Zrequestsr  rR   ZEVA_ACCOUNT_USEr   r   r  rd   r  r  r  ZpostrX   rY   r  r   Zcontentr   r=   )
r  r  r  r  Zmethod_argsZmethod_kwargsresultr   r-   r   r   r   r   call_eva_account*  s.    


r!  Zeva_db_upgrade_runningc                 C   s6   | st t } tjjt| ddds2tdt dS )u   Запускается перед миграций БД. Информирует приложение, что не следует открывать транзакции.r-  T)exr  zCannot lock N)r8   r  r  r  r  r   _DB_LOCK_KEYCmfError)r   r   r   r   app_db_upgrade_startP  s    r%  c                   C   s   t jt dS )u   Запускается после миграций БД. Информирует приложение, что можно продолжать работать.N)r  r  rg   r#  r   r   r   r   app_db_upgrade_stopX  s    r&     c                 C   s^   dd }d}t   }| rZ| r.t   | |krF|rBtdt ndS |d7 }t d qdS )u   Проверяем не заблокировано ли использование БД, если заблокировано, то можем дождаться разблокировки.c                   S   s,   t rt t  dkr(tjtat a tS )uW   используем кеш 1sec, чтобы часто не ходить в редисrq   )_db_lock_cache_tsr   r  r  rd   r#  _db_lock_cacher   r   r   r   
check_lock_  s    z!check_db_lock.<locals>.check_lockr   z
DB locked Frq   T)r   r$  r#  r  )r  r  Zraise_errorr*  r]   startr   r   r   r  ]  s    r  c                  C   s>   dd l } tjrd}ntj}| j|dd |  }|| d S )Nr   rS   z:%(asctime)s %(process)d %(name)s %(levelname)s %(message)s)rK  r9  )Zlogging.handlersrR   rS   Z	LOG_LEVELZbasicConfigZ	getLoggerZsetLevel)r<   rK  r  r   r   r   init_loggingt  s    r,  httpsc                 C   sR   t jpd}|ds|d7 }| rNt jr2dt j nd}| dt j | | S |S )Nr$   rz   rv   z://)rR   	BASE_HREFr   EXTERNAL_PORT_HTTPSr  )Zfull_urlZprotocol	base_href	port_specr   r   r   ra    s    

ra  c                 C   sl   t jrt j}nH| rD|rd}qHt jr.dt j nd}dt j | }nd}|t jpRd7 }|dsh|d7 }|S )Nzhttp://127.0.0.1:8080rz   rv   r  r$   )rR   ZAUTH_SERVER_URLr/  r  r.  r   )absoluteZinternalr0  r1  r   r   r   r    s    
r  )rv   N)r,  r-  )FF)N)NF)r   )N)FFNN)FNN)TNTFFFF)T)Tr   )NN)N)Tr'  T)Fr-  )FF)r  r  r<   rT   Zfcntlr  r   re   r   r  r   r  	threadingrf  r   r   pathlibr   urllib.parser   r   r   r   Zwerkzeug.utilsr	   r  r   r  ZCrypto.Hashr
   ZCrypto.Signaturer   r  r   r   Zflask.json.providerr   Zwerkzeug.exceptionsr   r   r   r  Zcmf.data_providersr   r#  Zcmf.system_datarP  rQ  r  r   r@   objectrA   r  r(   rR   r  r   rX   r  r  r  r  Zcache_in_project_roler  Z
rpc_modelsZclean_attributesr  r  Lockr  Zall_models_metaZ
SECRET_KEYZ
secret_keyZflask_socketior  r  r  r  r  r  r8   r  r  r  r  r  r   r  r  Zcfgr%   r  r  r  rd   r   rS   Zsocketio_kwargsr  r-   r  r  Zengineio.payloadr  Zmax_decode_packetsr  r  r  r   openr+   readr8  r  r   ZREDIS_DB_IDZREDIS_DB_ID_TIMERZerrorhandlerr  Zregister_error_handlerZprivate_key_pathZpublic_key_pathZCrypto.PublicKeyr  Z
import_key
read_bytesr  Zrsa_public_keyr  r  r	  r  r  r&  r   r  r  r(  propertyr}   r   r   r   r)  r+  r@  rI  r=   rb  r  r  r  r  r  r  r  r  r  r  r  r  r  Zafter_requestr  r  r  r  r  r   r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rF   r!  Zcache_notify_scheme_ruleZcache_person_notify_optZcache_cust_field_config_schemeZcache_email_listrt  r#  r)  r(  r%  r&  r  r,  ra  r  r   r   r   r   <module>   s  
           r



C 


	 



'

                        b	 "

!
   <
	
'0

&B

:    
5



	



