U
    Ohf                    @   s@  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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 d dl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/m0Z1 d dl2Z,d dl3Z3d dl4m5Z5 d dl	m6Z6 d dl7m8Z8 e39dZ:G dd de;Z;dd Z<G dd de=Z>G dd de)Z?e;e@deAjBdZCe?eCeC_DdeC_EdeC_Fg eC_GdeC_Hd eCjAd< i eC_IdeC_Ji eC_KdeC_LdeC_MdeC_NeO eC_Pi eC_QeAjReC_Sd dlTmUZUmVZV d d lWmXZX d dlYZYeZd!d"d#Z[i eC_\e[eC_[da]d$d% Z^dd'd(Z_G d)d* d*Z`e` ZaG d+d, d,Zbeb ZceceC_ce> Zdd d-lemfZf d.ef_gG d/d0 d0Zheh ZWejijd1rd d2lkmlZl eld3d4 ZmeXeAjnd5ZoeXeAjnd5ZpejqreAjBd6 rfeseAjBd6 Ztetu v eA_wW 5 Q R X eaeC_adeC_xd eC_yeCze{d7d8 Z|eC}e{e| eeAjBd9 Z~eeAjBd: Zd d;lmZ e~r ree~ eC_er ree eC_d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYgeC_dZd[ ZEd\d] Zd^d_ Zd`da Zdbdc ZFdeC_deC_deC_ddde Zdfdg Zdhdi ZeeEee_EeeEee_eeee_eeee_eeee_eeee_eeee_eeFee_Fdjdk Zeeee_dldm Zeeee_ddpdqZddrdsZdddtdudvZdwdx ZeCjdydz Zdd{d|Zdd}d~Zdd ZdddZdd Zdd Zd ddZdddZdddZdd ZdddZdd Zdd Zdd ZeCjdd Zdd Zdd Zdd ZeCjdddZdddZdddZdddg dddZdddZdd Zdd Zdd Zdd Zdd Zdd ZdddZd	ddZdd Zd
