
    NMAi                    H   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  e3j9        d          Z: G d de;          Z;d Z< G d de=          Z> G d de)          Z? e;e@deAjB                  ZC e?eC          eC_D        deC_E        deC_F        g eC_G        deC_H        d eCjA        d<   i eC_I        deC_J        i eC_K        deC_L        deC_M        deC_N         ejO                    eC_P        i eC_Q        eAjR        eC_S        d dlTmUZUmVZV d dlWmXZX d dlYZYd eZfd!Z[i eC_\        e[eC_[        da]d" Z^dd$Z_ G d% d&          Z` e`            Za G d' d(          Zb eb            ZceceC_c         e>            Zdd d)lemfZf d*ef_g         G d+ d,          Zh eh            ZWeji        j                    d-          rd d.lkmlZl eld/             Zm eXeAjn        0          Zo eXeAjn        0          Zpejq        r                    eAjB        d1z             rV eseAjB        d1z             5 Ztetu                                v                                eA_w        ddd           n# 1 swxY w Y   eaeC_a        deC_x        d eC_y        eCz                    e{          d2             Z|eC}                    e{e|            eeAjB                  d3z  Z~ eeAjB                  d4z  Zd d5lmZ e~r                                r' ej        e~                                          eC_        er                                r' ej        e                                          eC_        g d6eC_        d7 ZEd8 Zd9 Zd: Zd; ZFdeC_        deC_        deC_        d< Zd= Zd> Z eeE           ee          _E         eeE           ee          _         ee           ee          _         ee           ee          _         ee           ee          _         ee           ee          _         ee           ee          _         eeF           ee          _F        d? Z ee           ee          _        d@ Z ee           ee          _        ddCZddDZdddEdFZdG ZeCj        dH             ZddIZddJZdK ZddLZdM ZdN ZddOZddPZddQZdR ZddSZdT ZdU ZdV ZeCj        dW             ZdX ZdY ZdZ ZeCj        dd[            Zdd\Zdd]Zd^dd_g d`daZ	 	 ddbZdc Zdd Zde Zdf Zdg Zdh ZddiZddjZdk ZddleZfdmZddleZfdnZddleZfdoZddleZfdpZddleZfdqZddleZfdrZddleZfdsZddleZfdtZduej        e	j	                 dve	j	        fdwZdxe	j	        dve	j	        fdyZ G dz d{          Zd| Zd} Zdd~ZddZd Zd Zd ZdveZfdZdeZdefdZi eC_        i eC_        i eC_        i eC_        i eC_        i eC_        dZdadaddZd ZddZd ZddZdd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                   $     e Zd Z fdZd Z xZS )Flaskc                 :     t                      j        |i | d S N)super__init__)selfargskwargs	__class__s      ./cmf/app.pyr    zFlask.__init__0   s%    $)&)))))    c                       fd}|S )Nc                                          dd           }| j        }|                    d          d         }|dk    r	d|z   z   }n}||dz   | j        z   } j        ||| fi  t          |           | S )Nendpoint.index/)pop
__module__split__name__add_url_ruleprint)fr)   module_pathmodule_nameurloptionsruler!   s        r%   	decoratorzFlask.route.<locals>.decorator4   s    {{:t44H,K%++C004Kg%%K'$.&,qz9Dc8Q::':::(OOOHr&    )r!   r9   r8   r:   s   ``` r%   routezFlask.route3   s0    	 	 	 	 	 	 	 r&   )r1   r/   __qualname__r    r<   __classcell__)r$   s   @r%   r   r   /   sG        * * * * *      r&   r   c                 r    | r4t          j        dd                    d |D                                  d S d S )N%s c              3   4   K   | ]}t          |          V  d S r   str).0args     r%   	<genexpr>zprint_debug.<locals>.<genexpr>G   s(      %?%?3c#hh%?%?%?%?%?%?r&   )loggingdebugjoin)condr"   _kwargss      r%   print_debugrM   E   sJ     BdCHH%?%?$%?%?%?@@AAAAAB Br&   c                   ,   e Zd ZdZdZdZdZdZdZdZ	dZ
d8d9dZd Zd Zd Zd Zd:d	Zd
 Zd Zd Zd Zededefd            Zedefd            Zed;d            Zd Zd Zd Zd Zd Zd Zd Z d8dZ!d Z"d Z#d Z$d:dZ%d<d Z&d! Z'd" Z(d# Z)d$ Z*d% Z+d& Z,d' Z-d:d(Z.d) Z/d=d+Z0d, Z1d;d-Z2d. Z3e4d/             Z5e4d0             Z6e4d<d1            Z7e e8d23          d4                         Z9e4d5             Z:e4d6             Z;e4d7             Z<dS )>CmfCacheNFreturnc                    t                      | _        t                      | _        || _        || _        i | _        | j        r6| j                            dd           | j                            dd           d| _        d S )Nstat_hitr   	stat_missF)dict	cache_objcache_invalidateredis_dbmemorytexcom_growcache_hack_cacheincrbyjob_daemon_mode)r!   rW   rX   s      r%   r    zCmfCache.__init__T   sw     $ +-(= 	1M  Q///M  a000$r&   c                    t          t          j        p| j        dt          j                   | 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)rM   configDEBUGsysstderrrW   flushdbrT   rU   rV   publishjsondumpsr!   s    r%   rf   zCmfCache.flushdb`   s    FL.DJ0ECJWWWW= 	+M!!####!VVDN$(FFD!0$**T2B2BCCC5tzz65/7R7RSSSSSr&   c                    t          t          j        p| j        dt          j                   t          t                    }| j                                        }| j        	                    dd          D ]}t          | j        d| dt          j                   |dd	         
                                }| j                            |          }|`t          j        |          }|d
         }|d         ||         |<   |                    |           |                                 |                     |           d	S )u)   Инвалидируем весь jscachezCmfCache.flush_jscache!!!r]   zobj:jshash:*  countz"CmfCache.flush_jscache invalidate z!!!   Ncurrent_person_idjsver)rM   rb   rc   rd   re   r   rT   rW   pipeline	scan_iterdecodegetpickleloadsdeleteexecuteemit)r!   emit_msgpipekeyjshashjsresjspersons          r%   flush_jscachezCmfCache.flush_jscachej   s+   FL.DJ0KRUR\]]]]t$$}%%''=**>*FF 		 		C
$Q$Q$Q$QX[XbccccW^^%%FM%%c**E}L''E01H).wHXv&KK		(r&   c                    t          t          j        p| j        dt          j                   d}| j                                        }| j                            dd          D ]2}|                    d          r|dz  }|	                    |           3|
                                 t          t          j        p| j        d	| d
t          j                   dS )u+   Инвалидируем весь obj cachezCmfCache.flush_all_obj!!!r]   r   zobj:*rl   rm   s
   obj:jshash   zCmfCache.flush_all_obj: z recordsN)rM   rb   rc   rd   re   rW   rr   rs   
startswithrx   ry   )r!   rn   r|   r}   s       r%   flush_all_objzCmfCache.flush_all_obj|   s     	FL.DJ0KRUR\]]]]}%%''=**7$*?? 	 	C~~m,, QJEKKFL.DJ0Z50Z0Z0Zadakllllllr&   c                   	
 dd l dd l}dd lddlm ddlm	 |}	
fd
t          j        r	                    t          t          j        j                                        t          j        d          z
            dd                                                                                   d d         d	v r^ |j                    }|d
k    rIt$          j        r=t$          j        t$          j        k    r#t          j        j                                        S |D ]}|dz    
|          z   }d|v r|dz   t          |d                   z   }t+          |                                          D ]#\  }}|dk    r|dz   |z   dz    
|          z   }$| j        rwd|dd         z   dz   	                    |                                                                          z   }|                    dd          }|                    dd          }n?| d	                    |                                                                          z   }t3          | j        d|           |S )Nr   )timezone)ImmutableDictc                    t          |           }t          |t          j        j                  r'| j        r| j        } t          |           }n	d} t          }d}|t          t          t          fv r|t          k    r| dd         dk    rv	 	j
                            |           }|                    j                  }|                    dd          }|} t          d|            n# t           $ r
}Y d }~nd }~ww xY wt          |           }n|t"          k    r| D ]}| |          z   dz   }n|t$          k    s|k    r9|                                 D ]#\  }}||z   }|r| d	 |          z   }|dz   }$n| d
}n|t(          u rt          |           }nlt+          | d          rt          | j                  }nGd|j        z   d	z   
                    t3          j        |                                                     z   }|S )Nz... r      20)secondmicrosecondz!!!!! Date:,:Noneidz
todo2:obj:)type
issubclasscmfr   CmfType
is_definedvaluerD   intfloatparserparse
astimezoneutcreplacer3   	ExceptionlistrT   itemsboolhasattrr   r1   md5rv   ri   	hexdigest)valtresval1evkr   _all2strdateutilhashlibr   s          r%   r   zCmfCache.hash.<locals>._all2str   s5   S		A!SZ/00 > )CS		AACACS#u%%%88AaCD 0 0&o33C88"oohl;;"ll!lCC!}c2222%   #hhd 2 2A+c1CC2da=00IIKK ( (DAq'C (!$iii((1++5!Ci( d#hh 3%% gcf++CC&3c9GKKUXHYHY<Z<Z<d<d<f<ffCJs   	AC' '
C;6C;Z   daysro      )c92a103d860eddgUUUUUU?|r   z|id:r   zHASH:i  z|md5:
rA   _zDEBUG_CACHE HASH:)r   randomdateutil.parserdatetimer   werkzeug.datastructuresr   APPcache_optimizer   rD   r   r   CmfDatenowr   encoder   gcurrent_usersystem_usersortedr   rc   r   rM   )r!   prefixr"   r#   r   srr   r}   r   r   r   r   r   s            @@@@@r%   hashzCmfCache.hash   s   %%%%%%9999990	 0	 0	 0	 0	 0	 0	 0	 0	d  	0'++c#*2D2H2H2J2J8K]ceKfKfKf2f.g.ghijkhk.l.s.s.u.u"v"v  #A  #A  #C  #C  DF  EF  DF  #G  Ka  #a  #aACxxANxq~/N/Nz)--/// 	( 	(CC((3--'AA6>>F
S...Av||~~.. 	4 	4HCd{{C##hhsmm3AA: 	C!AcE("W,AHHJJ0G0G0Q0Q0S0SSA		$$$A		#s##AAw{{188::66@@BBBADJ 3Q777r&   c                    |t                      }|s|S t          t          |j                  }t                      }|j                                        D ]Z}|j                            |d           }|s!|                    d          r|	                    |d d                    n|	                    |           t          |t          j        j                  r0t          ||j        d           }|r|                     ||           t          |t          j        j        t          j        j        f          rrt          ||j        d           }|r|D ]}|                     ||           |                                D ])}	d|j         d|	j         }
|	                    |
           *\|	                    |j        dz   d                    t'          |                    z              |S )N_idr+   )r   ref_r   rA   r   )setgetattrmodels
class_name__dict__r`   r   ru   endswithaddr   r   CmfRelationBasesimple_objects_id_recursive
CmfM2MBaseCmfBackrefBaserelated_modelsr   rJ   r   )r!   objr   modelfields_str_set
field_name	field_clsfield_valuerel_obj	rel_modelrefs              r%   r   z$CmfCache.simple_objects_id_recursive   s   ;%%C 	J//,++-- 	! 	!J((T::I ""5)) /"":crc?3333"":...)SZ%?@@ !%c9+?FF K44[c4JJJI
(=sz?X'YZZ 	!%c9+?FF K#. K K88c8JJJJ "+!9!9!;!; ! !I@@@)*>@@CGGCLLLLsxx~(>(>???@@@
r&   c                    |sg S g }t                      }|                    d          D ]M}|j                            d          r#|                    |j        dd                    n|                    |j                   t          |t          j        j                  r-|	                    | 
                    |j                             t          |t          j        j        t          j        j        f          rw|j        r2|j        D ]*}|	                    | 
                    |                     +|                                D ])}d|j         d|j         }|                    |           *O|                    |j        j        dz   d	                    t%          |                    z              t'          t          |                    }|S )
u   
        Собираем ид связанных обьектов 2 уровня для настройки инвалидации
        :param obj:
        :return:
        Tr   r   Nr+   r   r   rA   r   )r   valuesr   r   r   
isinstancer   r   r   extendobjects_id_recursiver   r   r   r   r   appendrJ   r   r   )r!   r   r   r   fieldr   r   r   s           r%   r   zCmfCache.objects_id_recursive   s     	IZZ4Z00 	$ 	$E((// 5""5#3CRC#89999""5#3444%!;<< C

444U[AABBB%#*"79R!STT $; G#(; G G

4#<#<W#E#EFFFF!&!5!5!7!7 $ $I@@@)*>@@CJJsOOOO

36<#%1G1G(H(HHIII3s88nn
r&   c                     t          |          t          j        k    rt          dd           dS | j        r | j                            d| |           dS | j        r|| j        |<   dS d S )NuU   DEV: Слишком большой объект для кэширования — keyT)
debug_onlyFobj:)lenrb   CACHE_MAX_OBJ_SIZE	cmf_alertrW   r   rX   rU   )r!   r}   str_vals      r%   _obj_dict_setzCmfCache._obj_dict_set  s    w<<&333 n{  A  A  A  A5= 	MlSllG4444[ 	")DN34	 	r&   c                    t                      }|D ]}|                    d|            | j        r$ | j        j        | t	          |          k    rdS dS | j        r$|D ]}| j                            |          s dS  dS d S )Nr   TF)r   r   rW   existsr   rX   rU   ru   )r!   r`   hkeysr}   s       r%   _obj_dict_existszCmfCache._obj_dict_exists1  s     	$ 	$CIIlSll####= 	#t}#U+s4yy88tu[ 	 ! !~))#.. ! 55!44r&   c                    | j         rV| j                             d|           }|| j                             d           n| j                             d           |S | j        r| j                            |          S d S )Nr   rR   rS   )rW   ru   rZ   rX   rU   )r!   r}   r   s      r%   _obj_dict_getzCmfCache._obj_dict_getC  s    = 
	-##L3LL11C$$Z0000$$[111J[ 	>%%c***4r&   r~   inv_payloadc                     |  d| S )N::r;   )r~   r   s     r%   %_jshash_invalidate_confirm_member_keyz.CmfCache._jshash_invalidate_confirm_member_keyP  s    ))K)))r&   
member_keyc                 0    |                      dd          S )Nr   r   )maxsplitr0   )r   s    r%   +_jshash_invalidate_confirm_member_key_splitz4CmfCache._jshash_invalidate_confirm_member_key_splitT  s    q111r&   c                 J    | r| n|                     d          d         }d| S )Nr   zjscache-invalidate-confirm-set:r   )cache_idr~   set_keys      r%   "_jshash_invalidate_confirm_set_keyz+CmfCache._jshash_invalidate_confirm_set_keyX  s1     'A((FLL,=,=b,A::::r&   c                    t          t                    }|                                D ]\  }}t          d| |d |g           |                                D ]]\  }}|                    d          rC||                     |                                       |                     ||                     ^| j        r-|                                D ]\  }} | j        j	        |g|R   d S d S )Nzinvalidate-)roomevent_personsjshash:r~   )
r   r   r   cmf_emit_eventr   r  r   r   rW   sadd)	r!   msgsconfirmations	person_idinv_dictr~   r   r  confirm_lists	            r%   rz   zCmfCache.emit_  s4   #D))#'::<< 	Y 	YIx444hTZcYdeeee'/~~'7'7 Y Y#$$Y// Y!$"I"IQW"I"X"XY``BB6;WWY Y YY
 = 	;)6)<)<)>)> ; ;%""7:\:::::	; 	;; ;r&   c                 J   | j         st          d           | j         r|r|d         d         }|                     |          }t                      }|D ]7}|                    |                     |d         |d                              8 | j         j        |g|R   d S d S d S )Nu$   ERROR! Недоступен redis_dbr   r  r   )rW   r3   r  r   r   r   srem)r!   confirm_dictsample_jshashkey_cache_idr  confirms         r%   jshash_invalidate_confirmz"CmfCache.jshash_invalidate_confirmn  s    } 	:8999= 	<\ 	< )OA.MBB-BXXL66L' h h##D$N$NwWXz[bcd[e$f$fggggDM|;l;;;;;;	< 	< 	< 	<r&   c                      t           j        rt                                            j        r;                     |          } fd j                            |          D             S d S )Nc                 ^    g | ])}                     |                                          *S r;   )r  rt   )rE   memberr!   s     r%   
