
    i=2                       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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(m)Z) d d
l*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0 d dl1m2Z3 d dl4Z.d dl5Z5d dl6m7Z7 d dl
m8Z8 d dl9m:Z:m;Z; d dl<m=Z= d dl<m>Z> d dl<m?Z?  e5j                  d      ZA G d deB      ZBd ZC G d deD      ZE G d de+      ZF eBeGdeHj                        ZJ eFeJ      eJ_K        deJ_L        deJ_M        g eJ_N        deJ_O        d eJj                  d<   i eJ_P        d eJ_Q        i eJ_R        deJ_S        deJ_T        d eJ_U         ej                         eJ_W        i eJ_X        eHj                  eJ_Z        i eJ_[        d d!l\m]Z]m^Z^ d d"l_m`Z` d dlaZad#ebfd$Zci eJ_d        eceJ_c        daed% Zfdd&Zg G d' d(      Zh eh       Zi G d) d*      Zj ej       ZkekeJ_k         eE       Zld d+lmmnZn d,en_o        dd-Zp G d. d/      Zq eq       Z_ej                  j                  d0      rd d1ltmuZu eud2        Zv e`eHj                  3      Zx e`eHj                  3      Zyej                  j                  eHj                  d4z         rA e|eHj                  d4z         5 Z}e}j                         j                         eH_        ddd       eieJ_i        deJ_        d eJ_        eJj                  e      d5        ZeJj                  ee        eeHj                        d6z  Z eeHj                        d7z  Zd d8lmZ ej                         r' ej                  ej                               eJ_        ej                         r' ej                  ej                               eJ_        g d9eJ_        d: ZLd; Zd< Zd= Zd> ZMdeJ_        deJ_        deJ_        d? Zd@ ZdA Z eeL       ee      _L         eeL       ee      _         ee       ee      _         ee       ee      _         ee       ee      _         ee       ee      _         ee       ee      _         eeM       ee      _M        dB Z ee       ee      _        dC Z ee       ee      _        ddDZddEZdddFdGZdH ZeJjH                  dI        ZddJZddKZdL ZddMZdN ZdO ZddPZddQZddRZdS ZddTZdU ZdV ZdW ZeJjf                  dX        ZdY ZdZ Zd[ ZeJjp                  dd\       Zdd]Zdd^Zd_dd`g dadbZ	 	 ddcZdd Zde Zdf Zdg Zdh Zdi ZddjZddkZdl ZddmebfdnZddmebfdoZddmebfdpZddmebfdqZddmebfdrZddmebfdsZddmebfdtZddmebfduZdvej,                  e
j                     dwe
j                  fdxZdye
j                  dwe
j                  fdzZ G d{ d|      Zd} Zd~ ZddZddZd Zd Zd ZdwebfdZdebdefdZi eJ_        i eJ_        i eJ_        i eJ_        i eJ_        i eJ_        dZdadaddZd ZddZd ZddZy# 1 sw Y   xY w)    N)OrderedDictdefaultdict)Path)OptionalTuple)urlparseparse_qs	urlencodequote)	safe_join)SHA256)
PKCS1_v1_5)Responseflashhas_app_context)DefaultJSONProvider)HTTPExceptionfields)*)base)relativedelta)	timedelta)str_to_timedeltamake_prof_point)cache_v1_metrics)redis_metrics)postgres_metricsz^.*\.(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        |   |i | y N)super__init__)selfargskwargs	__class__s      ./cmf/app.pyr$   zFlask.__init__5   s    $)&)    c                       fd}|S )Nc                 
   j                  dd       }| j                  }|j                  d      d   }|dk7  r	d|z   z   }n}||dz   | j                  z   } j                  ||| fi  t        j                  d|       | S )Nendpoint.index/zFlask endpoint: %s)pop
__module__split__name__add_url_ruleloggingdebug)fr-   module_pathmodule_nameurloptionsruler%   s        r)   	decoratorzFlask.route.<locals>.decorator9   s    {{:t4H,,K%++C04Kg%K'$.&,qzz9Dc8Q:':MM.9Hr*    )r%   r>   r=   r?   s   ``` r)   routezFlask.route8   s    	 r*   )r5   r3   __qualname__r$   rA   __classcell__)r(   s   @r)   r    r    4   s    *r*   r    c                 b    | r-t        j                  ddj                  d |D                     y y )N%s c              3   2   K   | ]  }t        |        y wr"   str).0args     r)   	<genexpr>zprint_debug.<locals>.<genexpr>L   s     %?3c#h%?   )r7   r8   join)condr&   _kwargss      r)   print_debugrQ   J   s'    dCHH%?$%?@A r*   c                      e Zd ZdZdZdZdZdZdZdZ	dZ
d6d7dZd Zd Zd Zd Zd8dZd	 Zd
 Zd Zd Zededefd       Zedefd       Zed9d       Zd Zd Zd Zd Zd Zd Zd Z d6dZ!d Z"d Z#d Z$d8dZ%d:dZ&d  Z'd! Z(d" Z)d# Z*d$ Z+d% Z,d& Z-d8d'Z.d( Z/d;d)Z0d* Z1d9d+Z2d, Z3e4d-        Z5e4d.        Z6e4d:d/       Z7e e8d01      d2               Z9e4d3        Z:e4d4        Z;e4d5        Z<y)<CmfCacheNFc                     t               | _        t               | _        || _        || _        i | _        | j                  r8| j                  j                  dd       | j                  j                  dd       d| _        y )Nstat_hitr   	stat_missF)dict	cache_objcache_invalidateredis_dbmemorytexcom_growcache_hack_cacheincrbyjob_daemon_mode)r%   rZ   r[   s      r)   r$   zCmfCache.__init__Y   sb     $ +-(==MM  Q/MM  a0$r*   c                    t        t        j                  xs | j                  dt        j                         | j
                  r| j
                  j                          nt               | _        t               | _	        | j
                  j                  dt        j                  d              | j
                  j                  dt        j                  ddi             y )NzCmfCache.flushdb!!!filezCmfCache:flushdbCmfCache:inmemory_delkeysALL)rQ   configDEBUGsysstderrrZ   flushdbrW   rX   rY   publishjsondumpsr%   s    r)   ri   zCmfCache.flushdbe   s    FLL.DJJ0ECJJW==MM!!#!VDN$(FD!0$**T2BC5tzz65/7RSr*   c                 n   t        t        j                  xs | j                  dt        j                         t        t              }| j                  j                         }| j                  j                  dd      D ]  }t        | j                  d| dt        j                         |dd	 j                         }| j                  j                  |      }|^t        j                  |      }|d
   }|d   ||   |<   |j                  |        |j                          | j!                  |       y	)u)   Инвалидируем весь jscachezCmfCache.flush_jscache!!!r`   zobj:jshash:*  countz"CmfCache.flush_jscache invalidate z!!!   Ncurrent_person_idjsver)rQ   re   rf   rg   rh   r   rW   rZ   pipeline	scan_iterdecodegetpickleloadsdeleteexecuteemit)r%   emit_msgpipekeyjshashjsresjspersons          r)   flush_jscachezCmfCache.flush_jscacheo   s    FLL.DJJ0KRUR\R\]t$}}%%'==**>*F 		C

&HS$QX[XbXbcW^^%FMM%%c*E}LL'E01H).wHXv&KK		 			(r*   c                    t        t        j                  xs | j                  dt        j                         d}| j
                  j                         }| j
                  j                  dd      D ]*  }|j                  d      r|dz  }|j                  |       , |j                          t        t        j                  xs | j                  d	| d
t        j                         y)u+   Инвалидируем весь obj cachezCmfCache.flush_all_obj!!!r`   r   zobj:*ro   rp   s
   obj:jshash   zCmfCache.flush_all_obj: z recordsN)rQ   re   rf   rg   rh   rZ   ru   rv   
startswithr{   r|   )r%   rq   r   r   s       r)   flush_all_objzCmfCache.flush_all_obj   s     	FLL.DJJ0KRUR\R\]}}%%'==**7$*? 	C~~m,QJEKK		
 	FLL.DJJ2J5'QY0Zadakaklr*   c                   	
 dd l dd l}dd lddlm ddlm	 |}	
fd
t        j                  rj                  t        t        j                  j                  j                         t        j                  d      z
        dd j!                               j#                         d d d	v ro |j                         }|d
k  rYt$        j&                  rIt$        j&                  t$        j(                  k7  r(t        j                  j                  j                         S |D ]  }|dz    
|      z   } d|v r|dz   t        |d         z   }t+        |j-                               D ]  \  }}|dk(  r|dz   |z   dz    
|      z   }! | j.                  r^d|dd z   dz   j                  |j!                               j#                         z   }|j1                  dd      }|j1                  dd      }n3| dj                  |j!                               j#                         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(  rj| dd dk(  rb	 	j                  j                  |       }|j                  j                        }|j                  dd      }|} t        j                   d|        t        |       }|S |t$        k(  r| D ]  }| |      z   d	z   } |S |t&        k(  s|k(  r5| j)                         D ]   \  }}||z   }|r| d
 |      z   }|d	z   }" |S | d}|S |t*        u rt        |       }|S t-        | d      rt        | j.                        }|S d|j0                  z   d
z   
j3                  t5        j6                  |             j9                         z   }|S # t"        $ r!}t        j                   d|       Y d }~d }~ww xY w)Nz... r      20)secondmicrosecondzCmfCache.hash(): !!!!! Date: %sz CmfCache.hash(): !!!!! error: %s,:Noneidz
todo2:obj:)type
issubclasscmfr   CmfType
is_definedvaluerI   intfloatparserparse
astimezoneutcreplacer7   r8   	ExceptionlistrW   itemsboolhasattrr   r5   md5ry   rl   	hexdigest)valtresval1evkr   _all2strdateutilhashlibr   s          r)   r   zCmfCache.hash.<locals>._all2str   s   S	A!SZZ//0>>))CS	ACACS#u%%8AaD 0M'44S9#x||<#||1!|D"&GM #h0 J/ d 2A+c1C2, J) da=0IIK (DAq'C!$Qi(1+5!Ci(& J  J d#h J	 3%cff+C J '3c9GKKUXHY<Z<d<d<ffCJ5 % M&H!LLMs   A!G 	H#G??HZ   daysrr      )d860eddgUUUUUU?|r   z|id:r   zHASH:i  z|md5:
rF   _zDEBUG_CACHE HASH:)r   randomdateutil.parserdatetimer   werkzeug.datastructuresr   APPcache_optimizer   rI   r   r   CmfDatenowr   encoder   gcurrent_usersystem_usersortedr   rf   r   rQ   )r%   prefixr&   r'   r   srr   r   r   r   r   r   r   s            @@@@@r)   hashzCmfCache.hash   s   %90	 0	d '++c#**2D2D2H2H2J8K]K]ceKf2f.ghijk.l.s.s.u"v  #A  #A  #C  DF  EF  #G  KV  #VACxANNq~~/Nzz))--// 	(CC(3-'A	(6>F
S..Av||~. 	4HCd{C##hsm3A	4
 ::!Ac("W,AHHJ0G0Q0Q0SSA		$$A		#s#A(!w{{188:6@@BBADJJ 3Q7r*   c                    |
t               }|s|S t        t        |j                        }t               }|j                  j                         D ]_  }|j                  j                  |d       }|s#|j                  d      r|j                  |d d        n|j                  |       t        |t        j                  j                        r.t        ||j                  d       }|s| j                  ||       t        |t        j                  j                  t        j                  j                  f      st        ||j                  d       }|r|D ]  }| j                  ||        |j!                         D ]/  }	d|j"                   d|	j                   }
|j                  |
       1 b |j                  |j"                  dz   dj%                  t'        |            z          |S )N_idr/   )r   ref_r   rF   r   )setgetattrmodels
class_name__dict__rc   r   rx   endswithaddr   r   CmfRelationBasesimple_objects_id_recursive
CmfM2MBaseCmfBackrefBaserelated_modelsr   rN   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)"":cr?3"":.)SZZ%?%?@%c9+?+?F44[c4JI

(=(=szz?X?X'YZ%c9+?+?F#. K88c8JK "+!9!9!; !I )*>*>)?@CGGCL!'	!. 	sxx~(>??@
r*   c                    |sg S g }t               }|j                  d      D ]d  }|j                  j                  d      r|j	                  |j                  dd        n|j	                  |j                         t        |t        j                  j                        r*|j                  | j                  |j                               t        |t        j                  j                  t        j                  j                  f      s|j                  r1|j                  D ]"  }|j                  | j                  |             $ |j                         D ]/  }d|j                   d|j                   }|j!                  |       1 g |j!                  |j                  j                  dz   d	j#                  t%        |            z          t'        t        |            }|S )
u   
        Собираем ид связанных обьектов 2 уровня для настройки инвалидации
        :param obj:
        :return:
        Tr   r   Nr/   r   r   rF   r   )r   valuesr   r   r   
isinstancer   r   r   extendobjects_id_recursiver   r   r   r   r   appendrN   r   r   )r%   r   r   r   fieldr   r   r   s           r)   r   zCmfCache.objects_id_recursive  sz    IZZ4Z0 	$E((/""5#3#3CR#89""5#3#34%!;!;<

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

4#<#<W#EFG!&!5!5!7 $I )*>*>)?@CJJsO$	$ 	

366<<#%1G(HHI3s8n
r*   c                     t        |      t        j                  kD  rt        dd       y| j                  r | j                  j                  d| |       y| j                  r|| j                  |<   yy )NuU   DEV: Слишком большой объект для кэширования — keyT)
debug_onlyFobj:)lenre   CACHE_MAX_OBJ_SIZE	cmf_alertrZ   r   r[   rX   )r%   r   str_vals      r)   _obj_dict_setzCmfCache._obj_dict_set#  si    w<&333 m{  A==MMSElG4[[")DNN3 r*   c                    t               }|D ]  }|j                  d|         | j                  r' | j                  j                  | t	        |      k(  ryy| j
                  r%|D ]  }| j                  j                  |      r y yy )Nr   TF)r   r   rZ   existsr   r[   rX   rx   )r%   rc   hkeysr   s       r)   _obj_dict_existszCmfCache._obj_dict_exists6  s     	$CIISEl#	$==#t}}##U+s4y8[[ !~~))#. ! r*   c                    | j                   rZ| j                   j                  d|       }|| j                   j                  d       |S | j                   j                  d       |S | j                  r| j                  j                  |      S y )Nr   rU   rV   )rZ   rx   r]   r[   rX   )r%   r   r   s      r)   _obj_dict_getzCmfCache._obj_dict_getH  sy    ==--##d3%L1C$$Z0 J $$[1J[[>>%%c**r*   r   inv_payloadc                     |  d| S )N::r@   )r   r   s     r)   %_jshash_invalidate_confirm_member_keyz.CmfCache._jshash_invalidate_confirm_member_keyU  s    K=))r*   
member_keyc                 (    | j                  dd      S )Nr   r   )maxsplitr4   )r   s    r)   +_jshash_invalidate_confirm_member_key_splitz4CmfCache._jshash_invalidate_confirm_member_key_splitY  s    q11r*   c                 <    | r| n|j                  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_key]  s(     '(FLL,=b,A0	::r*   c                    t        t              }|j                         D ]v  \  }}t        d| |d |g       |j                         D ]K  \  }}|j	                  d      s|| j                  |         j                  | j                  ||             M x | j                  r6|j                         D ]"  \  }} | j                  j                  |g|  $ y y )Nzinvalidate-)roomevent_personsjshash:r   )
r   r   r   cmf_emit_eventr   r  r   r   rZ   sadd)	r%   msgsconfirmations	person_idinv_dictr   r   r  confirm_lists	            r)   r}   zCmfCache.emitd  s    #D)#'::< 	YIx[4hTZcYde'/~~'7 Y#$$Y/!$"I"IQW"I"XY``BB6;WYY	Y ==)6)<)<)> ;%"""7:\:; r*   c                 D   | j                   st        j                  d       | j                   rs|rp|d   d   }| j                  |      }t	               }|D ])  }|j                  | j                  |d   |d                +  | j                   j                  |g|  y y y )NuJ   CmfCache.jshash_invalidate_confirm(): ERROR! Недоступен redis_dbr   r  r   )rZ   r7   warningr  r   r   r   srem)r%   confirm_dictsample_jshashkey_cache_idr  confirms         r)   jshash_invalidate_confirmz"CmfCache.jshash_invalidate_confirms  s    }}OOhi==\ )OA.MBB-BXL6L' h##D$N$NwWXz[bcd[e$fghDMM|;l; *=r*   c                    t         j                  rt        j                          | j                  rW| j                  |      }| j                  j                  |      D cg c]!  }| j                  |j                               # c}S y c c}w r"   )	r   invalidated_keys	CMF_CACHE_do_invalidate_defferrZ   r  smembersr  rw   )r%   r  r  members       r)   jshash_invalidate_confirm_listz'CmfCache.jshash_invalidate_confirm_list  sw    
 ++-====hGG #mm44W=? @@Q? ? ?s   &B	c                    |sy | j                   r | j                   j                  |D cg c]  }d| 	 c}  t        j                  |       | j	                  |       i }|D ]  }| j
                  rd|vrt        d|        t        | j
                  d|        | j                   j                  d| d      x}s^t        | j
                  d|        | j
                  rt        d	|        | j                   j                         }|D ]H  }	|j                  d|	j                  d
              |j                  d|	j                  d
              J |j                         }
t        ||
dd d         D ]  \  }	}|	j                  d
      }	|t        j                  |      }|s2|d   }||vrt!               ||<   |dk(  r/|r-dj#                  t%        |D cg c]  }|dvr|
 c}            }nd}|d    d| d| d| }|||   |	<    | j                   j                  d| d      x}rx t'        j&                         }| j)                  |       t'        j&                         }||z
  dkD  rt*        j-                  d||z
   d       y y | j.                  r$|D ]  }|| j0                  v s| j0                  |=   y y c c}w c c}w )Nr   rq   z#DEBUG_CACHE JSHASH: try invalidate z*DEBUG_CACHE JSHASH: try invalidate:jshash:invalidate:jshash:d   rp   z*DEBUG_CACHE JSHASH: got invalidate:jshash:z#DEBUG_CACHE JSHASH: got invalidate utf-8r   r   rs   updater   )cache_fieldscmf_modified_atcmf_viewed_atcmf_modified_by_idONLYFORUPDATESrt         ?z_obj_dict_mdel emit got sec)rZ   r{   r  inmemory_delprofiler_invalidaterf   r  rQ   spopru   rx   rw   r|   zipry   rz   rW   rN   r   timer}   r   r8   r[   rX   )r%   rc   obj_changed_fieldsobj_idactionr   r~   invjsr   r   jshash_listr   r   r   changed_fieldsr   
emit_startemit_ends                     r)   _obj_dict_mdelzCmfCache._obj_dict_mdel  s   == DMM  4"@CT#<"@A""4($$T*H 7E::'"4"%H#NODJJ*TUXTY(Z[  $}}114Fse2LTW1XXeX

.XY\X],^_zz&)LSE'RS==113D"' E4g(>'?!@Ad6==+A*B$CDE #',,.K),UK14E)F 'E!'w!7& !=$ &U 3 ',-@'AH'x759V 2  &16H15$*7I ,@!+,4~+~ -. ,@ %A2"
 2B-27^,<BvhbPRSaRb*cK9DHX.v6O'E  $}}114Fse2LTW1XXeX7E@ JIIhyy{H*$s*28j3H2IMN +[[ ,$..(s+, _ #Al,@s   K"Kc                    | j                   rb| j                   j                         5 }|j                         D ]  \  }} |j                  d| g|   |j	                          d d d        y | j
                  rJ|D ]D  }|| j                  v r"| j                  |   j                  ||          3||   | j                  |<   F y y # 1 sw Y   y xY wNinvalidate:)rZ   ru   r   r  r|   r[   rY   r   )r%   r  r   r   r   s        r)   _invalidate_dict_msetzCmfCache._invalidate_dict_mset  s    =='') T#+>>#3 <KCDIIC51;F;<  [[ ?$///))#.55hsmD19#D))#.	?  s   ?CCc                     | j                   rA| j                   j                  d|       }|r|D cg c]  }|j                  d       c}S |S | j                  r| j                  j                  |      S y c c}w )Nr@  r'  )rZ   r!  rw   r[   rY   rx   )r%   namer   r   s       r)   _invalidate_dict_getzCmfCache._invalidate_dict_get  sl    ==--((;tf)=>C7:;

7+;;J[[((,,T22 <s   A6c                    | j                   ro| j                   j                         5 }|j                         D ](  \  }}|s	 | j                   j                  d| g|  * |j	                          d d d        y | j
                  r]|j                         D ]I  \  }}|D ]?  }|| j                  j                  |g       v s"| j                  |   j                  |       A K y y # 1 sw Y   y xY wr?  )	rZ   ru   r   r  r|   r[   rY   rx   remove)r%   r  r   rC  r   key_listr   s          r)   _invalidate_dict_mdelzCmfCache._invalidate_dict_mdel  s    =='') T$,NN$4 JLD&***[+?I&IJ 	  [["*.."2 @h# @Cd3377bAA--d3::3?@@
  s   C&2C&&C/c           	      	    t         j                  j                  d      rdt        _        y t
        j                  r|s j                  ry t        j                  v r j                  d       y t        j                  |      r8dt        _        t         j                  dt        j                  |              y  j                  |      }t        j                   j                  |t        j"                        }||k  rEdt        _        t         j                  dt        j"                   d j                  |              y i t$        j&                  j(                  j+                  |      }fd fd	}	|rt-        |t.              sqt1        |d
d       rd |	|       d}
t3        |j4                        t        j6                  v rt9        j:                  dd|j4                   dt        j6                          y |r+t-        |t.              rt1        |d   d
d       rd}
 |	|       nH|4d}
t=        |      t>        k7  r2t=        |      t@        k7  r t<        t2        k7  rn|sd}
d}ntC        d      d}|r?|d   r9t         j                  d|       |
dk(  rY|jD                  |d   vrH|d   D ]@  }||jD                   d|jD                   dfv s$d}|j4                   vrtG        d        n |sg }dg|jH                  D ]  }||d   v s|d   |   } |sdg}t/        |      t        jJ                  d<   |D ]`  }|dv rd }|d   D ]P  }|jM                  d!      d   }||k7  r d"|         d"| d#       4 d$| d%|         d$| d%| d#       R b |d   D ]  } d"| d#        |r|d   s d"| d#        j                  r#D ]  }t         j                  d&| d'          tO        jP                  |      } jS                  |      sdt        _*        |r t        jW                  |tY        |             d(t        v rt        jZ                  rxt         j                  d) dt        jZ                           j                  rt]        d) t        jZ                          j_                  d* t        jZ                  fi        j_                         y )+NNO_CACHETr   r   z%DEBUG_CACHE ADD SKIP CACHE LOCKED_BY z#DEBUG_CACHE ADD SKIP too old trans rF   c                     | j                  d      \  }}}|vrt               |<   |r|   j                   d|        y |   j                          y )NrF   )	partitionr   r   )bind_and_fieldsbindr   r   r  r   s       r)   bind_addzCmfCache.add.<locals>.bind_add.  sl     .77<OD!V8#!$""cU!F8#45  ""cU,r*   c                    t        | t              r| }n| g}g }|D ]k  }t        |j                  t        j                  j
                        rj                  |      }nt        j                  |            }|D ]
  } |        m y)u   
            Собираем списки ключей инвалидации
            :param val:
            :param invalidate_dict:
            :return:
            N)r   r   r   r   r   r   r   r   )r   obj_listr   itemrO  rP  r%   s        r)   bind_add_recursivez(CmfCache.add.<locals>.bind_add_recursive:  s     #t$ 7C  #dggszz'9'9:33D9Ct??EFC #DTN##r*   r   r   rE   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  )0osenvironrx   r   no_jscache_forcere   JOB_DAEMON_DISABLE_CACHEr^   r  $profiler_redis_invalidated_keys_skipr  cache_is_lockedrQ   rf   cache_locked_byget_last_invalidatecache_lockscache_transaction_startr   utilcmfutilget_model_by_namer   r   r   rI   r   skipcache_select_for_updater7   infor   r   r   r   r   r   cache_cluster_fieldsprofiler_datar4   ry   rl   r   cache_store_errorinmemory_addr   r   r  rA  )r%   r   r   obj_typequery_paramscache_inmemorylirl  	obj_modelrT  obj_casewhere_pkr   scopesc_fieldscope
model_namebindidstr_objrP  r  s   ``                 @@r)   r   zCmfCache.add  s   ::>>*%!%A **>dFZFZ !$$$5555A $$X.!%A