eZdddZdeZdddZdeZdddĄZdeZdddƄZdeZdddȄZdeZdddʄZdeZddd̄ZÐdeZddd΄Zeje	j	 e	j	dϜddфZe	j	e	j	dҜddԄZG ddք dփZdd؄ Zddڄ Zɐddd܄ZʐdddބZdd Zdd Zdd ZeZdddZeZedddZi eC_i eC_i eC_i eC_i eC_i eC_dZdadaڐdddZdd ZܐdddZdd ZސdddZߐdddZdS (      N)OrderedDictdefaultdict)Path)OptionalTuple)urlparseparse_qs	urlencodequote)	safe_join)SHA256)
PKCS1_v1_5)Responseflash)DefaultJSONProvider)HTTPExceptionfields)*)base)relativedelta)	timedeltastr_to_timedeltaz^.*\.(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   0   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%   	decorator4   s    zFlask.route.<locals>.decoratorr$   )r   r6   r5   r7   r$   r4   r%   route3   s    zFlask.route)r.   r,   __qualname__r   r8   __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>G   s     zprint_debug.<locals>.<genexpr>)loggingdebugjoin)Zcondr    _kwargsr$   r$   r%   print_debugE   s    rF   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   rO   rP   r$   r$   r%   r   T   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)rF   configDEBUGsysstderrrO   flushdbrL   rM   rN   publishjsondumpsr   r$   r$   r%   r\   `   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!!!rS   zobj:jshash:*  countz"CmfCache.flush_jscache invalidate z!!!   Ncurrent_person_idjsver)rF   rX   rY   rZ   r[   r   rL   rO   pipeline	scan_iterdecodegetpickleloadsdeleteexecuteemit)r   emit_msgpipekeyjshashjsresjspersonr$   r$   r%   flush_jscachej   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!!!rS   r   zobj:*ra   rb   s
   obj:jshash   zCmfCache.flush_all_obj: z recordsN)rF   rX   rY   rZ   r[   rO   rg   rh   
startswithrm   rn   )r   rc   rq   rr   r$   r$   r%   flush_all_obj|   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)secondmicrosecondz!!!!! Date:,:Noneidz
todo2:obj:)type
issubclasscmfr   CmfType
is_definedvaluer>   intfloatparserparse
astimezoneutcreplacer0   	ExceptionlistrL   itemsboolhasattrr   r.   md5rk   r_   	hexdigest)valtresZval1evkr{   _all2strdateutilhashlibrz   r$   r%   r      sH    




"zCmfCache.hash.<locals>._all2strZ   Zdaysrd      )Zc92a103Zd860eddgUUUUUU?|r   z|id:r   zHASH:i  z|md5:
r<   _zDEBUG_CACHE HASH:)r   randomZdateutil.parserdatetimerz   Zwerkzeug.datastructuresr{   APPcache_optimizer   r>   r   r   CmfDatenowr   encoder   gcurrent_usersystem_usersortedr   rY   r   rF   )	r   prefixr    r!   r   srr   rr   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   r<   r   )setgetattrmodels
class_name__dict__rV   r   rj   endswithaddr   r   CmfRelationBasesimple_objects_id_recursive
CmfM2MBaseCmfBackrefBaserelated_modelsr   rD   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   r<   r   )r   valuesr   r   r   
isinstancer   r   r   extendobjects_id_recursiver   r   r   r   r   appendrD   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:)lenrX   ZCACHE_MAX_OBJ_SIZE	cmf_alertrO   r   rP   rM   )r   rr   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   rO   existsr   rP   rM   rj   )r   rV   Zhkeysrr   r$   r$   r%   _obj_dict_exists1  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   rJ   rK   )rO   rj   rQ   rP   rM   )r   rr   r   r$   r$   r%   _obj_dict_getC  s    zCmfCache._obj_dict_getrs   inv_payloadc                 C   s   |  d| S )N::r$   r   r$   r$   r%   %_jshash_invalidate_confirm_member_keyP  s    z.CmfCache._jshash_invalidate_confirm_member_keyZ
member_keyc                 C   s   | j dddS )Nr   rw   )maxsplitr-   r   r$   r$   r%   +_jshash_invalidate_confirm_member_key_splitT  s    z4CmfCache._jshash_invalidate_confirm_member_key_splitc                 C   s    | r| n| dd }d| S )Nr   zjscache-invalidate-confirm-set:r   )cache_idrs   set_keyr$   r$   r%   "_jshash_invalidate_confirm_set_keyX  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:rs   )
r   r   r   cmf_emit_eventrx   r   r   r   rO   sadd)	r   ZmsgsZconfirmationsZ	person_idinv_dictrs   r   r   confirm_listr$   r$   r%   ro   _  s    

zCmfCache.emitc                 C   sp   | j std | j rl|rl|d d }| j|d}t }|D ]}|| |d |d  q:| j j|f|  d S )Nu$   ERROR! Недоступен redis_dbr   r   rw   )rO   r0   r   r   r   r   srem)r   Zconfirm_dictZsample_jshashZkey_cache_idr   Zconfirmr$   r$   r%   jshash_invalidate_confirmn  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   ri   )r?   memberr`   r$   r%   
<listcomp>  s   z;CmfCache.jshash_invalidate_confirm_list.<locals>.<listcomp>)r   invalidated_keys	CMF_CACHE_do_invalidate_defferrO   r   smembers)r   r   r   r$   r`   r%   jshash_invalidate_confirm_list|  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$   r?   rr   r$   r$   r%   r     s     z+CmfCache._obj_dict_mdel.<locals>.<listcomp>rc   z#DEBUG_CACHE JSHASH: try invalidate z*DEBUG_CACHE JSHASH: try invalidate:jshash:invalidate:jshash:d   rb   z*DEBUG_CACHE JSHASH: got invalidate:jshash:z#DEBUG_CACHE JSHASH: got invalidate r   utf-8r   r}   re   updater   c                 S   s   g | ]}|d kr|qS ))Zcache_fieldsZcmf_modified_atcmf_viewed_atZcmf_modified_by_idr$   r?   r   r$   r$   r%   r     s    ONLYFORUPDATESrf         ?z_obj_dict_mdel emit got sec)rO   rm   r   inmemory_delprofiler_invalidaterY   r   rF   Zspoprg   rj   ri   rn   ziprk   rl   rL   rD   r   timero   r   rC   rP   rM   )r   rV   obj_changed_fieldsobj_idactionrp   rr   Zinvjsrq   rs   Zjshash_listrt   ru   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:)rO   rg   r   r   rn   rP   rN   r   )r   r   rq   rr   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   ri   r   r$   r$   r%   r     s     z1CmfCache._invalidate_dict_get.<locals>.<listcomp>)rO   r   rP   rN   rj   )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  )	rO   rg   r   r   rn   rP   rN   rj   remove)r   r   rq   r  r   Zkey_listrr   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 r<   c                    sT   |  d\}}}| kr"t  |< |r@ |  d|  n |   d S )Nr<   )	partitionr   r   )Zbind_and_fieldsbindr   r   )r   rr   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_recursive5  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 = rs   #DEBUG_CACHE JSHASH: add invalidate r   )r  )/osenvironrj   r   no_jscache_forcerX   ZJOB_DAEMON_DISABLE_CACHErR   r   $profiler_redis_invalidated_keys_skipr   cache_is_lockedrF   rY   cache_locked_byget_last_invalidatecache_lockscache_transaction_startr   utilcmfutilget_model_by_namer   r   r   r>   r   skipcache_select_for_updater0   r   r   r   r   r   r   cache_cluster_fieldsprofiler_datar-   rk   r_   r   Zcache_store_errorinmemory_addr   rs   r   r  )r   rr   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   rr   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.  rN   Zcache_invalidate_keys)r   rL   r.  r   r   rG   DEBUG_PROFILE_VERBOSEr   )r   rV   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_hitrw   redis_cache_missr   Zredis_cache_hit_keysr   rL   r.  r   rG   r5  r   r   rr   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.  r7  rw   r6  r   Zredis_cache_miss_lastZredis_cache_miss_keysr8  r9  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_rw   )r   rL   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  rj   r  T.ZCACHEFrs   r   z*DEBUG_CACHE JSHASH: add invalidate jshash:r<   r  zDEBUG_CACHE HIT: zDEBUG_CACHE GET:zDEBUG_CACHE MISS: )r   r!  rj   r   TECHCOM_HACK3441r   r#  r   inmemory_getrF   rY   r   rk   rl   r   rs   r  r   r:  r/  r;  )r   rr   r1  Zfrom_inmemoryr   r   obj_sizer$   r$   r%   rj   !  s>    





zCmfCache.getc                 C   s   dS S )Nr   z%DEBUG_CACHE TRANS get_last_invalidatecache_last_invalidate_rF   rY   r   rO   rj   r   r4  r$   r$   r%   r&  G  s     zCmfCache.get_last_invalidatec                 C   s   t | jd |  t_d S )Nz)DEBUG_CACHE TRANS cache_transaction_start)rF   rY   gen_time_usr   r(  r`   r$   r$   r%   r(  L  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   rz   r   strftimer`   r$   r$   r%   rB  P  s    zCmfCache.gen_time_usc                 C   s   d S d S )NzDEBUG_CACHE TRANS cache_lockr?  cache_lock_)	rF   rY   r$  rB  rO   r   r   r'  r(  )r   r4  lr$   r$   r%   
cache_lockS  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_unlockrD  0)	r   r'  r   r%  r(  rF   rY   rO   r   )r   r4  Ztr_startZlock_trr$   r$   r%   cache_unlockd  s      
zCmfCache.cache_unlockc                 C   s   dS S )Nr   z%DEBUG_CACHE TRANS get cache_locked_byrD  r@  rA  r$   r$   r%   r%  t  s     zCmfCache.cache_locked_byc                 C   s   dS dS dS )NFr   rG  z/DEBUG_CACHE TRANS cache_is_locked drop deadlockrD  rH  T)	r%  r   r'  rj   r(  rF   rY   rO   r   )r   r4  Z_cache_locked_byr(  r$   r$   r%   r$  y  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 )Nr<   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   rK  r   r   r   r   r   r-   r   rV   rC   )r   r   r   r  r  stglob_inv_dictglob_inv_listr   rK  r   Zinv_valendr$   r$   r%   _do_invalidate  s2    
zCmfCache._do_invalidatec                 C   s   t dd 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 )Nr   rK  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   rj   r  r   rK  r
  r  rC   r   r   r   )r   rL  rM  rN  rK  Zst_invalidate_dict_mdelrO  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  r   z!DEBUG_CACHE start invalidate_ids r<   x   zinvalidate:*r   ra   )matchrc       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   re   r   rf   r   c                 s   s   | ]}d |   V  qdS r   Nr  r?   	query_keyr$   r$   r%   rA   "  s     z*CmfCache.invalidate_ids.<locals>.<genexpr>c                 s   s   | ]}d |   V  qdS )r   Nr  rU  r$   r$   r%   rA   #  s     c                 s   s   | ]}d |   V  qdS rT  r  )r?   rs   r$   r$   r%   rA   $  s     zinvalidate_ids(, ): z): no keys found.)r   r!  rj   rF  rF   rY   r   r   rO   rh   r   r-   r   r   r   rC   r   recompilerD   ri   rR  findallrk   rl   rL   rm   ro   )r   r4  idsr  Zinvalidate_keysZ
query_keysZjshashesrp   Zobj_id_by_query_keyid_rV   rr   Zinv_membersZ
inv_memberZid_reZtuuid_reZkey_decodedrV  Zquery_jshashesrs   rt   ru   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 )Nr|   c                    s6    | }|r2|| < tjd  d| |   d S )NDEBUG_CACHE INVAL: r<   )r  rF   rY   )invalrC   invdr  r   r   r$   r%   _check_inval.  s    
z8CmfCache.invalidate_ids_as_wrapper.<locals>._check_invalr  DEBUG_CACHE start invalidate r<   r   r   ref=obj.id=)r  )r|   )r   r!  rj   rF  rF   rY   rP  )r   r4  r\  r  rc  r]  r$   rb  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=r|   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 )	Nr<   z=cmfCache.invalidate(): ValueError: too many values to unpack(rX  Tabortr   r_  ra  )r  r   r   r-   r   rC   r   rF   rY   rG   r5  r.  rj   )r`  rC   change_fieldsra  Zinvd_affectedir   Zi_fieldstailZi_set_fieldsZtmprb  r$   r%   rc  P  s4    



z)CmfCache.invalidate.<locals>._check_invalr   )r   r  rd  r<   ZRelationCachezRelationCache.parent.id=)r   r  r   r   re  uY   DEV: FATAL в инвалидацию м2м поля не передали имя поляrf  )rj  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_versionr|   is_dummy)createrm   r   zref_new=zref_old=r   r(   zDEBUG_CACHE ivalidate: z not fields_have_changes--Zlogical_deleter  r'   u   Ошибка конфигурации моделей: cache_cluseter_fields может быть только по m2m и relation полямrh  Fz
where_m2m=zwhere_m2m_old=z
where_old=u   DEV: в методе ux    не загружается is_dummy, что приводит к лишним инвалидациям кластераr   zinvalidate got )r|   N)r  )r  )r  )1r   rC   r  collectionsr   r   r!  rj   rF  r   rF   rY   TRACEpdbZ	set_traceZ	parent_idr   r   rP  r   r   r   r   r   r   r   rm  r   rJ  oldnewr   r   r   r   r   r-  r   r   Zload_fieldsr   ZCmfTUUIDrX   ZRAISE_LAZYLOADload
api_methodrG   r5  r.  )r   r   r  r  Zm2m_field_namerL  rc  r   r0  rr  Z_check_inval_doneZ_do_invalidate_donerj  r   r   Zno_caching_fieldsZcluster_load_fieldsr3  Zcc_field_nameZ
cc_clusterZcluster_field_is_changedr$   rb  r%   
invalidateM  s   "% 


 
"








$&"
  ""

zCmfCache.invalidatec                 C   s<   | j D ]\}}td| q| j D ]\}}td| q$d S )NzDEBUG CmfCache.dumps)rM   r0   rN   r   )r   rr   r   r$   r$   r%   r_   b  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   r   rw   .S   DEV: inmemory_get вызван для модели без флага cache_inmemoryTrh  )r-   rG   rY   r   r)  r*  r+  KeyErrorr   in_memory_cacher1  r   in_memory_cache_skip_modelsprofiler_inmemory_data_skipr   r   INMEM_CACHEprofiler_inmemory_data_missrj   move_to_endprofiler_inmemory_data_hit)clsrr   r4  r   model_cacheretr$   r$   r%   r=  q  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  rW  r   []u/   DEV: skip inmemory_cache obj_size > 128000 — u	    байтzCmfCache:inmemory_add add key r'   r   rw   rx  Trh    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   rF   rY   r-   rG   r)  r*  r+  ry  r   rz  r1  r   r   r}  r   r0   popitem)r  rr   r   r>  Zdetailr4  r   Z	LRU_LIMITr  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 )	NrW   uS   CmfCache:inmemory_del Полный сброс inmemory_cache при REDISDB.flushdbr'   r   r   rw   rU   )rV   Zskip_app_id)rF   rY   r   r}  r-   rG   r   r)  r*  r+  ry  r1  r   r+   r   delayed_redis_eventsr^   r_   r   getpid)r  rV   
from_eventZ
event_keysrr   r4  r   r  r$   r$   r%   r    s.    