<listcomp>z;CmfCache.jshash_invalidate_confirm_list.<locals>.<listcomp>  s?     ? ? ? @@QQ? ? ?r&   )r   invalidated_keys	CMF_CACHE_do_invalidate_defferrW   r  smembers)r!   r  r  s   `  r%   jshash_invalidate_confirm_listz'CmfCache.jshash_invalidate_confirm_list|  s    
  	.++---= 	?==hGGG? ? ? ?"m44W==? ? ? ?	? 	?r&   c           	         |sd S | j         r | j         j        d |D               t                              |           |                     |           i }|D ]}| j        rd|vrt          d|            t          | j        d|            | j                             d| d          x}rt          | j        d|            | j        rt          d	|            | j         	                                }|D ]X}	|
                    d
|	                    d                      |                    d
|	                    d                      Y|                                }
t          ||
dd d                   D ]\  }	}|	                    d          }	|t          j        |          }|rr|d         }||vrt!                      ||<   |dk    r/|r-d                    t%          d |D                                 }nd}|d          d| d| d| }|||         |	<   | j                             d| d          x}t'          j                    }|                     |           t'          j                    }||z
  dk    r#t*                              d||z
   d           d S d S | j        r|D ]}|| j        v r| j        |= d S d S )Nc                     g | ]}d | S )r   r;   rE   r}   s     r%   r  z+CmfCache._obj_dict_mdel.<locals>.<listcomp>  s    "@"@"@C<#<<"@"@"@r&   rn   z#DEBUG_CACHE JSHASH: try invalidate z*DEBUG_CACHE JSHASH: try invalidate:jshash:invalidate:jshash:d   rm   z*DEBUG_CACHE JSHASH: got invalidate:jshash:z#DEBUG_CACHE JSHASH: got invalidate r   utf-8r   r   rp   updater   c                     g | ]}|d v|	S ))cache_fieldscmf_modified_atcmf_viewed_atcmf_modified_by_idr;   rE   r   s     r%   r  z+CmfCache._obj_dict_mdel.<locals>.<listcomp>  s0     ,@ ,@ ,@!+,4~+~+~ -.+~+~+~r&   ONLYFORUPDATESrq         ?z_obj_dict_mdel emit got sec)rW   rx   r  inmemory_delprofiler_invalidaterc   r  rM   spoprr   ru   rt   ry   ziprv   rw   rT   rJ   r   timerz   r   rI   rX   rU   )r!   r`   obj_changed_fieldsobj_idactionr{   r}   invjsr|   r~   jshash_listr   r   changed_fieldsr   
emit_startemit_ends                    r%   _obj_dict_mdelzCmfCache._obj_dict_mdel  s    	F= P	 DM "@"@4"@"@"@AA""4((($$T***H 7E 7E: P'"4"4"#N#N#NOOODJ(ZUX(Z(Z[[[  $}112Ls2L2LTW1XXXe 1E
,^Y\,^,^___z T&'RS'R'RSSS=1133D"' E E!@g(>(>!@!@AAA$C6==+A+A$C$CDDDD"&,,..K),UK14E)F)F 'E 'E!'w!7!7& !=$ &U 3 3  E',-@'AH'x7759VV 2  &116H115$* ,@ ,@7I ,@ ,@ ,@ %A %A2" 2"
 2B-27^*c*cv*c*c*c*cSa*c*cK9DHX.v6c  $}112Ls2L2LTW1XXXe 1Et JIIhy{{H*$s**M8j3HMMMNNNNN +*[ 	 , ,$.((s+, , Fr&   c                    | j         rs| j                                         5 }|                                D ]\  }} |j        d| g|R   |                                 d d d            d S # 1 swxY w Y   d S | j        rG|D ]B}|| j        v r'| j        |                             ||                    2||         | j        |<   Cd S d S Ninvalidate:)rW   rr   r   r  ry   rX   rV   r   )r!   r  r|   r}   r   s        r%   _invalidate_dict_msetzCmfCache._invalidate_dict_mset  sB   = 	'')) T#+>>#3#3 < <KCDI1C11;F;;;;;                  [ 	 ? ?$///)#.55hsmDDDD19#D)#..	? ? Fs   A A..A25A2c                     | j         r-| j                             d|           }|rd |D             S |S | j        r| j                            |          S d S )NrC  c                 8    g | ]}|                     d           S )r(  rt   r%  s     r%   r  z1CmfCache._invalidate_dict_get.<locals>.<listcomp>  s$    ;;;

7++;;;r&   )rW   r!  rX   rV   ru   )r!   namer   s      r%   _invalidate_dict_getzCmfCache._invalidate_dict_get  sq    = 	-(()=t)=)=>>C <;;s;;;;J[ 	(,,T222Fr&   c                    | j         rz| j                                         5 }|                                D ]\  }}|r | j         j        d| g|R   |                                 d d d            d S # 1 swxY w Y   d S | j        r^|                                D ]G\  }}|D ]?}|| j                            |g           v r | j        |                             |           @Hd S d S rB  )	rW   rr   r   r  ry   rX   rV   ru   remove)r!   r  r|   rH  r   key_listr}   s          r%   _invalidate_dict_mdelzCmfCache._invalidate_dict_mdel  sm   = 	'')) T$,NN$4$4 J JLD& J**+?+?+?I&IIII	                  [ 	"*.."2"2 @ @h# @ @Cd377bAAAA-d3::3???@@ @
 Fs   AA55A9<A9c           	      L
    t           j                            d          rdt          _        d S t
          j        r|s	 j        rd S t          j        v r 	                    d           d S t                              |          r>dt          _        t           j        dt                              |                      d S                      |          }t          j                            |t          j                  }||k     rFdt          _        t           j        dt          j         d                     |                      d S i t$          j        j                            |          }fd fd	}	|rzt-          |t.                    set1          |d
d           rT |	|           d}
t3          |j                  t          j        v r&t9          d|j         dt          j                    d S n|r:t-          |t.                    r%t1          |d         d
d           rd}
 |	|           n\|Dd}
t;          |          t<          k    r)t;          |          t>          k    rt:          t2          k    r	 n|sd}
d}ntA          d          d}|rN|d         rEt           j        d|           |
dk    rM|j!        |d         vr>|d         D ]5}||j!         d|j!         dfv rd}|j         vrtE          d            n6|sg }dg|j#        D ]}||d         v r|d         |         }|sdg}t/          |          t          j$        d<   |D ]u}|dv rd}|d         D ]d}|%                    d           d         }||k    r d!|             d!| d"           A d#| d$|             d#| d$| d"           ev|d         D ]} d!| d"           |r|d         s d!| d"            j        r D ]}t           j        d%| d&            tM          j'        |          } (                    |          sdt          _)        |r)t          *                    |tW          |                     d't          v rzt          j,        rnt           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 rA   c                     |                      d          \  }}}|vrt                      |<   |r!|                              d|            n|                                         d S )NrA   )	partitionr   r   )bind_and_fieldsbindr   r   r  r}   s       r%   bind_addzCmfCache.add.<locals>.bind_add)  s     .77<<OD!V8##!$ -""c#4#4F#4#45555""c8,,,Fr&   c                 $   t          | t                    r| }n| g}g }|D ]n}t          |j        t          j        j                  r                    |          }n"t                              |                    }|D ]} |           odS )u   
            Собираем списки ключей инвалидации
            :param val:
            :param invalidate_dict:
            :return:
            N)r   r   r   r   r   r   r   r   )r   obj_listr   itemrT  rU  r!   s        r%   bind_add_recursivez(CmfCache.add.<locals>.bind_add_recursive5  s     #t$$ # 7C  # #dgsz'9:: G33D99CCt??EEFFC # #DHTNNNN## #r&   r   r   zSkip add to cache z  g.skipcache_select_for_update: r   r   customemptyEmptyuG   Невозможный объект для хранения в кешеFr   zDEBUG_CACHE WHERE: r   z.idz.codezDEV: Obj in not in inv_dictparentcache_clustersScopeAll)NullNULLnullr   noneNr   r*   where_ScopeAll__insdelwhere_r   zDEBUG_CACHE BIND: z = r~   #DEBUG_CACHE JSHASH: add invalidate r
  )/osenvironru   r   no_jscache_forcerb   JOB_DAEMON_DISABLE_CACHEr[   r  $profiler_redis_invalidated_keys_skipr  cache_is_lockedrM   rc   cache_locked_byget_last_invalidatecache_lockscache_transaction_startr   utilcmfutilget_model_by_namer   r   r   rD   r   skipcache_select_for_updater3   r   r   r   r   r   r   cache_cluster_fieldsprofiler_datar0   rv   ri   r   cache_store_errorinmemory_addr   r~   r  rD  )r!   r}   r   obj_typequery_paramscache_inmemorylirq  	obj_modelrY  obj_casewhere_pkr   scopesc_fieldscope
model_namebindidstr_objrU  r  s   ``                 @@r%   r   zCmfCache.add	  s   :>>*%% 	!%A4 * 	> 	dFZ 	4 !$$$5555AAA4 $$X.. 	!%A
$qILeLefnLoLo$q$qrrr4 %%h//"#-"3"3Ha>W"X"X"R''!%A
  %K!Jc  %K  %Kfjf~f~  @H  gI  gI  %K  %K  L  L  L4H$66x@@	
	 
	 
	 
	 
	 
		# 	# 	# 	# 	# 	#,  &	gz#t,, &	gdD1I1I &	g s###H36{{a;;;r36rrSTSprrsss <  	gZT** 	gws1vtT/J/J 	g Hs####_H CyyCDII$6$643;;   	gH
 CCefff
  F	DL2 F	D
$9<HHH 5  <;Q)Q)Q".x"8  J!&<&<&<>V>V>V%WWW#'!f;h66%&CDDD X  4D  !)J9+IJ I IG,/?"@@@!-.>!?!H  *(\F48LL 01# K KE NNN &&28&< K K
 &0%5%5c%:%:1%=
#z11$H%Cz%C%CDDD$H%Jz%J%J%JKKKK$H%Be%B%Bj%B%BCCC$H%Ie%I%Ij%I%I%IJJJJK #/x"8 D DJ HBzBBBCCCC 	:<#9 	:H8x888999 : 	O" O ODJ(MV(M(M(M(MNNNN ,s##!!#w// 	'"&A 	;""3S\\::: q==QX=
$Z#$Z$ZPQPX$Z$Z[[[z VJSJJAHUUU&&#!('EFFF 	""8,,,,,r&   c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrt	          |          t           j        d<   n't           j        dxx         t	          |          z  cc<   t
          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  rV   cache_invalidate_keys)r   rT   rw  r   r   rO   DEBUG_PROFILE_VERBOSEr   )r!   r`   r   s      r%   r4  zCmfCache.profiler_invalidate  s    	a''"&&& 	 	 	FFFFF	Q_4425d))AO.//O.///3t99<///) 	B&ao==;= 78O34;;DAAAAA		B 	B   !$ 
99c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrdt           j        d<   nt           j        dxx         dz  cc<   dt           j        vrdt           j        d<   t          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  redis_cache_hitr   redis_cache_missr   redis_cache_hit_keysr   rT   rw  r   rO   r  r   r!   r}   r   s      r%   profiler_redis_data_hitz CmfCache.profiler_redis_data_hit  s    	a''"&&& 	 	 	FFFFF	AO3312AO-..O-...!3...Q_4423AO./) 	@%Q_<<:< 67O23::3?????		@ 	@r  c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrdt           j        d<   nt           j        dxx         dz  cc<   dt           j        vrdt           j        d<   |t           j        d<   t          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  r  r   r  r   redis_cache_miss_lastredis_cache_miss_keysr  r  s      r%   profiler_redis_data_missz!CmfCache.profiler_redis_data_miss   s   	a''"&&& 	 	 	FFFFF	Q_4423AO.//O.///14///AO3312AO-.36/0) 	A&ao==;= 78O34;;C@@@@@		A 	Ar  c                     	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wd| }|t           j        vrdt           j        |<   d S t           j        |xx         dz  cc<   d S )Nrw  invalidated_keys_skip_r   )r   rT   rw  r   )r!   r   r   r   s       r%   rl  z-CmfCache.profiler_redis_invalidated_keys_skip  s    	a''"&&& 	 	 	FFFFF	+T++AO##!"AOAOA!#r  c                    t           j                            d          st          j        rd S |t          j        v r|                     d           d S d}|rt                              |          }nd}t          | j
        d           |du r<d}|                     |          }|r#t          j        |          }t          |          }|durdt          v rzt          j        rn|                     d	| t          j        fi           t          | j
        d
| dt          j                    | j
        rt#          d| t          j                   t          | j
        d|            t          | j
        d|           |s3|r1|                     |           t                              |||           |S |                     |           t          | j
        d|            d S )NrO  ru   rP  T.CACHEFr~   r
  z*DEBUG_CACHE JSHASH: add invalidate jshash:rA   rg  zDEBUG_CACHE HIT: zDEBUG_CACHE GET:zDEBUG_CACHE MISS: )rh  ri  ru   r   TECHCOM_HACK3441r  rl  r  inmemory_getrM   rc   r   rv   rw   r   r~   rD  r  r  ry  r  )r!   r}   r|  from_inmemoryr   r   obj_sizes          r%   ru   zCmfCache.get!  s   :>>*%% 	); 	4!$$$5555AAA4 	((--CCCDJ(((#::!M$$S))C $l3''s88c>>1}}}**OcOOah[+IJJJDJ(eUX(e(e[\[c(e(efff: Z"#N#N#NPQPXYYY
$=$=$=>>>
$6<<<  ;^ ;,,S111&&sC:::J%%c***DJ :S : :;;;tr&   c                     dS Nr   rM   rc   r   rW   ru   r!   r  s     r%   ro  zCmfCache.get_last_invalidateG      qr&   c                 l    t          | j        d           |                                 t          _        d S )Nz)DEBUG_CACHE TRANS cache_transaction_start)rM   rc   gen_time_usr   rq  rj   s    r%   rq  z CmfCache.cache_transaction_startL  s/    DJ KLLL$($4$4$6$6!!!r&   c                     t          t          j                            t          j        j                                      d                    S )Nz%Y%m%d%H%M%S%f)r   r   r   r   r   strftimerj   s    r%   r  zCmfCache.gen_time_usP  s6    8$(():)>??HHIYZZ[[[r&   c                     d S r   )	rM   rc   rm  r  rW   r   r   rp  rq  )r!   r  ls      r%   
cache_lockzCmfCache.cache_lockS      r&   c                     d S r   )	r   rp  r   rn  rq  rM   rc   rW   r   )r!   r  tr_startlock_trs       r%   cache_unlockzCmfCache.cache_unlockd  r  r&   c                     dS r  r  r  s     r%   rn  zCmfCache.cache_locked_byt  r  r&   c                     dS NF)	rn  r   rp  ru   rq  rM   rc   rW   r   )r!   r  _cache_locked_byrq  s       r%   rm  zCmfCache.cache_is_lockedy  s    ur&   c                    t          j                     }t          j        }t          j        }t          j        }t                      }	||j        }|D ]}
|
|vrt          ||
                   ||
<   n!||
                             ||
                    ||
         D ]J}d|v r/|	                    |	                    d          d                    5|	                    |           K|                    |	           |
                    |d |                    d          D             ||	d           t          j                     }||z
  dk    r#t                              d||z
   d	           d S d S )
NrA   r   c                     g | ]}|S r;   r;   r/  s     r%   r  z+CmfCache._do_invalidate.<locals>.<listcomp>  s    "H"H"H1"H"H"Hr&   T)
is_changed)r9  r8  r:  inv_listr1  zPROF _do_invalidate got r2  )r7  r   r  r  r  r   r   r)  r   r0   r   r`   rI   )r!   r   r  r:  r9  stglob_inv_dictglob_inv_listr  r  r   inv_valends                r%   _do_invalidatezCmfCache._do_invalidate  s   Y[[

-55>fV 		* 		*A%%#&x{#3#3a  a ''444#A; * *'>>LLs!3!3A!67777LL))))	*
 	)))"H"Hchh$h.G.G"H"H"H 	
 
 	 	 	 ikk8c>>GG<sRx<<<===== >r&   c                    t                               dd           sd S t          j                    }t           j        }t           j        }|D ]2}|                     |d         |d         |d         |d                    3t          j                    }|                     |           t          j                    }||z
  dk    rt                               d||z
   d           t                               d	||z
   d
t          t           j	                              t                               d||z
   d
t          |                      t                      t           _	        i t           _        g t           _        d S )Nr  r  r8  r9  r:  r1  z_do_invalidate_deffer got r2  z)_do_invalidate_deffer _obj_dict_mdel got zsec len=z0_do_invalidate_deffer _invalidate_dict_mdel got )r   ru   r7  r  r  r@  rM  rI   r   r  r   )r!   r  r  r  r  st_invalidate_dict_mdelr  s          r%   r   zCmfCache._do_invalidate_deffer  s   uu'.. 	FY[[

% 	~ 	~H 4h?S6TV^_gVhjrs{j|}}}}"&)++""=111 ikk8c>>GG>r>>>???GG@WZ\@\fijkj|f}f}  A  A  AGG  CsMdGd  C  Cnqr  oA  oA  C  C  D  D  D UU



r&   r)  c                    t           j                            d          rd S || dh}|sd S |                     |           t	          | j        d| d| dt          |                      t                      }t                      }t                      }i }i }t          |          dk    r|D ]}	| j        	                    d|	 dd	          }
|
D ]X}| j        
                    |          }|r:|D ]7}|                    d
          d         }|                    |           |	||<   8Y|                    |
           n{t                              d           t!          | j        	                    dd	                    }
t                              dt          |
                      t#          j        dd                    |          z   dz             }t#          j        d          }t                              d           |