&KILeLefnLoKp$qr %%h/"#--"3"3Ha>W>W"X"R'!%A

&I!JcJcIddefjf~f~  @H  gI  fJ  %K  LHH$$66x@	
		#, z#t,dD1I s#H366{a;;;T%7x?_`a`}`}_~#  AZT*ws1vtT/J Hs#_H CyCDI$643;  H
 Ceff
 L2

$9<H 5 <;Q)Q".x"8 J!(8&<@PPU>V%WW#'!ffXh6%&CD   !)J9+I+IJ IG,/?"@@!-.>!?!HI  (\F48L 01# KE NN &&28&< K
 &0%5%5c%:1%=
#z1$zl%CD$zl'%JK$veWAj\%BC$veWAj\%IJKK #/x"8 DJ zl'BCD <#9xj89 ::" ODJJ*<VHCu(MNO
 ,,s#!!#w/"&A""3S\: q=QXX

&I#aPQPXPXz$Z[zz!DSEJAHHU&&'#!(('EF 	""8,r*   c                    	 dt         vrt               t         _        dt         j                  vrt	        |      t         j                  d<   n$t         j                  dxx   t	        |      z  cc<   t
        j                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  rY   cache_invalidate_keys)r   rW   rs  r   r   rS   DEBUG_PROFILE_VERBOSEr   )r%   rc   r   s      r)   r1  zCmfCache.profiler_invalidate  s    	a'"&& Q__425d)AOO./OO./3t9</))&aoo=;= 78OO34;;DA	 *  		s   C	 		CCc                    	 dt         vrt               t         _        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
                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  redis_cache_hitr   redis_cache_missr   redis_cache_hit_keysr   rW   rs  r   rS   r  r   r%   r   r   s      r)   profiler_redis_data_hitz CmfCache.profiler_redis_data_hit  s    	a'"&& AOO312AOO-.OO-.!3.Q__423AOO./))%Q__<:< 67OO23::3?	 *  		   C 	C/*C/c                 
   	 dt         vrt               t         _        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
                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  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'"&& Q__423AOO./OO./14/AOO312AOO-.36/0))&aoo=;= 78OO34;;C@	 *  		s   C/ /	D=Dc                     	 dt         vrt               t         _        d| }|t         j                  vrdt         j                  |<   y t         j                  |xx   dz  cc<   y # t        $ r
}Y d }~y d }~ww xY w)Nrs  invalidated_keys_skip_r   )r   rW   rs  r   )r%   r   r   r   s       r)   rg  z-CmfCache.profiler_redis_invalidated_keys_skip  si    	a'"&& %TF+AOO#!"AOOAOOA!#  		s   A$ $	A72A7c                    t         j                  j                  d      st        j                  ry |t        j
                  v r| j                  d       y d}|rt        j                  |      }nd}t        | j                  d       |du r6d}| j                  |      }|r!	 t        j                  |      }t#        |      }|durd	t        v rt        j$                  rx| j'                  d
| t        j$                  fi       t        | j                  d| dt        j$                          | j                  rt)        d| t        j$                         t        | j                  d|        t        | j                  d|       |s*|r(| j+                  |       t        j-                  ||       |S | j/                  |       t        | j                  d|        y # t        $ r t        j                   d       Y y w xY w)NrJ  rx   rK  T.CACHEFuR   FATAL. Проблемы с востановлением данных из кешаr   r  z*DEBUG_CACHE JSHASH: add invalidate jshash:rF   rb  zDEBUG_CACHE HIT: zDEBUG_CACHE GET:zDEBUG_CACHE MISS: )rc  rd  rx   r   TECHCOM_HACK3441r  rg  r  inmemory_getrQ   rf   r   ry   rz   ModuleNotFoundErrorr7   	exceptionr   r   rA  r  r  ru  r  )r%   r   rx  from_inmemoryr   r   obj_sizes          r)   rx   zCmfCache.get&  s   ::>>*%););!$$$5555A((-CCDJJ(#:!M$$S)C  ,,s+C
 s8c>1}**gcUOahh[+IJDJJ*TUXTYYZ[\[c[cZd(ef::"%H#NPQPXPXY

&7u$=>

$6< ^,,S1&&sC:J%%c*DJJ"4SE :;+ +  %%&z{ s   "G H ?H c                      yNr   rQ   rf   r   rZ   rx   r%   r  s     r)   rj  zCmfCache.get_last_invalidateQ      r*   c                 b    t        | j                  d       | j                         t        _        y )Nz)DEBUG_CACHE TRANS cache_transaction_start)rQ   rf   gen_time_usr   rl  rm   s    r)   rl  z CmfCache.cache_transaction_startV  s"    DJJ KL$($4$4$6!r*   c                     t        t        j                  j                  t        j                  j                        j                  d            S )Nz%Y%m%d%H%M%S%f)r   r   r   r   r   strftimerm   s    r)   r  zCmfCache.gen_time_usZ  s6    8$$(():):)>)>?HHIYZ[[r*   c                      y r"   )	rQ   rf   rh  r  rZ   r   r   rk  rl  )r%   r  ls      r)   
cache_lockzCmfCache.cache_lock]      r*   c                      y r"   )	r   rk  r   ri  rl  rQ   rf   rZ   r   )r%   r  tr_startlock_trs       r)   cache_unlockzCmfCache.cache_unlockn  r  r*   c                      yr  r  r  s     r)   ri  zCmfCache.cache_locked_by~  r  r*   c                      yNF)	ri  r   rk  rx   rl  rQ   rf   rZ   r   )r%   r  _cache_locked_byrl  s       r)   rh  zCmfCache.cache_is_locked  s    r*   c                 <   t        dd      }t        j                  }t        j                  }t        j                  }t               }	||j                  }|D ]r  }
|
|vrt        ||
         ||
<   n||
   j                  ||
          ||
   D ];  }d|v r$|	j                  |j                  d      d          +|	j                  |       = t |j                  |	       |j                  ||j                  d      D 
cg c]  }
|
 c}
||	d        |        y c c}
w )NzCmfCache._do_invalidate  rF   r   T)
is_changed)r6  r5  r7  inv_list)r   r   r  r  r  r   r   r(  r   r4   r   rc   )r%   r   r  r7  r6  
prof_pointglob_inv_dictglob_inv_listr  r  r   inv_vals               r)   _do_invalidatezCmfCache._do_invalidate  s   $%>D




--5>ffV 		*A%#&x{#3a a ''4#A; *'>LLs!3A!67LL)	*		* 	).1hh$h.G"H1"H 	
 	 		 #Is   =	D
c                    t         j                  dd       sy t        j                         }t         j                  }t         j                  }|D ]"  }| j                  |d   |d   |d   |d          $ t        j                         }| j                  |       t        j                         }||z
  dkD  rxt         j                  d||z
   d       t         j                  d	||z
   d
t        t         j                                t         j                  d||z
   d
t        |              t               t         _	        i t         _        g t         _        y )Nr  r  r5  r6  r7  r.  z_do_invalidate_deffer got r/  z)_do_invalidate_deffer _obj_dict_mdel got zsec len=z0_do_invalidate_deffer _invalidate_dict_mdel got )r   rx   r4  r  r  r=  rH  r8   r   r  r   )r%   str  r  r  st_invalidate_dict_mdelends          r)   r   zCmfCache._do_invalidate_deffer  sA   uu'.YY[



% 	~H 4h?S6TV^_gVhjrs{j|}	~ #'))+""=1 iik8c>GG0r
#>?GG?@WZ\@\?]]efijkj|j|f}e~  AGGFsMdGdFeemnqr  oA  nB  C  D U

r*   c                    t         j                  j                  d      ry || dh}|sy | j                  |       t	        | j
                  d| d| dt        |              t               }t               }t               }i }i }t        |      dk  r|D ]  }	| j                  j                  d|	 dd	      }
|
D ]Q  }| j                  j                  |      }|s!|D ],  }|j                  d
      d   }|j                  |       |	||<   . S |j                  |
        nJt        j                  d       t!        | j                  j                  dd	            }
t        j                  dt        |
              t#        j$                  ddj'                  |      z   dz         }t#        j$                  d      }t        j                  d       |
D ]  }|j)                         }|j+                  |      s%| j                  j                  |      }|rC|D ]>  }|j                  d
      d   }|j                  |       |j-                  |      d   ||<   @ |j                  |        |D ]  }| j                  j                  d|j)                                }|j                  |      }	|sC|D ]  }|j                  d
      d   }|j                  |       | j                  j                  d|j)                                }|sWt/        j0                  |      }|d   }||vrt3               ||<   d}|d    d| d|	 d| }|||   |j)                         <     g |d |D        d |D        d |D        }|r8t        j                  d| d| d|         | j                  j4                  |  nt        j                  d| d| d       | j7                  |       y ) NrJ  r   z!DEBUG_CACHE start invalidate_ids rF   x   zinvalidate:*r   ro   )matchrq       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   rs   r-  rt   r   c              3   B   K   | ]  }d |j                            ywr   Nrw   rJ   	query_keys     r)   rL   z*CmfCache.invalidate_ids.<locals>.<genexpr>*  s!     FiY%%'()F   c              3   B   K   | ]  }d |j                            yw)r%  Nr  r  s     r)   rL   z*CmfCache.invalidate_ids.<locals>.<genexpr>+  s"     TI"9#3#3#5"67Tr  c              3   B   K   | ]  }d |j                            ywr  r  )rJ   r   s     r)   rL   z*CmfCache.invalidate_ids.<locals>.<genexpr>,  s     >6V]]_%&>r  zinvalidate_ids(, ): z): no keys found.)rc  rd  rx   r  rQ   rf   r   r   rZ   rv   r!  r4   r   r(  r   r8   r   recompilerN   rw   r  findallry   rz   rW   r{   r}   )r%   r  idsr7  invalidate_keys