zCmfCache.inmemory_delrU   )channelc                    s6   | sd S | d   fdd}t tjd t| d S )NrV   c                      s    t tjd  tj dd d S )Nz*CmfCache:on_inmemory_del event with keys: T)r  )rF   rG   rY   r   r  r$   rV   r$   r%   handler  s    z)CmfCache.on_inmemory_del.<locals>.handlerz&CmfCache:on_inmemory_del spawn handler)rF   rG   rY   geventspawn)datarE   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_hitrw   inmemory_cache_missr   Zinmemory_cache_hit_keysr8  r  rr   r   r$   r$   r%   r    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_skiprw   Zinmemory_cache_skip_keysr8  r  r$   r$   r%   r|    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  rw   r  r   Zinmemory_cache_miss_keysr8  r  r$   r$   r%   r~  )  s    




z$CmfCache.profiler_inmemory_data_miss)NF)N)NN)NF)N)F)N)r   )NN)F)=r.   r,   r9   rM   rN   rO   rP   rY   r5  rq  ZPROCESS_EVICTED_FLUSHr   r\   rv   ry   r   r   r   r   r   r   staticmethodr>   r   r   r   ro   r   r   r
  r  r  r  r   r  r:  r;  r#  rj   r&  r(  rB  rF  rI  r%  r$  rP  r   r^  rg  rw  r_   classmethodr=  r/  r  Zon_server_eventr  r  r|  r~  r$   r$   r$   r%   rG   J   s   
S
#U
 T

&

m 
  
.
0!

rG   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   datetzinfoZ	isoformatr   iter	TypeErrorr   r   default)r   r   iterabler   r$   r$   r%   r  @  s    
zCustomJSONProvider.defaultN)r.   r,   r9   r  r$   r$   r$   r%   r  ?  s   r  )Zstatic_folderZ	root_pathTZSEND_FILE_MAX_AGE_DEFAULTF)SocketIO	Namespace)Client)
project_idc              2   C   s   t | } tj| }|stjj| ddddddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0g0d1}|rd2|_|tj| < |S )3NZui_form_schemeZ
logic_typeZlogic_prefixZcust_field_conf_schemeZdefault_gantt_task_typez1security_level_scheme.default_task_security_levelzcalendar.timezoneZtask_code_prefixZtask_code_use_logic_type_prefixZ	executorsZ
spectatorsactivityzactivity.prefixZresponsibleZauto_alarm_dateZmain_gantt_projectZadd_object_typeZdefault_agile_story_pointsZtask_allow_multiple_sprintsZsl_deadline_shiftZsl_only_owner_approveZsl_deny_no_approveZ)sl_allow_executor_change_nofatal_deadlineZsl_task_need_approveZsl_task_only_owner_closeZsl_readonly_closed_taskZ.sl_deny_closing_task_before_closing_checklistsz cmf_owner_assistants.cmf_deletedz"cmf_owner_assistants.does_not_workzcmf_owner.cmf_deletedzcmf_owner.does_not_workzcmf_owner.user_localzdefault_list.plan_start_datezdefault_list.plan_end_datezdefault_list.ordernozdefault_list.perm_has_aclzdefault_list.sys_typezdefault_list.logic_prefixzdefault_list.affect_gantt_taskz%default_list_if_empty.plan_start_datez#default_list_if_empty.plan_end_datezdefault_list_if_empty.ordernoz"default_list_if_empty.perm_has_aclzdefault_list_if_empty.sys_typez"default_list_if_empty.logic_prefixz'default_list_if_empty.affect_gantt_taskZdefault_attach_full_search_typeZsdesk_feedbackr   r   T)r>   r   cache_projectsrj   r   Z
CmfProjectreadonly)r  Zprojectr$   r$   r%   get_cache_projectq  sr    9
r  c               	   C   sZ   t sJtd} |  }W 5 Q R X d}||kr4td||d}t|a t jtt	 dS )Nzdist/cmf-angular/index.htmlz<base href="/">z3Base href tag absent in dist/cmf-angular/index.htmlz<base href="{{ base_href }}" />)r   	base_href)
_index_template_cacheopenread
ValueErrorr   Zjinja2ZTemplateZrenderr   app_base_href)Ztemplate_fileZtemplate_strZbase_href_substrr$   r$   r%   _render_index  s    

r  r|   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 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   pathrD   rX   PROJECT_DIR)r?   dr$   r$   r%   r     s     zsend_static.<locals>.<listcomp>T)Zconditional)r   r   r  isabsrD   isfiler  r  flaskZhelpersZ
BadRequestZ	send_filer   HOOK_STATIC_NOTFOUNDr  )Zreq_filenameZpluginsearch_dirsZ	directoryfilenamehookr$   r$   r%   send_static  s,    

r  c                   @   s   e Zd ZdZdejee 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)redisredis_instance_namec                 C   s   || _ i | _|| _d S r   )r  
memstorager  )r   r  r  r$   r$   r%   r     s    zCmfRedisMemoryWrapper.__init__c                    s    fdd}|S )Nc              
      sf   | j rZzt| j  j||W S  t jk
rV } ztjrBt| j |W 5 d }~X Y qbX nt	dd S )Nu&   Redis memory wrapper запрещен!)
r  r   r.   ConnectionErrorrX   CACHE_REDIS_FAILOWERREDIS_SETTINGS_MANAGERcheck_and_updater  CmfAbortError)r   r    r!   r   r1   r$   r%   wrapper  s    z/CmfRedisMemoryWrapper.fallback.<locals>.wrapperr$   )r1   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  rj   r   rr   r$   r$   r%   rj     s    zCmfRedisMemoryWrapper.getc                 C   s   | j   d S r   )r  clearr`   r$   r$   r%   r\     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   rr   r  r  r  r  r  r$   r$   r%   r    s    zCmfRedisMemoryWrapper.expirec                 C   s$   | j |d}||7 }|| j |< |S )Nr   r  )r   rr   amountr   r$   r$   r%   rQ     s    
zCmfRedisMemoryWrapper.incrbyrw   c                 C   s   |  ||S r   )rQ   )r   rr   r  r$   r$   r%   incr%  s    zCmfRedisMemoryWrapper.incrc                 G   s$   d}|D ]}|| j kr|d7 }q|S )Nr   rw   r  )r   namesr   nr$   r$   r%   r   )  s
    

zCmfRedisMemoryWrapper.existsc                 C   s   || j |< d S r   r  )r   rr   r   r$   r$   r%   r   1  s    zCmfRedisMemoryWrapper.set)NN)FFFF)rw   )r.   r,   r9   __doc__r  Redisr   r>   r   r  r   rj   r\   r  r  rQ   r  r   r   r$   r$   r$   r%   r    s.   






r  c                   @   s   e Zd ZdZdZdd Zee dddZeee	j
 dd	d
ZdeedddZee	j
dddZdd Zeeef dddZedddZdedddZdS ) RedisSettingsManageruR   
    Менеджер по управлению настройками Redis.
    r  c                 C   s   t d| _d| _d S )Nzredis-settingsF)rB   	getLoggerlogger_terminatingr`   r$   r$   r%   r   ?  s    zRedisSettingsManager.__init__rH   c                 C   s@   d}t jj}t jjjj}z|| }|j	}W 5 |  X |S )uX   
        Возвращает название инстанса Redis из БД
        N)
r   CmfGlobalSettingsdp_modeldpdata_driverSessionclosequeryfirstcache_redis_primary)r   redis_instancer  sessionsettingsr$   r$   r%   _get_instanceC  s    

z"RedisSettingsManager._get_instance)instancerI   c                 C   sV   t tdrRtj| d dkrRtj|  }|d d|krF|d tjf |S d S )Ncache_settingsr   r  Z	celery_db)r   rX   r  copyr+   r  r  )r   r  Zcfgr$   r$   r%   _init_redisT  s    