D ]}|                                }|                    |          s,| j        
                    |          }|rS|D ]P}|                    d
          d         }|                    |           |                    |          d         ||<   Q|                    |           |D ]}| j        
                    d|                                           }|                    |          }	|r|D ]}|                    d
          d         }|                    |           | j                            d|                                           }|sdt/          j        |          }|d         }||vrt3                      ||<   d}|d          d| d|	 d| }|||         |                                <   Ȑg |d |D             d |D             d |D             }|r3t                              d| d| d|             | j        j        |  n!t                              d| d| d           |                     |           d S ) NrO  r   z!DEBUG_CACHE start invalidate_ids rA   x   zinvalidate:*r   rl   )matchrn       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   rp   r0  rq   r   c              3   D   K   | ]}d |                                  V  dS r   NrG  rE   	query_keys     r%   rG   z*CmfCache.invalidate_ids.<locals>.<genexpr>"  s7      FFi)Y%%''))FFFFFFr&   c              3   D   K   | ]}d |                                  V  dS )r&  NrG  r  s     r%   rG   z*CmfCache.invalidate_ids.<locals>.<genexpr>#  s7      TTI79#3#3#5#577TTTTTTr&   c              3   D   K   | ]}d |                                  V  dS r  rG  )rE   r~   s     r%   rG   z*CmfCache.invalidate_ids.<locals>.<genexpr>$  s3      >>6&V]]__&&>>>>>>r&   zinvalidate_ids(, ): z): no keys found.)rh  ri  ru   r  rM   rc   r   r   rW   rs   r!  r0   r   r)  r   rI   r   recompilerJ   rt   r  findallrv   rw   rT   rx   rz   )r!   r  idsr:  invalidate_keys
query_keysjshashesr{   obj_id_by_query_keyid_r`   r}   inv_members
inv_memberid_retuuid_rekey_decodedr  query_jshashesr~   r   r   r=  r   	keys_lists                            r%   invalidate_idszCmfCache.invalidate_ids  s    :>>*%% 	F; ###$C 	F 	
###DJ dF d dZ d dZ]^aZbZb d deee%%UU
55 & s88s?? - - }..5JC5J5J5JRV.WW B BC"&-"8"8"="=K" B*5 B BJ)3)9)9$)?)?)BJ&NN:666>A/
;;&&t,,,,-  GG()))//oT/RRSSDGG,T,,--- JuSXXc]]25899Ez"oppHGG&''' 
) 
)!jjll{{;// "m44S99 [&1 [ [
%/%5%5d%;%;A%>
"z222:B:J:J;:W:WXY:Z+J77##C((((# 	F 	FI!]334]IYIYI[I[4]4]^^N%)))44C F, F FF#\\$//2FLL((( M--.FV]]__.F.FGGE  ! "L//E$%89Hx//-1VV* &6N%*7^"X"Xv"X"X"X"X"X"XK:EHX&v}}77

FF:FFF
 UTTTT
 ?>X>>>	
	  	LGGGjGGCGGIGGHHH DM ),,,GGJjJJCJJJKKK		(r&   c                 B    d fd	}t           j                            d          rd S |sd S                      |           t	           j        d d|            i |D ]9} |d| d| d            ||d	                                d |
           :d S )Nr   c                 ~                         |           }|r$|| <   t          j        d d| |             d S d S )NDEBUG_CACHE INVAL: rA   )rI  rM   rc   )invalrI   invdr:  r  r!   s      r%   _check_invalz8CmfCache.invalidate_ids_as_wrapper.<locals>._check_inval.  sd     ,,U33D W"&DJ(Uf(U(Uu(Ue(U(UVVVVVW Wr&   rO  DEBUG_CACHE start invalidate rA   r   r   ref=obj.id=)r9  )r   )rh  ri  ru   r  rM   rc   r  )r!   r  r  r:  r  r  r  s   `  `  @r%   invalidate_ids_as_wrapperz"CmfCache.invalidate_ids_as_wrapper-  s   	W 	W 	W 	W 	W 	W 	W 	W :>>*%% 	F 	F 	
###DJ U U U U UVVV 	D 	DCL222j22F;;;Li(((
 hsCCCC	D 	Dr&   c                     t                               dd|d|d|           t          j                    }d7 fd	}ddlm} t
          j                            d	          rd S                      |j	                   t           j        d
 d|j	                    |j	        }i  j        rdd l}	|	                                 |j	        dk    r ||j         d           dv r |d|j         d|j	         d           |st#          d            ||j         d|g            |d|j	         dd            |d|j         d|j	         dd           t          j                    }
                     |           t          j                    }||z
  dk    r$t                               d d||z
   d           d S t'                      }|                    d          D ]\  }}d}|j	        |v rt+          |t,          j        j                  rt3          |d           r|j        j        r|j        sd!v r%|r#|j        r |d|j         d|j	         d           d"v ro|j        rh|j        |j        k    rX |d|j        j         d|j	         d#            |d|j        j         d|j	         d$           |                    |           t+          |t,          j        j                   r"d"v r|j        r|                    |           1|j        r6t+          |t,          j        j!                  r|                    |           n|j        rW|j        |j        k    rG|                    |           |"                    d%          r|                    |d d&                    tG          |          dk    r'd"k    r!t           j        d' d(|j                   d S d)g}|j$        D ]}|                    |           tK          tM          |          d*d           r|'                    |           d!v r ||j         d           d"k    r ||j         d|           d"k    rB|D ]>}d+g|j$        D ]}t3          ||          stQ          tM          ||                   t,          j        j                   r&||         D ]} |d|j         d| d,| d           ltQ          tM          ||                   t,          j        j                  r |d||d%z             d| d,| d           tQ          tM          ||                   t,          j        j)                  r |d||          d| d,| d           t#          d-d.            |d| d,| d           @d/}d+g|j$        D ]=}t3          ||          r+||         j        r||         j        ||         j        k    rd}>d!v s|r7t3          |d           r|j        j        r|j        sd+g|j$        D ]}t3          ||          stQ          tM          ||                   t,          j        j                   rf||         D ]} |d|j         d| dd0           ||         j        r5||         j        r(||         j        D ]} |d|j         d| dd1           tQ          tM          ||                   t,          j        j                  r[ |d||d%z             d| dd           ||         j        r0||         j        r# |d||         j        j         d| dd2           9tQ          tM          ||                   t,          j        j)                  rX |d||          d| dd           ||         j        r0||         j        r# |d||         j        j         d| dd2           t#          d-d.           t3          |d           r|j        j        r|j        s |d| d           nktT          j+        r_d!v s|rYt3          |d           rI|j        j        s=|j        ,                                 |j        rt#          d3t           j-         d4           t\          j/        r1t           j0                            d5g           gz   t           j0        d5<   t          j                    }
                     |           t          j                    }||z
  dk    r#t                               d6||z
   d           d S d S )8NzRUN INVALIDATE: action=z obj=z item=z m2m_field_name=r   c           	                              |           }g }|rF|rt          |          }g }|D ]}d|vr|                    |           |                    d          ^}}}|rPt                              d|  d|            t          d|  d| d| d           |                    |           t          |                    d                    }	||	z  r|                    |           || <   n|| <   t          j        d d| |             i }
||
| <   t          j
        r5t          j                            dg           |
gz   t          j        d<   d S d S d S )	NrA   z=cmfCache.invalidate(): ValueError: too many values to unpack(r  Tabortr   r  r  )rI  r   r   r0   r   rI   r   rM   rc   rO   r  rw  ru   )r  rI   change_fieldsr  invd_affectedir   i_fieldstaili_set_fieldstmpr:  r  r!   s              r%   r  z)CmfCache.invalidate.<locals>._check_invalP  s    ,,U33DM V  +$'$6$6M$&M! 4 4a<<)00333$-.WWS\\*8d   %GG$qdi$q$qno$q$qrrr%&zfk&z&zpq&z&ztx&z&z  CG  H  H  H  H)00333$'*8>>#+>+>'?'?(<7 4)00333&3HUOO&*HUODJ(Uf(U(Uu(Ue(U(UVVV!E
1 V./o.A.A&.L.LPSu.TAOF+++=V V:V Vr&   r   )r   rO  r  rA   RelationCachezRelationCache.parent.id=)r   rK  r   r   r  uY   DEV: FATAL в инвалидацию м2м поля не передали имя поляr  )r  rd  re  zwhere=rf  r1  zinvalidate (action=z) got zjsec. _check_inval {_check_inval_done - st}sec, _do_invalidate {_do_invalidate_done - _check_inval_done}secTr   )r-  cmf_viewed_bycmf_versionr   is_dummy)createrx   r)  zref_new=zref_old=r   r+   zDEBUG_CACHE ivalidate: z not fields_have_changes--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 r   N)1r   rI   r7  collectionsr   rh  ri  ru   r  r   rM   rc   TRACEpdb	set_trace	parent_idr   r   r  r   r   r   r   r   r   r   r  r   r  oldnewr   r   r   r   r   rv  r   r   load_fieldsr   CmfTUUIDrb   RAISE_LAZYLOADload
api_methodrO   r  rw  )r!   r   r:  rX  m2m_field_namer  r  r   rz  r  _check_inval_done_do_invalidate_doner  r   r   no_caching_fieldscluster_load_fieldsr  cc_field_name
cc_clustercluster_field_is_changedr  s   ` `                  @r%   
invalidatezCmfCache.invalidateM  s   	M6MMSMMDMMNMMNNNY[[#	V #	V #	V #	V #	V #	V #	V #	VJ 	,+++++:>>*%% 	4'''DJ Y Y Y Y YZZZ> : 	(JJJ>_,,LCM+-GHHH)))L:::#.::FCCC! wuvvvLCFi?OPPPPLB3>BBBHMMMLC$'CCCNCCCXNNN !%	Xv666"&)++"R'#-- Wf W W<ORT<T W W W X X X F!$d!;!; 1	: 1	:J
 !V $555
  %!;<< $S*55:=,:QVYVb 111e11 L!C!C!C3>!C!CFKKK h''E,<'eiAWAW L!G!G!Gs~!G!G
SSS L!G!G!Gs~!G!G
SSS!((444%!677 Fx<P<PUZUe<P $$Z000 Jucj6O$P$P $$Z000  :EI$:$:$$Z000&&u-- :!((CRC999 }q  Vx%7%7
$^f$^$^$^`c`fgggF
  $f/ 	0 	0G&&w////499.55 	1OO/000
 ***LCFY///XLCFYmLLLL X+ Q Q
 '/%J1I%J Q QM"366 ! !$s='9":":CJ<QRR 	Q*-m*< e eJ(L)Y*-)Y)Y()Y)YZ)Y)Y[cdddde#D]);$<$<cj>XYY Q$%`c-2E.F%`%`%`%`T^%`%`bjkkkk#D]);$<$<cj>QRR Q$%Zc-.@%Z%Z8%Z%Zj%Z%Z\deeee! #DKOQ Q Q Q Q FxFF*FFxPPPP#( &B)AB 	0 	0MsM** 0M*50M*.#m2D2HHH+/( ***.F*!#z22 +7:|7N +SVS_ + #+!FS-E!F M MsM22 d3}#566
8MNN M&)-&8 _ _
$%Ojm%O%Oh%O%O%OQ]^^^^=)4 g]9K9O g*-m*<*@ g gJ(L)S*-)S)S()S)S)SUeffffS%7 8 8#*:TUU 
M L!X#me.C*D!X!Xx!X!X!XZbccc=)4 k]9K9O k$%[c-.@.D.G%[%[(%[%[%[]ijjjS%7 8 8#*:MNN M L!P#m*<!P!Px!P!P!PRZ[[[=)4 k]9K9O k$%[c-.@.D.G%[%[(%[%[%[]ijjj @GKM M M M M. C,, B1H BS\ B@x@@@AAA # 	z---1I-c:&& .,) . L| z  y!,  y  y  y  z  z  z) 	\*+/*=*=j*L*LPXl*ZAOJ' IKKC6222"ikk#c))GG S&9B&> S S S T T T T T *)r&   c                     | j         D ]\  }}t          d|           | j                                        D ]\  }}t          d|           d S )NzDEBUG CmfCache.dumps)rU   r3   rV   r   )r!   r}   r   s      r%   ri   zCmfCache.dumpsb  sk     	/ 	/HC(#....-3355 	/ 	/HC(#....	/ 	/r&   c                    |                     d          d         }t          j        r|                     d          d         }	 t          j        j                            |          }n# t          $ r Y dS w xY wt          j	        s2|j
        r|j        t          j        vrn|                     |           dS |j
        st          dd           d S |t          j        vr|                     |           dS t          j        |         }|                    |d          }|du r|                     |           |S |                    |           |                     |           |S )	Nr*   r   r   r   .S   DEV: inmemory_get вызван для модели без флага cache_inmemoryTr  )r0   rO   rc   r   rr  rs  rt  KeyErrorr   in_memory_cacher|  r   in_memory_cache_skip_modelsprofiler_inmemory_data_skipr   r   INMEM_CACHEprofiler_inmemory_data_missru   move_to_endprofiler_inmemory_data_hit)clsr}   r  r   model_cacherets         r%   r  zCmfCache.inmemory_getq  s|    YYs^^A&
> 	2#))#..q1J	H$66zBBEE 	 	 	33	   		
 # E,<@],],]//444s# 	ltxyyyy4S_,,++C0003oj1ooc3''#::++C000J ##C(((**3///Js   $A) )
A76A7c           	         |dk    rt          |t          j        j                  st	          j        |          rd| }nw|rut          |t                    r`t          |d         t          j        j                  st	          j        |d                   r!d|d         j         dt          |           d}t          | j
        d| d|            d S t          | j
        d|            |                    d	          d         }t          j
        r|                    d
          d         }	 t          j        j                            |          }n# t           $ r Y d S w xY wt"          j        s	|j        sd S |j        st)          dd           d S |j        rd}|t*          j        vrt/                      t*          j        |<   t*          j        |         }||v r,||         |k    rt1          d| d| d||                     d S |||<   t          |          |k    r3|                    d          \  }	}
t          | j
        d|	            d S d S )Ni  r  r   []u/   DEV: skip inmemory_cache obj_size > 128000 — u	    байтzCmfCache:inmemory_add add key r*   r   r   r  Tr    zInmemory cache error! key:z	 try_add:z exists:F)lastz"CmfCache:inmemory_add evicted key )r   r   r   	BaseModeldataclassesis_dataclassr   r   r   rM   rc   r0   rO   rr  rs  rt  r  r   r  r|  r   r   r  r   r3   popitem)r  r}   r   r  detailr  r   	LRU_LIMITr  evicted_keyr   s              r%   ry  zCmfCache.inmemory_add  s    f#sz344 >8PQT8U8U >#c >C.. >A
(<==>ALAYZ]^_Z`AaAa>=c!f/==#c((===	#pU]#p#phn#p#pqqq4 	CIEEEFFFYYs^^A&
> 	2#))#..q1J	H$66zBBEE 	 	 	FF	   	)= 	 4# 	ltxyyyyF 	IS_,,*5--COJ'oj1+ 33&&`3````kZ]N^``aaaFC{i''(00e0<<NK	#U#U#UVVVVV ('s   /$E 
E"!E"c                    g }|dk    r#t          | j        d           i t          _        d S |D ]}|                    d          d         }t
          j        r|                    d          d         }	 t          j        j        	                    |          }n# t          $ r Y vw xY w|j        s|                    |           |t          j        vrt          j        |         }|D ]}|                    |d            |sQ|rQt          j                            dt                               |t%          j                    d          g           d S d S d S )	Nra   uS   CmfCache:inmemory_del Полный сброс inmemory_cache при REDISDB.flushdbr*   r   r   r   r_   )r`   skip_app_id)rM   rc   r   r  r0   rO   r   rr  rs  rt  r  r|  r   r.   r   delayed_redis_eventsrh   ri   rh  getpid)r  r`   