query_keysjshashesr~   obj_id_by_query_keyid_rc   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	    ::>>*%; \#$C 	
#DJJ"CF81ZLXYZ]^aZbYc de%U
5 & s8s? - }}..|C55JRV.W BC"&--"8"8"=K"*5 BJ)3)9)9$)?)BJ&NN:6>A/
;BB  &&t,-  GG')//T/RSDGGjT,- JJuSXXc]2589Ezz"opHGGo' 
)!jjl{{;/"mm44S9&1 [
%/%5%5d%;A%>
"z2:B:J:J;:WXY:Z+J7[  ##C(
) $ 	FI!]]336HIYIYI[H\4]^N%)))4C, FF#\\$/2FLL( MM--V]]_4E.FGE  "LL/E$%89Hx/-1V* &6N%*7^$4BvhbRGW"XK:EHX&v}}7F		F&

F:F
 UT
 ?X>	
	 GGoj\C5I;GH DMM  ),GGoj\C58IJK		(r*   c                 &    d
 fd	}t         j                  j                  d      ry |sy  j                  |       t	         j
                  d d|        i |D ]/  } |d| d| d        ||d        j                  d |	       1 y )Nc                 t    j                  |       }|r$|| <   t        j                  d d| |         y y )NDEBUG_CACHE INVAL: rF   )rD  rQ   rf   )invalr8   invdr7  r  r%   s      r)   _check_invalz8CmfCache.invalidate_ids_as_wrapper.<locals>._check_inval6  sF     ,,U3D"&DJJ*=fXQugeW(UV r*   rJ  DEBUG_CACHE start invalidate rF   r   r   ref=obj.id=)r6  )r   )rc  rd  rx   r  rQ   rf   r  )r%   r  r  r7  r  r  r  s   `  `  @r)   invalidate_ids_as_wrapperz"CmfCache.invalidate_ids_as_wrapper5  s    	W ::>>*% 	
#DJJ"?xq UV 	DC4uAj\2F;i(
 hsC	Dr*   c                     t         j                  dd|d|d|       t        j                         }d6 fd	}ddlm} t
        j                  j                  d      ry  j                  |j                         t         j                  d	 d
|j                          |j                  }i  j                  rdd l}	|	j                          |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                         }
 j%                  |       t        j                         }||z
  dkD  rt         j                  d d||z
   d       y t'               }|j)                  d      D ]  \  }}d}|j                  |v rt+        |t,        j.                  j0                        rt3        |d      r"|j4                  j6                  r|j4                  sˉd v r1|r/|j                   r# |d|j                    d|j                   d       d!v r|j8                  r|j:                  |j<                  k7  rm |d|j                   j<                   d|j                   d"        |d|j                   j:                   d|j                   d#       |j?                  |       5t+        |t,        j.                  j@                        r#d!v r|j8                  r|j?                  |       ||j8                  r7t+        |t,        j.                  jB                        r|j?                  |       |j8                  s|j:                  |j<                  k7  s|j?                  |       |jE                  d$      s|j?                  |d d%        " tG        |      dk(  r+d!k(  r&t         j                  d& d'|j                          y d(g}|jH                  D ]  }|j?                  |        tK        tM        |      d)d       r|jO                  |       d v r ||j                    d       d!k(  r ||j                    d|       d!k(  r.|D ](  }d*g|jH                  D ]  }t3        ||      stQ        tM        ||         t,        j.                  j@                        r'||   D ]  } |d|j                    d| d+| d         htQ        tM        ||         t,        j.                  j0                        r |d||d$z       d| d+| d       tQ        tM        ||         t,        j.                  jR                        r |d||    d| d+| d       t#        d,d-         |d| d+| d       + d.}d*g|jH                  D ]A  }t3        ||      s||   j8                  s ||   j:                  ||   j<                  k7  s@d}C d v s|r\t3        |d      r#|j4                  j6                  r|j4                  s-d*g|jH                  D ]  }t3        ||      stQ        tM        ||         t,        j.                  j@                        rs||   D ]  } |d|j                    d| dd/        ||   j8                  su||   j:                  s||   j:                  D ]  } |d|j                    d| dd0        tQ        tM        ||         t,        j.                  j0                        ra |d||d$z       d| dd       ||   j8                  s||   j:                  s |d||   j:                  j                    d| dd1       EtQ        tM        ||         t,        j.                  jR                        r^ |d||    d| dd       ||   j8                  s||   j:                  s |d||   j:                  j                    d| dd1       t#        d,d-        t3        |d      r"|j4                  j6                  r|j4                  s |d| d       n{tT        jV                  rkd v s|ret3        |d      rY|j4                  j6                  sC|j4                  jY                          |j4                  rt#        d2t         jZ                   d3       t\        j^                  r5t         j`                  j                  d4g       gz   t         j`                  d4<   t        j                         }
 j%                  |       t        j                         }||z
  dkD  rt         j                  d5||z
   d       y y )7NzRUN INVALIDATE: action=z obj=z item=z m2m_field_name=c           	         j                  |       }g }|r-|rt        |      }g }|D ]  }d|vr|j                  |       |j                  d      ^}}}|rCt        j                  d|  d|        t        d|  d| d| d       |j                  |       rt        |j                  d            }	||	z  s|j                  |        || <   n|| <   t        j                  d d| |         i }
||
| <   t        j                  r6t        j                  j                  dg       |
gz   t        j                  d<   y y y )	NrF   z=cmfCache.invalidate(): ValueError: too many values to unpack(r  Tabortr   r  r  )rD  r   r   r4   r   r8   r   rQ   rf   rS   r  rs  rx   )r  r8   change_fieldsr  invd_affectedir   i_fieldstaili_set_fieldstmpr7  r  r%   s              r)   r  z)CmfCache.invalidate.<locals>._check_invalX  sr    ,,U3DM $'$6M$&M! 4a<)003$-.WWS\*8d  GG&cdicjjmnomp$qr%(efkellopqorrstxsy&z  CG  H)003$'*8>>#+>'?(<7)003!4" '4HUO&*HUODJJ*=fXQugeW(UV!E
11./oo.A.A&.LPSu.TAOOF+ 2; r*   r   )r   rJ  r  rF   RelationCachezRelationCache.parent.id=)r   rF  r   r   r  uY   DEV: FATAL в инвалидацию м2м поля не передали имя поляr  )r  r_  r`  zwhere=ra  r.  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)creater{   r(  zref_new=zref_old=r   r/   zDEBUG_CACHE ivalidate: z not fields_have_changes--logical_deleterX  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   r8   r4  collectionsr   rc  rd  rx   r  r   rQ   rf   TRACEpdb	set_trace	parent_idr   r   r  r   r   r   r   r   r   r   r  r   r  oldnewr   r   r   r   r   rr  r   r   load_fieldsr   CmfTUUIDre   RAISE_LAZYLOADload
api_methodrS   r  rs  )r%   r   r7  rS  m2m_field_namer  r  r   rv  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.invalidateU  sL	   	*6)6SF'D7:KN;LMNYY[#	VJ 	,::>>*%'DJJ"?xqHX YZ>> ::>>_,CMM?-GH))4y#..)9:FC!uvCFF8i?OP?3>>*:'BHM6$''!CNN+;7CXN !%		Xv6"&))+"R'#--fXV<ORT<T;U VW W X !$d!; 1	:J
 !V  $55
  %!;!;<$S*5#,,:Q:QVYVbVb11e 4z3>>2B!CFK h'E,<,<eiiAW 4~Qs~~6F!G
S 4~Qs~~6F!G
S!((4%!6!67Fx<PUZUeUe $$Z0Jucjj6O6O$P$$Z0 EII$:$$Z0&&u-!((CR9c1	:h }q Vx%7

&=fXE]$^`c`f`fg
  $f// 	0G&&w/	0 49.5OO/0
 **CFF8Y/XCFF8YmL X+ Q
 '/%J1I1I%J QM"36 !$s='9":CJJ<Q<QR*-m*< eJ(6*--(1ZL)Y[cde#D]);$<cjj>X>XY$vc-2E.F-Gq
RST^S_%`bjk#D]);$<cjj>Q>QR$vc-.@-A8*Aj\%Z\de! #DKOQQ2 xj*FxP;Q> $) &B)A)AB 	0MsM*M*55M*..#m2D2H2HH+/(		0 **.F!#z2s||7N7NSVS_S_ #+!FS-E-E!F MsM2d3}#56

8M8MN&)-&8 _
$vjmm_AhZw%OQ]^_=)44]9K9O9O*-m*<*@*@ gJ(6*--(7)SUefgS%7 8#**:T:TU 6#me.C*D)EQxjPW!XZbc=)44]9K9O9O$vc-.@.D.D.G.G-H(SZ%[]ijS%7 8#**:M:MN 6#m*<)=Qxj!PRZ[=)44]9K9O9O$vc-.@.D.D.G.G-H(SZ%[]ij @GKM%MR C,1H1HS\\xj@A ##--1Ic:&,,))LL||1!,,  @x  y  z))*+//*=*=j*LPXl*ZAOOJ' IIKC62"iik#c)GGo&9B&>%? @S S T *r*   c                     | j                   D ]  \  }}t        j                  d|        | j                  j	                         D ]  \  }}t        j                  d|        y )NzCmfCache.dumps(): %s)rX   r7   r8   rY   r   )r%   r   r   s      r)   rl   zCmfCache.dumpsj  sY     	7HCMM0#6	7--335 	7HCMM0#6	7r*   c                    |j                  d      d   }t        j                  r|j                  d      d   }	 t        j                  j
                  j                  |      }t        j                  s;|j                  r|j                  t        j                  vrn| j                  |       y|j                  st        dd       y |t        j                   vr| j#                  |       yt        j                   |   }|j%                  |d      }|du r| j#                  |       |S |j'                  |       | j)                  |       |S # t        $ r Y yw xY w)	Nr.   r   r   r   .S   DEV: inmemory_get вызван для модели без флага cache_inmemoryTr  )r4   rS   rf   r   rm  rn  ro  KeyErrorr   in_memory_cacherx  r   in_memory_cache_skip_modelsprofiler_inmemory_data_skipr   r   INMEM_CACHEprofiler_inmemory_data_missrx   move_to_endprofiler_inmemory_data_hit)clsr   r  r   model_cacherets         r)   r  zCmfCache.inmemory_gety  s3    YYs^A&
>>#))#.q1J	HH$$66zBE   
 ##E,<,<@]@],]//4##ktxyS__,++C0ooj1ooc3'#:++C0J ##C(**3/JG  		s   )E 	EEc           
         |dkD  rt        |t        j                  j                        st	        j
                  |      rd| }np|rnt        |t              r^t        |d   t        j                  j                        st	        j
                  |d         rd|d   j                   dt        |       d}t        | j                  d| d        y t        | j                  d|        |j                  d	      d   }t        j                  r|j                  d
      d   }	 t        j                  j                  j                  |      }t"        j$                  s|j&                  sy |j&                  st)        dd       y |j&                  rd}|t*        j,                  vrt/               t*        j,                  |<   t*        j,                  |   }||v r+||   |k7  r"t1        j2                  dd| d| d||           y |||<   t        |      kD  r`|j5                  d      \  }	}
t6        j8                  r!t:        j<                  j?                  d|       t        | j                  d|	        y y # t         $ r Y y w xY w)Ni  r  r   []u/   DEV: skip inmemory_cache obj_size > 128000 — u	    байтzCmfCache:inmemory_add add key r.   r   r   r  Tr  r  z"CmfCache.inmemory_add(): error: %szkey:z	 try_add:z exists:F)last)r  z"CmfCache:inmemory_add evicted key ) r   r   r   	BaseModeldataclassesis_dataclassr   r   r   rQ   rf   r4   rS   rm  rn  ro  r  r   r  rx  r   r   r  r   r7   r  popitemre   METRICS_API_CACHEr   inmemory_evicted_countwrite)r  r   r   r  detailr  r   	LRU_LIMITr  evicted_keyr   s              r)   ru  zCmfCache.inmemory_add  sN    f#szz3348P8PQT8UcUC.A

(<(<=AYAYZ]^_Z`Aac!f//0#c(1=		%TU]T^^ghngo#pq 	CII!?uEFYYs^A&
>>#))#.q1J	HH$$66zBE   )=)= ##ktxyIS__,*5-COOJ'ooj1+ 33&8DYseS[\ghk\l[m:np C{i'(00e0<NK'' 77==aJ=W		%G}#UV	 (7  		s   $)I5 5	J Jc                    g }|dk(  r"t        | j                  d       i t        _        y |D ]  }|j	                  d      d   }t
        j                  r|j	                  d      d   }	 t        j                  j                  j                  |      }|j                  sr|j                  |       |t        j                  vrt        j                  |   }|D ]  }|j                  |d          |sM|rJt        j                  j                  dt         j#                  |t%        j&                         d      g       y y y # t        $ r Y  w xY w)	Nrd   uS   CmfCache:inmemory_del Полный сброс inmemory_cache при REDISDB.flushdbr.   r   r   r   rb   )rc   skip_app_id)rQ   rf   r   r  r4   rS   r   rm  rn  ro  r  rx  r   r2   r   delayed_redis_eventsrk   rl   rc  getpid)r  rc   
from_event
event_keysr   r  r   r  s           r)   r0  zCmfCache.inmemory_del  s8   
5=		#xy CO 	+C3*J~~'--c215
((:::F ''c"0//*5K +T*+)	+, j""))+BDJJXbsus|s|s~O  EA  +B  C )z!  s   ()E  	EErb   )channelc                 ~    | sy | d   fd}t        t        j                  d       t        j                  |       y )Nrc   c                  j    t        t        j                  d        t        j	                   d       y )Nz*CmfCache:on_inmemory_del event with keys: T)r/  )rQ   rS   rf   r  r0  )rc   s   r)   handlerz)CmfCache.on_inmemory_del.<locals>.handler  s(    (TVZ[""4D"9r*   z&CmfCache:on_inmemory_del spawn handler)rQ   rS   rf   geventspawn)datarP   r4  rc   s      @r)   on_inmemory_delzCmfCache.on_inmemory_del  s6     F|	:
 	HNN&LNWr*   c                    	 dt         vrt               t         _        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
                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  inmemory_cache_hitr   inmemory_cache_missr   inmemory_cache_hit_keysr  r  r   r   s      r)   r  z#CmfCache.profiler_inmemory_data_hit  s    	a'"&&  q645AOO01OO01Q61 756AOO12))(?=? 9:OO56==cB	 *  		r  c                    	 dt         vrt               t         _        dt         j                  vrdt         j                  d<   nt         j                  dxx   dz  cc<   t        j
                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  inmemory_cache_skipr   inmemory_cache_skip_keysr  r=  s      r)   r  z$CmfCache.profiler_inmemory_data_skip"  s    	a'"&& !756AOO12OO12a72)))@>@ :;OO67>>sC	 *  		s   B7 7	C
C
c                    	 dt         vrt               t         _        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
                  rHdt         j                  vrg t         j                  d<   t         j                  d   j                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nrs  r;  r   r:  r   inmemory_cache_miss_keysr  r=  s      r)   r  z$CmfCache.profiler_inmemory_data_miss4  s    	a'"&& !756AOO12OO12a72q645AOO01)))@>@ :;OO67>>sC	 *  		r  r  returnNr"   NNF)r(  )=r5   r3   rB   rX   rY   rZ   r[   rf   r  r  PROCESS_EVICTED_FLUSHr$   ri   r   r   r   r   r   r   r   r   staticmethodrI   r   r  r  r}   r  r#  r=  rA  rD  rH  r   r1  r  r  rg  rx   rj  rl  r  r  r  ri  rh  r  r   r  r  r  rl   classmethodr  ru  r0  on_server_eventr8  r  r  r  r@   r*   r)   rS   rS   O   s   IHFE!E!
%T$mQf!F<&$ *c * * * 2 2 2 ; ;;<?Sj	 Q-fB"@&A($)VR
7\*"C G
:2kZD@STj7 + +\ 1W 1Wf C CB 45 6  C C& D D" D Dr*   rS   c                       e Zd Zd Zy)CustomJSONProviderc                    	 t        |t        j                  t        j                  f      r|j                  }t        |t
        j
                        st        |t
        j                        r/|j                  s|j                         dz   S |j                         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)   rU  zCustomJSONProvider.defaultK  s    	"# 2 2FNNCDii#x001ZX]]5Szz==?S00}}&C0yy CyH >!  		 #**455s$   BC C %C C 	C*%C*N)r5   r3   rB   rU  r@   r*   r)   rL  rL  J  s    6r*   rL  )static_folder	root_pathTSEND_FILE_MAX_AGE_DEFAULTF)SocketIO	Namespace)Client
project_idc                     t        |       } t        j                  j                  |       }|s?t        j
                  j                  | g d      }|rd|_        |t        j                  | <   |S )N)1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_task_only_owner_change_fatal_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_taskz!default_list.sl_task_auto_approvedefault_attach_full_search_typesdesk_feedbackr   r   T)rI   r   cache_projectsrx   r   
CmfProjectreadonly)r]  projects     r)   get_cache_projectr~  }  sg    ZJ  $$Z0G##'': 9?' 9t #G)0:&Nr*   c                  r   t         s\t        d      5 } | j                         }d d d        d}|vrt        d      |j	                  |d      }t
        j                  |      a dt        j                  j                  j                  i}t         j                  t        t               |      S # 1 sw Y   xY w)Nzdist/cmf-angular/index.htmlz<base href="/">z3Base href tag absent in dist/cmf-angular/index.htmlz<base href="{{ base_href }}" />front_socketio_compat)r   	base_hrefsettings)_index_template_cacheopenread
ValueErrorr   jinja2Templater   global_settingsr  r   renderapp_base_href)template_filetemplate_strbase_href_substrr  s       r)   _render_indexr    s     !/0 	0M(--/L	0 -</RSS#++,<>_` & ='):):)P)P)V)VWH ''!}QY'ZZ	0 	0s   B--B6c                    |rd| dg}ng d}|D cg c]0  }t         j                  j                  t        j                  |      2 c}D ]  }t        ||       }t         j                  j                  |      s t         j                  j                  ||      }	 t         j                  j                  |      so	 t        j                  j                  |d      c S  t        j                  D ]/  } ||       }|st        j                  j                  |d      c S  t!               S c c}w # t        t        f$ r t        j                  j                         w xY w)Nzcustom/plugins/z/static)zcustom/static/zcommon/static/zcmf/static/zdist/cmf-angular/T)conditional)rc  pathrN   re   PROJECT_DIRr   isabsisfilerT  r  flaskhelpers
BadRequest	send_filer   HOOK_STATIC_NOTFOUNDr  )req_filenamepluginsearch_dirsd	directoryfilenamehooks          r)   send_staticr    s4   (89!
 DOOabggll6#5#5q9O 	C	Y5ww}}X&ww||Ix8H	-77>>(+ , }}&&xT&BB	C (( G%==**8*FFG ? P :& 	---**,,	-s   5D+D00.E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y)CmfRedisMemoryWrapperut    Если есть self.redis - используется он
        Если нет - нужен фолбэк
    Nredisredis_instance_namec                 .    || _         i | _        || _        y r"   )r  
memstorager  )r%   r  r  s      r)   r$   zCmfRedisMemoryWrapper.__init__   s    
#6 r*   c                       fd}|S )Nc                    | j                   r'	  t        | j                   j                        |i |S t        d      # t         j                  $ r6}t        j
                  rt        j                  | j                         |d }~ww xY w)Nu&   Redis memory wrapper запрещен!)