z RedisSettingsManager._init_redisF)r  
with_flushc                 C   s   t jj}t jjjj}zx|| 	 }|r|| 
|}| jd z| || t  W n  tk
rz   | jd Y nX ||_|  W 5 |  X d S )Nu*   Выполняем очистку кешаu>   Не удалось выполнить очистку кеша)r   r  r  r  r  r  r  r  Zwith_for_updater  r  r  warning
init_cacher   r\   r   r  Zcommit)r   r  r  r  r  r  r  r$   r$   r%   
save_to_db]  s    
zRedisSettingsManager.save_to_db)r  r  c                 C   sJ   t tdrFtj| d dkr$|t_n"tj| d dkr>dt_ntdd S )Nr  r   r  rP   Tu&   Неизвестный тип кеша)r   rX   r  r   rO   rP   r   )r   r  r  r$   r$   r%   r  s  s    
zRedisSettingsManager.init_cachec                 C   sl   |   \}}| |t_|t_tjr2|s2| | tj	
drPtjd krPtdt| | |tj d S )NZ	run_uwsgiu?   При работе через uwsgi обязателен Redis)get_instancer  REDIS_DBr  r  rX   r  r  r   r!  rj   r   socketiostart_with_redisr  )r   is_db_instancer  r$   r$   r%   
init_redis|  s    



zRedisSettingsManager.init_redisc                 C   s6   t jr$|  }|rd}q.| j}d}n
d}| j}||fS )NTF)rX   r  r  DEFAULT_REDIS_INSTANCE)r   r  r  r$   r$   r%   r    s    z!RedisSettingsManager.get_instance)r  c                 C   s~   |   }||krz| jszd| _| jd| tdd}|dkrZ| jd| tj|dd | jd| t	
t	 tj d	S )
u   
        Проверяем, обновилась ли конфигурация Redis в БД
        и если да, то терминейтим app
        Tu<   Получена конфигурация Redis %s из БДr   <   uU   Ожидание %d секунд для применения конфигурацииFr   uv   Остановка процесса приложения для применения конфигурации Redis %sN)r  r  r  r  r   Zrandintr  sleepinfor   killr  signalSIGTERM)r   r  Zdb_instanceZsleep_secondsr$   r$   r%   r    s    z%RedisSettingsManager.check_and_updater  )intervalc                 C   s^   | j d |  \}}z| | W n" tk
rH   | j d| Y nX tj|dd qdS )u^   
        Переодический запуск проверки и смены Redis
        u,   Запуск periodic_check_and_update Redisu   Запуск periodic_check_and_update Redis завершился с ошибкой. Повторный запуск через %d секундFr  N)r  r  r  r  r   	exceptionr  r  )r   r  r   r  r$   r$   r%   periodic_check_and_update  s    
z.RedisSettingsManager.periodic_check_and_updateN)F)r  )r.   r,   r9   r  r  r   r   r>   r  r  r  r  r   r  r  r  r   r  r  r   r  r$   r$   r$   r%   r  8  s   		r  )Payloadr   c                   @   sx   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )CmfSocketIOWrapperu   
    Функционал:
    1. Отложенная активация, после получания доступа к Redis
    c                 C   s:   t dtjdd| _d | _d | _g | _g | _g | _g | _	d S )Nr   F)appZcors_allowed_originsr  Zengineio_logger)
r   rX   rY   socketio_kwargsr  r  lazy_on_handlerslazy_on_namespace_handlerslazy_init_apps	lazy_runsr`   r$   r$   r%   r     s    zCmfSocketIOWrapper.__init__c                 C   st   t d|  | jr2| j|kr*t d d S td| | tf | j| _|   |   | 	  | 
  || _d S )Nz%CmfSocketIOWrapper: start_with_redis u=   Warning. CmfSocketIOWrapper.start() вызван дваждыu)   CmfSocketIOWrapper уже запущен!)r0   r  r  r   _make_redis_connect_paramsr  r  _start_lazy_on_handlers!_start_lazy_on_namespace_handlers_start_lazy_init_app_start_lazy_run)r   r  r$   r$   r%   r    s    

z#CmfSocketIOWrapper.start_with_redisc                    s    fdd}|S )Nc                    s   j |  d d S )N)funcdec_args
dec_kwargs)r	  r   )r  r  r  r   r$   r%   wrap  s
    z#CmfSocketIOWrapper.on.<locals>.wrapr$   )r   r  r  r  r$   r  r%   on  s    zCmfSocketIOWrapper.onc                 C   s0   | j | | jr,td|  | j| d S )Nz!CmfSocketIOWrapper: on_namespace )r
  r   r  r0   on_namespace)r   r  r$   r$   r%   r    s    zCmfSocketIOWrapper.on_namespacec                 O   s>   | j ||d | jr:td| d|  | jj|| d S )N)r    r!   zCmfSocketIOWrapper: run r<   )r  r   r  r0   runr   r$   r$   r%   r    s    zCmfSocketIOWrapper.runc                 O   s   | j j|| d S r   )r  ro   r   r$   r$   r%   ro     s    zCmfSocketIOWrapper.emitc                 C   s0   | j | | jr,td|  | j| d S )NzCmfSocketIOWrapper: init_app )r  r   r  r0   init_app)r   r   r$   r$   r%   r  
  s    zCmfSocketIOWrapper.init_appc                 O   s   | j jjj||S r   )r  ZserverZmanagerget_participantsr   r$   r$   r%   r    s    z#CmfSocketIOWrapper.get_participantsc                 C   s<   | j D ]0}td|  | jj|d |d |d  qd S )Nu8   CmfSocketIOWrapper: регистрируем on handler r  r  r  )r	  r0   r  r  )r   Zlazy_on_handlerr$   r$   r%   r    s    
z*CmfSocketIOWrapper._start_lazy_on_handlersc                 C   s*   | j D ]}td|  | j| qd S )NuB   CmfSocketIOWrapper: регистрируем on_namespace handler )r
  r0   r  r  )r   Zlazy_on_namespace_handlerr$   r$   r%   r    s    
z4CmfSocketIOWrapper._start_lazy_on_namespace_handlersc                 C   s*   | j D ]}td|  | j| qd S )Nu2   CmfSocketIOWrapper: отложенный init_app )r  r0   r  r  )r   r  r$   r$   r%   r    s    
z'CmfSocketIOWrapper._start_lazy_init_appc                 C   s4   | j D ](}td|  | jj|d |d  qd S )Nu-   CmfSocketIOWrapper: отложенный run r    r!   )r  r0   r  r  )r   Zlazy_runr$   r$   r%   r  "  s    
z"CmfSocketIOWrapper._start_lazy_runc                 C   s  t tdrtj| d dkrtj| d }tj| dr~dtj| d  d| }dd	lm} ||d
dd}|| jd< nd}dtj| kr|tj| d 7 }dtj| kr|dtj| d  d7 }|tj| d 7 }|dtj| dd 7 }|d| 7 }|| jd< ntd d S )Nr  r   r  dbZunix_socket_pathzunix://z?db=r   )RedisManagerzflask-socketioF)r  Z
write_onlyclient_managerzredis://usernamepasswordr   @hostportZ6379r*   message_queueu|   ERROR! CmfSocketIOWrapper: в cache_settings не найден коннект к Redis. Socketio не активирован)r   rX   r  rj   r  r  r  r0   )r   r  r  r3   r  r  r$  r$   r$   r%   r  '  s"     z-CmfSocketIOWrapper._make_redis_connect_paramsN)r.   r,   r9   r  r   r  r  r  r  ro   r  r  r  r  r  r  r  r$   r$   r$   r%   r    s   		r  ZSOCKETIO_WORKER)postforkc                   C   s   t   d S r   )r  r  r$   r$   r$   r%   r  A  s    r  )r  z/custom/org_namec                 C   s   t d tj }t| tr`|  }| j| jd}|rBt	
 |d< | j|d< t||_d|_n4ddd}|rt	
 |d< t| |d< t|}d|_t| |S )Nz
App error:)coder  	tracebackdescriptionapplication/jsonr  zUnknown error)rB   r  rX   
PRODUCTIONr   r   Zget_responser&  r  r'  
format_excr(  r^   r_   r  content_typer>   Zjsonifystatus_codeset_cors_headers)r   Z
show_traceresponseZresponse_datar$   r$   r%   handle_exceptionS  s,    