from_event
event_keysr}   r  r   r  s           r%   r3  zCmfCache.inmemory_del  s   
5==	#xyyy COF 	+ 	+C3*J~ 6'--c2215
(:::FF    ' c"""00/*5K + +T****+ 	Cj 	C"))+BDJJXbsus|s~s~OO  EA  EA  +B  C  C  C  C  C	C 	C 	C 	Cs   3$B
B%$B%r_   )channelc                     | sd S | d         fd}t          t          j        d           t          j        |           d S )Nr`   c                  v    t          t          j        d            t                               d           d S )Nz*CmfCache:on_inmemory_del event with keys: T)r,  )rM   rO   rc   r  r3  )r`   s   r%   handlerz)CmfCache.on_inmemory_del.<locals>.handler  s8    (TVZ[[[""4D"99999r&   z&CmfCache:on_inmemory_del spawn handler)rM   rO   rc   geventspawn)datarL   r1  r`   s      @r%   on_inmemory_delzCmfCache.on_inmemory_del  s_      	FF|	: 	: 	: 	: 	:
 	HN$MNNNWr&   c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrdt           j        d<   nt           j        dxx         dz  cc<   dt           j        vrdt           j        d<   t          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  inmemory_cache_hitr   inmemory_cache_missr   inmemory_cache_hit_keysr  r  r}   r   s      r%   r  z#CmfCache.profiler_inmemory_data_hit  s    	a''"&&& 	 	 	FFFFF	q6645AO011O0111Q6111 7756AO12) 	C(??=? 9:O56==cBBBBB		C 	Cr  c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrdt           j        d<   nt           j        dxx         dz  cc<   t          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  inmemory_cache_skipr   inmemory_cache_skip_keysr  r:  s      r%   r  z$CmfCache.profiler_inmemory_data_skip  s    	a''"&&& 	 	 	FFFFF	 7756AO122O1222a7222) 	D)@@>@ :;O67>>sCCCCC		D 	Dr  c                    	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vrdt           j        d<   nt           j        dxx         dz  cc<   dt           j        vrdt           j        d<   t          j        rDdt           j        vrg t           j        d<   t           j        d                             |           d S d S )Nrw  r8  r   r7  r   inmemory_cache_miss_keysr  r:  s      r%   r  z$CmfCache.profiler_inmemory_data_miss)  s    	a''"&&& 	 	 	FFFFF	 7756AO122O1222a7222q6645AO01) 	D)@@>@ :;O67>>sCCCCC		D 	Dr  r  rP   Nr   NNF)r)  )=r1   r/   r=   rU   rV   rW   rX   rc   r  r  PROCESS_EVICTED_FLUSHr    rf   r   r   r   r   r   r   r   r   staticmethodrD   r   r  r  rz   r  r"  r@  rD  rI  rM  r   r4  r  r  rl  ru   ro  rq  r  r  r  rn  rm  r  r   r  r  r  ri   classmethodr  ry  r3  on_server_eventr5  r  r  r  r;   r&   r%   rO   rO   J   s)       IHFE!E!
% 
% 
% 
% 
%T T T  $m m mQ Q Qf! ! ! !F  <  &  $   *c * * * * \* 2 2 2 2 \2 ; ; ; \;; ; ;< < <? ? ?S S Sj  	 	 	   Q- Q- Q- Q-fB B B"@ @ @&A A A($ $ $ $$ $ $ $LR R R
7 7 7\ \ \* * *"C C C G G G
  > > > >>  2k k k kZD D D@ST ST ST STj/ / / + + [+\ .W .W [.W` C C C [CB _4555  65 \ C C [C& D D [D" D D [D D Dr&   rO   c                       e Zd Zd ZdS )CustomJSONProviderc                     	 t          |t          j        t          j        f          r|j        }t          |t
          j                  st          |t
          j                  r2|j        s|                                dz   S |                                S t          |t          j	                  r|j        S t          |          }t          |          S # t          $ r
}Y d }~nd }~ww xY wt          j        | |          S )NZ)r   r   CmfDateTimer   r   r   datetzinfo	isoformatr   iterr   	TypeErrorr   default)r!   r   iterabler   s       r%   rQ  zCustomJSONProvider.default@  s    	"# 2FNCDD  i#x011 !ZX]5S5S !z 1==??S00}}&C00 !y CyyH >>!  	 	 	DDDD	 #*4555s$   A>C C  C 6C 
C(#C(N)r1   r/   r=   rQ  r;   r&   r%   rH  rH  ?  s#        6 6 6 6 6r&   rH  )static_folder	root_pathTSEND_FILE_MAX_AGE_DEFAULTF)SocketIO	Namespace)Client
project_idc                     t          |           } t          j                            |           }|s;t          j                            | g d          }|rd|_        |t          j        | <   |S )N)0ui_form_scheme
logic_typelogic_prefixcust_field_conf_schemedefault_gantt_task_typez1security_level_scheme.default_task_security_levelzcalendar.timezonetask_code_prefixtask_code_use_logic_type_prefix	executors
spectatorsactivityzactivity.prefixresponsibleauto_alarm_datemain_gantt_projectadd_object_typedefault_agile_story_pointstask_allow_multiple_sprintssl_deadline_shiftsl_only_owner_approvesl_deny_no_approve)sl_allow_executor_change_nofatal_deadlinesl_task_need_approvesl_task_only_owner_closesl_readonly_closed_task.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_taskdefault_attach_full_search_typesdesk_feedbackr   r   T)rD   r   cache_projectsru   r   
CmfProjectreadonly)rY  projects     r%   get_cache_projectrz  q  s|    ZJ $$Z00G <1#'': 8? 8? 8?' 8 8r  	$#G)0:&Nr&   c                  j   t           st          d          5 } |                                 }d d d            n# 1 swxY w Y   d}||vrt          d          |                    |d          }t
                              |          a t                               t          t                                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   jinja2Templaterenderr   app_base_href)template_filetemplate_strbase_href_substrs      r%   _render_indexr    s     ! >/00 	0M(--//L	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 -<//RSSS#++,<>_`` & = = ''!}'GGGs   8<<r   c                 b   |rd| dg}ng d}d |D             D ]}t          ||           }t          j                            |          s t          j                            ||          }	 t          j                            |          srn3# t          t          f$ r t          j	        
                                w xY wt          j	                            |d          c S t          j        D ]2} ||           }|r#t          j	                            |d          c S 3t                      S )Nzcustom/plugins/z/static)zcustom/static/zcommon/static/zcmf/static/zdist/cmf-angular/c                 b    g | ],}t           j                            t          j        |          -S r;   )rh  pathrJ   rb   PROJECT_DIR)rE   ds     r%   r  zsend_static.<locals>.<listcomp>  s+    OOOabgll6#5q99OOOr&   T)conditional)r   rh  r  isabsrJ   isfilerP  r  flaskhelpers
BadRequest	send_filer   HOOK_STATIC_NOTFOUNDr  )req_filenamepluginsearch_dirs	directoryfilenamehooks         r%   send_staticr    sa    !88889! ! !
 PO;OOO 	C 	C	Y55w}}X&& 	9w||Ix88H	-7>>(++ :& 	- 	- 	--**,,,	-}&&xT&BBBBB( G G4%% 	G=**8*FFFFF	G??s   -B0B>c                       e Zd ZdZddej        dee         fdZd Z	e	d             Z
e	d             Z
e	d	             Ze	d
             Ze	d             Ze	dd            Ze	d             Ze	dd            Ze	d             Ze	d             ZdS )CmfRedisMemoryWrapperut    Если есть self.redis - используется он
        Если нет - нужен фолбэк
    Nredisredis_instance_namec                 0    || _         i | _        || _        d S r   )r  
memstorager  )r!   r  r  s      r%   r    zCmfRedisMemoryWrapper.__init__  s    
#6   r&   c                       fd}|S )Nc                     | j         re	  t          | j         j                  |i |S # t           j        $ r2}t          j        rt                              | j                   |d }~ww xY wt          d          )Nu&   Redis memory wrapper запрещен!)
r  r   r1   ConnectionErrorrb   CACHE_REDIS_FAILOWERREDIS_SETTINGS_MANAGERcheck_and_updater  CmfAbortError)r!   r"   r#   r   r4   s       r%   wrapperz/CmfRedisMemoryWrapper.fallback.<locals>.wrapper  s    z N:74:qz::DKFKKK,   2 Z.??@XYYYG
 $$LMMMs   * A+-A&&A+r;   )r4   r  s   ` r%   fallbackzCmfRedisMemoryWrapper.fallback  s(    		N 		N 		N 		N 		N r&   c                     t           r   NotImplementedErrorr!   r"   r#   s      r%   r!  zCmfRedisMemoryWrapper.smembers      !!r&   c                     t           r   r  r  s      r%   r!  zCmfRedisMemoryWrapper.smembers
  r  r&   c                 6    | j                             |          S r   r  ru   r!   r}   s     r%   ru   zCmfRedisMemoryWrapper.get      ""3'''r&   c                 8    | j                                          d S r   )r  clearrj   s    r%   rf   zCmfRedisMemoryWrapper.flushdb  s    r&   c                 6    | j                             |          S r   )r  ttlr  s     r%   r  zCmfRedisMemoryWrapper.ttl  r  r&   Fc                 B    | j                             ||||||          S )N)nxxxgtlt)r  expire)r!   r}   r7  r  r  r  r  s          r%   r  zCmfRedisMemoryWrapper.expire  s%    %%c4B2"%LLLr&   c                 Z    | j                             |d          }||z  }|| j         |<   |S r  r  )r!   r}   amountr   s       r%   rZ   zCmfRedisMemoryWrapper.incrby  s3    ##C++$r&   r   c                 .    |                      ||          S r   )rZ   )r!   r}   r  s      r%   incrzCmfRedisMemoryWrapper.incr%  s    {{3'''r&   c                 0    d}|D ]}|| j         v r|dz  }|S )Nr   r   r  )r!   namesr   ns       r%   r   zCmfRedisMemoryWrapper.exists)  s2     	 	ADO##Qr&   c                     || j         |<   d S r   r  )r!   r}   r   s      r%   r   zCmfRedisMemoryWrapper.set1  s    $r&   rA  )FFFF)r   )r1   r/   r=   __doc__r  Redisr   rD   r    r  r!  ru   rf   r  r  rZ   r  r   r   r;   r&   r%   r  r    sw        7 7ek 7xPS} 7 7 7 7
   " " X" " " X" ( ( X(     X  ( ( X( M M M XM   X ( ( ( X(   X % % X% % %r&   r  c                       e Zd ZdZdZd Zdee         fdZdedee	j
                 fdZdded	efd
Zdede	j
        fdZd Zdeeef         fdZdefdZddefdZdS )RedisSettingsManageruR   
    Менеджер по управлению настройками Redis.
    rQ  c                 F    t          j        d          | _        d| _        d S )Nzredis-settingsF)rH   	getLoggerlogger_terminatingrj   s    r%   r    zRedisSettingsManager.__init__?  s#    '(899!r&   rP   c                    d}t           j        j        }t           j        j        j        j        }	 |                    |                                          }|j        }|	                                 n# |	                                 w xY w|S )uX   
        Возвращает название инстанса Redis из БД
        N)
r   CmfGlobalSettingsdp_modeldpdata_driverSessionqueryfirstcache_redis_primaryclose)r!   redis_instancer  sessionsettingss        r%   _get_instancez"RedisSettingsManager._get_instanceC  sv    
 +4*-9A	}}X..4466H%9NMMOOOOGMMOOOOs   .A3 3B	instancec                 2   t          t          d          rt          j        |         d         dk    ret          j        |                                         }|                    d           d|v r|                    d           t          j        di |S d S d S )Ncache_settingsr   r  	celery_dbr;   )r   rb   r  copyr.   r  r  )r!   r  cfgs      r%   _init_redisz RedisSettingsManager._init_redisT  s    6+,, 	&1Fx1PQW1X\c1c1c'16688CGGFOOOc!!$$$;%%%%%	& 	&1c1cr&   F
with_flushc                 z   t           j        j        }t           j        j        j        j        }	 |                    |                                                                          }|r| 	                    |          }| j
                            d           	 |                     ||           t                                           n*# t          $ r | j
                            d           Y nw xY w||_        |                                 |                                 d S # |                                 w xY w)Nu*   Выполняем очистку кешаu>   Не удалось выполнить очистку кеша)r   r  r  r  r  r  r  with_for_updater  r  r  warning
init_cacher  rf   r   r  commitr  )r!   r  r  r  r  r  r  s          r%   
save_to_dbzRedisSettingsManager.save_to_db]  s'   +4*-9A	}}X..>>@@FFHHH j!%!1!1(!;!;##$PQQQjOOHn===%%''''  j j jK''(hiiiiij ,4H(NNMMOOOOOGMMOOOOs0   A*D$ /C	 D$ 	$C0-D$ /C00D$ $D:r  c                     t          t          d          rct          j        |         d         dk    r|t          _        d S t          j        |         d         dk    rdt          _        d S t          d          d S )Nr  r   r  rX   Tu&   Неизвестный тип кеша)r   rb   r  r  rW   rX   r   )r!   r  r  s      r%   r  zRedisSettingsManager.init_caches  s}    6+,, 	J$X.v6'AA%3	"""&x08HDD#'	    HIII	J 	Jr&   c                    |                                  \  }}|                     |          t          _        |t          _        t
          j        r|s|                     |           t          j	        
                    d          rt          j        t          d          t                              |           |                     |t          j                   d S )N	run_uwsgiu?   При работе через uwsgi обязателен Redis)get_instancer  REDIS_DBr  r  rb   r  r  rh  ri  ru   r   socketiostart_with_redisr  )r!   is_db_instancer  s      r%   
init_rediszRedisSettingsManager.init_redis|  s    #'#4#4#6#6 ))(33'/$ & 	&~ 	&OOH%%%:>>+&& 	c~% abbb!!(+++(.11111r&   c                 z    t           j        r#|                                 }|rd}n| j        }d}n	d}| j        }||fS )NTF)rb   r  r  DEFAULT_REDIS_INSTANCE)r!   r  r  s      r%   r  z!RedisSettingsManager.get_instance  sT    & 		3))++H '!% 7!&"N2Hx''r&   r  c                    |                                  }||k    r| j        sd| _        | j                            d|           t	          j        dd          }|dk    r1| j                            d|           t          j        |d           | j                            d|           t          j
        t          j                    t          j                   d	S d	S d	S )
u   
        Проверяем, обновилась ли конфигурация Redis в БД
        и если да, то терминейтим app
        Tu<   Получена конфигурация Redis %s из БДr   <   uU   Ожидание %d секунд для применения конфигурацииFr   uv   Остановка процесса приложения для применения конфигурации Redis %sN)r  r  r  r  r   randintr2  sleepinforh  killr+  signalSIGTERM)r!   r  db_instancesleep_secondss       r%   r  z%RedisSettingsManager.check_and_update  s     ((**---d6G- $DK ^`klll"N1b11M!!##${  ~K  L  L  L]6666 K  V  Xc  d  d  dGBIKK00000 .---r&   r  intervalc                    | j                             d           |                                 \  }}	 	 |                     |           n+# t          $ r | j                             d|           Y nw xY wt          j        |d           Y)u^   
        Переодический запуск проверки и смены Redis
        u,   Запуск periodic_check_and_update RedisTu   Запуск periodic_check_and_update Redis завершился с ошибкой. Повторный запуск через %d секундFr  )r  r  r  r  r   	exceptionr2  r  )r!   r  r   r  s       r%   periodic_check_and_updatez.RedisSettingsManager.periodic_check_and_update  s    
 	GHHH!%!2!2!4!4	.%%&9::::   %%QRZ    
 Lu----	.s   A
 
%A21A2NrB  )r  )r1   r/   r=   r  r  r    r   rD   r  r  r  r  r   r  r  r  r   r  r  r   r  r;   r&   r%   r  r  8  s<         '" " "x}    "&C &HU[,A & & & & 3 D    ,J3 J J J J J2 2 2&(eD#I. ( ( ( (1C 1 1 1 1&. .# . . . . . .r&   r  )Payloadr'  c                   `    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd ZdS )CmfSocketIOWrapperu   
    Функционал:
    1. Отложенная активация, после получания доступа к Redis
    c                     t           dt          j        dd| _        d | _        d | _        g | _        g | _        g | _        g | _	        d S )Nr   F)appcors_allowed_originsr  engineio_logger)
r   rb   rc   socketio_kwargsr  r  lazy_on_handlerslazy_on_namespace_handlerslazy_init_apps	lazy_runsrj   s    r%   r    zCmfSocketIOWrapper.__init__  sU     $'l$ 
  
 " "*,' r&   c                    t          d|            | j        r+| j        |k    rt          d           d S t          d          |                     |           t          di | j        | _        |                                  |                                  | 	                                 | 
                                 || _        d S )Nz%CmfSocketIOWrapper: start_with_redis u=   Warning. CmfSocketIOWrapper.start() вызван дваждыu)   CmfSocketIOWrapper уже запущен!r;   )r3   r  r  r   _make_redis_connect_paramsrV  r  _start_lazy_on_handlers!_start_lazy_on_namespace_handlers_start_lazy_init_app_start_lazy_run)r!   r  s     r%   r  z#CmfSocketIOWrapper.start_with_redis  s    FnFFGGG= 	I"n44UVVVGHHH''777 884#788$$&&&..000!!###,r&   c                       fd}|S )Nc                 D    j                             | d           d S )N)funcdec_args
dec_kwargs)r  r   )r  r  r  r!   s    r%   wrapz#CmfSocketIOWrapper.on.<locals>.wrap  s;    !(($(* *     r&   r;   )r!   r  r  r  s   ``` r%   onzCmfSocketIOWrapper.on  s/    	 	 	 	 	 	 	 r&   c                     | j                             |           | j        r.t          d|            | j                            |           d S d S )Nz!CmfSocketIOWrapper: on_namespace )r  r   r  r3   on_namespace)r!   r1  s     r%   r!  zCmfSocketIOWrapper.on_namespace  s`    '..w777= 	0?g??@@@M&&w/////	0 	0r&   c                     | j                             ||d           | j        r)t          d| d|             | j        j        |i | d S d S )N)r"   r#   zCmfSocketIOWrapper: run rA   )r  r   r  r3   runr  s      r%   r#  zCmfSocketIOWrapper.run  s    
 
 	 	 	 = 	/<T<<F<<===DMt.v.....	/ 	/r&   c                 *     | j         j        |i | d S r   )r  rz   r  s      r%   rz   zCmfSocketIOWrapper.emit  s"    D+F+++++r&   c                     | j                             |           | j        r.t          d|            | j                            |           d S d S )NzCmfSocketIOWrapper: init_app )r  r   r  r3   init_app)r!   r   s     r%   r&  zCmfSocketIOWrapper.init_app
  s`    ""3'''= 	(7#77888M""3'''''	( 	(r&   c                 :     | j         j        j        j        |i |S r   )r  servermanagerget_participantsr  s      r%   r*  z#CmfSocketIOWrapper.get_participants  s"    <t}#+<dMfMMMr&   c                     | j         D ]A}t          d|              | j        j        |d         i |d         |d                    Bd S )Nu8   CmfSocketIOWrapper: регистрируем on handler r  r  r  )r  r3   r  r  )r!   lazy_on_handlers     r%   r  z*CmfSocketIOWrapper._start_lazy_on_handlers  sr    #4 	u 	uO^_^^___[DMoj9[_\=Z[[\klr\stttt	u 	ur&   c                 r    | j         D ].}t          d|            | j                            |           /d S )NuB   CmfSocketIOWrapper: регистрируем on_namespace handler )r  r3   r  r!  )r!   lazy_on_namespace_handlers     r%   r  z4CmfSocketIOWrapper._start_lazy_on_namespace_handlers  sU    )-)H 	B 	B%rWprrsssM&&'@AAAA	B 	Br&   c                 r    | j         D ].}t          d|            | j                            |           /d S )Nu2   CmfSocketIOWrapper: отложенный init_app )r  r3   r  r&  )r!   r  s     r%   r  z'CmfSocketIOWrapper._start_lazy_init_app  sN    & 	( 	(CLsLLMMMM""3''''	( 	(r&   c                 z    | j         D ]2}t          d|             | j        j        |d         i |d          3d S )Nu-   CmfSocketIOWrapper: отложенный run r"   r#   )r  r3   r  r#  )r!   lazy_runs     r%   r  z"CmfSocketIOWrapper._start_lazy_run"  s_     	G 	GHL(LLMMMDMx/F8H3EFFFF	G 	Gr&   c                    t          t          d          rWt          j        |         d         dk    r:t          j        |         d         }t          j        |                             d          r>dt          j        |         d          d| }dd	lm}  ||d
d          }|| j        d<   d S d}dt          j        |         v r|t          j        |         d         z  }dt          j        |         v r|dt          j        |         d          dz  }|t          j        |         d         z  }|dt          j        |                             dd           z  }|d| z  }|| j        d<   d S t          d           d S )Nr  r   r  dbunix_socket_pathzunix://z?db=r   )RedisManagerzflask-socketioF)r.  
write_onlyclient_managerzredis://usernamepasswordr   @hostport6379r-   message_queueu|   ERROR! CmfSocketIOWrapper: в cache_settings не найден коннект к Redis. Socketio не активирован)r   rb   r  ru   r  r5  r  r3   )r!   r  r3  r7   r5  r7  r>  s          r%   r  z-CmfSocketIOWrapper._make_redis_connect_params'  s   6+,, 	S1Fx1PQW1X\c1c1c&x06B$X.223EFF F] 5h ?@R S]]Y[]]111111!-c;KX]!^!^!^9G$%5666 +!6x!@@@!V%:8%DZ%PPM!6x!@@@!%W)>x)H)T%W%W%WWM!6x!@!HH!ZV%:8%D%H%HQW%X%X!Z!ZZR)8E$_555  R  S  S  S  S  Sr&   N)r1   r/   r=   r  r    r  r  r!  r#  rz   r&  r*  r  r  r  r  r  r;   r&   r%   r	  r	    s            - - -  0 0 0/ / /, , ,( ( (N N Nu u u
B B B
( ( (
G G G
S S S S Sr&   r	  SOCKETIO_WORKER)postforkc                  8    t                                            d S r   )r  r  r;   r&   r%   r  r  A  s    ))+++++r&   )r  z/custom/org_namec                    t          j        d           t          j         }t	          | t
                    rl|                                 }| j        | j        d}|rt          j
                    |d<   | j        |d<   t                              |          |_        d|_        nEddd}|r(t          j
                    |d<   t!          |           |d<   t#          |          }d|_        t'          |           |S )Nz
App error:)coderH  	tracebackdescriptionapplication/jsonr  zUnknown error)rH   r  rb   
PRODUCTIONr   r   get_responserC  rH  rD  
format_excrE  rh   ri   r4  content_typerD   jsonifystatus_codeset_cors_headers)r   
show_traceresponseresponse_datas       r%   handle_exceptionrQ  S  s   l### &&J!]## #>>##FF
 
  	@)2)=)?)?M+&'(}m$