r  r   r5   ConnectionErrorre   CACHE_REDIS_FAILOWERREDIS_SETTINGS_MANAGERcheck_and_updater  CmfAbortError)r%   r&   r'   r   r9   s       r)   wrapperz/CmfRedisMemoryWrapper.fallback.<locals>.wrapper  sx    zz:74::qzz:DKFKK $$LMM ,, 22.??@X@XYGs   %A   B	1BB	r@   )r9   r  s   ` r)   fallbackzCmfRedisMemoryWrapper.fallback  s    		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                 8    | j                   j                  |      S r"   r  rx   r%   r   s     r)   rx   zCmfRedisMemoryWrapper.get      ""3''r*   c                 8    | j                   j                          y r"   )r  clearrm   s    r)   ri   zCmfRedisMemoryWrapper.flushdb   s    r*   c                 8    | j                   j                  |      S r"   )r  ttlr  s     r)   r  zCmfRedisMemoryWrapper.ttl$  r  r*   c                 D    | j                   j                  ||||||      S )N)nxxxgtlt)r  expire)r%   r   r4  r  r  r  r  s          r)   r  zCmfRedisMemoryWrapper.expire(  s$    %%c4B2"%LLr*   c                 f    | j                   j                  |d      }||z  }|| j                   |<   |S r  r  )r%   r   amountr   s       r)   r]   zCmfRedisMemoryWrapper.incrby,  s4    ##C+$r*   c                 &    | j                  ||      S r"   )r]   )r%   r   r  s      r)   incrzCmfRedisMemoryWrapper.incr3  s    {{3''r*   c                 @    d}|D ]  }|| j                   v s|dz  } |S )Nr   r   r  )r%   namesr   ns       r)   r   zCmfRedisMemoryWrapper.exists7  s2     	ADOO#Q	 r*   c                 "    || j                   |<   y r"   r  )r%   r   r   s      r)   r   zCmfRedisMemoryWrapper.set?  s    $r*   rE  )FFFF)r   )r5   r3   rB   __doc__r  Redisr   rI   r$   r  r!  rx   ri   r  r  r]   r  r   r   r@   r*   r)   r  r    s    7ekk 7xPS} 7
 " " " " ( (     ( ( M M   ( (   % %r*   r  c            
           e Zd ZdZdZd Z	 	 ddedee   dee   dee   f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y)RedisSettingsManageruR   
    Менеджер по управлению настройками Redis.
    rU  c                 p    t        j                  d      | _        d| _        d | _        d | _        d | _        y )Nzredis-settingsF)r7   	getLoggerlogger_terminating
_cert_file	_key_file_ca_filerm   s    r)   r$   zRedisSettingsManager.__init__M  s2    ''(89!r*   Ninstancecar   crtc                    |s|s|st        d      d| }|r>| j                  s2t        j                  j                  j                  || d      | _        |r>| j                  s2t        j                  j                  j                  || d      | _        |r@| j                  s3t        j                  j                  j                  || d      | _        y y y )NuY   Хотя бы один параметр должен быть указан: ca, key, certzredis-z-ca-z-key-z-cert-)r  r  r   rm  rn  write_temp_filer  r  )r%   r  r  r   r  r   s         r)   _prepare_tls_filesz'RedisSettingsManager._prepare_tls_filesT  s     #cxyy($dmmHH,,<<RF84QDMt~~ XX--==cfXUCSTDNt!hh..>>svhfDUVDO '3r*   rD  c                 <   d}t         j                  j                  }t         j                  j                  j                  j
                  }	 |j                  |      j                         }|j                  }|j                          |S # |j                          w xY w)uX   
        Возвращает название инстанса Redis из БД
        N)
r   CmfGlobalSettingsdp_modeldpdata_driverSessionqueryfirstcache_redis_primaryclose)r%   redis_instancer  sessionr  s        r)   _get_instancez"RedisSettingsManager._get_instancec  sz    
 ++44**--99AA	}}X.446H%99NMMO MMOs   +B	 	Bc                    t        t        d      r`t        j                  |   d   dk(  rEt        j                  |   j                         }|j	                  d       |j	                  dd        |j	                  dd       }|j                  d      }|j	                  dd       }|j                  d      }|j	                  d	d       }|j                  d
      }|r|s|r|s|r|rt        d      |s|s|r| j                  ||||       | j                  r| j                  |d<   | j                  r| j                  |d
<   | j                  r| j                  |d<   t        j                  di |S y y )Ncache_settingsr   r  	celery_db
ssl_ca_strssl_ca_certsssl_key_strssl_keyfilessl_cert_strssl_certfileu   Указаны противоречивые настройки Redis: ssl_ca_str/ssl_ca_certs, ssl_key_str/ssl_keyfile, ssl_cert_str/ssl_certfile)r  r   r  r@   )r   re   r  copyr2   rx   r  r  r  r  r  r  r  )	r%   r  cfgr  r  r   r  r  r  s	            r)   _init_redisz RedisSettingsManager._init_redist  sM   6+,1F1Fx1PQW1X\c1c''1668CGGFOGGK&t,B77>2L''-.C''-0K''.$/C77>2L|,SV M  SC''RSc'J}}&*mmN#&*ooN#~~%)^^M";;%%%9 2d,r*   
with_flushc                 f   t         j                  j                  }t         j                  j                  j                  j
                  }	 |j                  |      j                         j                         }|rS| j                  |      }| j                  j                  d       	 | j                  ||       t        j                          ||_        |j#                          |j%                          y # t        $ r | j                  j                  d       Y Nw xY w# |j%                          w xY w)Nu*   Выполняем очистку кешаu>   Не удалось выполнить очистку кеша)r   r  r  r  r  r  r  with_for_updater  r  r  r  
init_cacher  ri   r   r  commitr  )r%   r  r  r  r  r  r  s          r)   
save_to_dbzRedisSettingsManager.save_to_db  s    ++44**--99AA	}}X.>>@FFHH!%!1!1(!;##$PQjOOHn=%%' ,4H(NNMMO ! jKK''(hij MMOs1   
AD &&C4 D 4$DD DD D0r  c                     t        t        d      rUt        j                  |   d   dk(  r|t        _        y t        j                  |   d   dk(  rdt        _        y t        d      y )Nr  r   r  r[   Tu&   Неизвестный тип кеша)r   re   r  r  rZ   r[   r   )r%   r  r  s      r)   r  zRedisSettingsManager.init_cache  s^    6+,$$X.v6'A%3	"&&x08HD#'	  HII -r*   c                    | j                         \  }}| j                  |      t        _        |t        _        t
        j                  r|s| j                  |       t        j                  j                  d      rt        j                  t        d      t        j                  |       | j                  |t        j                         y )N	run_uwsgiu?   При работе через uwsgi обязателен Redis)get_instancer  REDIS_DBr  r  re   r  r  rc  rd  rx   r   socketiostart_with_redisr  )r%   is_db_instancer  s      r)   
init_rediszRedisSettingsManager.init_redis  s    #'#4#4#6 ))(3'/$ &&~OOH%::>>+&~~% abb!!(+(..1r*   c                     t         j                  r*| j                         }|rd}||fS | j                  }d}||fS d}| j                  }||fS )NTF)re   r  r  DEFAULT_REDIS_INSTANCE)r%   r  r  s      r)   r  z!RedisSettingsManager.get_instance  sj    &&))+H!% x'' !77!& x'' #N22Hx''r*   r  c                    | j                         }||k7  r| j                  sd| _        | j                  j                  d|       t	        j
                  dd      }|dk7  r3| j                  j                  d|       t        j                  |d       | j                  j                  d|       t        j                  t        j                         t        j                         y	y	y	)
u   
        Проверяем, обновилась ли конфигурация Redis в БД
        и если да, то терминейтим app
        Tu<   Получена конфигурация Redis %s из БДr   <   uU   Ожидание %d секунд для применения конфигурацииFr   uv   Остановка процесса приложения для применения конфигурации Redis %sN)r  r  r  r  r   randintr5  sleeprq  rc  killr.  signalSIGTERM)r%   r  db_instancesleep_secondss       r)   r  z%RedisSettingsManager.check_and_update  s     ((*--d6G6G $DKK ^`kl"NN1b1M!##${  ~K  L]6 KK  V  Xc  dGGBIIK0 7H-r*   intervalc                 
   | j                   j                  d       | j                         \  }}	 	 | j                  |       t        j                  |d       *# t        $ r | j                   j                  d|       Y ?w xY w)u^   
        Переодический запуск проверки и смены Redis
        u,   Запуск periodic_check_and_update Redisu   Запуск periodic_check_and_update Redis завершился с ошибкой. Повторный запуск через %d секундFr  )r  rq  r  r  r   r  r5  r  )r%   r  r   r  s       r)   periodic_check_and_updatez.RedisSettingsManager.periodic_check_and_update  s    
 	GH!%!2!2!4%%&9: LLu-   %%QRZs   A %BB)NNNrF  )r  )r5   r3   rB   r  r	  r$   rI   r   r  r  r  r  r  r   r  r  r  r   r  r  r   r  r@   r*   r)   r  r  F  s     ' MQ!WW!)#W<DSMWc]Wx} "&C &HU[[,A &>3 D ,J3 J J2&(eD#I. (1C 1&.# .r*   r  )Payloadr&  c                     t         j                  xs d}|j                  d      s|dz  }| r>t         j                  rdt         j                   nd}| dt         j                   | | S |S )Nr1   r   r   z://)re   	BASE_HREFr   EXTERNAL_PORT_HTTPSAPP_FQDN)full_urlprotocolr  	port_specs       r)   r  r     so      'CIc"S	8>8R8Ra2234XZ	3v/	{9+FFr*   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y)CmfSocketIOWrapperu   
    Функционал:
    1. Отложенная активация, после получания доступа к Redis
    c                    ddl m} |j                  t        j                  rt
        j                  nt
        j                         d}t        d|d|d| _	        d | _
        d | _        g | _        g | _        g | _        g | _        y )Nr   )default_loggerz	socket.ior   F)appcors_allowed_originsr  engineio_loggerr  )socketio.serverr"  setLevelre   rf   r7   INFOWARNINGr   socketio_kwargsr  r  lazy_on_handlerslazy_on_namespace_handlerslazy_init_apps	lazy_runs)r%   r"  socketio_paths      r)   r$   zCmfSocketIOWrapper.__init__  sw     	3'//R $ $'$$! 
 " "*,' r*   c                    t        j                  d|       | j                  r0| j                  |k(  rt        j                  d       y t        d      | j                  |       t        di | j                  | _        | j                          | j                          | j                          | j                          || _        y )Nz'CmfSocketIOWrapper: start_with_redis %su4   CmfSocketIOWrapper.start() вызван дваждыu)   CmfSocketIOWrapper уже запущен!r@   )r7   rq  r  r  r  r   _make_redis_connect_paramsrZ  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    >O==""n4 VWGHH''7 84#7#78$$&..0!!#,r*   c                       fd}|S )Nc                 D    j                   j                  | d       y )N)funcdec_args
dec_kwargs)r+  r   )r8  r9  r:  r%   s    r)   wrapz#CmfSocketIOWrapper.on.<locals>.wrap9  s%    !!(($(* r*   r@   )r%   r9  r:  r;  s   ``` r)   onzCmfSocketIOWrapper.on8  s    	 r*   c                     | j                   j                  |       | j                  r2t        j                  d|       | j                  j                  |       y y )Nz#CmfSocketIOWrapper: on_namespace %s)r,  r   r  r7   rq  on_namespace)r%   r4  s     r)   r>  zCmfSocketIOWrapper.on_namespaceA  sC    ''..w7==LL>IMM&&w/ r*   c                     | j                   j                  ||d       | j                  r8t        j                  d| d|         | j                  j
                  |i | y y )N)r&   r'   zCmfSocketIOWrapper.run(): %srF   )r.  r   r  r7   rq  runr  s      r)   r@  zCmfSocketIOWrapper.runG  s`    
 	 ==LL7D66(9KLDMMt.v. r*   c                 <     | j                   j                  |i | y r"   )r  r}   r  s      r)   r}   zCmfSocketIOWrapper.emitP  s    D+F+r*   c                     | j                   j                  |       | j                  r2t        j                  d|       | j                  j                  |       y y )NzCmfSocketIOWrapper.init_app(%s))r-  r   r  r7   rq  init_app)r%   r   s     r)   rC  zCmfSocketIOWrapper.init_appS  sC    ""3'==LL:C@MM""3' r*   c                 b     | j                   j                  j                  j                  |i |S r"   )r  servermanagerget_participantsr  s      r)   rG  z#CmfSocketIOWrapper.get_participantsY  s*    <t}}##++<<dMfMMr*   c                     | j                   D ]C  }t        j                  d|         | j                  j                  |d   i |d   |d          E y )Nu:   CmfSocketIOWrapper: регистрируем on handler %sr9  r:  r8  )r+  r7   rq  r  r<  )r%   lazy_on_handlers     r)   r2  z*CmfSocketIOWrapper._start_lazy_on_handlers\  s[    #44 	uOLLUWfg[DMMoj9[_\=Z[\klr\st	ur*   c                     | j                   D ]3  }t        j                  d|       | j                  j	                  |       5 y )NuD   CmfSocketIOWrapper: регистрируем on_namespace handler %s)r,  r7   rq  r  r>  )r%   lazy_on_namespace_handlers     r)   r3  z4CmfSocketIOWrapper._start_lazy_on_namespace_handlersa  s=    )-)H)H 	B%LL_az{MM&&'@A	Br*   c                     | j                   D ]3  }t        j                  d|       | j                  j	                  |       5 y )Nu4   CmfSocketIOWrapper: отложенный init_app %s)r-  r7   rq  r  rC  )r%   r#  s     r)   r4  z'CmfSocketIOWrapper._start_lazy_init_appf  s9    && 	(CLLOQTUMM""3'	(r*   c                     | j                   D ]:  }t        j                  d|        | j                  j                  |d   i |d    < y )Nu/   CmfSocketIOWrapper: отложенный run %sr&   r'   )r.  r7   rq  r  r@  )r%   lazy_runs     r)   r5  z"CmfSocketIOWrapper._start_lazy_runk  sI     	GHLLJHUDMMx/F8H3EF	Gr*   c                    t        t        d      rKt        j                  |   d   dk(  r1t        j                  |   d   }t        j                  |   j                  d      r=dt        j                  |   d    d| }dd	lm}  ||d