r0  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_vacationr  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)rX   AUTH_ENABLEDr   system_personr   	CmfPersonrj   current_person_fieldsr   rB   r  r`   r$   r$   r%   r:    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 для проверки прав доступаjsurlr|   /share/Tr   r      r*   r   z*^(?P<obj_type>[^:-]*)[:-](?P<obj_code>.*)$docZDOCCmfDocumentZflZFLZIN_WORK	CmfFolderCmfListZEPI-r   r   sharelink_hashr  )r&  r   )#requestr  rx   headersrj   r  ujsonrl   r   rB   r  r   rL   r   r   sharelink_access_requestr   r  r   r-   rY  rR  groupsr   rC  rD  rE  r   r   Z	CmfEntityr   r>   rG  sharelink_access_grantedsharelink_access_obj)
r?  Zjson_resr3   Z
hash_paramZobj_keyrR  r0  Zobj_coder2  r   r$   r$   r%   _check_sharelink_access  s^    
(
rO  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
    rV  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 )NrP  ZFAIL_recursionz#Warning!!! Lazy Calc Current PersonrS   )	r   r:  rX   r9  r0   r'  print_stackrZ   stdout)r   Zcpr$   r$   r%   current_person	  s    rY  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   r|   c                 3   s   | ]}  V  qd S r   )choice)r?   r   Zalphabetsecretsr$   r%   rA   &	  s     zapp_key.<locals>.<genexpr>    zapp.app_key() error)r   rZ  r   r  rj   r   r)  r*  disable_aclstringr]  ascii_lettersdigitsrD   rangesaver   rB   r  )r   r  r`  r$   r\  r%   rZ  	  s     
rZ  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   re  r   r   r;  rj   r<  r  r  lockacquirereleaser   r)  r*  r_  system_dataZcreate_anonymous_userr:  ddcommit_all_dsr   rB   r  r   Z
redis_lockr$   r$   r%   rQ  4	  s8      

rQ  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.ruTrf  z$create-sharelink-anonymous-user-lockrg  rh  z%app._sharelink_anonymous_user() error)r   rq  r   r   r;  rj   r<  r  r  rj  rk  rl  r   r)  r*  r_  rm  Zcreate_sharelink_anonymous_userr:  rn  ro  r   rB   r  rp  r$   r$   r%   rS  T	  s<      

rS  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.ruTrf  zcreate-test-guest-user-lockrg  rh  zapp._test_guest_user() error)r   rr  r   r;  rj   r   r<  r  r  rj  rk  rl  r   r)  r*  r_  rm  Zcreate_test_guest_userr:  rn  ro  r   rB   r  rp  r$   r$   r%   test_guest_userv	  s4      

rs  c                 C   s
   t j S r   )r   r  Zget_settingsr`   r$   r$   r%   global_settings	  s    rt  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   ru  r   ZCmfGlobalVarrj   r`   r$   r$   r%   
global_var	  s    rv  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 linesrw   r   z#%s: %s:%s: %.1f KiBi   z    %sc                 s   s   | ]}|j V  qd S r   sizer?   statr$   r$   r%   rA   	  s     zdisplay_top.<locals>.<genexpr>z%s other: %.1f KiBc                 s   s   | ]}|j V  qd S r   rz  r|  r$   r$   r%   rA   	  s     zTotal allocated size: %.1f KiB)Zfilter_tracestracemallocZFilterZ
statisticsr0   	enumerater'  r   seprD   r  r-   rw  r{  	linecachegetlinestripformatsumr   )ZsnapshotZkey_typelimitZ	top_statsr)   r}  framer  lineZllotherr{  totalr$   r$   r%   display_top	  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
   rh  )loginr   c                 S   s(   i | ] \}}| d s|dkr||qS )Zcmf_r   )rx   )r?   r   r   r$   r$   r%   
<dictcomp>	  s
   
  z+create_person_from_auth.<locals>.<dictcomp>Tr   Z	cmf_ownerZ
cmf_authorZcmf_modified_byZServiceDeskClient)r&  )Z	only_data)r   r)  r*  ZCmfLockr   r;  rj   r  r   r<  r   r   r   r6  r2  r   ZCmfPersonGroupZsupport_groupr3  Z
user_groupr7  r_  rd  rn  ro  )authr6  is_servicedeskrU  Zperson_valuesr$   r$   r%   create_person_from_auth	  s,    



r  )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 )NrY   ra   r}   r.  Zselect_countZselectr   r   insertmr*   z(+z)mszs zu zi r   r;   r<   c                 s   s   | ]}t |V  qd S r   r=   )r?   partr$   r$   r%   rA   
  s     zdebug.<locals>.<genexpr>zPROF debug funcion got ms)r  r   rX   r   r>   rB   INFOrY   roundr   debug_start	debug_nowrj   rL   rH  r    
request_idlogrD   r   )r  r  messagesZdebug_str   r   r  ZscZscsZscuZscir  partsZ	debug_endr$   r$   r%   rC   	  s@    
   "

rC   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/r  /with-contextsystemZdeny)rH  rI  rj   r  rx   r>   r   r  )ZrefererZreferer_pathr$   r$   r%   set_api_scope
  s$    $r  c               	      sb  t jdkrdS ttj tj tjfrDtj t	
tj W 5 Q R X ddlm  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_0dt_1dt_2dt_3dt_4dt_5dt_6dt_7dt_8t9 t_:dt_;dt_<dt_=t>j>?t>j@jAt_Bdf fdd	t_?tjBC t_Ddg fdd	t_Cdt_Ei t_Fi t_Gg t_Hg t_Ig t_Jg t_Kg t_Lg t_Mg t_Ni t_Og t_Pi t_Qdt_Rdt_StT t_Ui t_Vg t_Wdt_Xdt_Ydt_Zg t_[i t_\i t_]i t_^tT t__i t_`i t_ag t_bi t_ci t_dg t_eg t_ftgt_gdt_hdt_idt_jdt_ktT t_ldt_mtnjop  tnjqp  tjrstsd dS t jtudrdS tjstjstgdtv  d tj tgdtv  d tjstgdtv  d twjxdkrHty  tz  t{  tj|rbt}  tj~rpt  dt_tgdtv  d ntgdtv  d W 5 Q R X tjrd
"tddt_md}d}t jtudst jtudrt jd}|s4t jd}|r4|ud r0|td d }nd}|sFt jd!}|rtnj|}tnjj|dtjd"}tgd#|dd  d$| d%|  |std&t jt j td'd(d)d*S t jtd+krtnjjtjd,}t jtut  d-r<d.}d/t jkrt jd/ }t|}|s0td/|i}tt  d0| }t| |S d1}	|  }
|st jd2}t jd3}|rtnj|\t_'t_<tj=rdt_=t  n|rtnj|t_'tj'rtjotnjjtj'j(jd4}tjr|sdt_'tj'rtj'j(jt_(d5d6tj'j(gg}tnjj|tjd7}d8tj( d9}	|r~|jrLtgd8|j( d: d}n0t|d;r|jrd8|j( d<}	tg|	 d}nN|rt|tj'jd=}n6tj'jrttj'tj'jd=}ntjjrttj'dd>}|  |
 d?krtgd@|  |
   t jtudApt jtudBpt jtudC}dDdE }|rr|j(jt_(tj'rRtj'jt_+tj'j t_)ndt_+|j t_)dt_,ts| nN|s| rtj}t  tj5rtj}dt_*dt_,ts| ndt_,tstj tj	pDt jtudF	pDt jtudG	pDt jtdHk	pDt jtudI	pDt jtudJ	pDt jtudK	pDt jtudL	pDt jtdMk	pDt jtudN	pDt jtudrnt jdOdPkrnt jdQk	pDt jtudR	pDt jtdSk	pDt jtudT	pDt jtudUrt jdQk	pDt jtudVrt jdQk	pD| rt jtudWrtnj 	pD| 	rt jtudX	rtnj 	pDt jtudY	r$tj(	pDtt jt	pDt jtudZ	oDtj(}tj}tj}|  }
tnjq  |  |
 d?k	rtgd[|  |
   |	s| 	rdS tj:d\k	r|	stj'	rt|	S t|	S |j
s|j
stj
st S ntj'	r|	st|	S t jtd.k
r6|
r6|j
s6tj
s6|j
r,td]S td^S n|
sDtd_S |j
s\tj
s\td`S tj,
rjt S tj,
sttndad
r|
r|j
r|  }
tnj 
stt  dbS |  |
 d?k
rtgdc|  |
   tjsdt_|  }
t  |  |
 d?krtgdd|  |
   tj<r^|  }