=11 2 #
 
  	2)2)=)?)?M+&+.q66M-(=))"XOr&   jwt_rsazjwt_rsa.pub)RSA)cmf_deletedrg_member_ofdefault_projectemailphone
user_localphone_internalprimary_roleonline_statusvacation_startvacation_endon_vacationrd  does_not_workauth_inactive_blockis_admin
is_supportservicedesk_allow
first_name	last_nameztwo_factor.two_factor_optztwo_factor.application_verifiedztwo_factor.applicationlic_evaprojectlic_evawikilic_evaservicedesk
lic_evagitlic_evatestlic_evacicd
lic_evarmsc                    t           j        sd S 	 t          j        s5t          j                            dt          j                  t          _        n## t          $ r t          j
        d            w xY wt          j        S )Nz.CmfPerson:00000000-0000-0000-0000-000000000001ru  zapp.system_person() error)rb   AUTH_ENABLEDr   system_personr   	CmfPersonru   current_person_fieldsr   rH   r  rj   s    r%   rp  rp    s     t
   	g & 0 4 4CCLe !5 !g !gC   5666 s   AA  A2c                  2   t           j                            d          r t           j                            d          } nt           j        sdS 	 t          j        t           j                  }n%# t          $ r t          j
        d           Y dS w xY w|dS t          |t                    o|                    dd          } | sdS t          |           }|j                            d          sdS dt          _        t!          |j                                      d	dg          d
         }|rt%          |          dk    rdS |j                            d          d         }|sdS t)          j        d|          x}r|                                \  }}ndS |dk    s|dk    s|dk    rt.          j        }nJ|dk    s|dk    s|dk    s|dk    rt.          j        }n%|dk    s|dk    rt.          j        }nt.          j        }t7          |t8          j        j                  sdS d|v r$|                    |j         d| ddg          }	n|                    |ddg          }	|	sdS |t?          |	j                   k    rd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>.*)$docDOCCmfDocumentflFLIN_WORK	CmfFolderCmfListEPI-r   r   sharelink_hashru  )rC  r   )#requestr  r   headersru   r4  ujsonrw   r   rH   r  r   rT   r   r   sharelink_access_requestr	   r  r   r0   r  r  groupsr   r{  r  r  r   r   	CmfEntityr   rD   r  sharelink_access_grantedsharelink_access_obj)
rv  json_resr7   
hash_paramobj_keyr  rz  obj_coder~  r   s
             r%   _check_sharelink_accessr    s    |x(( I##I.. | 	F	{7<00HH 	 	 	  \  ]  ]  ]FF	 F8T**Hx||GR/H/H 
5//C 8y))  "&A#)$$(("66q9J ZA--hnnS!!"%G  FPPPu "\\^^(( 5H--]1J1J&			T		X--Y1F1F(VaJaJa$			Y		(e"3"3N		 &	 i!566 
hmm)"6CCCC$(*:#;  = = mm$8H1ImJJ  S+,,,,%)"!$
Fs   A. .BBc                     | t           _        | r4| 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)persons    r%   set_current_personr  	  s<    A U&,0@&@#06!:T0T-r&   c                     t          | dd           }|dk    r| j        S t          j        sd S ||S t	          d           t          j        t          j                   d S )Nr  FAIL_recursionz#Warning!!! Lazy Calc Current Personr]   )	r   rp  rb   ro  r3   rD  print_stackrd   stdout)r!   cps     r%   current_personr  	  so    	($	/	/B	!! t	~	 

/000sz****4r&   c                 &   	 t           j        st          j                            dg          }|j        st
          j        j                                        5  dd l	}dd l
|j        |j        z   d                    fdt          d          D                       |_        |                                 d d d            n# 1 swxY w Y   |j        t           _        n## t           $ r t#          j        d            w xY wt           j        S )Napp_keyr   r   r   c              3   B   K   | ]}                               V  d S r   )choice)rE   r   alphabetsecretss     r%   rG   zapp_key.<locals>.<genexpr>&	  s/      .[.[Aw~~h/G/G.[.[.[.[.[.[r&       zapp.app_key() error)r   r  r   r  ru   r   rr  rs  disable_aclstringr  ascii_lettersdigitsrJ   rangesaver   rH   r  )r!   r  r  r  r  s      @@r%   r  r  	  sP   { 
	+/33I;3GGH# $X%1133 $ $!MMM"NNN%3fmCH')ww.[.[.[.[.[QVWYQZQZ.[.[.['['[H$MMOOO$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ #*CK   /000 ;s1   AC$ A C;C$ CC$ CC$ $ Dc                 d   t          | dd           | j        S 	 t          j        s6t          j                            ddt          j                  t          _        t          j        | _        | j        st          j        	                    dd          }|
                                 	 t          j                            ddt          j                  | _        | j        swt          j        j                                        5  t          j                            | j                  | _        d d d            n# 1 swxY w Y   t%          j                     |                                 n# |                                 w xY w| j        S # t*          $ r t-          j        d            w xY w)	N_anonymous_userzanonymous@evateam.ruTrC  include_deletedr   zcreate-anonymous-user-lock   timeoutzapp._anonymous_user() error)r   r  r   r   rq  ru   rr  r  r  lockacquirer   rr  rs  r  system_datacreate_anonymous_userrp  ddcommit_all_dsreleaser   rH   r  r!   
redis_locks     r%   r  r  4	  s   t&--9##" 	2"("2"6"6+T0 #7 #2 #2C  #2# 	%!,,-IST,UUJ   %'-'7';';/4 (< (6 (6$ + ')5577 i i/2/T/TUYUg/h/h,i i i i i i i i i i i i i i i $&&&""$$$$
""$$$$##   7888I   BF +AE/ *D<0E/ <E  E/ E E/ F /F	F  F/c                 d   t          | dd           | j        S 	 t          j        s6t          j                            ddt          j                  t          _        t          j        | _        | j        st          j        	                    dd          }|
                                 	 t          j                            ddt          j                  | _        | j        swt          j        j                                        5  t          j                            | j                  | _        d d d            n# 1 swxY w Y   t%          j                     |                                 n# |                                 w xY w| j        S # t*          $ r t-          j        d            w xY w)	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   rq  ru   rr  r  r  r  r  r   rr  rs  r  r  create_sharelink_anonymous_userrp  r  r  r  r   rH   r  r  s     r%   r  r  T	  s   t0$77C--, 	.,2,<,@,@14, -A -. -.C) *-)F&- 	%!,,-S]^,__J   %171A1E1E944 2F 26 26. 5 ')5577 0 09<9h9h .:0 :060 0 0 0 0 0 0 0 0 0 0 0 0 0 0 $&&&""$$$$
""$$$$--   ABBBr  c                     t          | dd           | j        S 	 t          j                            ddt
          j                  | _        | j        st          j        	                    dd          }|
                                 	 t          j                            ddt
          j                  | _        | j        swt          j        j                                        5  t          j                            | j                  | _        d d d            n# 1 swxY w Y   t%          j                     |                                 n# |                                 w xY w| j        S # t*          $ r t-          j        d            w xY w)	N_test_guest_userztest-guest@evateam.ruTr  zcreate-test-guest-user-lockr  r  zapp._test_guest_user() error)r   r  r   rq  ru   r   rr  r  r  r  r  r   rr  rs  r  r  create_test_guest_userrp  r  r  r  r   rH   r  r  s     r%   test_guest_userr  v	  s    t'..:$$ & 0 4 4($, !5 !. !. $ 	%!,,-JTU,VVJ   %(.(8(<(<0$4 )= )6 )6% , ')5577 k k030V0VW[Wi0j0j-k k k k k k k k k k k k k k k $&&&""$$$$
""$$$$$$   8999sI   A.E- 	AE $*DE DE !D"E 8E- E##	E- - Fc                 >    t           j                                        S r   )r   r  get_settingsrj   s    r%   global_settingsr  	  s    #00222r&   c                     t          | d          rt          | dd           | j        S t          j                            ddg          | _        | j        S )N_global_varaccount_sync_statusaccount_sync_lastr   )r   r   r  r   CmfGlobalVarru   rj   s    r%   
global_varr  	  sZ    t]##  mT(J(J(V*..7LNa6b.ccDr&   lineno   c           	         |                      t                              dd          t                              dd          f          } |                     |d          }t	          d|z             t          |d |         d          D ]\  }}|j        d         }t          j        	                    |j
                            t          j                  d	d                    }t	          d
|||j        |j        dz  fz             t                              |j
        |j                                                  }|rt	          d|z             |j                                        D ]}	t	          |	           ||d          }
|
r=t%          d |
D                       }t	          dt'          |
          |dz  fz             t%          d |D                       }t	          d|dz  z             d S )NFz<frozen importlib._bootstrap>z	<unknown>T)
cumulativezTop %s linesr   r   z#%s: %s:%s: %.1f KiBi   z    %sc              3   $   K   | ]}|j         V  d S r   sizerE   stats     r%   rG   zdisplay_top.<locals>.<genexpr>	  s$      //49//////r&   z%s other: %.1f KiBc              3   $   K   | ]}|j         V  d S r   r  r  s     r%   rG   zdisplay_top.<locals>.<genexpr>	  s$      00d	000000r&   zTotal allocated size: %.1f KiB)filter_tracestracemallocFilter
statisticsr3   	enumeraterD  rh  seprJ   r  r0   r  r  	linecachegetlinestripformatsumr   )snapshotkey_typelimit	top_statsr,   r  framer  linellotherr  totals                r%   display_topr  	  s   %%5"ABB5+..'  H ##H#==I	.5
 !!! 6E6!2A66 
 
tq!6;;u~33BF;;BCC@AA$%,	D0@AB 	C 	C 	C  >>DDFF 	#(T/""".'')) 	 	B"IIII	 effE @///////"c%jj$+%>>???00i00000E	
*edl
;<<<<<r&   c                    t           j        j                            dd          5  t          j                            | j        t          j	                  }|sd | 
                    d          D             }t          j        |d<   t          j        |d	<   t          j        |d
<   t	          j        di |}|rzd|_        |j                            t          j                                                   d|_        |j                            t          j                                                   |r?d|_        |j                            t          j                            d                     t           j        j                                        5  |                    d           d d d            n# 1 swxY w Y   t/          j                     |cd d d            S # 1 swxY w Y   d S )Nzcreate-current_person-lock
   r  )loginr   c                 P    i | ]#\  }}|                     d           s	|dk     ||$S )cmf_r   )r   )rE   r   r   s      r%   
<dictcomp>z+create_person_from_auth.<locals>.<dictcomp>	  sE     ; ; ;Aq||F++; 12T		 109		r&   Tr   	cmf_owner
cmf_authorcmf_modified_byServiceDeskClient)rC  )	only_datar;   )r   rr  rs  CmfLockr   rq  ru   r  r   rr  r   r   r   rc  rU  r   CmfPersonGroupsupport_grouprY  
user_grouprd  r  r  r  r  )authrc  is_servicedeskr  person_valuess        r%   create_person_from_authr  	  sL   			!	!">	!	K	K  !%%DJs?X%YY 	; ; JJ$J77; ; ;M *+M+&*+-M,'/0}M+,%6666F O$(!#**6+@+N+N+P+PQQQ$(!#**6+@+K+K+M+MNNN `+/(#**6+@+D+DJ]+D+^+^___!--// , ,d+++, , , , , , , , , , , , , , , 5                 s6   E2G(F<0G(<G 	 G(G 	G((G,/G,)forcelevelc                    t          j                     }t          t          dd           s| s|r|+t          |t                    rt          t
          |          }n| rt
          j        }nt
          j        }t          j                     }t	          t          |t          j
        z
  dz  d                    }t	          t          |t          j        z
  dz  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||	z   |
z    ddg|}t          j        |dd                    d |D                                  t          j                     t          _        t'          t          j                     |z
  dz            }|dk    rt          j        |dd| d           d S d S d S )Nrc   rl   r   rw  select_countselectr   r)  insertmr-   z(+z)mszs zu zi r   r@   rA   c              3   4   K   | ]}t          |          V  d S r   rC   )rE   parts     r%   rG   zdebug.<locals>.<genexpr>
  s(      *G*G3t99*G*G*G*G*G*Gr&   zPROF debug funcion got ms)r7  r   rb   r   rD   rH   INFOrc   roundr   debug_start	debug_nowru   rT   r  r"   
request_idlogrJ   r   )r   r  messagesdebug_str   r   r  scscsscuscir  parts	debug_ends                 r%   rI   rI   	  s4   y{{Hvw%% N N% N%%% 0// 	"LEEMEikksQ]*d2A6677sQ[(D0!4455UU?B''++NDFFCCffXq!!ffXq!!ffXq!!LS!!LAC;;3;;#;;sS;;;

 
 	E4*G*G*G*G*G!H!HIIIikk X-t344	q==Kt%Ly%L%L%LMMMMM;N N8 =r&   c                  t   t           j                            d          } t           j                            d          rw| rut          t          |           j                  }|                    t                       d          rdS |                    d          s|                    d          rdS nt           j                            d          rdS t           j                            d	          st           j                            d          rd