d      }|| j                  d<   y 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                  |   j                  dd       z  }|d| z  }|| j                  d<   y t        j                  d       y )Nr  r   r  dbunix_socket_pathzunix://z?db=r   )RedisManagerzflask-socketioF)r1  
write_onlyclient_managerzredis://usernamepasswordr   @hostport6379r1   message_queueuu   CmfSocketIOWrapper: в cache_settings не найден коннект к Redis. Socketio не активирован)	r   re   r  rx   r  rR  r*  r7   error)r%   r  rP  r<   rR  rT  r[  s          r)   r1  z-CmfSocketIOWrapper._make_redis_connect_paramsp  s   6+,1F1Fx1PQW1X\c1c&&x06B$$X.223EF 5 5h ?@R STTXY[X\]1!-c;KX]!^9G$$%56"*!6!6x!@@!V%:%:8%DZ%PPM!6!6x!@@!q)>)>x)H)T(UUV%WWM!6!6x!@!HH1V%:%:8%D%H%HQW%X$Y!ZZ1RD)8E$$_5MM  R  Sr*   N)r5   r3   rB   r  r$   r  r<  r>  r@  r}   rC  rG  r2  r3  r4  r5  r1  r@   r*   r)   r   r   	  sM    6-0/,(Nu
B
(
G
Sr*   r   SOCKETIO_WORKER)postforkc                  ,    t         j                          y r"   )r  r  r@   r*   r)   r  r    s    ))+r*   )r  z/custom/org_namec                    t        j                  d       t        j                   }t	        | t
              rs| j                         }| j                  | j                  d}|rt        j                         |d<   | j                  |d<   t        j                  |      |_        d|_        n>ddd}|r%t        j                         |d<   t!        |       |d<   t#        |      }d|_        t'        |       |S )Nz
App error:)coderC  	tracebackdescriptionapplication/jsonr  zUnknown error)r7   r  re   
PRODUCTIONr   r   get_responsera  rC  rb  
format_excrc  rk   rl   r7  content_typerI   jsonifystatus_codeset_cors_headers)r   
show_traceresponseresponse_datas       r)   handle_exceptionro    s    l# &&&J!]#>>#FFFF
 )2)=)=)?M+&'(}}m$

=1 2 #
 )2)=)=)?M+&+.q6M-(=)"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_vacationrh  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y 	 t        j                  s8t        j
                  j                  dt        j                        t        _        t        j                  S # t        $ r t        j                  d        w xY w)Nz.CmfPerson:00000000-0000-0000-0000-000000000001ry  zapp.system_person() error)re   AUTH_ENABLEDr   system_personr   	CmfPersonrx   current_person_fieldsr   r7   r  rm   s    r)   r  r    sy    
    & 0 0 4 4CCLeLe !5 !gC 	  56s   AA+ + Bc                     t         j                  j                  d      r t         j                  j	                  d      } n\t         j
                  sy	 t        j                  t         j
                        }|yt        |t              xr |j	                  dd      } | syt        |       }|j                  j                  d      sydt        _        t!        |j"                        j	                  d	dg      d
   }|rt%        |      dk7  ry|j                  j'                  d      d   }|syt)        j*                  d|      x}r|j-                         \  }}ny|dk(  s
|dk(  s|dk(  rt.        j0                  }nP|dk(  s|dk(  s
|dk(  s|dk(  rt.        j2                  }n+|dk(  s|dk(  rt.        j4                  }nt.        j0                  }t7        |t8        j.                  j:                        syd|v r%|j	                  |j<                   d| ddg      }	n|j	                  |ddg      }	|	sy|t?        |	j@                        k(  rdt        _!        |	t        _"        y# t        $ r t        j                  d       Y yw xY w)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      r1   r  z*^(?P<obj_type>[^:-]*)[:-](?P<obj_code>.*)$docDOCCmfDocumentflFLIN_WORK	CmfFolderCmfListEPI-r   r   sharelink_hashry  )ra  r   )#requestr  r   headersrx   r7  ujsonrz   r   r7   r  r   rW   r   r   sharelink_access_requestr	   r  r   r4   r  r  groupsr   r  r  r  r   r   	CmfEntityr   rI   r  sharelink_access_grantedsharelink_access_obj)
r  json_resr<   
hash_paramobj_keyr  rv  obj_coderz  r   s
             r)   _check_sharelink_accessr    sS    ||x(##I. ||	{{7<<0H 8T*Hx||GR/H
5/C 88y) "&A#))$(("6q9JZA-hhnnS!"%G FPPuP"\\^( 5H-]1J&&		T	X-Y1F(VaJa$$		Y	(e"3NN	 &&	 i!5!56
hmm)"6"6!7q
C$(*:#;  = mm$8H1ImJ S++,,%)"!$
U  	  \  ]	s   #I I?>I?c                     | t         _        | r8| 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  M	  s?    A&,0@0@&@#06!:T:T0T-r*   c                     t        | dd       }|dk(  r| j                  S t        j                  sy ||S t	        j
                  d       y )Nr  FAIL_recursionzLazy Calc Current Person)r   r  re   r  r7   r  )r%   cps     r)   current_personr  V	  sN    	($	/B	!!!	~	 OO./r*   c                 @   	 t         j                  st        j                  j	                  dg      }|j                  st
        j                  j                  j                         5  dd l	}dd l
|j                  |j                  z   dj                  fdt        d      D              |_        |j                          d d d        |j                  t         _        t         j                  S # 1 sw Y   .xY w# t         $ r t#        j$                  d        w xY w)Napp_keyr   r   r   c              3   @   K   | ]  }j                          y wr"   )choice)rJ   r   alphabetsecretss     r)   rL   zapp_key.<locals>.<genexpr>p	  s     .[Aw~~h/G.[s       zapp.app_key() error)r   r  r   r  rx   r   rm  rn  disable_aclstringr  ascii_lettersdigitsrN   rangesaver   r7   r  )r%   r  r  r  r  s      @@r)   r  r  f	  s    {{//33I;3GH##XX%%113 $!"%33fmmCH')ww.[QVWYQZ.['[H$MMO$ #**CK
 ;;$ $  /0s%   A%C= )AC1C= 1C:6C= = Dc                    t        | dd       | j                  S 	 t        j                  s9t        j                  j                  ddt        j                        t        _        t        j                  | _        | j                  st        j                  j                  dd      }|j                          	 t        j                  j                  ddt        j                        | _        | j                  sst        j                  j                  j                         5  t        j                  j!                  | j"                        | _        d d d        t%        j&                          |j)                          | j                  S | j                  S # 1 sw Y   ExY w# |j)                          w xY w# t*        $ r t-        j.                  d        w xY w)	N_anonymous_userzanonymous@evateam.ruTra  include_deletedr   zcreate-anonymous-user-lock   timeoutzapp._anonymous_user() error)r   r  r   r   r  rx   r  r  r  lockacquirer   rm  rn  r  system_datacreate_anonymous_userr  ddcommit_all_dsreleaser   r7   r  r%   
redis_locks     r)   r  r  ~	  s   t&-9###"""("2"2"6"6+T00 #7 #2C  #22##!,,-IST,UJ %'-'7'7';';/44 (< (6$ ++))557 i/2/T/TUYUgUg/h,i $$&""$###t###i i
 ""$ 78C   BF5 8A)F  !/FF  ,F5 F5 FF   F22F5 5 Gc                    t        | dd       | j                  S 	 t        j                  s9t        j                  j                  ddt        j                        t        _        t        j                  | _        | j                  st        j                  j                  dd      }|j                          	 t        j                  j                  ddt        j                        | _        | j                  sst        j                  j                  j                         5  t        j                  j!                  | j"                        | _        d d d        t%        j&                          |j)                          | j                  S | j                  S # 1 sw Y   ExY w# |j)                          w xY w# 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   r  rx   r  r  r  r  r  r   rm  rn  r  r  create_sharelink_anonymous_userr  r  r  r  r   r7   r  r  s     r)   r  r  	  s   t0$7C---,,,2,<,<,@,@14,, -A -.C) *-)F)F&--!,,-S]^,_J %171A1A1E1E9444 2F 26. 55))557 09<9h9h ..:060 $$&""$---t---0 0 ""$ ABr  c                 ^   t        | dd       | j                  S 	 t        j                  j	                  ddt
        j                        | _        | j                  st        j                  j                  dd      }|j                          	 t        j                  j	                  ddt
        j                        | _        | j                  sst        j                  j                  j                         5  t        j                  j!                  | j"                        | _        d d d        t%        j&                          |j)                          | j                  S | j                  S # 1 sw Y   ExY w# |j)                          w xY w# 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   r  rx   r   r  r  r  r  r  r   rm  rn  r  r  create_test_guest_userr  r  r  r  r   r7   r  r  s     r)   test_guest_userr  	  sl    t'.:$$$ & 0 0 4 4($,, !5 !. $$!,,-JTU,VJ %(.(8(8(<(<0$44 )= )6% ,,))557 k030V0VW[WiWi0j-k $$&""$$$$t$$$k k
 ""$ 89sC   A3F A)E7 8/E+'E7 F F +E40E7 7F		F  F,c                 >    t         j                  j                         S r"   )r   r  get_settingsrm   s    r)   r  r  	  s    ##0022r*   c                     t        | d      rt        | dd       | j                  S t        j                  j                  ddg      | _        | j                  S )N_global_varaccount_sync_statusaccount_sync_lastr   )r   r   r  r   CmfGlobalVarrx   rm   s    r)   
global_varr  	  sU    t]#mT(J(V**..7LNa6b.cDr*   c           	         | j                  t        j                  dd      t        j                  dd      f      } | j                  |d      }t	        d|z         t        |d | d      D ]  \  }}|j                  d   }t        j                  j                  |j                  j                  t        j                        d	d        }t	        d
|||j                  |j                  dz  fz         t        j                  |j                  |j                        j!                         }|rt	        d|z         |j                  j#                         D ]  }	t	        |	         ||d  }
|
r.t%        d |
D              }t	        dt'        |
      |dz  fz         t%        d |D              }t	        d|dz  z         y )NFz<frozen importlib._bootstrap>z	<unknown>T)
cumulativezTop %s linesr   r   z#%s: %s:%s: %.1f KiBi   z    %sc              3   4   K   | ]  }|j                     y wr"   sizerJ   stats     r)   rL   zdisplay_top.<locals>.<genexpr>
  s     /499/   z%s other: %.1f KiBc              3   4   K   | ]  }|j                     y wr"   r  r  s     r)   rL   zdisplay_top.<locals>.<genexpr>
  s     0d		0r  zTotal allocated size: %.1f KiB)filter_tracestracemallocFilter
statisticsprint	enumeraterb  rc  seprN   r  r4   linenor  	linecachegetlinestripformatsumr   )snapshotkey_typelimit	top_statsr0   r  framer  linellotherr  totals                r)   display_topr  	  s   %%5"AB5+.' H ##H#=I	.5
 ! 6E!2A6 
tq!66;;u~~33BFF;BC@A$%,,		D0@AB 	C  >DDF(T/"..'') 	B"I	
 efE///"c%j$+%>>?0i00E	
*edl
;<r*   c                 d   t         j                  j                  j                  dd      5  t        j
                  j                  | j                  t        j                        }|s| j                  d      D ci c]  \  }}|j                  d      s|dk7  r||  }}}t        j                  |d	<   t        j                  |d
<   t        j                  |d<   t	        j
                  di |}|r|d|_        |j                  j!                  t        j"                  j%                                d|_        |j                  j!                  t        j"                  j)                                |r@d|_        |j                  j!                  t        j"                  j                  d             t         j                  j                  j-                         5  |j/                  d       d d d        t1        j2                          |cd d d        S c c}}w # 1 sw Y   .xY w# 1 sw Y   y xY w)Nzcreate-current_person-lock
   r  )loginr   Tr   cmf_r   	cmf_owner
cmf_authorcmf_modified_byServiceDeskClient)ra  )	only_datar@   )r   rm  rn  CmfLockr   r  rx   r  r   r  r   r   r   r   r  rs  r   CmfPersonGroupsupport_grouprw  
user_groupr  r  r  r  r  )authr  is_servicedeskr  r   r   person_valuess          r)   create_person_from_authr  
  s   				!	!">	!	K !!%%DJJs?X?X%Y !JJ$J7;Aq||F+T	 1;M ; *+M+&*+--M,'/0}}M+,%%66F$(!##**6+@+@+N+N+PQ$(!##**6+@+@+K+K+MN+/(##**6+@+@+D+DJ]+D+^_!!--/ ,d+, 5 
;", ,- s7   AH&>#H!D9H&H-H&H&H#	H&&H/)forcelevelc                 8   t        j                          }t        t        dd       s| s|r|!t        |t              r4t        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        j                  di       j                  dt                     }|j                  dd      }|j                  dd      }	|j                  d	d      }
t        j                  j                  d
      }t        j                   d|d| d| dd| d|	 d|
 d||	z   |