tj< }|  |
 d?krTtgde|  |
   |r^|S dS )huJ  
    Должны вернуть Response or None
    Особенности поведения:
      В случае web запроса:
        - response - view не выполняется, сразу отправляем response
        - None - выполняем view
        - Exception(в т.ч. и abort) - обработчик выводит трейс клиенту
      Системный контекст(shell, celery, socket, other with cmf_context):
        - None, Response - нет разницы
        - Exception - прерывает выполнение.
    ZOPTIONSNr   r   FZ
run_pytest1r  )choicesr|   Z0123456789abcdef   )r   c                    s   t j |  S r   )r   _nowoffsetr   r$   r%   <lambda>i
      z before_request.<locals>.<lambda>c                    s   t j |  S r   )r   _dater  r   r$   r%   r  k
  r  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  r  zX-Eva-TokenZAuthorizationzBearer token)api_token_hashr3  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?uU   Требуется авторизация. Введите логин и пароль.session_tokenaccess_token)r  r  ==filterr   u   Учётная запись uQ    заблокирована. Обратитесь к администраторуu    заблокирована.r5  uo    заблокирована за неактивность, обратитесь к администратору)r6  )r  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/)rH  r  rx   r$   r$   r$   r%   is_allow_publicV  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 r  r  r  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 )N)N)rH  methodallr   first_request_init_donefirst_request_init_skiprX   r  first_request_init_lockr  r  r  r  cmf.util.cmfutilr   check_db_lockr   r(  rn  before_requestr   r"  r'  flagsremove_filesr   r!  rj   Ztestr  r   r  r  r  rD   r  Zsave_only_data_hackalertnoter  r  Zis_guest_userZis_anonymousr6  Zis_system_contextrR  rT  Zdisable_notifyZimport_modesession_tab_idcomponent_idZinteractive_shellrK  rM  rv  Zapi_argsZ
api_kwargsr  	api_scoperN  r  Zhack_session_need_commitr   r   rz   r   r  r  r  Zrelaxed_bz_python_mode	emit_listsocket_eventsserver_eventsdeferred_audit_listdeffered_history_columnsdeferred_audit_notrans_listdeferred_job_listdeferred_comment_audit_listdeferred_statsdeferred_fullsearch_dirty_listdeferred_notify_messages"deferred_hide_closed_task_notifiesrP  Zjscache_timelifer   r   r   rK  ZTEXCOM_ENABLE_GROWCACHE_HACKr<  rz  r{  Zacquired_locksZacquired_locks_shZacquired_lock_timignsr,  Zfulltext_search_headlinesZfulltext_search_debug_labelr  Zproject_perm_browse_cacheZ%project_perm_timetrackerhistory_cacheZshow_bg_progressbarZapi_hack_fieldsrC   Z
new_acl_idZapi_license_requiredZ license_disable_user_count_hooksZbackbone_syncZcurrent_save_objects	csp_noncer   ZCmfDeferredJobZinit_contextCmfAccessListr9  rV  r  rx   r  r  r  r  app_init_aclapp_init_project_permissionWHATSAPP_MESSENGER_URLspawn_messenger_socketio_clientWHATSAPP_WEB_SOCKETspawn_whatsapp_socketio_clientCSP_ENABLEDZsamplerI  r   r    r;  Z
hash_tokenr<  rB   r  r   Z
CmfWebhookZget_token_personauth_base_hrefr   check_sso_redirectr	   redirectr.  ZcookiesZ
CmfSessionZ
from_token
cmf_commitCmfAuthZfrom_jwtZIS_AUTHORIZATORr   r4  r   r5  r  Zjwt_is_supportrt  Zservicedesk_allow_auth_guestsZjwt_is_match_orgr3  rQ  rO  rS  r   Zremote_addrZ	CmfPluginZcheck_secretSTATIC_URL_RErR  r:  Zsetup_contextreject_responser7  r   r  Zlicense_ui_accessr  prepare_plan_cache_doneprepare_plan_cacheZtfa_check_two_factor)r  r  Zauth_personZ	real_authZ	api_tokenr  r  r   qserr_msgprof_str  r  _filterZis_force_publicr  Zanon_personZis_allow_without_authr   r$   r   r%   r  $
  s`   



   $


















	

 


#	
"
$
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disabledr  Fr  Zservicedesk_supportT)r  )r   r  r   r   ZCmfAuthOpenIdPluginrj   Zlogin_redirect)r  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| }t| |S d S )Nr  r  zJRequest reject access: path=%s, auth=%s, login=%s, api_scope=%s, person=%sr  r  r  znot authorizedr  r  r  r  Z
auth_errormessager  zservicedesk/auth/signin?r  )rH  r  r   r  rB   r  r  r  rP  rx   r   r
   r3   r   r	   r  r  r  r.  )r  Zskip_ssor  paramsr  r   r$   r$   r%   r    s>        




r  c                   C   s   t   t  t  d S r   )rn  ro  emit_eventsemit_server_eventsr$   r$   r$   r%   commit_with_event&  s    r  c              	   C   s   | ri t _d S t dsd S t j D ]\}}d|krd|d kr|d d |d rtjj|d }|r|	 D ]}|d 
|jj qvtd|d  |d|dd	d
 q&i t _d S )Nr  relation_personsZ__DEFERRED_all_relation_personsr   is_changed-r   r*   r   private)	namespacer   )r   r  rj   r   r  r   r)  r*  Zget_obj_by_idZall_relation_personsr   r   r   r   )
only_cleanr   r   r   pr$   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   rJ  event_current_personr   r  uY   DEV: INFO Кривой евент, в event_person попал объект, а не str: r<   )r   r   r  r^   r_   r   r0   r   r  ro   rx   r   r   r   r  r   r   r>   )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_dictA  sF    


 
""
 
r
  c                   C   s   t dd d S )Nr   delay)emit_events_with_delayr$   r$   r$   r%   r  q  s    r  c                 C   sf   | ri t _d S dd l}t ds$d S i }|t jD ]$}|dr4t j| ||< t j|= q4t| d S )Nr   r  Zproject_notify)r   r  r  rj   rx   r
  )r  r  r  r  r$   r$   r%   emit_project_eventsu  s    


r  c                    s^   t |d |ri t_dS tdp$i i t_rN rN fdd}t| nrZt dS )u   Запускаемся в контексте, но отправляем в отдельном таске вне контекста, после паузы, чтобы не держать запрос.r  Nr  c                      s   t   t d S r   )r  r  r
  r$   r  r  r$   r%   emitter  s    
z'emit_events_with_delay.<locals>.emitter)r  r   r  rj   r  r  r
  )r  r  r  r$   r  r%   r    s    
r  c                 C   s^   | rg t _d S t dpg }g t _|D ]2\}}t d| d|  tj|t| q&d S )Nr  zemit_server_events: rW  )	r   r  rj   rC   r  r  r]   r^   r_   )r  r  r  r  r$   r$   r%   r    s    r  c                   C   s   t   i t_d S r   )rn  Zrollback_all_dsr   r  r$   r$   r$   r%   rollback_purge_event  s    r  c                 C   s@   | rg t _d S t dg D ]}tj|rt| qg t _d S )Nr  )r   r  rj   r   r  r   r  )r  r  r$   r$   r%   apply_deferred_remove_files  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_cookies  s    r  c                 C   sT   t jrPtjdstjdr<dtj dtj d| jd< ndtj d| jd< d S )Nz/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-Policyz}'; style-src 'self' 'unsafe-inline'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; img-src 'self' data: blob:;)rX   r  rH  r  rx   r   r  rI  )r/  r$   r$   r%   set_csp_headers  s    

r  c                 C   sl   t j}tjd}t jrD|rD|dr6|tdd  }|t jkrD|}d| | jd< d| jd< d| jd< d S )NZOriginhttps://zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)rX   APP_FQDNrH  rI  rj   ZCORS_ALLOWED_DOMAINSrx   r   )r/  Zorigin_domainZrequest_originr$   r$   r%   r.    s    



r.  c                 C   s2   t ddd t|  t|  t|  d| jd< | S )uk   
    Запускается только если небыло ошибок
    :param r:
    :return:
    Tr}   )after_hooksevent_delaybyteszAccept-ranges)r  r  r  r.  rI  r  r$   r$   r%   acao  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  rX   r9  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   s4  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j	dgd}|rr|  |  ddd	gd
ddd	gdddggfD ],}|dddgg}tjj|dddddgd qtjj	dgd}|r|  |  tjj	dgd}|r
|  |  tjj	dgd}|r0|  |  d S )Nr  z/opt/eva-appr   )r   ro  )Zorder_byZcache_action=rd  ORrn  Z	cmf_modelCmfTaskZjson_filterZjson_entry_pointZjson_actionZ	func_nameZ	json_datar  )r   rX   r   r)  r*  r_  r   r%  Zcreate_dummy_taskrj   Zdelete_dummy_taskZsave_prepareZ_load_perm_fieldsZ
CmfTriggerr   rE  
CmfComment	CmfNotify)Zdummy_task_dataZ
dummy_taskr   Z_frE  cr  r$   r$   r%   r    s2    
$r  c                 C   s   t | d d S )Nr  )cmf_rollbackr)  r$   r$   r%   teardown_request4  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=r  r   zcmf_alert Stack:
)rX   rY   rB   ZWARNINGr  r   rC   r*  rD   r'  format_stackr  r  r   )r  ri  r   
devel_onlyr  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/  )	rX   rY   rB   r  r   rC   r*  r  r   )r  r   r1  r  r$   r$   r%   cmf_noteU  s    
 
r2  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   re   r  r|   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   )r  r   rL   r  r   r   rY  r   r   r   r  r^   r_   rx   r0   localsr   r   r   r   r  r   r>   
setdefault)r  r  r  r   r   r    r!   r   Zevent_paramsZmutedZ
muted_debtr	  r  Z
event_listr$   r$   r%   r   j  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} r|   zsudo z 2>&1z0{0} bash -c "export BOOTUP="noncolor";{1}{2}{3}"r   r  T)shellrX  r[   u6   Произошла ошибка при вызове %sz
STDOUT: %sz
STDERR: %su4   Произошла ошибка при вызове )NN)r  r  
subprocessPopenPIPEZcommunicateri   
returncoderB   errorRuntimeErrorr   )ZcommandZsudori  waitZseparate_out_and_errZ	do_decodeZdo_raiseZmeasure_runtimeZtimeout_cmdZ_sudoZ	_redirectcmdr  Zpopen_startZprocessouterrZerrcoder  r$   r$   r%   run_bash_command  sH    
r@  c                 C   sL   t tj}t }||   ||}t	|
 }|  d| }|S )ua   
    Подписываем токен сертификатом
    :param jwt:
    :return:
    r'   )r   rt  r   rsa_private_keyr   r   r   signbase64	b64encoderi   )jwtZsignerZdigestrB  r   r$   r$   r%   rsa_sign_pack_jwt  s    
rF  c                 C   sH   ddd}t t|  }t t|   } | d|  S )uD   
    Создаем токен
    :param payload:
    :return:
    ZRS256ZJWT)Zalgtypr'   )rC  rD  r^   r_   r   ri   )payloadheaderr$   r$   r%   
create_jwt  s    
rJ  c                   C   s   t jS )u2   
    Текущая версия
    :return:
    )rX   ZCMF_VERSIONr$   r$   r$   r%   cmf_get_version  s    rK  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    
rL  c                  C   sh   t js
d S t jdrd S dt jj dt j } tjj	| }|rdtjj
|  t| dd d S )NZfield_options_list
DEFERRORS_r   r   z<br>)r   rv  r   r   r   r  r   r  r  rj   rm   r   ri   r   )	redis_keyr:  r$   r$   r%   _deferred_errors_check  s    rO  c                 C   sx   t jd dtj d}|t 7 }dtjj dtj	 }t j
j|}|r`| d | }n|}t j
j|| d S )Nr   uL   Ошибка в after_request, после выполнения метода z