S t           j                            d          s>t           j                            d          st           j                            d          rdS t           j                            d          rdS t           j                            d          rdS dS )Nru  /files/servicedesksd_api/docs/rw  pub_api/servicedesk/api/api/pub//auth/r  /with-contextsystemdeny)r  r  ru   r  r   rD   r   r  )refererreferer_paths     r%   set_api_scoper(  
  s   o!!),,G|y)) g 8G,,122""moo#B#B#BCC 	8""8,, 	0G0G	0R0R 	9			 	 	0	0 	x		 	 	)	) W\-D-DY-O-O u		 	 	)	) W\-D-DX-N-N RYR^RiRijsRtRt y		 	 	*	* v		 	 	1	1 x6r&   c                  d*   t           j        dk    rdS t          t          j         t          j         t          j        f          rBt          j        5  t          j
        t          j                   ddd           n# 1 swxY w Y   ddlm t                       t                                            t%          j                     dt(          _        i t(          _        i t(          _        g t(          _        t2          j                            d          dk    t(          _        ddlm}  dd	lm}  |             t(          _         t(          j         t(          _!        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(          _0        dt(          _1        dt(          _2        dt(          _3        dt(          _4        dt(          _5        dt(          _6        dt(          _7        dt(          _8        ts                      t(          _:        dt(          _;        dt(          _<        dt(          _=        t|          j>        ?                    t|          j@        jA                  t(          _B        dffd	t(          _?        t(          jB        C                                t(          _D        dffd	t(          _C        dt(          _E        i t(          _F        i t(          _G        g t(          _H        g t(          _I        g t(          _J        g t(          _K        g t(          _L        g t(          _M        g t(          _N        i t(          _O        g t(          _P        i t(          _Q        i t(          _R        dt(          _S        dt(          _T        t                      t(          _V        i t(          _W        g t(          _X        dt(          _Y        dt(          _Z        dt(          _[        g t(          _\        i t(          _]        i t(          _^        i t(          __        t                      t(          _`        i t(          _a        i t(          _b        g t(          _c        i t(          _d        i t(          _e        g t(          _f        g t(          _g        t          t(          _h        dt(          _i        dt(          _j        dt(          _k        dt(          _l        t                      t(          _m        dt(          _n        t          jp        q                                 t          jr        q                                 t          js        st          d           dS t           ju        v                    d          rdS t          j        st          j        st(          h                    dt3          jw                     d           t          j        5  t(          h                    dt3          jw                     d           t          j        st(          h                    dt3          jw                     d           t          jy        t          z                                 t                       t                       t          j}        rt                       t          j        rt                       	 ddl}ddlm} |                                 n# t
          t          f$ r Y nw xY wdt          _        t(          h                    dt3          jw                     d           n/t(          h                    dt3          jw                     d           ddd           n# 1 swxY w Y   t          j        r2d
"                    t=          j        dd                    t(          _n        d}d}t           ju        v                    d          s t           ju        v                    d          rKt           j                            d          }|sQt           j                            d          }|r0|v                    d           r|t          d           d         }nd}|st           j                            d!          }|rt          j                            |          }t          j                            |dt          j        "          }t(          h                    d#|dd          d$| d%|            |s>t          j        d&t           j        t           j                   t#          d'd(d)*          S t           ju        d+k    r*t          j                            t          j        ,          }t           ju        v                    t)                       d-          rzd.}d/t           j        v rt           j        d/         }t-          |          }	|	s4t/          d/|i          }
t1          t)                       d0|
           }	t3          |	           |	S d1} |             }|st           j                            d2          }t           j                            d3          }|r^t          j                            |          \  t(          _'        t(          _<        t(          j=        rdt(          _=        t;                       n+|r)t          j                            |          t(          _'        t(          j'        rZt          j        o3t          j                            t(          j'        j(        j        4          }t          j        r|sdt(          _'        t(          j'        rmt(          j'        j(        j        t(          _(        d5d6t(          j'        j(        gg}t          j                            |t          j        7          }d8t(          j(         d9}|rm|j        r&t(          h                    d8|j(         d:           d}nΐtG          |d;          r.|j        r'd8|j(         d<}t(          h                    |           d}n|r"tK          |t(          j'        j        =          }njt(          j'        j        r,tK          t(          j'        t(          j'        j        =          }n-t(          j        j        rtK          t(          j'        d>          } |             |z
  d?k    r(t(          h                    d@ |             |z
              t           ju        v                    dA          p=t           ju        v                    dB          pt           ju        v                    dC          }dD }|r|j(        j        t(          _(        t(          j'        r8t(          j'        j        t(          _+        t(          j'        j         t(          _)        ndt(          _+        |j         t(          _)        dt(          _,        t          |           n|s
 |            r[t(          j        }tY                       t(          j5        rt(          j        }dt(          _*        dt(          _,        t          |           n%dt(          _,        t          t(          j                   t(          j        pt           ju        v                    dE          pt           ju        dFk    pt           ju        v                    dG          pt           ju        dHv pt           ju        v                    dI          pt           ju        v                    dJ          pnt           ju        v                    dK          pNt           ju        v                    dL          p.t           ju        dMk    pt           ju        v                    dN          pt           ju        v                    d          o2t           j                            dO          dPk    ot           j        dQk    pt           ju        v                    dR          pt           ju        dSk    pyt           ju        v                    dT          pYt           ju        v                    dU          ot           j        dQk    p)t           ju        v                    dV          ot           j        dQk    p| o<t           ju        v                    dW          ot          j                                        p| o<t           ju        v                    dX          ot          j                                        pzt           ju        v                    dY          ot(          j(        pOtd                              t           ju                  p*t           ju        v                    dZ          ot(          j(        }t(          j        }t(          j        } |             }t          jr                                          |             |z
  d?k    r(t(          h                    d[ |             |z
              |s
 |            rdS t(          j:        d\k    rY|s,t(          j'        rtm          |          S tm          |          S |j        s"|j        st          j        stm                      S ngt(          j'        r|stm          |          S t           ju        d.k    r<|r:|j        s3t          j        s'|j        rt1          d]          S t1          d^          S |stm          d_          S |j        st          j        stm          d`          S t(          j,        rtm                      S t(          j,        stq          t          dad          r|r|j        r |             }t          j                                        s t1          tw                       db          S  |             |z
  d?k    r(t(          h                    dc |             |z
              t          j        s^dt          _         |             }t{                        |             |z
  d?k    r(t(          h                    dd |             |z
              t(          j<        re |             }t(          j<                                        }	 |             |z
  d?k    r(t(          h                    de |             |z
              |	r|	S dS dS )guJ  
    Должны вернуть Response or None
    Особенности поведения:
      В случае web запроса:
        - response - view не выполняется, сразу отправляем response
        - None - выполняем view
        - Exception(в т.ч. и abort) - обработчик выводит трейс клиенту
      Системный контекст(shell, celery, socket, other with cmf_context):
        - None, Response - нет разницы
        - Exception - прерывает выполнение.
    OPTIONSNr   r   F
run_pytest1r7  )choicesr   0123456789abcdef   )r   c                 4    t           j         |           z   S r   )r   _nowoffsetr   s    r%   <lambda>z before_request.<locals>.<lambda>i
  s    )9)9&)A)A A r&   c                 4    t           j         |           z   S r   )r   _dater3  s    r%   r5  z before_request.<locals>.<lambda>k
  s    +;+;F+C+C!C r&   Tz/memOKz"Wait first_request_init lock (pid=)z!Got lock first_request_init (pid=zStart first_request_init (pid=)uwsgi_restartszDone first_request_init (pid=z%Already done first_request_init (pid=>qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789   r  r  zX-Eva-TokenAuthorizationzBearer token)api_token_hashrY  r   zAuth API Token(z...): hash=z	, person=z6Invalid API token: request.headers=%s, request.args=%szInvalid API token  
text/plainrJ  /pub/webhookr   zauth/not_authorizedr-   next_urlauth/signin?uU   Требуется авторизация. Введите логин и пароль.session_tokenaccess_token)r  r  ==filterr   u   Учётная запись uQ    заблокирована. Обратитесь к администраторуu    заблокирована.ra  uo    заблокирована за неактивность, обратитесь к администратору)rc  )r  g?z-PROF before_request get auth and session got z/pub/pub_apiz/docsz/sharec                  ~    t           j                            d          pt           j                            d          S )Nrt  /socket.io/)r  r  r   r;   r&   r%   is_allow_publicz'before_request.<locals>.is_allow_publicb  s4     L##H-- 6|&&}55	7r&   z/health_check/z/metricsz
/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 r   )r  methodallr   first_request_init_donefirst_request_init_skiprb   r  first_request_init_lockr2  r3  r  r  cmf.util.cmfutilr   check_db_lockr  rq  r  before_requestr   rj  rp  flagsremove_filesrh  ri  ru   testr7  r   r.  r  r  rJ   r  save_only_data_hackalertnoter  r  is_guest_useris_anonymousrc  is_system_contextr  r  disable_notifyimport_modesession_tab_idcomponent_idinteractive_shellr  r  r  api_args
api_kwargsr(  	api_scoper  r  hack_session_need_commitr   r   r   r   r2  rL  r7  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_notifiesdeferred_update_task_projectr  jscache_timelifer   r  r  r  TEXCOM_ENABLE_GROWCACHE_HACKr  r  r  acquired_locksacquired_locks_shacquired_lock_timignsru  fulltext_search_headlinesfulltext_search_debug_labelr*  project_perm_browse_cache%project_perm_timetrackerhistory_cacheshow_bg_progressbarapi_hack_fieldsrI   
new_acl_idapi_license_required license_disable_user_count_hooksbackbone_synccurrent_save_objects	csp_noncer   CmfDeferredJobinit_contextCmfAccessListro  r  r  r   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uwsgicommonr:  increment_uwsgi_restart_counterImportErrorModuleNotFoundErrorCSP_ENABLEDsampler  r   r"   rq  
hash_tokenrr  rH   r  r   
CmfWebhookget_token_personauth_base_hrefr   check_sso_redirectr
   redirectrM  cookies
CmfSession
from_token
cmf_commitCmfAuthfrom_jwtIS_AUTHORIZATORr   r`  r   ra  r  jwt_is_supportr  servicedesk_allow_auth_guestsjwt_is_match_orgrY  r  r  r  r   remote_addr	CmfPlugincheck_secretSTATIC_URL_REr  rp  setup_contextreject_responserd  r   rP  license_ui_accessr  prepare_plan_cache_doneprepare_plan_cachetfa_check_two_factor)r7  r.  r  r:  auth_person	real_auth	api_tokenr?  rD  r   qserr_msgprof_strF  rG  _filteris_force_publicrM  anon_personis_allow_without_authr   r   s                        @r%   rX  rX  $
  s    ~""t
''''#   K
 ( 	K 	KL/IJJJ	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 211111OOO%%'''AAMAGANZ^^L))S0AF$&&AKKAM7777#5;;;<<AL!AAGAF AFAGAOANALA"&A,0A)AAMAANA!&A!&AALAJAL//AK!AAI!%A""8#4#899AFAAAAAAEfkkmmAGCCCCCAF  %AAKAOAOA!#A$&A!A$&A!A')A$!#A+-A(%'A"A AAAJAJ%*A"AA$&A!AA A$'EEA!"$A$&A!A"$A.0A+AAAGAL!A)-A& AO UUAAK
&&(((
%%'''  4   |v&& t
 & -Ps/J -P	CRY[[CCCDDD ( "	P "	PGGF	FFFGGG.  PGGGGHHH >)*55777
 +---0 63555- 52444 LLL555555"BBDDDD#%89    D
 /3+F	FFFGGGGN	NNNOOOE"	P "	P "	P "	P "	P "	P "	P "	P "	P "	P "	P "	P "	P "	P "	PJ  sggfm,lnpqqrr
 KI |w'' V7<+B+B9+M+M V
 O''66	 	%++O<<I %''	22 % )#i..// :II $I 	3 ))'22Y 	V#-88CCN *..-$sG` / b bKGGfimffffYdffggg V XZaZikrkwxxx 4cUUUU |~%%'88@Y8ZZ |."2"2GGGHH 	''~j1Hx(( 	@J122BN,,>>">>??AfGdffG 6S++O<<**>:: 		; & 1 < <] K KAFAI ) -2* 	;^,,\::AF6 	._6>3E3EAFLL^3E3_3_I % i 6  	Sfl(AG $-/G !*..gcF_.``K PQW  P  P  PG  S, 	'GGj;;Ljjjkkk #'KK[*?@@ '[Ed ' @[=N  @  @  @GGGG$$$"&K S5iAFLabbb& S5afI^___"@ S5afTRRR tvv#	R@PRRSSS l--n== -<""7++-<""8,, 
7 7 7   *#)6 	960AL"#&"99AOO !AL"-"88AO $;''''	 *OO-- *&!!!% 	54K#;'''' #1=)))
 F F|&&'788F |z)F |&&|44	F
 |IIF |&&|44F |&&'?@@F |&&'ABBF |&&'EFFF |CCF |&&'9::F |&&w// 7GN4F4Fv4N4NRX4X 7';6F  |&&}55!F$ |66%F& |&&~66'F* |&&y11Xg6I[6X+F, |&&v..U73F+3U-F0 #"kw|'>'>w'G'GkFL\LiLiLkLk1F2 #"kw|'>'>w'G'GkFL\LiLiLkLk3F6 |&&{33?7F8 ""7<009F< |&&'899EagA H 	
A	A dffG
&&(((tvv#	[RYIY[[\\\  ,[ 1 1 ,[	
	 	  	,v 0&w///"7+++, 	%[5K 	%TZTj 	%"$$$ 
 [ [w'''				[5K	TZTj	( 	'O,,,I&&& [JKKK# [F,B [ NOOO	
	 [     " 	[wv|T'J'J 	[{ 	[_j_u 	[dffG$6688 D=?? B B BCCCtvv#%%YttvvPWGWYYZZZ & X&*#$&&466Gc!!GGVDDFFWDTVVWWW 	y $&&I**,,466Gc!!GGXddffwFVXXYYY 	H 	 	sJ   A==BB!C"^3\#"^3#\96^38\99A.^33^7:^7c                     g dg}t           j        dk    r|                    g d           t          j                            |          }|r|                    |           S d S )N)disabledrH  Fr  )servicedesk_supportrH  T)rJ  )r   ri  r   r   CmfAuthOpenIdPluginru   login_redirect)rD  r  openids      r%   r  r    su    ((()G{h:::;;;'++7+;;F /$$X.../ /r&   c                    t           j        dk    st          j        dk    rKt	          j        dt           j        t          j        t          j        t          j        t          j                   t           j        	                    d          s/t           j        	                    d          st           j        dk    rt          | pddd	
          S t          t           j                  }d|i}| rt          | d           | |d<   t          |          }d }|st          |          }|sQt          j        dk    r!t!          t#                       d|           }n t!          t#                       d|           }t%          |           |S )Nr#  r$  zJRequest reject access: path=%s, auth=%s, login=%s, api_scope=%s, person=%srL  r  rC  znot authorizedr@  rA  rB  rD  
auth_errormessager  zservicedesk/auth/signin?rE  )r  r  r   ri  rH   r  r  r  r  r   r   r   r7   r   r
   r  r  r  rM  )r  skip_ssorD  paramsr  r   s         r%   r  r    sv   |&&!+*A*AXL!&!'1;8I	K 	K 	K L##M22|&&w// |~--3#3S|TTTT%%h' 	('<((( 'F9v 	-"8,,A 	D{h&& 0 0NN"NNOO 0 0BBbBBCCr&   c                  d    t          j                     t                       t                       d S r   )r  r  emit_eventsemit_server_eventsr;   r&   r%   commit_with_eventr  3  s,    MMMr&   c           
      P   | ri t           _        d S t                               d          sd S t           j                                        D ]\  }}d|v rd|d         v r|d                             d           |d         rht
          j        j                            |d                   }|r<|	                                D ]'}|d         
                    |j        j                   (t          d|d          |d|                    dd	          
           i t           _        d S )Nrl  relation_persons__DEFERRED_all_relation_personsr   is_changed-r   r-   r  private)	namespacer  )r   rl  ru   r   rK  r   rr  rs  get_obj_by_idall_relation_personsr   r   r   r  )
only_cleanr   r   r   ps        r%   emit_list_applyr  ;  s?    55 +##%% 	o 	o3$$)JcRdNe)e)e"#**+LMMM4y Ch&44SY?? C 5577 C C./66qtzBBBB8S%688#SVSZSZ[aclSmSmnnnnnAKKKr&   c                    |                                  D ]V\  }}|D ]L}|d         }|d= t          |d                   }|d= |d                                         }	 t                              |           t                              |           t                              |           n2# t
          $ r%}t          d| d| d| d|            Y d }~d }~ww xY wt          |t                    s" |j	        |g|d         R i |d	|d	         i |d
         r:|d
         dk    s.|d
         |d
<    |j	        |g|d         R i |d	|d	         i ;|
                    d          r{|d         rsd|d         d         v r'|                    |d         d         d                    d|d         d         v r,|d         d         d         D ]}|                    |           |D ]~}	t          |	t          j        j                  r(t          d|	 d| d| d|            |	j        j        }
nt#          |	          }
|
|d
<    |j	        |g|d         R i |d	|d	         i NXd S )Nsocket_clientr	  r#   uP   DEV: FATAL emit пришел с несериализуемыми данными z! socket_client:z; event_persons:z; event_param:r"   r  r  r  r  event_current_personr   r  uY   DEV: INFO Кривой евент, в event_person попал объект, а не str: rA   )r   r   r  rh   ri   r   r3   r   rV  rz   r   r   r   r   r!  r   r   rD   )
event_dictmsgevent_param_listevent_paramr  r	  emit_kwargsr   user_idevent_personevent_persons_strs              r%   emit_events_dictr  N  s   !+!1!1!3!3 ,q ,q+ +	q +	qK'8MO,O <==MO,%h/4466K

3

;'''

;''''     Fij  F  F  }J  F  F  \i  F  F  yD  F  F  G  G  G mX66 ""3pV)<pppppWbcnWopppp 6" ;v+>)+K+K&1&&9F#""3pV)<pppppWbcnWopppp~~l++ 7v& 7-V1DQ1GGG%))+f*=a*@AW*XYYY)[-@-CCC'26':1'=>P'Q 7 7G)--g6666 - 
q 
q lCJ,@AA :  g  wC  g  g  FI  g  g  LW  g  g  Ze  g  g  h  h  h(4(=%%(+L(9(9%&7F#""3pV)<pppppWbcnWoppppp
qC+	q,q ,qs   AB--
C7CCc                  &    t          d           d S )Nr   delay)emit_events_with_delayr;   r&   r%   r  r  ~  s    ######r&   c                 :   | ri t           _        d S dd l}t                               d          sd S i }|                    t           j                  D ]9}|                    d          r"t           j        |         ||<   t           j        |= :t          |           d S )Nr   rm  project_notify)r   rm  r  ru   r   r  )r  r  rm  r  s       r%   emit_project_eventsr    s     KKK55!! Myy)) % %>>*++ 	%!"!5M#$]#####r&   c                      t          |           |ri t          _        dS t                              d          pi i t          _        r r fd}t	          j        |           dS rt                     dS dS )u   Запускаемся в контексте, но отправляем в отдельном таске вне контекста, после паузы, чтобы не держать запрос.r  Nrm  c                  N    t          j                    t                     d S r   )r2  r  r  )r  rm  s   r%   emitterz'emit_events_with_delay.<locals>.emitter  s'    L]+++++r&   )r  r   rm  ru   r2  r3  r  )r  r  r  rm  s   `  @r%   r  r    s    z**** EE/**0bMAO 	( 	(	, 	, 	, 	, 	, 	, 	W	 ('''''( (r&   c                 6   | rg t           _        d S t                               d          pg }g t           _        |D ]]\  }}t                               d| d|            t          j                            |t                              |                     ^d S )Nrn  zemit_server_events: r  )	r   rn  ru   rI   r  r  rg   rh   ri   )r  rn  r.  r4  s       r%   r  r    s     EE/**0bMAO& : :	8w88$88999w

4(8(89999: :r&   c                  D    t          j                     i t          _        d S r   )r  rollback_all_dsr   rm  r;   r&   r%   rollback_purge_eventr    s    AOOOr&   c                     | rg t           _        d S t                               dg           D ]5}t          j                            |          rt          j        |           6g t           _        d S )NrZ  )r   rZ  ru   rh  r  r   rK  )r  r  s     r%   apply_deferred_remove_filesr    se     EE."--    7>>(## 	 IhANNNr&   c                 v    t           j        r,t          j                            t           j        |            dS dS )u   Сессия может быть продлена через SSO, надо продлить куку

    Args:
        r (response): ответ браузеру в котором обновляем куки
    N)r   r  r   r  set_session_tokenr   s    r%   update_cookiesr    s8     	y 7((A666667 7r&   c                    t           j        rt          j                            d          st          j                            d          r'dt
          j         dt
          j         d| j        d<   d S dt
          j         d| j        d<   d S 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:;)rb   r  r  r  r   r   r  r  )rO  s    r%   set_csp_headersr    s     0<""#788 	0GL<S<ST\<]<] 	0,-.[, ,,-K, , , 67770-.[0 0 0 67770 0r&   c                 2   t           j        }t          j                            d          }t           j        r>|r<|                    d          r|t          d          d          }|t           j        v r|}d| | j        d<   d| j        d<   d| j        d<   d S )NOriginhttps://zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)rb   APP_FQDNr  r  ru   CORS_ALLOWED_DOMAINSr   r   )rO  origin_domainrequest_origins      r%   rM  rM    s    OM_((22N" +~ +$$Z00 	>+C
OO,<,<=NV888*M6P6P6PH23;AH787LH3444r&   c                     t          dd           t          |            t          |            t          |            d| j        d<   | S )uk   
    Запускается только если небыло ошибок
    :param r:
    :return:
    Tr   )after_hooksevent_delaybyteszAccept-ranges)r  r  r  rM  r  r  s    r%   acaor    sR     4Q////1AQ!(AIoHr&   c                  4   ddl m}  t          j        sd S t          j        t
          _        t          j        j	        
                                5  t          j        j        j                                         d d d            n# 1 swxY w Y    |              d S )Nr   spawn_server_event_listener)cmf.cmf_server_event_listenerr
  rb   ro  DISABLE_PERMISSIONSr   disable_permissionsr   rr  rs  r  includer   r  load_acl_datar	  s    r%   r  r    s    IIIIII $8C			%	%	'	' 9 9(668889 9 9 9 9 9 9 9 9 9 9 9 9 9 9  !!!!!s   )BB
Bc                     t          t          j        j        d          sd S t          j        j                                        5  t          j        j        j                                         d d d            d S # 1 swxY w Y   d S )NCmfProjectPermScheme)	r   r   r  r   rr  rs  r  r  load_project_permission_datar;   r&   r%   r  r    s    3;%'=>> 			%	%	'	' O O/LLNNNO O O O O O O O O O O O O O O O O Os   )A;;A?A?c                  0   t          t          d          dk    rd S t          j        j                                        5  t          j                                        } t          j        	                    | d                   }|
                                 d d d            n# 1 swxY w Y   t          j        	                    dg          }|r(|                                 |                                 g ddg dg d	gfD ]+}|g d
g}t          j                            |g d           ,t          j        	                    dg          }|r(|                                 |                                 t          j        	                    dg          }|r(|                                 |                                 t          j        	                    dg          }|r*|                                 |                                 d S d S )Nr  z/opt/eva-appr   )r   r  )order_by)cache_action=r  OR)r  r  r  )	cmf_modelr  CmfTask)json_filterjson_entry_pointjson_action	func_name	json_datarI  )r   rb   r   rr  rs  r  r   r  create_dummy_taskru   delete_dummy_tasksave_prepare_load_perm_fields
CmfTriggerr   r  
CmfComment	CmfNotify)dummy_task_data
dummy_taskr   _fr  cr  s          r%   r  r    sZ   v}%%77 
		%	%	'	' ' ' .::<<^''?4+@'AA
$$&&&' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 	TF++A 		 -,,t5R5R5RTsTsTs.tu  ///0b1}1}1}~~~~TF++A 		v..A 		tf--A 		 s   AB$$B(+B(c                 &    t          |            d S )Nr  )cmf_rollbackr+  s    r%   teardown_requestr-  A  s    9%%%%%%r&   c           
         |rt           j        sdS ||rt          j        nt          j        }t
                              d| d|d|d||           ||t           j         k    rdS |rRd                    t          j
                              }t
                              d|            t          |           | t
          j        vr!t
          j                            |            dS dS )	   
    Глобальная функция для оповещения фронта о предупреждениях
    :param msg:
    :return:
    Nzcmf_alert: msg=z abort= debug_only= devel_only=r  r   zcmf_alert Stack:
)rb   rc   rH   WARNINGr
  r   rI   rG  rJ   rD  format_stackr  r]  r   )r  r  r   
devel_onlyr  	stack_strs         r%   r   r   H  s      &, }#(:glGGE#EEEE*EE
EEUGSSS*V5F1F"G"G !IIi46677		0Y00111C   
!'	s r&   c                    |rt           j        sdS |t          j        }t                              d| d|d||           ||t           j         k    rdS | t          j        vr!t          j                            |            dS dS )r/  Nzcmf_note: msg=r0  r1  r2  )	rb   rc   rH   r
  r   rI   rG  r^  r   )r  r   r5  r  s       r%   cmf_noter8  b  s      &, }GG;;;
;;j;;5GIII*V5F1F"G"G
!&	c r&   r-   r  )r  r  r  r	  c                   |st           }	 dt          vrt                      t          _        n# t          $ r}Y d }~d S d }~ww xY wt          |          dk    r'dt          j        rt          j        j        j        pd ig}t          |d                   t          k    rWdt          v rt          j
        |d         d<   nd|d         d<   t          j        rt          j        j        j        pd |d         d<   t          ||||          }t                              |           ||d<   d	}	d
D ]}
|                     |
          rd}	 n|	rt          dt                                  |s-t          j        g}|	st!          dt                                  g }|D ]c}t#          |t$          j        j                  r |                    |j        j                   A|                    t-          |                     d||d<   t                              |d                    t          j                            | g           }||vr|                    |           d S d S )Nrm  r   rp   rd  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-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   rT   rm  r   r   r  r   r   r   rd  rh   ri   r   r3   localsr   r   r   r   r!  r   rD   
setdefault)r  r  r  r  r	  r"   r#   r   event_paramsmuted
muted_debtr  r  
event_lists                 r%   r  r  w  s     ! !##"ffAO   
4yyA~~$a&6&T1;K;N;T&\X\]^DG}}q  ()(8DG$%%(*DG$%*+*:*Xq?O?R?X*`\`Q&'T&IDQQQLJJ|$1L!Ep  
>>*%% 	EE	  `^TZT\T\^^___ J)* 	J  I  E  G  G  I  I  J  J  J % 8 8lCJ$899 	8$$\_%:;;;;$$S%6%67777$5L! 	JJ|O,---++C44J:%%,''''' &%s   !- 
AAc                    |rd                     |          nd}|rdnd}	|rdnd}
d                     |	|| |
          g}|rddlm}  |            }t          j        |dt          j        t          j        	          }|r|                                \  }}|r(|                                }|                                }|j        }|rS|rQt          j	        d
|           t          j	        d|           t          j	        d|           t          d|           |g}|r+|                    |           |                    |           n|                    |p|           |r |                     |            |z
             |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)shellr  re   u6   Произошла ошибка при вызове %sz
STDOUT: %sz
STDERR: %su4   Произошла ошибка при вызове rA  )r  r7  
subprocessPopenPIPEcommunicatert   
returncoderH   errorRuntimeErrorr   )commandsudor  waitseparate_out_and_err	do_decodedo_raisemeasure_runtimetimeout_cmd_sudo	_redirectcmdr7  popen_startprocessouterrerrcoder  s                      r%   run_bash_commandrZ    s    9@H$++G444SK%HH#E+9I>EE	  	C  DFFs$&0o&0o7 7 7G  &&((S 	**,,C**,,C$ 	]x 	]MRTWXXXM,,,,M,,,,[VY[[\\\i 	#JJsOOOJJsOOOOJJszc""" 	+JJttvvk)***
:r&   c                 :   t          j        t          j                  }t	          j                    }|                    |                                            |                    |          }t          j	        |          
                                }|  d| }|S )ua   
    Подписываем токен сертификатом
    :param jwt:
    :return:
    r*   )r   r  r   rsa_private_keyr   r)  r   signbase64	b64encodert   )jwtsignerdigestr]  r   s        r%   rsa_sign_pack_jwtrc    s|     ^C/00FZ\\F
MM#**,,;;vDD!!((**D//4//CJr&   c                 Z   ddd}t          j        t                              |                                                                                    }t          j        t                              |                                                                                     } | d|  S )uD   
    Создаем токен
    :param payload:
    :return:
    RS256JWT)algtypr*   )r^  r_  rh   ri   r   rt   )payloadheaders     r%   
create_jwtrk    s     U++Fdjj007799::AACCFtzz'2299;;<<CCEEG  w   r&   c                      t           j        S )u2   
    Текущая версия
    :return:
    )rb   CMF_VERSIONr;   r&   r%   cmf_get_versionrn    s    
 r&   c                 d    | t           j        vr!t           j                            |            dS dS )ux   
    Удаления файлов после коммита транзакции
    :param filename:
    :return:
    N)r   rZ  r   )r  s    r%   cmf_remove_filerp  
  s5     q~%%	h''''' &%r&   c                     t           j        sd S t           j                            d          rd S dt           j        j         dt           j         } t          j        j        	                    |           }|r[t          j        j        
                    |            t          |                                                    dd                     d S d S )Nfield_options_list
DEFERRORS_r   r   z<br>)r   r  r   r   r   rd  r   r  r  ru   rx   r   rt   r   )	redis_keyrH  s     r%   _deferred_errors_checkru    s    < |122 CQ^.CC1ACCIL""9--E 8!!),,,%,,..((v66777778 8r&   c                    t           j                            d           dt          j         d}|t          j                    z  }dt          j        j         dt          j	         }t           j
        j                            |          }|r|                                dz   |z   }n|}t           j
        j                            ||           d S )Nr   uL   Ошибка в after_request, после выполнения метода z

rs  r   z


)r   r  r  r   r  rD  rI  r   r   rd  r  r  ru   rt   r   )r   r  rt  rH  s       r%   _deferred_errors_saverw  %  s    J%%%
kYZYe
k
k
kC9!!!CCQ^.CC1ACCIL""9--E )C/L9e,,,,,r&   c                    t          j        |            ddlm} |j                            d           t          |j        d          r|j                            d           t          |j        d          r|j        	                    d           t          t          d	          rNt          j        rBt                      5  |j                            d           d d d            n# 1 swxY w Y   n|j                            d           |j                            d           t          |d
          r|j                            d           |j                            d           t+          d           t-          d           t/          d           t1          d           t3          d           g t          _        d S )Nr+  r   r   Tr  (apply_deferred_hide_closed_task_notifies)rollback"apply_deferred_update_task_projectrq  CmfStat)r  r  cmf.includer   r%  apply_deferred_notify_messagesr   r  rz  r|  r   rq  cmf_contextCmfAuditapply_deferred_auditCmfFullSearchapply_deferred_dirtyr}  apply_deferred_statsr$  !apply_deferred_comment_audit_listapply_deferred_jobsr  r  r  r  rp  )r  r   s     r%   r,  r,  2  s&   y))))"""""" 33t3DDDv~HII O???NNNv~BCC I9949HHHq.// <A4Q <]] 	@ 	@O00$0???	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	,,d,;;;
--->>>vy!! =++t+<<<
7747HHH4((((4((((d++++$''''40000!#As   C..C25C2c                    t          j                     | rot          j                    }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<   i t          _        t          j        |d<   g t          _        t          j        |d<   g t          _        t          j        |d<   g t          _        t-          |                                          }|rIt1          j        t4          t          j        j        t          j        t          j        t          j        |fi | t          j                     t          j                    |z
  dk    r*tA          dt          j                    |z
              d S d S d S )Nr   ry  rv  rw  ro  rq  ru  rr  rt  rs  rx  rm  rl  rn  rZ  rp  {Gz?z PROF cmf_commit after_hooks got )!r  r  r7  r~  r   r  r   r   rv  rw  ro  rq  ru  rr  rt  rs  rx  rm  rl  rn  rZ  rp  anyr   r2  r3  cmf_commit_after_requestr   r   rd  r  ri  r3   )r  r  r  r   after_request_params
need_spawns         r%   r  r  N  sO    /N)++&&&&&&'')))  ";<;U78%'"EFEiAB/1,676K23 ">?>[:;(*%ABAa=>+-(454G01 121A-.>?>[:;(*%?@?];<)+&01_-,-K[)01_-/0~^,;<;U78%'"-446677
 	? L11>3DaFVXYXdfgfq%? ?)=? ? ? 	9;; 4''LTY[[75JLLMMMMM_/N /N\ ('r&   c                    t          d           t          j                    }t                      5  	 t          t          j                            | t          j        j	        j
                             |t          _        |t          _        |t          _        |t          _        |t          _        |t          _        |t          _        |	t          _        |
t          _        |t          _        |t          _        |t          _        |t          _        |t          _        |t          _        |t          _        |t          _        t          j                                         t?          t          j         d          rt          j         !                                 t          j"        #                                 t          j$        %                                 t          j&        '                                 tQ                       t?          t          d          rt          j)        *                                 t          j+        ,                                 t?          t          j         d          rt          j         -                                 t]                       t_          |           ta                       tc                       te          j3                     t          j                    |z
  dk    r1t          4                    dt          j                    |z
              n## tj          $ r}tm          |           |d }~ww xY wd d d            d S # 1 swxY w Y   d S )	NzRun cmf_commit_after_requestr   rz  r}  r|  r  r  z"PROF cmf_commit_after_request got )7r3   r7  r  r  r   rq  ru   r   r  r   rr  r   rd  r  ri  rv  rw  ro  rq  ru  rr  rt  rs  rx  rm  rl  rn  rZ  rp  r%  r  r   r  rz  r  r  r  r  CmfOrmColumnHistoryapply_deffered_history_columnsr  r}  r  r$  r  r|  r  r  r  r  r  r  rI   r   rw  )current_user_idrd  r  ri  r  rv  rw  ro  rq  ru  rr  rt  rs  rx  rm  rl  rn  rZ  rp  after_request_prof_str   s                        r%   r  r    s    

())) IKK 
 . .-	v/33OCGKLm3nnooo-A%AL#AK)AA&3UA0$7A!,GA)/MA,"3A-A,GA)-IA*+AO#AK+AO)AN)AA&;;===v~&PQQ JGGIIIO00222 55777&EEGGG!!!vy)) 633555??AAAv~&JKK DAACCC!!!"5555   ')))y{{22T99bTY[[K`=`bbccc 	 	 	!!$$$G	Y. . . . . . . . . . . . . . . . . .s5   MK-L! M!
M+L<<MMMMr4  c                     ddl m} | pd} t          |          }|                    dddd          }|                                 r,|                     d                                          r| dz  } | ||           z   }t          |          S )Nr   r   r   hourminuter   r   +-r  )rV  r   _ensure_localr   r  lstripisdigit_to_utcr4  r   r   
base_localstart_locals        r%   start_of_dayr    s    111111\rFt$$J$$!AaQ$OOK||~~ &----5577 # 0 0 8 88K;r&   c                     ddl m} | pd} t          |          }|                                 r,|                     d                                          r| dz  } |                    dddd          }| ||           z   }t          |          S )	Nr   r   r   r  r     ;   r  rV  r   r  r  r  r  r   r  )r4  r   r   r  	end_locals        r%   
end_of_dayr    s    111111\rFt$$J||~~ &----5577 #""2aQ"OOI,,V444I9r&   c                 z   ddl m} | pd} t          |          }|                                 r,|                     d                                          r| dz  } |                                dz   dz  }|t          |          z  }|                    dddd	          }| ||           z   }t          |          S )
Nr   r   r   r  wr   r   r   r  
rV  r   r  r  r  r  weekdayr   r   r  )r4  r   r   r  days_since_sundayr  s         r%   start_of_weekr    s    111111\rFt$$J||~~ &----5577 ##++--1Q6)!23333J$$!AaQ$OOK 0 0 8 88K;r&   c                    ddl m} | pd} t          |          }|                                 r,|                     d                                          r| dz  } |                                dz   dz  }|t          |          z
                      dddd	          }|t          d
          z                       dddd	          }| ||           z   }t          |          S )Nr   r   r   r  r  r   r   r   r  r0  r  r  r  )r4  r   r   r  r  week_start_localweek_end_locals          r%   end_of_weekr    s   111111\rFt$$J||~~ &----5577 # $++--1Q6"Y4E%F%F%FFOOq P   '):):)::CC1! D  N $&6&6v&>&>>N>"""r&   c                    ddl m} t          |          }|                                 r,|                     d                                          r| dz  } |                    ddddd          }| ||           z   }t          |          S )Nr   r   r  Mr   dayr  r  r   r   r  r  s        r%   start_of_monthr    s    111111t$$J||~~ &----5577 #$$1QTU$VVK 0 0 8 88K;r&   c                    ddl m} t          |          }|                                 r,|                     d                                          r| dz  } |                    ddddd          }|t          d          z   }|t          d          z
  }|                    d	d
dd          }| ||           z   }t          |          S )Nr   r   r  r  r   r  )monthsr   r  r  r  )
rV  r   r  r  r  r  r   r   r   r  )r4  r   r   r  start_month_localnext_month_locallast_day_localr  s           r%   end_of_monthr    s    111111t$$J||~~ &----5577 #"**qq1Z[*\\(=+B+B+BB%	q(9(9(99N&&Br!QR&SSI,,V444I9r&   c                    ddl m} |                                 r,|                     d                                          r| dz  } t          |          }|                    dddddd          }| ||           z   }t          |          S )Nr   r   r  yr   monthr  r  r  r   r   )rV  r   r  r  r  r  r   r  r  s        r%   start_of_yearr    s    111111||~~ &----5577 #t$$J$$1!!Aa]^$__K 0 0 8 88K;r&   c                 R   ddl m} t          |          }|                                 r,|                     d                                          r| dz  } |                    dddddd          }|                    ddd	d
dd          }| ||           z   }t          |          S )Nr   r   r  r  r   r        r  r  r  )r4  r   r   r  start_year_localend_year_locals         r%   end_of_yearr  %  s    111111t$$J||~~ &----5577 #!))qqSTbc)dd%--BBRPR[\jk-llN#&6&6v&>&>>N>"""r&   r   rP   c                     t           j                                                                         }|j        }| |S | j        |                     |          S |                     |          S )uP  Возвращает datetime в локальной зоне сервера (aware).

    - Если base=None, берём текущее локальное время.
    - Если base naive, присваиваем локальную зону.
    - Если base aware, конвертируем в локальную зону.
    NrM  )r   r   r   rM  r   )r   	local_nowlocal_tzs      r%   r  r  1  se     !%%''2244IH|{||8|,,,??8$$$r&   dtc                     | j         I|                     t          j                                                                        j                   } |                     t          j        j                  S )un   Переводит aware datetime в UTC (aware). Для naive сначала делает локальным.Nr  )rM  r   r   r   r   r   r   )r  s    r%   r  r  @  sS    	yZZx04466AACCJZKK==*.///r&   c                   $    e Zd Zdd	dZd Zd ZdS )
r  FTrP   Nc                 `    t                               d          | _        || _        || _        d S )Nr#  )r   test_request_contextctxinit_views_and_dspreprocess_request)r!   r  r  s      r%   r    zcmf_context.__init__G  s-    ++O<<!2"4r&   c                 
   ddl m}  |            rt          d          | j                                         | j        r!t                       t          j                     | j	        rt          	                                 d S d S )Nr   )has_app_contextu;   Контекст нельзя включать дважды)r  r  r   r  	__enter__r  start_viewsr  init_dsr  r   )r!   r  s     r%   r  zcmf_context.__enter__L  s    ))))))? 	[YZZZ! 	MMMJLLL" 	%""$$$$$	% 	%r&   c                     	 |rt          |           nt          d           | j                            |||           d S # | j                            |||           w xY w)Nr+  T)r  )r,  r  r  __exit__)r!   excr   rD  s       r%   r  zcmf_context.__exit__W  st    	5 -s+++++t,,,,Hc5)44444DHc5)4444s   #A A!)FTr@  )r1   r/   r=   r    r  r  r;   r&   r%   r  r  F  sK        5 5 5 5 5
	% 	% 	%5 5 5 5 5r&   r  c                  H   g d} t          j        d | D              }|D ]\  }}}|                    t          j        d          }|                    d          r|D ]}|                    d          s|                    d          r|                    d          smd                    d	 |                    d
          D                       }t          
                    |dz   |                    d          d         z   d            t                              d
dt                     t                              ddt                     t                              ddt                     t                              ddt                     t                       d S )N)z	cmf/viewszcmf/modulesr  moduleszcustom/commonzcustom/modulesc                 X    g | ]'}t          j        t          j         d | d          (S )r-   T)followlinks)rh  walkrb   r  )rE   
search_dirs     r%   r  zstart_views.<locals>.<listcomp>c  sH     $' $' $' 	6%44
44$GGG$' $' $'r&   r   z/viewsz.pyz.pycz__init__.pyr*   c              3      K   | ]}||V  	d S r   r;   )rE   r   s     r%   rG   zstart_views.<locals>.<genexpr>k  s'      *N*NA*N1*N*N*N*N*N*Nr&   r-   r   )packagerO  )r)   	view_funcz/<path:req_filename>distz/static/<path:req_filename>staticz,/plugins/<plugin>/static/<path:req_filename>plugins_static)	itertoolschainr   rb   r  r   r   rJ   r0   	importlibimport_moduler   r2   r  app_before_run)r  search_iterdirnamedirnames	filenamesr  r5   s          r%   r  r  a  s   fffK/ $' $'%$' $' $' (K )4 f f$9//&"4b99H%% 	f% f f%%e,, f0A0A&0I0I fS[SfSfgtSuSu f"%((*N*NgmmC6H6H*N*N*N"N"NK++K#,=s@S@STU@V,V`d+eee S6[AAA+fTTT%K     CN^juvvvr&   c                      d S r   r;   r;   r&   r%   r  r  }  s    Dr&   c                 $   |                     dd           ||d<   ||d<   t          t          j        j                  |d<   t          j        |d<   t          j        |d<   t          j        |d<   t          j        	                    | |g           d S )	N	countdownr   r"   r#   g_current_user_idg_acl_admin_modeg_component_idg_session_tab_id)
r<  rD   r   r   r   acl_admin_modere  rd  rr  r   )jobr"   r#   r8   s       r%   schedule_deferred_jobr    s     {A&&&GFOGH#&q~'8#9#9G "#"2G !G"#"2GW~.....r&   c                    | rg t           _        d S t           j        sd S t                               dt          t           j                   d           t           j        D ]\  }} |j        di | g t           _        d S )Nz	Schedule z deferred job(s)r;   )r   rr  rI   r   apply_async)r  r  r8   s      r%   r  r    s       GGBA/00BBBCCC+ # #W""'""""Ar&   c                  V    d } t           j        rt          j        | dg           d S d S )Nc                     i }t           j                            dd           rdt          j        i}t
                              t          j        | |           d S )NSOCKETIOr  
namespacesr  )rh  ri  ru   rb   ORG_NAMEwhatsapp_sioconnectr  r  s     r%   messenger_connectz:spawn_messenger_socketio_client.<locals>.messenger_connect  sa    :>>*d++ 	0v/GV:(2G 	 	E 	E 	E 	E 	Er&   z	/whatsapp)r  )rb   r  r2  r3  )r  s    r%   r  r    sL    E E E $ B&K=AAAAAAB Br&   c                  X    t          j        t          j        t          j                   d S r   )r2  r3  whatsapp_go_sior  rb   r  r;   r&   r%   r  r    s     
L(&*DEEEEEr&   c                      dd l } t          j        ddt          j         dt          j                    |                     t          j        t          j        ddd           d S )Nr   r@   uY   Подключаемся к удаленной отладке config.REMOTE_DEBUG_SERVER=z config.REMOTE_DEBUG_PORT=TF)r<  stdoutToServerstderrToServersuspend)pydevd_pycharmrH   r  rb   REMOTE_DEBUG_SERVERREMOTE_DEBUG_PORTsettrace)r
  s    r%   cmf_pycharm_debugr    s    L	@'-'A	@ 	@%+%=	@ 	@A A A
 F6V=Ufj+/  @ @ @ @ @r&   c                  `   t          t          j        t          j        t	          t          t          j                                        t	          t          t          j                    dz                       t          j        j	        d          } t          |           }t          |          S )Nr  guid)issorg_nameiatexpr  jti)rT   rb   r  r   rD   r   r7  r   r  r   rk  rc  )ri  r`  s     r%   gen_eva_app_tokenr    s}    v"O3ty{{++,,3ty{{R/00119?  G W

CS!!!r&   urir4  c                    ddl m} t          j        rt          j        dk    rUt	          t
          j        |d                   }|                    dg           }|                    di           } ||i |}n |            }ddd	d
|_        t                       |  }t                      |d<   |                    |t                              |                    }	|	j        dk    r"t          d| d|	j         d|	j                   |	                                }|rd|v rt          d|           t"                              |           |S )Nr   )r  FalserQ  r"   r#   rF  rA  r(  )zContent-typeAcceptzContent-Encodingeva_app_token)r4     u9   Не удалось отправить запрос, url=z, status_code=z, res=rH  u(   Сервер вернул ошибку: )requestsr  rb   EVA_ACCOUNT_USEr   r   r  ru   r  r  r  postrh   ri   rL  r   contentr   rI   )
r  r4  r  rQ  method_argsmethod_kwargsresultr   r7   r   s
             r%   call_eva_accountr$    s         ! QV%;w%F%Fh88hhvr**2..666GII%7*(/1 1	  !!(3(( 1 3 3_ffStzz$//f00?c!! DC  D  D_b_n  D  Dvy  wB  D  DE E E 	Qg''OvOOPPPGGFOOOMr&   eva_db_upgrade_runningc                 $   | s t          t          j                              } t          t          d          st
                                           t          j                            t          | dd          st          dt                     dS )u   Запускается перед миграций БД. Информирует приложение, что не следует открывать транзакции.r  r  T)exr  zCannot lock N)rD   rh  r+  r   r  r  r  r  r   _DB_LOCK_KEYCmfError)r   s    r%   app_db_upgrade_startr*    s     !BIKK  8W%% ,))+++>lEbTBB 64l445556 6r&   c                  N    t           j                            t                     dS )u   Запускается после миграций БД. Информирует приложение, что можно продолжать работать.N)r  r  rx   r(  r;   r&   r%   app_db_upgrade_stopr,    s    N,'''''r&      c                     d }d}t          j                     } |            rZ| rt          j                     |z
  |k    r|rt          dt                     dS |dz  }t          j        d            |            ZdS )u   Проверяем не заблокировано ли использование БД, если заблокировано, то можем дождаться разблокировки.c                  &   t           rt          j                    t           z
  dk    ret          t          d          st                                           t          j                            t                    a	t          j                    a t          S )uW   используем кеш 1sec, чтобы часто не ходить в редисr   r  )
_db_lock_cache_tsr7  r   r  r  r  r  ru   r(  _db_lock_cacher;   r&   r%   
check_lockz!check_db_lock.<locals>.check_lock  so     ! 	,TY[[3D%D$I$I 8W-- 4&11333%^//==N $	r&   r   z
DB locked Fr   T)r7  r)  r(  r  )rL  r  raise_errorr2  rn   starts         r%   rW  rW    s    
 
 
 EIKKE
*,,  		e+w66 :L::;;;u

1 *,,  4r&   c                      dd l } t          j        rd}nt          j        } | j        |d            | j                    }|                    |           d S )Nr   rc   z:%(asctime)s %(process)d %(name)s %(levelname)s %(message)s)r  r  )logging.handlersrb   rc   	LOG_LEVELbasicConfigr  setLevel)rH   r  r  s      r%   init_loggingr:    sh    | ! Ge,hiiiiW  F
OOEr&   httpsc                     t           j        pd}|                    d          s|dz  }| r2t           j        rdt           j         nd}| dt           j         | | S |S )Nr-   r   r   z://)rb   	BASE_HREFr   EXTERNAL_PORT_HTTPSr  )full_urlprotocolr|  	port_specs       r%   r  r  %  s}     'CIc"" S	 G8>8RZ42444XZ	FFvF	F9FFFr&   c                     t           j        rt           j        }nI| r4|rd}n1t           j        rdt           j         nd}dt           j         | }nd}|t           j        pdz  }|                    d          s|dz  }|S )Nzhttp://127.0.0.1:8080r   r   r  r-   )rb   AUTH_SERVER_URLr>  r  r=  r   )absoluteinternalr|  rA  s       r%   r  r  /  s     -*		 	 D4		@F@Zb< :<<<`b	CvC	CC		IV%,,	c"" S	r&   r  )r  r  )FFr   r  rB  )r   F)FFNN)FNN)TNTFFFF)T)Tr   rA  )Tr-  T)Fr;  )r"  r  rH   r   rd   fcntlrh  r  r^  r   rv   rC  r7  rD  	threadingr  r   r   pathlibr   typingr   r   urllib.parser   r	   r
   r   werkzeug.utilsr   r2  r   r  Crypto.Hashr   Crypto.Signaturer   r  r   r   flask.json.providerr   werkzeug.exceptionsr   r   r   r~  cmf.data_providersr   r  cmf.system_datar  dateutil.relativedeltar   r   rV  r   r  r  r   rM   objectrO   rH  r1   rb   r  r   rh   rp  r  r  r  cache_in_project_roler  
rpc_modelsclean_attributesrT  rS  LockrU  all_models_meta
SECRET_KEY
secret_keyflask_socketiorV  rW  r  rX  r  rD   rz  rv  r}  r  r  r  r  r  r  r  engineio.payloadr  max_decode_packetsr	  ri  ru   uwsgidecoratorsr@  r  rc   r  r  r  r   r~  r4   r  r  r   REDIS_DB_IDREDIS_DB_ID_TIMERerrorhandlerr   rQ  register_error_handlerprivate_key_pathpublic_key_pathCrypto.PublicKeyrS  
import_key
read_bytesr\  rsa_public_keyrr  r  r  r  r  r  r   r  r  r  propertyr   r   r   r   r  r  r  r  rI   r(  rX  r  r  r  r  r  r  r  r  r  r  r  r  r  rM  after_requestr  r  r  r  r-  r   r8  r  rZ  rc  rk  rn  rp  ru  rw  r,  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rT   r$  cache_notify_scheme_rulecache_cmf_security_levelcache_person_notify_optcache_cust_field_config_schemecache_email_listr  r(  r1  r0  r*  r,  rW  r:  r  r  r;   r&   r%   <module>rp     s             



  				                   0 0 0 0 0 0 0 0       " " " " " " " "  = = = = = = = = = = = = $ $ $ $ $ $          ' ' ' ' ' ' ! ! ! ! ! ! ! ! 3 3 3 3 3 3 - - - - - -           ) ) ) ) ) )     				 0 0 0 0 0 0       - - - - - -
  f  g  g    E   ,B B B
qD qD qD qD qDv qD qD qDj/6 6 6 6 6, 6 6 6* eHDF4FGGGc""   *+
& ' #  " # ,in..  " . . . . . . . .       @ @ @ @ @F  ) 
  H H H*   8E% E% E% E% E% E% E% E%P ! ""G. G. G. G. G. G. G. G.T .-// 3 HJJ	 % $ $ $ $ $  oS oS oS oS oS oS oS oSb  :>>#$$ ,((((((, , X, vV\***&--- 7>>&$'99:: +	f #55	6	6 +!&&((..**+ + + + + + + + + + + + + + +   )  D   9&6 7 7 74*++i7 $v)**]:             H(#.)9)D)D)F)FGGC F'(B(B(D(DEEC     "_ _ _D       &   $    @  D  > !//Q h}--Q !.11Q #+8,D#E#EQ  "(?33Q !.11Q x//Q (7##Q3 3 3 #(?33Q    Xj))Q = = = =>   <  t N N N N NB  , ] ] ]@/ / / /" " " "J     &-q -q -q`$ $ $$ $ $ $( ( ( (*: : : :     7 7 70 0 02M M M     
" 
" 
"O O O$ $ $N & & & &   4   * *-Dy`b 8( 8( 8( 8( 8(v in5:2 2 2 2j  	! 	! 	!  ( ( (8 8 8
- 
- 
-$ $ $ $81N 1N 1N 1Nh= = =@
  
  
  
  
  
 
 
s 
 
 
 
   #        # # # # # #(	  	 3 	  	  	  	      	  	 # 	  	  	  	 
# 
# 
# 
# 
# 
#%(9: %x?P % % % %0! 0h&7 0 0 0 05 5 5 5 5 5 5 56  8	 	 	/ / / /	 	 	 		B 	B 	BF F F@ @ @	"3 	" 	" 	" 	"# T    4  " !   %' "  ( 	6 	6 	6 	6( ( (
   6           s   .,K&&K*-K*