z    ddg|}t        j"                  |ddj%                  d |D                     t        j                          t        _        t'        t        j                          |z
  dz        }|dkD  rt        j"                  |dd| d       y y y )Nrf   ro   r   rs  select_countselectr   r(  insertmr1   z(+z)mszs zu zi r   rE   rF   c              3   2   K   | ]  }t        |        y wr"   rH   )rJ   parts     r)   rL   zdebug.<locals>.<genexpr>P
  s     *G3t9*GrM   zPROF debug funcion got ms)r4  r   re   r   rI   r7   r(  rf   roundr   debug_start	debug_nowrx   rW   r  r&   
request_idlogrN   r   )r  r  messagesdebug_str   r   r  scscsscuscir   parts	debug_ends                 r)   r8   r8   7
  s   yy{Hvw%%%%/LLEMMEiiksQ]]*d2A67sQ[[(D0!45UU?B'++NDFCffXq!ffXq!ffXq!LLS!LLA3b3C53%r#bsS(9;

 
 	E4*G*G!HIiik X-t34	q=KKt'>yk%LM 9 38r*   c                  <   t         j                  j                  d      } t         j                  j	                  d      ra| r_t        t        |       j                        }|j	                  t                d      ry|j	                  d      s|j	                  d      ryyt         j                  j	                  d      ryt         j                  j	                  d	      st         j                  j	                  d      ry
t         j                  j	                  d      s>t         j                  j	                  d      st         j                  j	                  d      ryt         j                  j	                  d      ryt         j                  j	                  d      ryy)Nr  /files/servicedesksd_api/docs/r  pub_api/servicedesk/api/api/pub//auth/r  /with-contextsystemdeny)r  r  rx   r  r   rI   r   r  )refererreferer_paths     r)   set_api_scoperA  X
  s"   oo!!),G||y)g8G,112""mo%6k#BC""8,0G0G	0R  
	 	 	0		 	 	)W\\-D-DY-O		 	 	)W\\-D-DX-NRYR^R^RiRijsRt		 	 	*		 	 	1r*   c            
      N.   t         j                  dk(  ryt        t        j                   t        j
                   t        j                  f      r<t        j                  5  t        j                  t        j                         ddd       ddlm t                t         j#                          t%        j&                          dt(        _        i t(        _        i t(        _        g t(        _        t2        j4                  j7                  d      dk(  t(        _        ddlm}  dd	lm}  |        t(        _         t(        j@                  t(        _!        d
jE                   |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        dt(        _9        tu               t(        _;        dt(        _<        dt(        _=        dt(        _>        t~        j~                  j                  t~        j                  j                        t(        _C        dtfd	t(        _@        t(        j                  j                         t(        _E        dtfd	t(        _D        dt(        _F        i t(        _G        i t(        _H        g t(        _I        g t(        _J        g t(        _K        g t(        _L        g t(        _M        g t(        _N        g t(        _O        i t(        _P        g t(        _Q        i t(        _R        i t(        _S        t               t(        _U        dt(        _V        dt(        _W        t               t(        _X        i t(        _Y        g t(        _Z        dt(        _[        dt(        _\        dt(        _]        g t(        _^        i t(        __        i t(        _`        i t(        _a        t               t(        _b        i t(        _c        i t(        _d        g t(        _e        i t(        _f        i t(        _g        g t(        _h        g t(        _i        t        t(        _j        dt(        _k        dt(        _l        dt(        _m        dt(        _n        t               t(        _o        dt(        _p        dt(        _q        dt(        _r        dt(        _s        t        j                  j                          t        j                  j                          t        j                  st        d       yt         j                  j                  d      ryt        j                  st        j
                  s{t(        j                  dt3        j                          d       t        j                  5  t(        j                  dt3        j                          d       t        j                  st(        j                  dt3        j                          d       t        j                  r'ddl~}|j                  t        j                   dd       t        j                  t        j                          t	                t                t        j                  rt                t        j                  rt                t        j                  r6ddl}|j                  j                  j                  j                          t!        t        d      r t        j"                  j%                          	 ddl}t        j                  rddlm} ddlm} |j1                          ddlm} |j;                          dt        _        t(        j                  dt3        j                          d       n+t(        j                  dt3        j                          d       ddd       t        j<                  r/d
jE                  t=        j>                  dd            t(        _p        d}d}	t         j                  j                  d       s t         j                  j                  d!      rt         j@                  j7                  d"      }
|
sEt         j@                  j7                  d#      }
|
r#|
j                  d$      r|
tC        d$      d }
nd}
|
s t         jD                  j7                  d%      }
|
r{t        jF                  jI                  |
      }t        jJ                  j7                  |dd&g d'(      }|r|jL                  r^|jL                  t~        j~                  j                         k  r2tO        jP                  d)|jL                         tS        d*d+d,-      S t        jF                  j7                  d.d/|jT                  jV                  gg d0gt        jX                  1      }|r/t(        j                  d2|
dd  d3| d4| d5|jZ                          |sFtO        jP                  d6t         j@                  t         jD                         tS        d7d8d,-      S t         j                  d9k(  r1t        j\                  j_                  t        jX                  :      }t         j                  j                  ta                d;      st         j                  j                  d<      rmd=}d>t         jb                  v rt         jb                  d>   }te        |      }|s(tg        d>|i      }ti        ta                d?|       }tk        |       |S d@}tm        dAdBdC      }|st         jn                  j7                  dD      }t         jn                  j7                  dE      }|r`t        jp                  js                  |      \  t(        _'        t(        _=        t(        j|                  rFdt(        _>        tu        ddF       n,|r*t        jv                  jy                  |      t(        _'        t(        jN                  rut        jz                  xrD t        jv                  j7                  t(        jN                  jP                  j|                  G      }	t        jz                  r|	sdt(        _'        t(        jN                  rt(        jN                  jP                  j|                  t(        _(        dHd/t(        jN                  jP                  gg}t        jF                  j7                  |t        jX                  1      }dIt(        jP                   dJ}|ru|j~                  r&t(        j                  dI|jP                   dK       d}nt!        |dL      r|j                  rdI|jP                   dM}t(        j                  |       d}n|	r(t        |	t(        jN                  j                  N      }nt(        jN                  j                  r6t        t(        jN                  t(        jN                  j                  N      }n8t(        j                  j                  rt        t(        jN                  dO      } |        t         j                  j                  dP      xs@ t         j                  j                  dQ      xs t         j                  j                  dR      }dS }|r|jP                  j|                  t(        _(        t(        jN                  rJt(        jN                  j                  t(        _+        t(        jN                  j                   t(        _)        n"dt(        _+        |j                   t(        _)        dt(        _,        t        |       n|s |       r_t(        j                  }t                t(        jl                  rt(        j                  }dt(        _*        dt(        _,        t        |       n%dt(        _,        t        t(        j                         t(        j8                  xs t         j                  j                  dT      xsq t         j                  dUk(  xs[ t         j                  j                  dV      xs9 t         j                  duv xs$ t         j                  j                  dW      xs t         j                  j                  dX      xs t         j                  j                  dY      xs t         j                  j                  dZ      xs t         j                  d[k(  xs t         j                  j                  d\      xsd t         j                  j                  d<      xsB t         j                  j                  d       xr9 t         jb                  j7                  d]      d^k(  xr t         j                  d_k(  xs t         j                  j                  d`      xs t         j                  dak(  xs t         j                  j                  db      xs t         j                  j                  dc      xr t         j                  d_k(  xsS t         j                  j                  dd      xr t         j                  d_k(  xs | xrA t         j                  j                  de      xr  t        j                  j                         xs | xrA t         j                  j                  df      xr  t        j                  j                         xs t         j                  j                  dg      xr t(        jP                  xsX t        j                  t         j                        xs1 t         j                  j                  dh      xr t(        jP                  }t(        j                  }t(        j                  }tm        didBdC      }t        j                  j                           |        |s |       ryt(        jv                  djk(  rc|s(t(        jN                  rt        |      S t        |      S |j                  ss|j                  set        jz                  sSt               S t(        jN                  r|st        |      S t         j                  d=k(  rE|rC|j                  s6t        jz                  s%|j                  rti        dk      S ti        dl      S |st        dm      S |j                  st        jz                  st        dn      S t(        jX                  rt               S t(        jX                  sot        t        dod      r]|r[|j                  rNtm        dpdBdC      }t        j                  j                         sti        t                dq      S  |        t        j                  s*dt        _        tm        drdB      }t                 |        t(        jz                  r:tm        dsdBdC      }t(        jz                  j                         } |        |r|S yy# 1 sw Y   sxY w# t2        t4        f$ r Y Rw xY w# 1 sw Y   xY w)vuJ  
    Должны вернуть 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r4  )choicesr   0123456789abcdef   )r   c                 6    t         j                   |       z   S r"   )r   _nowoffsetr   s    r)   <lambda>z before_request.<locals>.<lambda>
  s    )9&)A A r*   c                 6    t         j                   |       z   S r"   )r   _daterM  s    r)   rO  z before_request.<locals>.<lambda>
  s    +;F+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=)dsnsend_default_piitraces_sample_rateCmfFullSearch)CmfUwsgiStatCollector)uwsgi_restarts)CmfCustomClasszDone first_request_init (pid=z%Already done first_request_init (pid=>qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789   r8  r2  zX-Eva-TokenAuthorizationzBearer tokenr9  )rX  expiration_datelast_used_atr   )r   
is_revokedr   r   z%Expired API token: expiration_date=%szToken expiredi  
text/plainrh  r   ==)rw  rd  Tfilterr   zAuth API Token (new)(z...): hash=z	, person=z, type=z6Invalid API token: request.headers=%s, request.args=%szInvalid API token  /pub/webhookr   zauth/not_authorizedz/auth/not_authorizedr1   next_urlauth/signin?uU   Требуется авторизация. Введите логин и пароль.z#before_request.get_auth_and_sessionr&  )track_ok_countsession_tokenaccess_token)after_hookssync)r  r  u   Учётная запись uQ    заблокирована. Обратитесь к администраторуu    заблокирована.r  uo    заблокирована за неактивность, обратитесь к администратору)r  )r  z/pub/pub_apiz/docsz/sharec                      t         j                  j                  d      xs t         j                  j                  d      S )Nr  /socket.io/)r  r  r   r@   r*   r)   is_allow_publicz'before_request.<locals>.is_allow_public  s2     LL##H- 6||&&}5	7r*   z/health_check/z/metricsz
/auth/syncz
/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.htmlz*before_request.CmfAccessList.setup_contextr4  r7  r5  u)   Требуется авторизацияu-   Доступ в раздел запрещен
CmfLicensez before_request.license_ui_accessznolicense.htmlz!before_request.prepare_plan_cachez#before_request.tfa_check_two_factorr"   )z/auth/invitez/auth/restore_password)r  methodallr   first_request_init_donefirst_request_init_skipre   r  first_request_init_lockr5  r6  r  r  cmf.util.cmfutilr   check_db_lockr  rl  r  before_requestr   re  rk  flagsremove_filesrc  rd  rx   testr4  r   rH  r&  r%  rN   r'  save_only_data_hackalertnoter  r  is_guest_useris_anonymousr  is_system_contextis_after_requestr  r  disable_notifyimport_modesession_tab_idcomponent_idinteractive_shellr  r  r  api_args
api_kwargsrA  	api_scoper  r  hack_session_need_commitr   r   r   r   rL  rP  rQ  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   deferred_force_show_progressbarr  jscache_timelifer  r  r  TEXCOM_ENABLE_GROWCACHE_HACKr  r  r  acquired_locksacquired_locks_shacquired_lock_timignsrp  fulltext_search_headlinesfulltext_search_debug_labelr-  project_perm_browse_cache%project_perm_timetrackerhistory_cacheshow_bg_progressbarapi_hack_fieldsr8   
new_acl_idapi_license_required license_disable_user_count_hooksbackbone_synccurrent_save_objects	csp_nonce'_essential_update_project_job__force_fg$_subtree_update_parent_job__force_fg
api_callidr   CmfDeferredJobinit_contextCmfAccessListr  r  r  r   r.  SENTRY_INIT
sentry_sdkinit
SENTRY_DSNr  r  r  app_init_aclapp_init_project_permissionWHATSAPP_MESSENGER_URLspawn_messenger_socketio_clientWHATSAPP_WEB_SOCKETspawn_whatsapp_socketio_clientADVANCED_METRICScmf.util.metricsrm  metricsMetricManagerspawn_gevent_workersr   rW  &gevent_bm25_stat_words_load_with_delayuwsgicmf.metrics.uwsgi_metricsrX  commonrY  increment_uwsgi_restart_counterImportErrorr  cmf.models.base_modelrZ  reload_modelsCSP_ENABLEDsampler  r   r&   r  
hash_tokenCmfAccessTokenr_  r7   r  r   rX  r   r  r   
CmfWebhookget_token_personauth_base_hrefr   check_sso_redirectr
   redirectrk  r   cookies
CmfSession
from_token
cmf_commitCmfAuthfrom_jwtIS_AUTHORIZATORr   r~  r  r  jwt_is_supportr  servicedesk_allow_auth_guestsjwt_is_match_orgrw  r  r  r  r   remote_addr	CmfPlugincheck_secretSTATIC_URL_REr  r  setup_contextreject_responser  r   ru  license_ui_accessr  prepare_plan_cache_doneprepare_plan_cachetfa_check_two_factor)r4  rH  r  r   r  rX  rY  rZ  auth_person	real_auth	api_tokenapi_token_hashrm  ri  r   qserr_msgr  rl  _filteris_force_publicrr  anon_personis_allow_without_authr   r   s                            @r)   r}  r}  n
  s    ~~"
''''''## 
 (( 	KLL/IIJ	K 2O%%'AAMAGANZZ^^L)S0AF&AKKKAM777#5;<AL!AAGAF AFAGAOANALAA"&A,0A)AAMAANA!&A!&AALAJAL/AK!AAI!%A""8#4#4#8#89AFAAEffkkmAGCAF  %AAKAOAOA!#A$&A!A$&A!A')A$!#A+-A(%'A"(+A%A AAAJAJ%*A"AA$&A!AA A$'EA!"$A$&A!A"$A.0A+AAAGAL!A)-A& AO UAAK05A--2A*AL
&&(
%%' 4 ||v&
 &&s/J/J	4RYY[MCD (( :	PGG7		}AFG..8QGH%%%OO"--)-+, $  >>)*557
 +-0035--24**+HH$$22GGI6?3((OOQ
 ..S5"BBD A ,,..2+7		}AFG?		}ANOu:	Pz ggfmm,lnpqr
 KI ||w'7<<+B+B9+M
 OO''6	++O<I''	2 )#i./ :I $I ))'2Y#--88CN "0044# L	 5 L //L4P4PS[SdSdShShSj4jOO$K\MiMij#mcUU %..22D$H[H[H^H^;_a{:|:=:S:S 3 UGG3IbqM?+nM]]fgrfssz  |H  |M  |M  {N  O  P  XZaZiZikrkwkwx"3cUU ||~%''88@Y@Y8Z ||."2!33FGHGLLLcLcdzL{'~~j1Hx(J12BN,-\">?AeG !F\abJ++O<**>: & 1 1 < <] KAFAI ))-2*u59^^,,\:AF66.._6>>3E3EAFFLLL^L^3E3_I %%i66ffll((AG $-/G !**..gcF_F_.`K4QWWI  >O  PG ,,GG:;;L;L:MMijk #'K[*?@[EdEd <[=N=N<O  P  @GGGG$"&K5iAFFLaLab&&5affI^I^_""@@5affTR L ll--n= -<<""7+-<<""8, 
7 ##))666600AL"#&&"9"99AO !AL"-"8"88AO $;'	O-&&!%%44K#;' #1==)
 FF G||&&9G ||*G ||&&5	G
 ||KKG ||&&5G ||&&)?AG ||&&)ACG ||&&)EGG ||!CDG ||&&)9;G ||&&)=?G ||&&0 7W^^5G5G5OSY5Y 7'';6G" ||&&6#G& ||!67'G( ||&&7)G, ||&&2Yw7J7Jk7Y-G. ||&&/VG4G4G;4V/G2 #"lw||'>'>'HlVM]M]MjMjMl3G4 #"lw||'>'>'HlVM]M]MjMjMl5G8 ||&&4@9G: ""7<<0;G> ||&&:FqwwC J 	
A	A !!MschiJ
&&(L  1	
	 vv&w//"7++,,[5K5KTZTjTj"$$ 
w''		[5K5KTZTjTj((l,,f&&JKK##F,B,B NOO	
		    ""wv|T'J{_j_u_u()KSafgJ$$668=?"3> BCCL &&&*#$%H#N
 	yy$%JC`ef
II**,H  i	K 	Kl $%89  Y:	P :	PsN    $A[5FA\2A\A9A\[5A[?\A\\A\\A\\A\\A\$c                     g dg}t         j                  dk(  r|j                  g d       t        j                  j                  |      }|r|j                  |       S y )N)disabledrd  Fr4  )servicedesk_supportrd  T)rf  )r   r  r   r   CmfAuthOpenIdPluginrx   login_redirect)ri  r  openids      r)   r  r    sU    ()G{{h:;''++7+;F$$X.. r*   c                    t         j                  dk7  st        j                  dk7  r`t	        j
                  dt         j                  t        j                  t        j                  t        j                  t        j                         t         j                  j                  dd      j                         j                  d      ryt         j                  j                  d      s2t         j                  j                  d	      st         j                  d
k(  rt        | xs ddd      S t        t         j                         }d|i}| rt#        | d       | |d<   t%        |      }d }|st'        |      }|sDt        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=%sz
User-Agentr   officez8EvaApp. MS Office blank page. Open this page in browser.rq  r8  rh  znot authorizedrg  rb  rc  ri  
auth_errormessager4  zservicedesk/auth/signin?rj  )r  r  r   r  r7   r  r  r  r  r  rx   lowerr   r   r   r   r<   r   r
   r  r  r  rk  )r  skip_ssori  paramsr  r   s         r)   r  r    sX   ||&!++*AXLL!&&!''1;;8I8I	K <,224==hGI LL##M2||&&w/||~-3#3S|TT%h''<( 'F9v"8,A{{h& 011I"NO 01bTBCr*   c                  T    t        j                          t                t                y r"   )r  r  emit_eventsemit_server_eventsr@   r*   r)   commit_with_eventr    s    Mr*   c           
         | ri t         _        y t         j                  d      sy t         j                  j                         D ]  \  }}d|v rd|d   v r|d   j	                  d       |d   rkt
        j                  j                  j                  |d         }|r=|j                         D ]*  }|d   j                  |j                  j                         , t        d|d    |d|j                  dd	      
        i t         _        y )Nr  relation_persons__DEFERRED_all_relation_personsr   is_changed-r   r1   r
  private)	namespacer
  )r   r  rx   r   rF  r   rm  rn  get_obj_by_idall_relation_personsr   r   r   r  )
only_cleanr   r   r   ps        r)   emit_list_applyr    s    55++##% 	o3$)JcRdNe)e"#**+LM4yhh&&44SY? 557 C./66qttzzBCS%6$78#SVSZSZ[aclSmn	o AKr*   c                    | j                         D ]  \  }}|D ]  }|d   }|d= t        |d         }|d= |d   j                         }	 t        j	                  |       t        j	                  |       t        j	                  |       t        |t              s! |j                  |g|d	   i |d
|d
   i |d   st        j                  d| d|        |d   r1|d   dk(  s)|d   |d<    |j                  |g|d	   i |d
|d
   i |j                  d      rT|d	   rOd|d	   d   v r|j                  |d	   d   d          d|d	   d   v r!|d	   d   d   D ]  }|j                  |        |D ]  }	t        |	t        j                  j                         r9t        j                  dd|	 d| d| d|        |	j"                  j$                  }
nt'        |	      }
|
|d<    |j                  |g|d	   i |d
|d
   i    y # t
        $ r-}t        j                  dd| d| d| d|        Y d }~(d }~ww xY w)Nsocket_clientr  r'   rE   uP   DEV: FATAL emit пришел с несериализуемыми данными z! socket_client:z; event_persons:z; event_param:r&   r  r
  u<   DEV: FATAL в emit не указана комната, msg: z; event_param: r
  r  event_current_personr   r  uY   DEV: INFO Кривой евент, в event_person попал объект, а не str: rF   )r   r   r  rk   rl   r  r7   r  r   r   r}   r\  r   r   r   r   r!  r   r   rI   )
event_dictmsgevent_param_listevent_paramr  r  emit_kwargsr   user_idevent_personevent_persons_strs              r)   emit_events_dictr    s   !+!1!1!3 8q+ 7	qK'8MO,O <=MO,%h/446K	

3

;'

;' m-?@"""3pV)<ppWbcnWopv& \]`\aapq|p}~ 6";v+>)+K&1&&9F#"""3pV)<ppWbcnWop~~l+v&-V1DQ1GG%))+f*=a*@AW*XY)[-@-CC'26':1'=>P'Q 7G)--g67 !. q lCJJ,@,@AMM))5auAk]!K=Z[ )5(=(=%(+L(9%&7F#"""3pV)<ppWbcnWopqS7	q8q  !!fghfi j&&3_4D]OSabmanpq s   ?H	I"IIc                      t        d       y )Nr   delay)emit_events_with_delayr@   r*   r)   r  r    s
    #r*   c                 (   | ri t         _        y dd l}t         j                  d      sy i }|j                  t         j                        D ];  }|j	                  d      st         j                  |   ||<   t         j                  |= = t        |       y )Nr   r  project_notify)r   r  r  rx   r   r  )r  r  r  r  s       r)   emit_project_eventsr#    sx    55!Myy) %>>*+!"!5M#$% ]#r*   c                      t        |       |ri t        _        yt        j                  d      xs i i t        _        r r fd}t	        j
                  |       yrt               yy)u   Запускаемся в контексте, но отправляем в отдельном таске вне контекста, после паузы, чтобы не держать запрос.r  Nr  c                  F    t        j                          t               y r"   )r5  r  r  )r  r  s   r)   emitterz'emit_events_with_delay.<locals>.emitter)  s    LL]+r*   )r  r   r  rx   r5  r6  r  )r  r  r'  r  s   `  @r)   r   r     sZ    z*EE/*0bMAO	, 	W	' 
r*   c                    | rg t         _        y t         j                  d      xs g }g t         _        |D ]S  \  }}t         j                  d| d|        t        j
                  j                  |t        j                  |             U y )Nr  zemit_server_events: r  )	r   r  rx   r8   r  r  rj   rk   rl   )r  r  r1  r7  s       r)   r  r  4  ss    EE/*0bMAO& :	&wir$89w

4(89:r*   c                  B    t        j                          i t        _        y r"   )r  rollback_all_dsr   r  r@   r*   r)   rollback_purge_eventr+  ?  s    AOr*   c                     | rg t         _        y t         j                  dg       D ]7  }t        j                  j                  |      s#t        j                  |       9 g t         _        y )Nr  )r   r  rx   rc  r  r   rF  )r  r  s     r)   apply_deferred_remove_filesr-  E  sN    EE."-  77>>(#IIh  ANr*   c                     t         j                  r/t        j                  j	                  t         j                  |        yy)u   Сессия может быть продлена через SSO, надо продлить куку

    Args:
        r (response): ответ браузеру в котором обновляем куки
    N)r   r  r   r  set_session_tokenr   s    r)   update_cookiesr1  P  s(     	yy((A6 r*   c                 J   t         j                  rt        j                  j	                  d      st        j                  j	                  d      r3dt
        j                   dt
        j                   d| j                  d<   y dt
        j                   d| j                  d<   y y )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:;)re   r  r  r  r   r   r  r  )rm  s    r)   set_csp_headersr3  Z  s    <<""#78GLL<S<ST\<]--.[[M :,,-KK= 9+, 67--.[[M :/0 67 r*   c                 L   t         j                  }t        j                  j	                  d      }t         j
                  r5|r3|j                  d      r|t        d      d  }|t         j
                  v r|}d| | j                  d<   d| j                  d<   d| j                  d<   y )NOriginhttps://zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)re   r  r  r  rx   CORS_ALLOWED_DOMAINSr   r   )rm  origin_domainrequest_origins      r)   rk  rk  s  s    OOM__((2N""~$$Z0+C
O,<=NV888*M8@6PH23;AH787LH34r*   c                     t        ddd       t        |        t        |        t        |        d| j                  d<   | S )uk   
    Запускается только если небыло ошибок
    :param r:
    :return:
    Tr   F)rn  event_delayro  byteszAccept-ranges)r  r1  r3  rk  r  r0  s    r)   acaor>    s;     4QU;1AQ!(AIIoHr*   c                  P   ddl m}  t        j                  sy t        j                  t
        _        t        j                  j                  j                         5  t        j                  j                  j                  j                          d d d         |         y # 1 sw Y   xY w)Nr   spawn_server_event_listener)cmf.cmf_server_event_listenerrA  re   r  DISABLE_PERMISSIONSr   disable_permissionsr   rm  rn  r  includer   r  load_acl_datar@  s    r)   r  r    sn    I$88C				%	%	' 9((6689  !9 9s   3BB%c                  ,   t        t        j                  j                  d      sy t        j                  j
                  j                         5  t        j                  j                  j                  j                          d d d        y # 1 sw Y   y xY w)NCmfProjectPermScheme)	r   r   rE  r   rm  rn  r  rH  load_project_permission_datar@   r*   r)   r  r    se    3;;%%'=>				%	%	' O//LLNO O Os   3B

Bc                     t        t        d      dk7  ry t        dd      } t        j                  j
                  j                         5  t        j                  j                         }t        j                  j                  |d         }|j                          d d d        t        j                  j                  dg      }|r |j                          |j                          g d	d
g d	g dgfD ]+  }|g dg}t        j                  j                  |g d       - t        j                   j                  dg      }|r |j                          |j                          t        j"                  j                  dg      }|r |j                          |j                          t        j$                  j                  dg      }|r |j                          |j                           |         y # 1 sw Y   YxY w)Nr  z/opt/eva-appr  i,  r   )r   r  )order_by)cache_action=r  OR)rL  rM  r  )	cmf_modelrM  CmfTask)json_filterjson_entry_pointjson_action	func_name	json_datare  )r   re   r   r   rm  rn  r  r   rP  create_dummy_taskrx   delete_dummy_tasksave_prepare_load_perm_fields
CmfTriggerr   r  
CmfComment	CmfNotify)r  dummy_task_data
dummy_taskr   _fr  cr  s           r)   r  r    s   v}%7 !!5s;J				%	%	' ' ..::<^^''?4+@'A
$$&' 	TF+A		 -t5RTs.tu /0b1}~ 	TF+A		v.A		tf-A		L=' 's   	AG22G<c                     t        |        y )Nr  )cmf_rollbackrb  s    r)   teardown_requestrd    s
    9%r*   c           
         |rt         j                  sy|"|rt        j                  nt        j                  }t
        j                  d| d|d|d||       ||t         j                   k(  ry|rFdj                  t        j                               }t
        j                  d|        t        |       | t
        j                  vr t
        j                  j                  |        yy)	   
    Глобальная функция для оповещения фронта о предупреждениях
    :param msg:
    :return:
    Nzcmf_alert: msg=z abort= debug_only= devel_only=r  r   zcmf_alert Stack:
)re   rf   r7   r)  r(  r   r8   re  rN   rb  format_stackr  r  r   )r  r  r   
devel_onlyr  	stack_strs         r)   r   r     s     &,,}#(gllGG#x*m
}EUGS*V5F5F1F"GIIi4467		$YK01C  
!''	s r*   c                     |rt         j                  sy|t        j                  }t        j                  d| d|d||       ||t         j                   k(  ry| t        j                  vr t        j                  j                  |        yy)rf  Nzcmf_note: msg=rg  rh  ri  )	re   rf   r7   r(  r   r8   re  r  r   )r  r   rk  r  s       r)   cmf_notern    s{     &,,}GGom
}Mj];5GI*V5F5F1F"G
!&&	c r*   r1   r
  )r  r  r
  r  c                   |st         }	 dt        vrt               t        _        t        |      dk(  r=dt        j                  xr$ t        j                  j                  j                  xs d ig}t        |d         t        k(  rgdt        v rt        j                  |d   d<   nd|d   d<   t        j                  xr$ t        j                  j                  j                  xs d |d   d<   t        ||||      }t        j                  |       ||d<   d	}	d
D ]  }
| j                  |
      sd}	 n |	rt        j                  dt!                      |s)t        j                  g}|	st#        dt!                       g }|D ]f  }t%        |t&        j(                  j*                        r&|j-                  |j                  j                         M|j-                  t/        |             h ||d<   t        j                  |d          t        j                  j1                  | g       }||vr|j-                  |       y y # t        $ r
}Y d }~y d }~ww xY w)Nr  r   rs   r  r   r  )r&   r'   r  r
  r  F)
zevent-zinvaldebug-ztask-comment-zaudit-task-comment-znotify-person-r	  zcomment-z	notify-osznotify-important-DEBUG_TuE   DEV: WARNING в cmf_emit_event не указали cmf_emit_event: %su   DEV: FATAL!!!!!!!!!!!!!! Добавьте меня в спринт Баги реактивности. 10.10.2022 в cmf_emit_event не указали cmf_emit_event: r  )r  r   rW   r  r   r   r  r   r   r   r  rk   rl   r   r7   r\  localsr   r   r   r   r!  r   rI   
setdefault)r  r  r  r
  r  r&   r'   r   event_paramsmuted
muted_debtr  r  
event_lists                 r)   r  r    s$     !#"fAO 4yA~$a&6&6&T1;K;K;N;N;T;T&\X\]^DG}q ()(8(8DG$%(*DG$%*+*:*:*Xq?O?O?R?R?X?X*`\`Q&'T&IDQLJJ|$1L!Ep 
>>*%E	
 ]_e_gh))*UU[U]T^`a
 % 8lCJJ$8$89$$\__%:%:;$$S%67	8 %6L! 	JJ|O,-++C4J:%,' &c  s   H? ?	IIc                    |rdj                  |      nd}|rdnd}	|rdnd}
dj                  |	|| |
      g}|rddlm}  |       }t        j                  |dt        j                  t        j                  	      }|r|j                         \  }}|r |j                         }|j                         }|j                  }|rR|rPt        j                  d
|       t        j                  d|       t        j                  d|       t        d|       |g}|r#|j                  |       |j                  |       n|j                  |xs |       |r|j                          z
         |S y)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   rG  T)shellstdoutrh   u6   Произошла ошибка при вызове %sz
STDOUT: %sz
STDERR: %su4   Произошла ошибка при вызове rE  )r  r4  
subprocessPopenPIPEcommunicaterw   
returncoder7   r\  RuntimeErrorr   )commandsudor  waitseparate_out_and_err	do_decodedo_raisemeasure_runtimetimeout_cmd_sudo	_redirectcmdr4  popen_startprocessouterrerrcoder  s                      r)   run_bash_commandr  E  sM    9@$++G4SKH#E+I>EE	 	C Fs$&0oo&0oo7G &&(S**,C**,C$$xMMRTWXMM,,MM,,!UVYUZ[\\iJJsOJJsOJJszc"JJtvk)*
r*   c                 (   t        j                  t        j                        }t	        j                         }|j                  | j                                |j                  |      }t        j                  |      j                         }|  d| }|S )ua   
    Подписываем токен сертификатом
    :param jwt:
    :return:
    r.   )r   r   r   rsa_private_keyr   r(  r   signbase64	b64encoderw   )jwtsignerdigestr  r   s        r)   rsa_sign_pack_jwtr  z  sp     ^^C//0FZZ\F
MM#**,;;vDD!((*DE4&/CJr*   c                 *   ddd}t        j                  t        j                  |      j	                               j                         }t        j                  t        j                  |       j	                               j                         } | d|  S )uD   
    Создаем токен
    :param payload:
    :return:
    RS256JWT)algtypr.   )r  r  rk   rl   r   rw   )payloadheaders     r)   
create_jwtr    su     U+Fdjj0779:AACFtzz'299;<CCEGXQwi  r*   c                  "    t         j                  S )u2   
    Текущая версия
    :return:
    )re   CMF_VERSIONr@   r*   r)   cmf_get_versionr    s    
 r*   c                 h    | t         j                  vr t         j                  j                  |        yy)ux   
    Удаления файлов после коммита транзакции
    :param filename:
    :return:
    N)r   r  r   )r  s    r)   cmf_remove_filer    s'     q~~%	h' &r*   c                     t         j                  sy t         j                  j                  d      ry dt         j                  j                   dt         j
                   } t        j                  j                  j                  |       }|rSt        j                  j                  j                  |        t        |j                         j                  dd             y y )Nfield_options_list
DEFERRORS_r   r   z<br>)r   r  r   r   r   r  r   r  r  rx   r{   r   rw   r   )	redis_keyr\  s     r)   _deferred_errors_checkr    s    <<||12Q^^../q1A1A0BCILL""9-E!!),%,,.((v67 r*   c                    t         j                  j                  d       dt        j                   d}|t        j                         z  }dt        j                  j                   dt        j                   }t         j                  j                  j                  |      }|r|j                         dz   |z   }n|}t         j                  j                  j                  ||       y )Nr   uL   Ошибка в after_request, после выполнения метода z

r  r   z


)r   r  r  r   r  rb  rg  r   r   r  r  r  rx   rw   r   )r   r  r  r\  s       r)   _deferred_errors_saver    s    JJ%XYZYeYeXffj
kC9!!CQ^^../q1A1A0BCILL""9-E)C/LL9e,r*   c                    t        j                  |        ddlm} |j                  j                  d       t        |j                  d      r|j                  j                  d       t        |j                  d      r|j                  j                  d       t        t        d	      rJt        j                  r:t               s0t               5  |j                  j                  d       d d d        n|j                  j                  d       |j                   j#                  d       t        |d
      r|j$                  j'                  d       |j(                  j+                  d       t-        d       t/        d       t1        d       t3        d       t5        d       g t        _        t9               t        _        y # 1 sw Y   xY w)Nrb  r   r   Tr%  (apply_deferred_hide_closed_task_notifies)rollback"apply_deferred_update_task_projectr  CmfStat)r  r  cmf.includer   r\  apply_deferred_notify_messagesr   rP  r  r  r   r  r   cmf_contextCmfAuditapply_deferred_auditrW  apply_deferred_dirtyr  apply_deferred_statsr[  !apply_deferred_comment_audit_listapply_deferred_jobsr#  r   r  r-  r  r   r  )r  r   s     r)   rc  rc    se   y)" 33t3Dv~~HI???Nv~~BC9949H/0))!] 	@OO00$0?	@ 	@ 	,,d,;
--->vy!++t+<
7747H4(4(d+$'40!#A(+A%	@ 	@s   GGc           	      ^   |dk(  rit         j                  st         j                  dvrGt         j                  s7t         j	                  dt         j                  dt         j                         t        j                          | r(t        j                         }ddlm	} t        j                          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         j0                  |d<   g t         _        t         j2                  |d<   g t         _        t         j4                  |d<   t7               t         _        t9        |j;                               }|r|rTt=        dt         j>                  j@                  t         jB                  t         j                  t         j                  |fi | nbtE        jF                  t<        dt         j>                  j@                  t         jB                  t         j                  t         j                  |fi | t        j                          t        j                         |z
  dkD  r,tI        jJ                  dt        j                         |z
         y y y )NT)r>  r=  uS   DEV: не применяется after_request в API запросе: g.api_method=z g.api_scope=r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  F{Gz?z"PROF cmf_commit after_hooks got %s)&r   r  r  r  r8   r  r  r4  r  r   r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   anyr   cmf_commit_after_requestr   r   r  r5  r6  r7   rq  )rn  r<  ro  prof_str   after_request_params
need_spawns          r)   r  r    s   t|<N)NXYXjXj	fYZYeYeXgguijitithvwx))+&'')  ";<;U;U78%'"EFEiEiAB/1,676K6K23 ">?>[>[:;(*%ABAaAa=>+-(454G4G01 121A1A-.>?>[>[:;(*%?@?]?];<)+&01_-,-KK[)01_-/0~~^,;<;U;U78%'"BCBcBc>?,/E)-4467
 (0A0A1CSCSUVUaUacdcncn%?)=? 5tQ^^=N=NPQP`P`bcbnbnpqp{p{%?)=?
 	99; 4'LL=tyy{W?TU (k r*   c                    t        j                  d       t        j                         } G d d      }| rt        }n|} |       5  	 | rLt	        t
        j                  j                  |t        j                  j                  j                               dt        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |	t        _        |
t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        |t        _        t
        j@                  jC                          tE        t
        jF                  d      rt
        jF                  jI                          t
        jJ                  jM                          t
        jN                  jQ                          t
        jR                  jU                          tW                tE        t
        d      rt
        jX                  j[                          t
        j\                  j_                          tE        t
        jF                  d      rt
        jF                  ja                          tc                te        |	       tg                ti                | rtk        jl                          t        j                         |z
  d
kD  r-t        j                  dt        j                         |z
          d d d        y # tn        $ r}tq        |       |d }~ww xY w# 1 sw Y   y xY w)NzRun cmf_commit_after_requestc                       e Zd Zd Zd Zd Zy)5cmf_commit_after_request.<locals>.DummyContextManagerc                      y r"   r@   rm   s    r)   r$   z>cmf_commit_after_request.<locals>.DummyContextManager.__init__4      r*   c                      y r"   r@   rm   s    r)   	__enter__z?cmf_commit_after_request.<locals>.DummyContextManager.__enter__6  r  r*   c                      y r"   r@   )r%   exc_type	exc_valuerb  s       r)   __exit__z>cmf_commit_after_request.<locals>.DummyContextManager.__exit__8  r  r*   Nr5   r3   rB   r$   r  r  r@   r*   r)   DummyContextManagerr  3  s    			r*   r  r   Tr  r  r  r  r  z"PROF cmf_commit_after_request got )9r7   r8   r4  r  r  r   r  rx   r   r#  r   r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r\  r  r   rP  r  r  r  rW  r  CmfOrmColumnHistoryapply_deffered_history_columnsr  r  r  r[  r  r  r#  r   r  r-  r  r  r   r  )is_gevent_forkcurrent_user_idr  r  r  r<  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  after_request_prof_str  contextr   s                            r)   r  r  #  sV    MM01 IIK  %	 10	"6#3#3#7#7PSPWPWP[P[PqPq#7#rs!%A-A%AL#AK)AA&3UA0$7A!,GA)/MA,"3A-A,GA)-IA*+AO#AK+AO)AN)AA&0OA-;;=v~~&PQGGIOO002  557&&EEG!vy)335??Av~~&JKAAC!"5 ')  "yy{22T9<TYY[K`=`<abc]1 1^  	!!$G	_1 1s+   MK$L55	M>MMMMrN  c                     ddl m} | xs d} t        |      }|j                  dddd      }| j	                         r$| j                  d      j                         r| dz  } | ||       z   }t        |      S )Nr   rD  r   hourminuter   r   +-r  )r{  r   _ensure_localr   r  lstripisdigit_to_utcrN  r   r   
base_localstart_locals        r)   start_of_dayr  t  sr    1\rFt$J$$!AaQ$OK||~&---557# 0 88K;r*   c                     ddl m} | xs d} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                  dddd      }| ||       z   }t        |      S )	Nr   rD  r   r  r     ;   r  r{  r   r  r  r  r  r   r  )rN  r   r   r  	end_locals        r)   
end_of_dayr    sr    1\rFt$J||~&---557#""2aQ"OI,V44I9r*   c                 8   ddl m} | xs d} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                         dz   dz  }|t        |      z  }|j                  dddd	      }| ||       z   }t        |      S )
Nr   rD  r   r  wr   r   r   r  
r{  r   r  r  r  r  weekdayr   r   r  )rN  r   r   r  days_since_sundayr  s         r)   start_of_weekr    s    1\rFt$J||~&---557##++-1Q6)!233J$$!AaQ$OK 0 88K;r*   c                 x   ddl m} | xs d} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                         dz   dz  }|t        |      z
  j                  dddd	      }|t        d
      z   j                  dddd	      }| ||       z   }t        |      S )Nr   rD  r   r  r  r   r   r   r  rJ  r  r  r  )rN  r   r   r  r  week_start_localweek_end_locals          r)   end_of_weekr    s    1\rFt$J||~&---557# $++-1Q6"Y4E%FFOOq P  ')::CC1! D N $&6v&>>N>""r*   c                     ddl m} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                  ddddd      }| ||       z   }t        |      S )Nr   rD  r  Mr   dayr  r  r   r   r  r  s        r)   start_of_monthr    sl    1t$J||~&---557#$$1QTU$VK 0 88K;r*   c                 J   ddl m} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                  ddddd      }|t        d      z   }|t        d      z
  }|j                  d	d
dd      }| ||       z   }t        |      S )Nr   rD  r  r  r   r  )monthsr   r  r  r  )
r{  r   r  r  r  r  r   r   r   r  )rN  r   r   r  start_month_localnext_month_locallast_day_localr  s           r)   end_of_monthr    s    1t$J||~&---557#"**qq1Z[*\(=+BB%	q(99N&&Br!QR&SI,V44I9r*   c                     ddl m} | j                         r$| j                  d      j	                         r| dz  } t        |      }|j                  dddddd      }| ||       z   }t        |      S )Nr   rD  r  yr   monthr  r  r  r   r   )r{  r   r  r  r  r  r   r  r  s        r)   start_of_yearr    sn    1||~&---557#t$J$$1!!Aa]^$_K 0 88K;r*   c                    ddl m} t        |      }| j                         r$| j	                  d      j                         r| dz  } |j                  dddddd      }|j                  ddd	d
dd      }| ||       z   }t        |      S )Nr   rD  r  r   r   r        r  r  r  )rN  r   r   r  start_year_localend_year_locals         r)   end_of_yearr	    s    1t$J||~&---557#!))qqSTbc)d%--BBRPR[\jk-lN#&6v&>>N>""r*   r   rD  c                     t         j                   j                         j                         }|j                  }| |S | j                  | j	                  |      S | j                  |      S )uP  Возвращает datetime в локальной зоне сервера (aware).

    - Если base=None, берём текущее локальное время.
    - Если base naive, присваиваем локальную зону.
    - Если base aware, конвертируем в локальную зону.
    rQ  )r   r   r   rQ  r   )r   	local_nowlocal_tzs      r)   r  r    sa     !!%%'224IH|{{||8|,,??8$$r*   dtc                     | j                   F| j                  t        j                  j                         j	                         j                         } | j	                  t        j
                  j                        S )un   Переводит aware datetime в UTC (aware). Для naive сначала делает локальным.r  )rQ  r   r   r   r   r   r   )r  s    r)   r  r    sU    	yyZZx00446AACJJZK==**..//r*   c                   "    e Zd ZdddZd Zd Zy)r  Nc                 T    t         j                  d      | _        || _        || _        y )Nr<  )r   test_request_contextctxinit_views_and_dspreprocess_request)r%   r  r  s      r)   r$   zcmf_context.__init__  s$    ++O<!2"4r*   c                 r   ddl m}  |       rt        d      | j                  rt	                t        j                          | j                  j                          	 | j                  rt        j                          y y # t        $ r-  | j                  j                  t        j                            w xY w)Nr   )r   u;   Контекст нельзя включать дважды)r  r   r   r  start_viewsr  init_dsr  r  r  r   r  rg   exc_info)r%   r   s     r)   r  zcmf_context.__enter__  s    )YZZ!!MJJL	&&&&( ' 	DHHs||~.	s    B   6B6c                     	 |rt        |       nt        d       | j                  j                  |||       y # | j                  j                  |||       w xY w)Nrb  T)rn  )rc  r  r  r  )r%   excr   rb  s       r)   r  zcmf_context.__exit__  sG    	5s+t,HHc5)4DHHc5)4s	   ; A)FTrC  r  r@   r*   r)   r  r    s    5
"5r*   r  c            
      8   g d} t        j                  | D cg c],  }t        j                  t        j
                   d| d      . c} }|D ]  \  }}}|j                  t        j
                  d      }|j                  d      s9|D ]  }|j                  d      s|j                  d      s&|j                  d	      r8d
j                  d |j                  d      D              }t        j                  |d
z   |j                  d
      d   z   d          t        j                  ddt               t        j                  ddt               t        j                  ddt               t        j                  ddt               t!                y c c}w )N)z	cmf/viewszcmf/modulesr  moduleszcustom/commonzcustom/modulesr1   T)followlinksr   z/viewsz.pyz.pycz__init__.pyr.   c              3   &   K   | ]	  }|s|  y wr"   r@   )rJ   r   s     r)   rL   zstart_views.<locals>.<genexpr>#  s     *NA1*Ns   r   )packagert  )r-   	view_funcz/<path:req_filename>distz/static/<path:req_filename>staticz,/plugins/<plugin>/static/<path:req_filename>plugins_static)	itertoolschainrc  walkre   r  r   r   r   rN   r4   	importlibimport_moduler   r6   r  app_before_run)r  
search_dirsearch_iterdirnamedirnames	filenamesr  r:   s           r)   r  r    sw   fK//%$' 	6%%&a
|4$G$' (K )4 f$9//&"4"4b9H%% f%%e,0A0A&0IS[SfSfgtSu"%((*NgmmC6H*N"NK++K#,=s@STU@V,V`d+eff S6[A+fT%K   CN^juv/$'s   1Fc                       y r"   r@   r@   r*   r)   r*  r*  5  s    r*   c                 <   |j                  dd       ||d<   ||d<   t        t        j                  j                        |d<   t        j
                  |d<   t        j                  |d<   t        j                  |d<   t        j                  j                  | |g       y )	N	countdownr   r&   r'   g_current_user_idg_acl_admin_modeg_component_idg_session_tab_id)
rr  rI   r   r   r   acl_admin_moder  r  r  r   )jobr&   r'   r=   s       r)   schedule_deferred_jobr9  9  s     {A&GFOGH#&q~~'8'8#9G "#"2"2G !G"#"2"2GW~.r*   c                 X   | rg t         _        t               t         _        y t         j                  sy t         j	                  dt        t         j                         d       t         j                  D ]  \  }} |j                  di |  g t         _        t               t         _        y )Nz	Schedule z deferred job(s)r@   )r   r  r   r  r8   r   apply_async)r  r8  r=   s      r)   r  r  G  s     ,/E)GGiA//011ABC++ #W"'"#A(+A%r*   c                  \    d } t         j                  rt        j                  | dg       y y )Nc                     i }t         j                  j                  dd       rdt        j                  i}t
        j                  t        j                  | |       y )NSOCKETIOr
  
namespacesr  )rc  rd  rx   re   ORG_NAMEwhatsapp_sioconnectr  r?  s     r)   messenger_connectz:spawn_messenger_socketio_client.<locals>.messenger_connectV  sH    ::>>*d+v/GV::(2G 	 	Er*   z	/whatsapp)r@  )re   r  r5  r6  )rD  s    r)   r  r  U  s)    E $$&K=A %r*   c                  h    t        j                  t        j                  t        j
                         y r"   )r5  r6  whatsapp_go_siorC  re   r  r@   r*   r)   r  r  a  s    
LL((&*D*DEr*   c                      dd l } t        j                  ddt        j                   dt        j
                          | j                  t        j                  t        j
                  ddd       y )Nr   rE   uY   Подключаемся к удаленной отладке config.REMOTE_DEBUG_SERVER=z config.REMOTE_DEBUG_PORT=TF)rY  stdoutToServerstderrToServersuspend)pydevd_pycharmr7   rq  re   REMOTE_DEBUG_SERVERREMOTE_DEBUG_PORTsettrace)rK  s    r)   cmf_pycharm_debugrO  e  sh    LL''-'A'A&B
$V%=%=$>	@A
 F66V=U=Ufj+/  @r*   c                  N   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)rW   re   r  rA  rI   r   r4  r   r  r   r  r  )r  r  s     r)   gen_eva_app_tokenrW  p  si    v"OO3tyy{+,3tyy{R/0199??G W
CS!!r*   urir7  c                 L   ddl m} t        j                  sJt	        t
        j                  |d         }|j                  dg       }|j                  di       } ||i |}n |       }dddd	|_        t                |  }t               |d
<   |j                  |t        j                  |            }	|	j                  dk7  r(t        d| d|	j                   d|	j                          |	j                         }|rd|v rt        d|       t"        j%                  |       |S )Nr   )r  rv  r&   r'   rd  rb  r'  )zContent-typeAcceptzContent-Encodingeva_app_token)r7     u9   Не удалось отправить запрос, url=z, status_code=z, res=r\  u(   Сервер вернул ошибку: )requestsr  re   EVA_ACCOUNT_USEr   r   r  rx   r  r  rW  postrk   rl   rj  r   contentr   r8   )
rX  r7  r  rv  method_argsmethod_kwargsresultr   r<   r   s
             r)   call_eva_accountrd  |  s0    !!h8hhvr*2.66I%7*(/1	  !"3%( 1 3_ffStzz$/f0??c!KC5P^_b_n_n^oouvy  wB  wB  vC  DE Eg'FvhOPPGGFOMr*   eva_db_upgrade_runningc                     | st        t        j                               } t        t        d      st
        j                          t        j                  j                  t        | dd      st        dt               y)u   Запускается перед миграций БД. Информирует приложение, что не следует открывать транзакции.r     T)exr  zCannot lock N)rI   rc  r.  r   r  r  r  r  r   _DB_LOCK_KEYCmfError)r   s    r)   app_db_upgrade_startrk    s^    BIIK 8W%))+>>lEbTBl^455 Cr*   c                  J    t         j                  j                  t               y)u   Запускается после миграций БД. Информирует приложение, что можно продолжать работать.N)r  r  r{   ri  r@   r*   r)   app_db_upgrade_stoprm    s    NN,'r*   c                     d }d}t        j                          } |       rS| rt        j                          |z
  |kD  r|rt        dt               y|dz  }t        j                  d        |       rSy)u   Проверяем не заблокировано ли использование БД, если заблокировано, то можем дождаться разблокировки.c                     t         rt        j                         t         z
  dkD  r[t        t        d      st        j                          t        j                  j                  t              a	t        j                         a t        S )uW   используем кеш 1sec, чтобы часто не ходить в редисr   r  )
_db_lock_cache_tsr4  r   r  r  r  r  rx   ri  _db_lock_cacher@   r*   r)   
check_lockz!check_db_lock.<locals>.check_lock  sX     !TYY[3D%D$I 8W-&113%^^//=N $		r*   r   z
DB locked Fr   T)r4  rj  ri  r  )r  r  raise_errorrr  rq   starts         r)   r|  r|    sk    
 EIIKE
,		e+w6L>:;;


1 , r*   c                      dd l } t        j                  rd}nt        j                  } | j                  |d        | j
                         }|j                  |       y )Nr   rf   z:%(asctime)s %(process)d %(name)s %(levelname)s %(message)s)r  r  )logging.handlersre   rf   	LOG_LEVELbasicConfigr  r'  )r7   r  r  s      r)   init_loggingry    sK    ||  Ge,hiW F
OOEr*   c                 *   t         j                  rt         j                  }n[| r@|rd}n=t         j                  rdt         j                   nd}dt         j                   | }nd}|t         j                  xs dz  }|j                  d      s|dz  }|S )Nzhttp://127.0.0.1:8080r   r   r6  r1   )re   AUTH_SERVER_URLr  r  r  r   )absoluteinternalr  r  s       r)   r  r    s    **	3	@F@Z@Za : :;<`b	&v&7	{C	IV%%,,	c"S	r*   r  )Fhttps)r  rg  )FFr"   r  rF  )r   F)FFNN)FNN)TNTFFFF)T)Tr   TrE  )T   T)atexitr"  r%  r7   r   rg   fcntlrc  r  r  r   ry   rz  r4  rb  	threadingr  r   r   pathlibr   typingr   r   urllib.parser   r	   r
   r   werkzeug.utilsr   r5  r   r  Crypto.Hashr   Crypto.Signaturer   r  r   r   r   flask.json.providerr   werkzeug.exceptionsr   r   r   r  cmf.data_providersr   r  cmf.system_datar  dateutil.relativedeltar   r   r{  r   r   cmf.metricsr   r   r   r  r  r    rQ   objectrS   rL  r5   re   r  r   rk   r  r  r  rD  cache_in_project_roler  
rpc_modelsclean_attributesry  rx  Lockrz  all_models_meta
SECRET_KEY
secret_keymetrics_cacheflask_socketiorZ  r[  r  r\  r  rI   r~  rz  r  r  r  r  r  r  r  r  engineio.payloadr  max_decode_packetsr  r   rd  rx   uwsgidecoratorsr^  r  rf   rB  rF  r  r   r  r9   r  r  rA  REDIS_DB_IDREDIS_DB_ID_TIMERerrorhandlerr   ro  register_error_handlerprivate_key_pathpublic_key_pathCrypto.PublicKeyrq  
import_key
read_bytesr  rsa_public_keyr  r  r  r  r  r  r   r  r  r  propertyr   r   r   r   r  r  r  r  r8   rA  r}  r  r  r  r  r  r  r#  r   r  r+  r-  r1  r3  rk  after_requestr>  r  r  r  rd  r   rn  r  r  r  r  r  r  r  r  rc  r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r*  r9  r  r  r  rO  rW  rW   rd  cache_notify_scheme_rulecache_cmf_security_levelcache_person_notify_optcache_cust_field_config_schemecache_email_listr  ri  rq  rp  rk  rm  r|  ry  r  r@   r*   r)   <module>r     s        
  	          0  "  = = $     ' 2 2 3 -   )  	 0  > ( % ( 

  f  gE ,B
wDv wDv/6, 6* HDF4F4FGc"   *+

& ' #  " # ,inn.  ""  .  A AH  ) 
  [,8E% E%P !"o. o.d ./ 3 J	 %  zS zSz  ::>>#$(, , V\\*- 77>>&$$'99:	f  #55	6 +!&&(..*+   ) D   9&6 7**+i7 v))*]:  (#..)9)D)D)FGC'(B(B(DEC "_D &   $  @D> !/Q }-Q !.1Q #+,D#EQ  "?3Q !.1Q /Q 7#Q3 #?3Q  j)Q =><  t NB, N Nb/*Z&9qx$$(*:702M    
"O&R & &4* *-Dy`b :(z in5:2j	!(8
-.@;V|Nb
  
 
s 
 #  # #(	 3 	  	 # 	 
# 
#%(9(9: %x?P?P %0!! 0h&7&7 05 5B8	/.	BF@	"3 	"# T 4  " !   %' "  ( 	6(
6SB+ +s   $Y::Z