rM  r   z


)r   r  r  r   rv  r'  r+  r   r   r  r  r  rj   ri   r   )r   r  rN  r:  r$   r$   r%   _deferred_errors_save  s    rP  c              	   C   s   t j| d ddlm} |jjdd t|jdr@|jjdd tt	drrt	j
rrt  |jjdd W 5 Q R X n|jjdd |jjdd t|d	r|jjdd |jjdd tdd tdd tdd tdd tdd g t	_d S )
Nr)  r   r   Tr  (apply_deferred_hide_closed_task_notifies)Zrollbackr  CmfStat)rn  ro  cmf.includer   r'  apply_deferred_notify_messagesr   r%  rR  r   r  cmf_contextCmfAuditapply_deferred_auditCmfFullSearchapply_deferred_dirtyrS  apply_deferred_statsr&  !apply_deferred_comment_audit_listapply_deferred_jobsr  r  r  r  r  )r  r   r$   r$   r%   r*  %  s&    





r*  c                 C   sb  t   | r^t }ddlm} t  i }tj|d< g t_tj	|d< i t_	tj
|d< g t_
tj|d< g t_tj|d< i t_tj|d< g t_tj|d	< g t_tj|d
< g t_tj|d< i t_tj|d< i t_tj|d< g t_tj|d< g t_tj|d< g t_t| }|r.tjttjjtjtj|f| t   t | dkr^tdt |   d S )Nr   rQ  r  r  r  r  r  r  r  r  r  r  r  r  r  {Gz?z PROF cmf_commit after_hooks got )rn  ro  r  rT  r   r   r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  anyr   r  r  cmf_commit_after_requestr   r   r  rv  r0   )r  r  r  r   Zafter_request_paramsZ
need_spawnr$   r$   r%   r  ?  sT    












r  c                 C   s  t d t }t b z(ttjj| tjj	j
d |t_|t_|t_|t_|t_|t_|t_|	t_|
t_|t_|t_|t_|t_|t_|t_tj  ttjdrtj  tj !  tj"#  tj$%  t&  ttdrtj'(  tj)*  t+  t,|d t-  t.  t/0  t | dkrBt1dt |   W n0 t2k
rt } zt3| |W 5 d }~X Y nX W 5 Q R X d S )NzRun cmf_commit_after_requestr   rR  rS  r  r^  z"PROF cmf_commit_after_request got )4r0   r  rV  rV  r   r;  rj   r   r  r   r<  r   r  rv  r  r  r  r  r  r  r  r  r  r  r  r  r  r'  rU  r   r%  rR  rW  rX  rY  rZ  ZCmfOrmColumnHistoryZapply_deffered_history_columnsr]  rS  r[  r&  r\  r  r  r  r  rn  ro  rC   r   rP  )Zcurrent_user_idr  rv  r  r  r  r  r  r  r  r  r  r  r  r  r  r  Zafter_request_prof_str   r$   r$   r%   r`  q  sP    









r`  r  c                 C   s`   ddl m} | pd} t|}|jddddd}|  rL| d rL| d7 } |||  }t|S )Nr   r   r|   hourminuter~   r   +-r  )r  r   _ensure_localr   r  lstripisdigit_to_utcr  r   r   
base_localstart_localr$   r$   r%   start_of_day  s    rl  c                 C   s`   ddl m} | pd} t|}|  r:| d r:| d7 } |||  }|jddddd}t|S )	Nr   r   r|   rd  r     ;   ra  r  r   re  r  rf  rg  r   rh  )r  r   r   rj  	end_localr$   r$   r%   
end_of_day  s    rq  c                 C   s~   ddl m} | pd} t|}|  r:| d r:| d7 } |||  }| d d }|t|d8 }|jddddd	}t	|S )
Nr   r   r|   rd  wrw   r   r   ra  )
r  r   re  r  rf  rg  weekdayr   r   rh  )r  r   r   rj  days_since_sundayrk  r$   r$   r%   start_of_week  s    ru  c                 C   s   | pd} t |}|  r.| d r.| d7 } |t|  }| d d }|t|d jddddd}|td	d jd
dddd}t|S )Nr|   rd  rr  rw   r   r   r   ra  r  rm  rn  )	re  r  rf  rg  r   rs  r   r   rh  )r  r   rj  rt  Zweek_start_localZweek_end_localr$   r$   r%   end_of_week  s&          rv  c                 C   sZ   ddl m} t|}|  r2| d r2| d7 } |jdddddd}|||  }t|S )Nr   r   rd  Mrw   dayrb  rc  r~   r   ro  ri  r$   r$   r%   start_of_month  s    rz  c                 C   sx   t |}|  r&| d r&| d7 } |jddddddt|  }|tdd }|tdd }|jdd	ddd
}t|S )Nrd  rw  rw   r   rx  )Zmonthsr   rm  rn  ra  )	re  r  rf  rg  r   r   r   r   rh  )r  r   rj  Zstart_month_localZnext_month_localZlast_day_localrp  r$   r$   r%   end_of_month  s    r{  c                 C   s\   ddl m} |  r*| d r*| d7 } t|}|jddddddd}|||  }t|S )Nr   r   rd  yrw   Zmonthry  rb  rc  r~   r   )r  r   r  rf  rg  re  r   rh  ri  r$   r$   r%   start_of_year  s    r~  c                 C   sb   t |}|  r&| d r&| d7 } |jdddddddt|  }|jdddd	ddd}t|S )
Nrd  r|  rw   r   r}        rm  rn  )re  r  rf  rg  r   r   rh  )r  r   rj  Zstart_year_localZend_year_localr$   r$   r%   end_of_year  s    r  )r   rI   c                 C   s@   t j   }|j}| dkr |S | jdkr6| j|dS | |S )uP  Возвращает datetime в локальной зоне сервера (aware).

    - Если base=None, берём текущее локальное время.
    - Если base naive, присваиваем локальную зону.
    - Если base aware, конвертируем в локальную зону.
    Nr  )r   r   r   r  r   )r   Z	local_nowZlocal_tzr$   r$   r%   re  
  s    
re  )dtrI   c                 C   s0   | j dkr"| jtj  j d} | tjjS )un   Переводит aware datetime в UTC (aware). Для naive сначала делает локальным.Nr  )r  r   r   r   r   rz   r   )r  r$   r$   r%   rh    s    
rh  c                   @   s,   e Zd ZdddddZdd Zd	d
 ZdS )rV  FTNrH   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_viewsrn  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  0  s
    zcmf_context.__exit__)FT)r.   r,   r9   r   r  r  r$   r$   r$   r%   rV    s   rV  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   walkrX   r  )r?   Z
search_dirr$   r$   r%   r   <  s   zstart_views.<locals>.<listcomp>r|   z/viewsz.pyz.pycz__init__.pyr'   c                 s   s   | ]}|r|V  qd S r   r$   )r?   r   r$   r$   r%   rA   D  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   rX   r  r   rx   rD   r-   	importlibimport_moduler   r/   r  app_before_run)r  Zsearch_iterdirnamedirnames	filenamesr  r2   r$   r$   r%   r  :  s(    

$  r  c                   C   s   d S r   r$   r$   r$   r$   r%   r  V  s    r  c                 K   s^   | dd ||d< ||d< ttjj|d< tj|d< tj|d< tj|d< tj	| |g d S )	NZ	countdownr}   r    r!   Zg_current_user_idZg_acl_admin_modeZg_component_idZg_session_tab_id)
r4  r>   r   r   r   Zacl_admin_moder  r  r  r   )jobr    r!   r5   r$   r$   r%   schedule_deferred_jobZ  s    


r  c                 C   sV   | rg t _d S t jsd S t dtt j d t jD ]\}}|jf | q6g t _d S )Nz	Schedule z deferred job(s))r   r  rC   r   Zapply_async)r  r  r5   r$   r$   r%   r]  h  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   
namespacesrI  )r   r!  rj   rX   ORG_NAMEwhatsapp_sioconnectr  r  r$   r$   r%   messenger_connectu  s    
 z:spawn_messenger_socketio_client.<locals>.messenger_connectz	/whatsapp)r  )rX   r  r  r  )r  r$   r$   r%   r  t  s    r  c                   C   s   t tjtj d S r   )r  r  whatsapp_go_sior  rX   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   r;   uY   Подключаемся к удаленной отладке config.REMOTE_DEBUG_SERVER=z config.REMOTE_DEBUG_PORT=TF)r#  ZstdoutToServerZstderrToServerZsuspend)pydevd_pycharmrB   r  rX   ZREMOTE_DEBUG_SERVERZREMOTE_DEBUG_PORTsettrace)r  r$   r$   r%   cmf_pycharm_debug  s     r  rH   c                  C   sH   t tjtjttt ttt d tjj	dd} t
| }t|S )Nr  Zguid)ZissZorg_nameZiatZexprZ  Zjti)rL   rX   r  r  r>   r   r  r   rZ  r   rJ  rF  )rH  rE  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)  r  r   )zContent-typeZAcceptzContent-EncodingZeva_app_token)r     u9   Не удалось отправить запрос, url=z, status_code=z, res=r:  u(   Сервер вернул ошибку: )Zrequestsr  rX   ZEVA_ACCOUNT_USEr   r   r  rj   rI  r  r  Zpostr^   r_   r-  r   Zcontentr   rC   )
r  r  r  r  Zmethod_argsZmethod_kwargsresultr   r3   r   r$   r$   r%   call_eva_account  s.    


r  Zeva_db_upgrade_runningc                 C   sH   | st t } ttds"t  tjjt	| dddsDt
dt	 dS )u   Запускается перед миграций БД. Информирует приложение, что не следует открывать транзакции.r  rx  T)exr  zCannot lock N)r>   r   r  r   r  r  r  r  r   _DB_LOCK_KEYCmfError)r   r$   r$   r%   app_db_upgrade_start  s    
r  c                   C   s   t jt dS )u   Запускается после миграций БД. Информирует приложение, что можно продолжать работать.N)r  r  rm   r  r$   r$   r$   r%   app_db_upgrade_stop  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tds&t  tjta	t a t	S )uW   используем кеш 1sec, чтобы часто не ходить в редисrw   r  )
_db_lock_cache_tsr  r   r  r  r  r  rj   r  _db_lock_cacher$   r$   r$   r%   
check_lock  s    
z!check_db_lock.<locals>.check_lockr   z
DB locked Frw   T)r  r  r  r  )r<  ri  Zraise_errorr  rc   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   rY   z:%(asctime)s %(process)d %(name)s %(levelname)s %(message)s)r  r  )Zlogging.handlersrX   rY   Z	LOG_LEVELZbasicConfigr  ZsetLevel)rB   r  r  r$   r$   r%   init_logging  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*   r   r|   z://)rX   	BASE_HREFr   EXTERNAL_PORT_HTTPSr  )Zfull_urlZprotocolr  	port_specr$   r$   r%   r    s    

r  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:8080r   r|   r  r*   )rX   ZAUTH_SERVER_URLr  r  r  r   )absoluteZinternalr  r  r$   r$   r%   r    s    
r  )r|   N)rw  rx  )FF)N)NF)F)F)r   F)F)F)N)FFNN)FNN)TNTFFFF)T)Tr   )r|   N)r|   N)r|   N)r|   N)r|   N)r|   N)r|   N)r|   N)NN)F)N)Tr  T)Fr  )FF)r  r  rB   r   rZ   Zfcntlr   r   rC  r   rk   r6  r  r'  	threadingrp  r   r   pathlibr   typingr   r   urllib.parser   r   r	   r
   Zwerkzeug.utilsr   r  r   rJ  ZCrypto.Hashr   ZCrypto.Signaturer   r  r   r   Zflask.json.providerr   Zwerkzeug.exceptionsr   r   r   rT  Zcmf.data_providersr   rn  Zcmf.system_datarY  Zdateutil.relativedeltar   r   r  r   rZ  r  r   rF   objectrG   r  r.   rX   r  r   r^   r:  rZ  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>   r  r  r  r  r  r  r  r  r  r   Zengineio.payloadr  Zmax_decode_packetsr  r!  rj   Zuwsgidecoratorsr%  r  rY   r  r  r  r   r  r1   r  r  r  ZREDIS_DB_IDZREDIS_DB_ID_TIMERZerrorhandlerr   r0  Zregister_error_handlerZprivate_key_pathZpublic_key_pathZCrypto.PublicKeyr1  Z
import_key
read_bytesrA  Zrsa_public_keyr<  rO  rV  rY  re  rq  r   rQ  rS  rs  propertyr   r   r   r   rt  rv  r  r  rC   r  r  r  r  r  r  r
  r  r  r  r  r  r  r  r  r.  Zafter_requestr  r  r  r  r+  r   r2  r   r@  rF  rJ  rK  rL  rO  rP  r*  r  r`  rl  rq  ru  rv  rz  r{  r~  r  re  rh  rV  r  r  r  r]  r  r  r  r  rL   r  Zcache_notify_scheme_ruleZcache_cmf_security_levelZcache_person_notify_optZcache_cust_field_config_schemeZcache_email_listr}  r  r  r  r  r  r  r  r  r  r$   r$   r$   r%   <module>   s  
            


C
H q

"

                        b	 "

!
   V
	
%
0

';   
52:
		
