B
    fuo                @   s$  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZmZ d dlmZ d dlmZmZmZ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 d dlmZ d d	l m!Z! d d
l"m#Z# d dl$T d dl%m&Z' d dl(Z"d dl)Z)e)*dZ+G dd de,Z,dd Z-G dd de.Z/dd Z0G dd deZ1e,e2de3j4dZ5e1e5_6de5_7de5_8g e5_9de5_:d e5j3d< i e5_;de5_<i e5_=de5_>d dl?m@Z@mAZA d dlBmCZC d dlBmDZD d dlEZEi e5_FeGdd d!ZHeHe5_Hdd#d$ZIG d%d& d&ZJeJ ZKeLe3d'rle3jMd( d) d*krle3jMd( N ZOeOPd) d+eOkr^eOPd+ eEjQf eOeK_EeRjSTd,reKjEdkreUd-e5d.e3jVdd/ZWeLe3d're3jMd( d) d*kre3jMd( d0 ZXe3jMd( Td1rd2e3jMd( d1  d3eX ZYeCeYd4dd5ZZeZeWd6< nd7Z[d8e3jMd( kr6e[e3jMd( d8 7 Z[d9e3jMd( kr`e[d:e3jMd( d9  d;7 Z[e[e3jMd( d< 7 Z[e[d:e3jMd( Td=d> 7 Z[e[d?eX 7 Z[e[eWd@< d dAl\m]Z] dBe]_^e@f eWZBeDe3jVdCZ_eDe3jVdCZ`eRjabe3j4dD rece3j4dD Zdede f e3_gW dQ R X eLe3d'rle3jMd( d) d*krBe/eKjEdEZhn(e3jMd( d) dFkrbe/ddGZhneUdHne/ ZheKe5_Kde5_id e5_je5keUdIdJ Zle5meUel ee3j4dK Znee3j4dL Zod dMlpmqZq enb reqrens e5_teob reqreos e5_udNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbge5_vdcdd Z7dedf Zwdgdh Zxdidj Zydkdl Z8de5_zde5_{de5_|dmdn Z}dodp Z~dqdr Zee7ee_7ee7ee_ee}ee_}ee~ee_~eeee_eeyee_yeeyee_ee8ee_8dsdt Zeeee_dudv Zeeee_ddydzZdd{d|Zddd}d~dZdd Ze5jdd ZdddZdddZdd Zdd Zdd Zdd Zdd ZdddZdd Zdd Zdd Zdd Ze5jdd Zdd Zdd Zdd Ze5jdd Ze5jdddZdddZdddZd?ddg dddZdddZdd Zdd Zdd Zdd ZdddZdddZG dd dZdd ZddÄ ZdddńZddǄ ZddɄ Zdd˄ ZeGd̜dd΄ZeGedϜddфZi e5_i e5_i e5_i e5_dZdadadddԄZddք ZdddلZddۄ ZdddބZdddZdS )    N)OrderedDictdefaultdict)Path)urlparseparse_qs	urlencodequote)SHA256)
PKCS1_v1_5)Response)JSONEncoder)HTTPException)fields)*)basez^.*\.(png|jpeg|ico)|^(/plugins/|/sso/|/drawio/|/pub/|/docs/|/share/|/files/|/tinymce/|/app/assets/|/socket.io/).*|^.*/forms/CmfForm:.*|^.*(styles|vendor|runtime|polyfills|main).*\.js$|/styles.*\.css$c                   s$   e Zd Z fddZdd Z  ZS )Flaskc                s   t  j|| d S )N)super__init__)selfargskwargs)	__class__ ./cmf/app.pyr   &   s    zFlask.__init__c                s    fdd}|S )Nc                sn     dd }| j}|dd }|dkr6d|  }n}|d krP|d | j }j||| f  t| | S )Nendpoint.index/)pop
__module__split__name__add_url_ruleprint)fr   module_pathZmodule_nameurl)optionsruler   r   r   	decorator*   s    zFlask.route.<locals>.decoratorr   )r   r)   r(   r*   r   )r(   r)   r   r   route)   s    zFlask.route)r"   r    __qualname__r   r+   __classcell__r   r   )r   r   r   %   s   r   c             O   s$   | r t dddd |D  d S )Nz%s c             s   s   | ]}t |V  qd S )N)str).0argr   r   r   	<genexpr>=   s    zprint_debug.<locals>.<genexpr>)loggingdebugjoin)Zcondr   _kwargsr   r   r   print_debug;   s    r7   c               @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
daddddZdd Zdd	 Zd
d Zdd ZdbddZdd Zdd Zdd Zdd ZeeedddZeedddZedcddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Z ddd.d/Z!d0d1 Z"d2d3 Z#d4d5 Z$ded6d7Z%d8d9 Z&d:d; Z'd<d= Z(d>d? Z)d@dA Z*dBdC Z+dDdE Z,dfdFdGZ-dgdIdJZ.dKdL Z/dhdMdNZ0dOdP Z1e2dQdR Z3e2dSdT Z4e2didUdVZ5ee6dWdXdYdZ Z7e2d[d\ Z8e2d]d^ Z9e2d_d` Z:dS )jCmfCacheNF)returnc             C   sH   t  | _t  | _|| _|| _i | _| jrD| jdd | jdd d S )Nstat_hitr   	stat_miss)dict	cache_objcache_invalidateredis_dbmemoryZtexcom_growcache_hack_cacheincrby)r   r?   r@   r   r   r   r   M   s    zCmfCache.__init__c             C   sj   t tjp| jdtjd | jr*| j  nt | _t | _	| j
dtd  | j
dtddi d S )NzCmfCache.flushdb!!!)filezCmfCache:flushdbzCmfCache:inmemory_delkeysALL)r7   configDEBUGsysstderrr?   flushdbr<   r=   r>   publishjsondumps)r   r   r   r   rI   X   s    zCmfCache.flushdbc             C   s   t tjp| jdtjd tt}| j }x| jj	dddD ]p}t | jd| dtjd |dd	 
 }| j|}|d	krq<t|}|d
 }|d || |< || q<W |  | | d	S )u)   Инвалидируем весь jscachezCmfCache.flush_jscache!!!)rB   zobj:jshash:*i  )countz"CmfCache.flush_jscache invalidate z!!!   Ncurrent_person_idjsver)r7   rE   rF   rG   rH   r   r<   r?   pipeline	scan_iterdecodegetpickleloadsdeleteexecuteemit)r   emit_msgpipekeyjshashjsresjspersonr   r   r   flush_jscacheb   s    

zCmfCache.flush_jscachec             C   s   t tjp| jdtjd d}| j }x6| jjdddD ]"}|drHq8|d7 }|	| q8W |
  t tjpr| jd	| d
tjd dS )u+   Инвалидируем весь obj cachezCmfCache.flush_all_obj!!!)rB   r   zobj:*i  )rM   s
   obj:jshash   zCmfCache.flush_all_obj: z recordsN)r7   rE   rF   rG   rH   r?   rQ   rR   
startswithrW   rX   )r   rM   r[   r\   r   r   r   flush_all_objt   s    

zCmfCache.flush_all_objc       	         s  dd l dd l}dd lddlm ddlm  |} fddtjr	t
tjj tjdd dd   d d	 d
kr| }|dkrtjrtjtjkrtjj S x|D ]}|d | }qW d|kr|d t
|d  }x@t| D ]0\}}|dkrq|d | d | }qW | jr~d|dd  d 	|   }|dd}|dd}n| d	|   }t| jd| |S )Nr   )timezone)ImmutableDictc          
      s  t | }t|tjjr4| jr,| j} t | }nd} t}d}|ttt	fkr|tkr| dd dkry8j
| }|j}|jddd}|} td|  W n" tk
r } zW d d }~X Y nX t| }n|tkrx| D ]}|| d }qW n|tks| krBx|  D ]4\}}|| }|r2| d	| }n|d }qW n^| d krRd
}nN|tkrft| }n:t| dr~t| j}n"d|j d	 t|   }|S )Nz... r      Z20)secondZmicrosecondz!!!!! Date:,:Noneidz
todo2:obj:)type
issubclasscmfr   CmfType
is_definedvaluer/   intfloatparserparseZ
astimezoneutcreplacer$   	Exceptionlistr<   itemsboolhasattrrl   r"   md5rU   rL   	hexdigest)valtresZval1evk)re   _all2strdateutilhashlibrd   r   r   r      sH    





"zCmfCache.hash.<locals>._all2strZ   )ZdaysrN      )Zc92a103Zd860eddgUUUUUU?|rl   z|id:rj   zHASH:i  z|md5:
r.   _zDEBUG_CACHE HASH:)r   randomZdateutil.parserdatetimerd   Zwerkzeug.datastructuresre   APPcache_optimizer~   r/   ro   r   CmfDatenowZ	timedeltaencoder   gcurrent_usersystem_usersortedr{   rF   rx   r7   )	r   prefixr   r   r   srr   r\   r   )re   r   r   r   rd   r   hash   s4    2D

&zCmfCache.hashc             C   s>  |d krt  }|s|S tt|j}t  }x|j D ]}|j|d }|sLq4|drj|	|d d  n
|	| t
|tjjrt||jd }|r| j||d q4t
|tjjtjjfr4t||jd }|rx|D ]}| j||d qW x.| D ]"}	d|j d|	j }
|	|
 qW q4W |	|jd dt|  |S )N_idr   )r   ref_r   r.   ri   )setgetattrmodels
class_name__dict__rC   r   rT   endswithaddrn   ro   CmfRelationBasesimple_objects_id_recursive
CmfM2MBaseCmfBackrefBaserelated_modelsrl   r5   r   )r   objr   modelfields_str_set
field_nameZ	field_clsZfield_valuerel_obj	rel_modelrefr   r   r   r      s6    


z$CmfCache.simple_objects_id_recursivec             C   s  |sg S g }t  }x|jddD ]}|jdrF||jdd  n||j t|tjjrr|	| 
|j t|tjjtjjfr |jrx|jD ]}|	| 
| qW x.| D ]"}d|j d|j }|| qW q W ||jjd d	t|  tt |}|S )
u   
        Собираем ид связанных обьектов 2 уровня для настройки инвалидации
        :param obj:
        :return:
        T)rq   r   Nr   r   r   r.   ri   )r   valuesr   r   r   
isinstancero   r   r   extendobjects_id_recursiverr   r   r   r   rl   appendr5   r   rz   )r   r   r   r   fieldr   r   r   r   r   r   r      s(     zCmfCache.objects_id_recursivec             C   sT   t |tjkrtddd dS | jr<| jd| | dS | jrP|| j|< dS d S )NuU   DEV: Слишком большой объект для кэширования — keyT)
debug_onlyFzobj:)lenrE   ZCACHE_MAX_OBJ_SIZE	cmf_alertr?   r   r@   r=   )r   r\   Zstr_valr   r   r   _obj_dict_set  s    
zCmfCache._obj_dict_setc             G   sx   t  }x|D ]}|d|  qW | jrH| jj| t|krBdS dS n,| jrpx|D ]}| j|sTdS qTW dS d S d S )Nzobj:TF)r   r   r?   existsr   r@   r=   rT   )r   rC   Zhkeysr\   r   r   r   _obj_dict_exists)  s    

zCmfCache._obj_dict_existsc             C   sX   | j r>| j d| }|d k	r.| j d n| j d |S | jrP| j|S d S d S )Nzobj:r:   r;   )r?   rT   rA   r@   r=   )r   r\   r   r   r   r   _obj_dict_get;  s    zCmfCache._obj_dict_get)r]   inv_payloadc             C   s   |  d| S )Nz::r   )r]   r   r   r   r   %_jshash_invalidate_confirm_member_keyH  s    z.CmfCache._jshash_invalidate_confirm_member_key)
member_keyc             C   s   | j dddS )Nz::ra   )maxsplit)r!   )r   r   r   r   +_jshash_invalidate_confirm_member_key_splitL  s    z4CmfCache._jshash_invalidate_confirm_member_key_splitc             C   s    | r| n| dd }d| S )Nrj   zjscache-invalidate-confirm-set:)r!   )cache_idr]   set_keyr   r   r   "_jshash_invalidate_confirm_set_keyP  s    z+CmfCache._jshash_invalidate_confirm_set_keyc       	      C   s   t t}xj| D ]^\}}td| |d |gd x<| D ]0\}}|dr<|| j|d | || q<W qW | jrx&| D ]\}}| jj	|f|  qW d S )Nzinvalidate-)roomevent_personszjshash:)r]   )
r   rz   r{   cmf_emit_eventrb   r   r   r   r?   sadd)	r   ZmsgsZconfirmationsZ	person_idinv_dictr]   r   r   confirm_listr   r   r   rY   W  s    
zCmfCache.emitc             C   sf   | j rb|rb|d d }| j|d}t }x&|D ]}|| |d |d  q.W | j j|f|  d S )Nr   )r]   ra   )r?   r   rz   r   r   srem)r   Zconfirm_dictZsample_jshashZkey_cache_idr   Zconfirmr   r   r   jshash_invalidate_confirmf  s    

z"CmfCache.jshash_invalidate_confirmc                s.    j r* |} fdd j |D S d S )Nc                s   g | ]}  | qS r   )r   rS   )r0   member)r   r   r   
<listcomp>x  s   z;CmfCache.jshash_invalidate_confirm_list.<locals>.<listcomp>)r?   r   smembers)r   r   r   r   )r   r   jshash_invalidate_confirm_listr  s    

z'CmfCache.jshash_invalidate_confirm_listc          	   C   s  |sd S | j r| j jdd |D   t| | | i }x|D ]}| jrhd|krhtd|  t| jd|  | j d| }|rFt| jd|  | jrtd|  x|D ]}|	d	}| jrd|krtd
| d|  t| jd|  | j 
d| }	|	d kr qt|	}	|	r|	d }
|
|krLt ||
< |dkr~|r~dtdd |jddD }nd}|	d  d| d| d| }|||
 |< | j d|  | j d| | qW | | qFW n2| jrx(|D ]}|| jkr| j|= qW nd S d S )Nc             S   s   g | ]}d | qS )zobj:r   )r0   r\   r   r   r   r     s    z+CmfCache._obj_dict_mdel.<locals>.<listcomp>rM   z#DEBUG_CACHE JSHASH: try invalidate z*DEBUG_CACHE JSHASH: try invalidate:jshash:zinvalidate:jshash:z*DEBUG_CACHE JSHASH: got invalidate:jshash:z#DEBUG_CACHE JSHASH: got invalidate zutf-8z"DEBUG_CACHE JSHASH: do invalidate r.   z)DEBUG_CACHE JSHASH: do invalidate jshash:zobj:rO   updatez::c             S   s   g | ]}|d kr|qS ))Zcache_fieldscmf_modified_atcmf_viewed_atZcmf_modified_by_idr   )r0   r   r   r   r   r     s    T)
is_changedONLYFORUPDATESrP   )r?   rW   	CMF_CACHEinmemory_delprofiler_invalidaterF   r   r7   r   rS   rT   rU   rV   r<   r5   r   rC   r   rY   r@   r=   )r   rC   r   obj_idactionrZ   r\   Zinvjsr]   r^   r_   changed_fieldsr   r   r   r   _obj_dict_mdel{  sV    







zCmfCache._obj_dict_mdelc          	   C   s   | j rR| j  :}x*| D ]\}}|jd| f|  qW |  W d Q R X nH| jrx@|D ]2}|| jkr| j| ||  q^|| | j|< q^W nd S d S )Nzinvalidate:)r?   rQ   r{   r   rX   r@   r>   r   )r   r   r[   r\   r   r   r   r   _invalidate_dict_mset  s    

zCmfCache._invalidate_dict_msetc             C   sH   | j r.| j d| }|r*dd |D S |S | jr@| j|S d S d S )Nzinvalidate:c             S   s   g | ]}| d qS )zutf-8)rS   )r0   r\   r   r   r   r     s    z1CmfCache._invalidate_dict_get.<locals>.<listcomp>)r?   r   r@   r>   rT   )r   namer   r   r   r   _invalidate_dict_get  s    zCmfCache._invalidate_dict_getc          	   C   s   | j rX| j  @}x0| D ]$\}}|r| j jd| f|  qW |  W d Q R X nR| jrxJ| D ]8\}}x.|D ]&}|| j|g krv| j| | qvW qhW nd S d S )Nzinvalidate:)	r?   rQ   r{   r   rX   r@   r>   rT   remove)r   r   r[   r   r   Zkey_listr\   r   r   r   _invalidate_dict_mdel  s    
zCmfCache._invalidate_dict_mdelc                s  t jdrdt_d S t|rBdt_tjdt	|  d S 
|}tj|tj}||k rdt_tjdtj d
|  d S i tjj|}fdd  fdd	}	|rt|tst|d
r|	| d}
t|jtjkrtd|j dtj  d S n~|rFt|trFt|d d
rFd}
|	| nN|d k	r|d}
t|tkrt|tkrttkrn|sd}
d}ntdd}|r*|d r*tjd| |
dkr|j|d krxL|d D ]@}||j d|j dfkrd}|j krtd P qW |s*g }x.d*|jD ] }||d kr4|d | }q4W |sddg}t|tjd< x|D ]}|dkrd}xt|d D ]h}| d d }||krЈ d!|   d!| d" n* d#| d$|   d#| d$| d" qW qxW x"|d D ]} d!| d" qW |r:|d sJ d!| d" jrzx&D ]}tjd%| d&  qXW t!"|}#|sdt_$|rt%|t&| d'tkrtj'rtjd( dtj'  jrt(d( tj' )d) tj'fi ) d S )+NNO_CACHETz%DEBUG_CACHE ADD SKIP CACHE LOCKED_BY z#DEBUG_CACHE ADD SKIP too old trans r.   c                sT   |  d\}}}| kr"t  |< |r@ |  d|  n |   d S )Nr.   )	partitionrz   r   )Zbind_and_fieldsbindr   r   )r   r\   r   r   bind_add  s    
zCmfCache.add.<locals>.bind_addc                sl   t | tr| }n| g}g }xL|D ]D}t |jtjjr@|}nt|}x|D ]} | qTW q W dS )u   
            Собираем списки ключей инвалидации
            :param val:
            :param invalidate_dict:
            :return:
            N)r   rz   rl   ro   r   rp   r   r   )r   Zobj_listr   itemr   )r   r   r   r   bind_add_recursive  s    


z(CmfCache.add.<locals>.bind_add_recursiverl   r   zSkip add to cache z  g.skipcache_select_for_update: r   rz   ZcustomemptyZEmptyuG   Невозможный объект для хранения в кешеFr   zDEBUG_CACHE WHERE: r   z.idz.codezDEV: Obj in not in inv_dictparentZcache_clustersZScopeAll)ZNullZNULLZnullrk   ZnoneNrk   r   where_ScopeAll__insdelwhere_r   zDEBUG_CACHE BIND: z = r]   z#DEBUG_CACHE JSHASH: add invalidate zjshash:)r   )*osenvironrT   r   no_jscache_forcer   cache_is_lockedr7   rF   cache_locked_byget_last_invalidatecache_lockscache_transaction_startro   utilcmfutilget_model_by_namer   rz   r}   r/   rl   skipcache_select_for_updater$   rm   rs   rt   ry   r   r   cache_cluster_fieldsprofiler_datar!   rU   rL   r   Zcache_store_errorinmemory_addr   r]   r   r   )r   r\   r   obj_typeZquery_paramscache_inmemoryZlir   	obj_modelr   Zobj_caseZwhere_pkr   Zscopesc_fieldZscope
model_nameZbindidZstr_objr   )r   r   r\   r   r   r     s    

 "

&


"

zCmfCache.addc          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrRt|t jd< nt jd  t|7  < tjrdt jkrg t jd< t jd | d S )Nr   r>   Zcache_invalidate_keys)r   r<   r   ry   r   r8   DEBUG_PROFILE_VERBOSEr   )r   rC   r   r   r   r   r     s    


zCmfCache.profiler_invalidatec          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrNdt jd< nt jd  d7  < dt jkrtdt jd< tjrdt jkrg t jd< t jd | d S )Nr   redis_cache_hitra   redis_cache_missr   Zredis_cache_hit_keys)r   r<   r   ry   r8   r  r   )r   r\   r   r   r   r   profiler_redis_data_hit  s    




z CmfCache.profiler_redis_data_hitc          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrNdt jd< nt jd  d7  < dt jkrtdt jd< |t jd< tjrdt jkrg t jd< t jd | d S )Nr   r  ra   r  r   Zredis_cache_miss_lastZredis_cache_miss_keys)r   r<   r   ry   r8   r  r   )r   r\   r   r   r   r   profiler_redis_data_miss  s    





z!CmfCache.profiler_redis_data_missc             C   s0  t jdstjrd S d}|r*t|}nd}t| jd |dkrfd}| 	|}|rft
|}t|}|dk	rdtkrtjr| d| tjfi t| jd| d	tj  | jrtd
| tj t| jd|  t| jd| |s|r| | t||| |S | | t| jd|  d S )Nr   T.ZCACHEFr]   zjshash:z*DEBUG_CACHE JSHASH: add invalidate jshash:r.   z#DEBUG_CACHE JSHASH: add invalidate zDEBUG_CACHE HIT: zDEBUG_CACHE GET:zDEBUG_CACHE MISS: )r   r   rT   r   TECHCOM_HACK3441r   inmemory_getr7   rF   r   rU   rV   r   r]   r   r   r  r   r  )r   r\   r   Zfrom_inmemoryr   r   obj_sizer   r   r   rT     s8    




zCmfCache.getc             C   s   dS S )Nr   z%DEBUG_CACHE TRANS get_last_invalidatecache_last_invalidate_)r7   rF   rs   r?   rT   )r   r  r   r   r   r     s     zCmfCache.get_last_invalidatec             C   s   t | jd |  t_d S )Nz)DEBUG_CACHE TRANS cache_transaction_start)r7   rF   gen_time_usr   r   )r   r   r   r   r     s    z CmfCache.cache_transaction_startc             C   s   t tjtjjdS )Nz%Y%m%d%H%M%S%f)rs   r   r   rd   rw   Zstrftime)r   r   r   r   r    s    zCmfCache.gen_time_usc             C   s   d S d S )NzDEBUG_CACHE TRANS cache_lockr  cache_lock_)	r7   rF   r   r  r?   r   r   r   r   )r   r  lr   r   r   
cache_lock  s          zCmfCache.cache_lockc             C   s`   d S xVt j D ]H\}}| |}||ks8t j|d krt| jd | jd| d qW d S )Nr   i zDEBUG_CACHE TRANS cache_unlockr  0)	r   r   r{   r   r   r7   rF   r?   r   )r   r  Ztr_startZlock_trr   r   r   cache_unlock  s      
zCmfCache.cache_unlockc             C   s   dS S )Nr   z%DEBUG_CACHE TRANS get cache_locked_byr  )r7   rF   rs   r?   rT   )r   r  r   r   r   r   /  s     zCmfCache.cache_locked_byc             C   s   dS dS dS )NFr   i z/DEBUG_CACHE TRANS cache_is_locked drop deadlockr  r  T)	r   r   r   rT   r   r7   rF   r?   r   )r   r  Z_cache_locked_byr   r   r   r   r   4  s           zCmfCache.cache_is_lockedc             C   s   g }|d kr|j }xF|D ]>}x8|| D ],}d|krH||dd  q&|| q&W qW | |||| | | | jrtd| d| | d S )Nr.   r   zinvaldebug--)rl   r   r!   r   r   rF   r   )r   r   r   r   r   Zinv_listr   Zinv_valr   r   r   _do_invalidateC  s    

zCmfCache._do_invalidater   c          	   C   s@  t jdrd S |d kr$| dh}|s,d S | | t| jd| d| dt|  t }t }t }i }i }xz|D ]r}	| jj	d|	 ddd}
xJ|
D ]B}| j
|}|rx,|D ]$}|d	d
 }|| |	||< qW qW ||
 qxW x|D ]}| j
d|  }||}	|rx|D ]}|d	d
 }|| | jd|  }|s^q"t|}|d }||krt ||< d}|d  d| d|	 d| }||| | < q"W qW |dd |D dd |D dd |D }|rtd| d| d|  | jj|  ntd| d| d | | d S )Nr   rj   z!DEBUG_CACHE start invalidate_ids r.   zinvalidate:*r   d   )matchrM       r   zinvalidate:jshash:zobj:rO   r   rP   z::c             s   s   | ]}d |   V  qdS )zobj:N)rS   )r0   	query_keyr   r   r   r2     s    z*CmfCache.invalidate_ids.<locals>.<genexpr>c             s   s   | ]}d |   V  qdS )zinvalidate:jshash:N)rS   )r0   r  r   r   r   r2     s    c             s   s   | ]}d |   V  qdS )zobj:N)rS   )r0   r]   r   r   r   r2     s    zinvalidate_ids(z, z): z): no keys found.)r   r   rT   r  r7   rF   r   r   r?   rR   r   r!   r   r   rS   rU   rV   r<   r   r4   rW   rY   )r   r  idsr   Zinvalidate_keysZ
query_keysZjshashesrZ   Zobj_id_by_query_keyid_rC   r\   Zinv_membersZ
inv_memberr  Zquery_jshashesr]   r^   r_   r   r   Z	keys_listr   r   r   invalidate_idsT  sb    
"










zCmfCache.invalidate_idsc                s   d fdd	}t jdr"d S |s*d S | tjd  d|  i x>|D ]6}|d| d| d	 ||d
 jd  |d qVW d S )Nrf   c                s6    | }|r2|| < tjd  d| |   d S )NzDEBUG_CACHE INVAL: r.   )r   r7   rF   )invalr4   invd)r   r   r   r   r   _check_inval  s    
z8CmfCache.invalidate_ids_as_wrapper.<locals>._check_invalr   zDEBUG_CACHE start invalidate r.   r   r   zref=zobj.id=)r   )rf   )r   r   rT   r  r7   rF   r  )r   r  r  r   r  r  r   )r   r   r   r   invalidate_ids_as_wrapper  s    


z"CmfCache.invalidate_ids_as_wrapperc          
      s  d, fdd	}ddl m} tjdr.d S |j tjd  d|j  |j}i j	rtdd l
}|  |jd	kr||j d
  dkr|d|j d|j d |std ||j d|gd |d|j dd |d|j d|j dd |  d S t }	xl|jddD ]Z\}
}d}|j|krFq(t|tjjr dkr|r|jr|d|j d|j d  dkr|jr|j|jkr|d|jj d|j d |d|jj d|j d |	|
 q(t|tjjr dkr|jr|	|
 q(|jrDt|tjjrD|	|
 q(|jr(|j|jkr(|	|
 |
dr(|	|
d d  q(W t|	dkr dkrtjd  d |j d S d!g}x|jD ]}|| qW tt |d"d r|!|  dkr||j d  dkr.||j d|	d  dkrXx|	D ]}
xd-|jD ]}t"||sfqRt#t || tjjrx|| D ]$}|d|j d| d$|
 d qW nt#t || tjjr|d||d   d| d$|
 d nFt#t || tjj$r*|d||  d| d$|
 d ntd%dd& qRW |d| d$|
 d q@W d'}xFd.|jD ]8}t"||rh|| jrh|| j|| jkrhd}qhW  dks|rjxd/|jD ]}t"||sؐqt#t || tjjrhx,|| D ] }|d|j d| dd( qW || jrT|| jrTx.|| jD ] }|d|j d| dd) qBW nt#t || tjjr|d||d   d| dd || jrT|| jrT|d|| jj d| dd* nzt#t || tjj$rH|d||  d| dd || jrT|| jrT|d|| jj d| dd* ntd%dd& qW |d| d t%j&rt'j(d+g g t'j(d+< |  d S )0Nrf   c                s   | }g }|r|rt|}g }x|D ]}d|krB|| q*|d^}}}|rtd|  d|  td|  d| d| dd || q*t|d}	||	@ r*|| q*W || < n|| < tjd  d| |   i }
||
| < t	j
rtjdg |
g tjd< d S )	Nr.   z=cmfCache.invalidate(): ValueError: too many values to unpack(z): T)abortri   zDEBUG_CACHE INVAL: r  )r   r   r   r!   r   r4   r   r7   rF   r8   r  r   rT   )r  r4   change_fieldsr  Zinvd_affectedir   Zi_fieldstailZi_set_fieldsZtmp)r   r   r   r   r   r    s4    




z)CmfCache.invalidate.<locals>._check_invalr   )r   r   zDEBUG_CACHE start invalidate r.   ZRelationCachezRelationCache.parent.id=)r   r   r   r   zref=uY   DEV: FATAL в инвалидацию м2м поля не передали имя поляzobj.id=)r!  r   r   zwhere=r   T)rq   )r   Zcmf_viewed_byZcmf_versionrf   )createrW   r   zref_new=zref_old=r   r   zDEBUG_CACHE ivalidate: z not fields_have_changesz--Zlogical_deleter   r   u   Ошибка конфигурации моделей: cache_cluseter_fields может быть только по m2m и relation полям)r   Fz
where_m2m=zwhere_m2m_old=z
where_old=r   )rf   N)r   )r   )r   ))collectionsr   r   r   rT   r  r   r7   rF   TRACEpdbZ	set_traceZ	parent_idrl   r   r  rz   r{   r   ro   r   r   r   oldnewr   r   r   r   r   r   r   rm   load_fieldsr}   rn   ZCmfTUUIDr8   r  r   r   )r   r   r   r   Zm2m_field_namer  r   r   r'  r!  r   r   Zno_caching_fieldsZcluster_load_fieldsr  Zcc_field_nameZ
cc_clusterZcluster_field_is_changedr   )r   r   r   r   
invalidate  s    % 

 
"






&&"
 " ""zCmfCache.invalidatec             C   sD   x| j D ]\}}td| qW x | j D ]\}}td| q*W d S )NzDEBUG CmfCache.dumps)r=   r$   r>   r{   )r   r\   r   r   r   r   rL     s    zCmfCache.dumpsc             C   s   | dd }tjr"| dd }ytjj|}W n tk
rH   dS X tj	sr|j
rd|jtjkrdn| | dS |j
stddd d S |tjkr| | dS tj| }||d}|dkr| | |S || | | |S d S )	Nr   r   rj   ra   .uS   DEV: inmemory_get вызван для модели без флага cache_inmemoryT)r   )r!   r8   rF   ro   r   r   r   KeyErrorr   in_memory_cacher   r   in_memory_cache_skip_modelsprofiler_inmemory_data_skipr   r   INMEM_CACHEprofiler_inmemory_data_missrT   move_to_endprofiler_inmemory_data_hit)clsr\   r  r   model_cacheretr   r   r   r
    s4    




	

zCmfCache.inmemory_getc             C   s  |dkrt |tjjs t|r,d| }nJ|rvt |trvt |d tjjsZt|d rvd|d j dt| d}t	| j
d| d|  d S t	| j
d|  |d	d }tj
r|d
d }ytjj|}W n tk
r   d S X tjs|jsd S |jstddd d S |jr&d}|tjkr>t tj|< tj| }||kr|| |kr~td| d| d||   d S |||< t||kr|jdd\}	}
t	| j
d|	  d S )Ni  z, r   []u/   DEV: skip inmemory_cache obj_size > 128000 — u	    байтzCmfCache:inmemory_add add key r   rj   ra   uS   DEV: inmemory_get вызван для модели без флага cache_inmemoryT)r   i  zInmemory cache error! key:z	 try_add:z exists:F)Zlastz"CmfCache:inmemory_add evicted key )r   ro   r   	BaseModeldataclassesZis_dataclassrz   r   r   r7   rF   r!   r8   r   r   r   r,  r   r-  r   r   r   r0  r   r$   popitem)r4  r\   r   r  Zdetailr  r   Z	LRU_LIMITr5  Zevicted_keyr   r   r   r   r     sD     

zCmfCache.inmemory_addc          	   C   s   g }|dkr"t | jd i t_d S x|D ]}|dd }tjrN|dd }ytjj	|}W n t
k
rv   w(Y nX |jsq(|| |tjkrq(tj| }x|D ]}||d  qW q(W |s|rtjdt|t dg d S )	NrD   uS   CmfCache:inmemory_del Полный сброс inmemory_cache при REDISDB.flushdbr   r   rj   ra   zCmfCache:inmemory_del)rC   Zskip_app_id)r7   rF   r   r0  r!   r8   ro   r   r   r   r,  r   r   r   r   delayed_redis_eventsrK   rL   r   getpid)r4  rC   
from_eventZ
event_keysr\   r  r   r5  r   r   r   r   &  s.    




zCmfCache.inmemory_delzCmfCache:inmemory_del)channelc                s6   | sd S | d   fdd}t tjd t| d S )NrC   c                  s    t tjd  tj dd d S )Nz*CmfCache:on_inmemory_del event with keys: T)r>  )r7   r8   rF   r   r   r   )rC   r   r   handlerP  s    z)CmfCache.on_inmemory_del.<locals>.handlerz&CmfCache:on_inmemory_del spawn handler)r7   r8   rF   geventspawn)datar6   r@  r   )rC   r   on_inmemory_delH  s    zCmfCache.on_inmemory_delc          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrNdt jd< nt jd  d7  < dt jkrtdt jd< tjrdt jkrg t jd< t jd | d S )Nr   inmemory_cache_hitra   inmemory_cache_missr   Zinmemory_cache_hit_keys)r   r<   r   ry   r8   r  r   )r4  r\   r   r   r   r   r3  X  s    




z#CmfCache.profiler_inmemory_data_hitc          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrNdt jd< nt jd  d7  < tjrdt jkrzg t jd< t jd | d S )Nr   Zinmemory_cache_skipra   Zinmemory_cache_skip_keys)r   r<   r   ry   r8   r  r   )r4  r\   r   r   r   r   r/  l  s    


z$CmfCache.profiler_inmemory_data_skipc          
   C   s   ydt krt t _W n" tk
r6 } zd S d }~X Y nX dt jkrNdt jd< nt jd  d7  < dt jkrtdt jd< tjrdt jkrg t jd< t jd | d S )Nr   rF  ra   rE  r   Zinmemory_cache_miss_keys)r   r<   r   ry   r8   r  r   )r4  r\   r   r   r   r   r1  ~  s    




z$CmfCache.profiler_inmemory_data_miss)NF)N)NN)NF)F)N)r   )NN)F);r"   r    r,   r=   r>   r?   r@   rF   r  r&  ZPROCESS_EVICTED_FLUSHr   rI   r`   rc   r   r   r   r   r   r   staticmethodr/   r   r   r   rY   r   r   r   r   r   r   r   r   r  r  rT   r   r   r  r  r  r   r   r  r  r  r+  rL   classmethodr
  r   r   Zon_server_eventrD  r3  r/  r1  r   r   r   r   r8   C   sv   
S
#	<
 I
!

T 
 p/1!r8   c             C   sN   t | }x@| D ]4\}}t|trytj|||< W q   Y qX qW |S )N)r   r{   r   r/   r   ru   rv   )ZlstZdctr   r   r   r   r   CustomJSONDecoder  s    

rI  c               @   s   e Zd Zdd ZdS )CustomJSONEncoderc             C   s   yht |tjtjfr|j}t |tjs2t |tjrL|jsD| d S | S t |tj	r^|jS t
|}W n tk
r|   Y n
X t|S t| |S )NZ)r   r   ZCmfDateTimer   rr   r   dateZtzinfoZ	isoformatrp   iter	TypeErrorrz   r   default)r   r   iterabler   r   r   rO    s    zCustomJSONEncoder.defaultN)r"   r    r,   rO  r   r   r   r   rJ    s   rJ  )Zstatic_folderZ	root_pathTZSEND_FILE_MAX_AGE_DEFAULTF)SocketIO	Namespace)RedisManager)Client)
project_idc             C   s6   t j| }|s2tjj| ddddgd}|t j| < |S )NZui_form_scheme
logic_typelogic_prefixZcust_field_conf_scheme)rl   r   )r   cache_projectsrT   r   Z
CmfProject)rU  Zprojectr   r   r   get_cache_project  s
    
rY  rf   c          
   C   s   |rd| dg}nddddg}xdd |D D ]p}t j|| }tj|s\tj||}ytj|slw0W n" tt	fk
r   t j
 Y nX t jj|d	d
S W x*tjD ] }|| }|rt jj|d	d
S qW t jdS )Nzcustom/plugins/z/staticzcustom/static/zcommon/static/zcmf/static/zdist/cmf-angular/c             S   s   g | ]}t jtj|qS r   )r   pathr5   rE   PROJECT_DIR)r0   dr   r   r   r     s    zsend_static.<locals>.<listcomp>T)Zconditionalzdist/cmf-angular/index.html)flaskZhelpersZ	safe_joinr   rZ  isabsr5   isfilerN  
ValueErrorZ
BadRequestZ	send_filer   HOOK_STATIC_NOTFOUND)Zreq_filenameZpluginsearch_dirsZ	directoryfilenamehookr   r   r   send_static  s*    re  c               @   s   e Zd ZdZdejdddZdd Zedd	 Zed
d	 Zedd Z	edd Z
edd ZedddZedd Zedd ZdS )CmfRedisMemoryWrapperut    Если есть self.redis - используется он
        Если нет - нужен фолбэк
    N)redisc             C   s   || _ i | _d S )N)rg  
memstorage)r   rg  r   r   r   r     s    zCmfRedisMemoryWrapper.__init__c                s    fdd}|S )Nc                s6   | j rt| j  j||S td | f||S d S )Nu&   Redis memory wrapper запрещен!)rg  r   r"   CmfAbortError)r   r   r   )r%   r   r   wrapper  s    z/CmfRedisMemoryWrapper.fallback.<locals>.wrapperr   )r%   rj  r   )r%   r   fallback  s    zCmfRedisMemoryWrapper.fallbackc             O   s   t d S )N)NotImplementedError)r   r   r   r   r   r   r      s    zCmfRedisMemoryWrapper.smembersc             O   s   t d S )N)rl  )r   r   r   r   r   r   r     s    c             C   s   | j |S )N)rh  rT   )r   r\   r   r   r   rT   	  s    zCmfRedisMemoryWrapper.getc             C   s   | j   d S )N)rh  clear)r   r   r   r   rI     s    zCmfRedisMemoryWrapper.flushdbc             C   s$   | j |d}||7 }|| j |< |S )Nr   )rh  rT   )r   r\   amountrr   r   r   r   rA     s    
zCmfRedisMemoryWrapper.incrbyra   c             C   s   |  ||S )N)rA   )r   r\   rn  r   r   r   incr  s    zCmfRedisMemoryWrapper.incrc             G   s(   d}x|D ]}|| j kr
|d7 }q
W |S )Nr   ra   )rh  )r   namesr   nr   r   r   r     s
    

zCmfRedisMemoryWrapper.existsc             C   s   || j |< d S )N)rh  )r   r\   rr   r   r   r   r   $  s    zCmfRedisMemoryWrapper.set)N)ra   )r"   r    r,   __doc__rg  Redisr   rk  r   rT   rI   rA   ro  r   r   r   r   r   r   rf    s   
rf  cache_settingsrO  rm   rg  Z	celery_dbZ	run_uwsgiu?   При работе через uwsgi обязателен Redisr   )ZappZcors_allowed_originsloggerZengineio_loggerdbZunix_socket_pathzunix://z?db=zflask-socketio)r?  Z
write_onlyclient_managerzredis://ZusernameZpasswordrj   @ZhostportZ6379r   message_queue)Payloadr  )ru  z/custom/org_name)r?   r@   )r@   u&   Неизвестный тип кешаc             C   s   t |  t t  t| tr||  }t| j	| j
| jt d|_d|_tjdd|jd< d|jd< d|jd	< |S t }d
|d< d|d< t| |d< t |d< t|}d
|_tjdd|jd< d|jd< d|jd	< |S d S )N)coder   description	tracebackzapplication/jsonOriginr   zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headersi  r|  zUnknown errorr   r}  r~  )r   r4   r~  
format_excr   r   Zget_responserK   rL   r|  r   r}  rC  content_typerequestheadersrT   r<   r/   Zjsonifystatus_code)r   Zresponser   r   r   handle_exceptionv  s2    





r  Zjwt_rsazjwt_rsa.pub)RSAcmf_deletedrg_member_ofZdefault_projectZemailZphone
user_localZphone_internalZprimary_roleZonline_statusZvacation_startZvacation_endZon_vacationactivitydoes_not_workauth_inactive_blockZis_admin
is_supportservicedesk_allowZ
first_name	last_nameztwo_factor.two_factor_optc             C   sP   t js
d S ytjs&tjjdtjdt_W n  tk
rH   t	
d  Y nX tjS )Nz.CmfPerson:00000000-0000-0000-0000-000000000001)rl   r   zapp.system_person() error)rE   AUTH_ENABLEDr   system_personr   	CmfPersonrT   current_person_fieldsry   r3   	exception)r   r   r   r   r    s    
r  c        
      C   s  t jdrt jd} n\t js$dS ytt j}W n tk
rR   t	
d dS X |dkr`dS t|tot|dd} | s~dS t| }|jdsdS dt_t|jd	dgd
 }|rt|dkrdS |jdd }|sdS td|}|r | \}}ndS |dks"|dks"|dkr*tj}nR|dksR|dksR|dksR|dkrZtj}n"|dksn|dkrvtj}ntj}t|tjjsdS d|kr|j|j d| ddgd}	n|j|ddgd}	|	sdS |t|	j krdt_!|	t_"dS )u  
    Проверяем, что пользователь пришел из share-ссылки
    Если идёт обращение к /files, то проверяем Referer
    Т.к. jsurl передаётся только в апи для других ендпоинтов не смысла путаться парсить body
      Вообще, для API тоже лучше использовать реферер, тогда не придётся по два раза парсить json
    Выставляем:
     - g.sharelink_access_request = True, если пользователь пришел по /share ссылке
     - g.sharelink_access_granted = True, если проверка hash прошла
     - g.sharelink_access_obj = объект, по которому проверяли ключ. Используется в API для доп.фильтрации
    z/filesRefererNu{   _check_sharelink_access не смогли распарсить request.data для проверки прав доступаjsurlrf   z/share/Tr   r      r   r   z*^(?P<obj_type>[^:-]*)[:-](?P<obj_code>.*)$docZDOCCmfDocumentZflZFLZIN_WORK	CmfFolderCmfListZEPIr  rj   rl   sharelink_hash)rl   r   )r|  r   )#r  rZ  rb   r  rT   rC  ujsonrV   ry   r3   r  r   r<   r   r   sharelink_access_requestr   Zqueryr   r!   rer  groupsr   r  r  r  rn   ro   Z	CmfEntityr   r/   r  sharelink_access_grantedsharelink_access_obj)
r  Zjson_resr'   Z
hash_paramZobj_keyr  r   Zobj_coder  r   r   r   r   _check_sharelink_access  s^    
(
r  c             C   s(   | t _| r"| t jkt _| t jkt _t jS )uh   !!! Эта функция не меняет контекст, только инициализирует.)r   _current_personanonymous_usercurrent_user_is_anonymoussharelink_anonymous_user#current_user_is_sharelink_anonymous)personr   r   r   set_current_person!  s
    r  c             C   sJ   t | dd }|dkr| jS tjs$d S |d k	r0|S td tjtjd d S )Nr  ZFAIL_recursionz#Warning!!! Lazy Calc Current Person)rB   )	r   r  rE   r  r$   r~  print_stackrG   stdout)r   Zcpr   r   r   current_person*  s    r  c          	      s   yt jstjjdgd}|jsztjj J dd l	}dd l
|j|j  d fddtdD |_|  W d Q R X |jt _W n  tk
r   td  Y nX t jS )	Napp_key)r   r   rf   c             3   s   | ]}  V  qd S )N)choice)r0   r   )alphabetsecretsr   r   r2   D  s    zapp_key.<locals>.<genexpr>    zapp.app_key() error)r   r  r   CmfGlobalSettingsrT   ro   r   r   disable_aclstringr  Zascii_lettersdigitsr5   rangesavery   r3   r  )r   Zsettingsr  r   )r  r  r   r  :  s     
r  c          	   C   s   t | dd d k	r| jS ytjs4tjjddtjdt_tj| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W d Q R X t  W d |  X | jS  tk
r   td  Y nX d S )	N_anonymous_userzanonymous@evateam.ruT)r|  include_deletedr   zcreate-anonymous-user-lock   )timeoutzapp._anonymous_user() error)r   r  r   r   r  rT   r  REDIS_DBrg  lockacquirero   r   r   r  system_dataZcreate_anonymous_userr  ddcommit_all_dsreleasery   r3   r  )r   
redis_lockr   r   r   r  R  s0    

r  c          	   C   s   t | dd d k	r| jS ytjs4tjjddtjdt_tj| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W d Q R X t  W d |  X | jS  tk
r   td  Y nX d S )	N_sharelink_anonymous_userzsharelink-anonymous@evateam.ruT)r|  r  r   z$create-sharelink-anonymous-user-lockr  )r  z%app._sharelink_anonymous_user() error)r   r  r   r   r  rT   r  r  rg  r  r  ro   r   r   r  r  Zcreate_sharelink_anonymous_userr  r  r  r  ry   r3   r  )r   r  r   r   r   r  r  s2    

r  c          	   C   s   t | dd d k	r| jS ytjjddtjd| _| jstjj	ddd}|
  zPtjjddtjd| _| jstjj  tj| j| _W d Q R X t  W d |  X | jS  tk
r   td  Y nX d S )	N_test_guest_userztest-guest@evateam.ruT)r|  r  r   zcreate-test-guest-user-lockr  )r  zapp._test_guest_user() error)r   r  r   r  rT   r   r  r  rg  r  r  ro   r   r   r  r  Zcreate_test_guest_userr  r  r  r  ry   r3   r  )r   r  r   r   r   test_guest_user  s,    

r  c             C   s
   t j S )N)r   r  Zget_settings)r   r   r   r   global_settings  s    r  c             C   s:   t | dr t| dd d k	r | jS tjjddgd| _| jS )N_global_varZaccount_sync_statusZaccount_sync_last)r   )r}   r   r  r   ZCmfGlobalVarrT   )r   r   r   r   
global_var  s    r  lineno   c             C   s>  |  tddtddf} | j|dd}td|  xt|d | dD ]\}}|jd }tj	|j
tjd	d  }td
|||j|jd f  t|j
|j }|rtd|  x|j D ]}	t|	 qW qLW ||d  }
|
rtdd |
D }tdt|
|d f  tdd |D }td|d   d S )NFz<frozen importlib._bootstrap>z	<unknown>T)Z
cumulativezTop %s linesra   r   z#%s: %s:%s: %.1f KiBi   z    %sc             s   s   | ]}|j V  qd S )N)size)r0   statr   r   r   r2     s    zdisplay_top.<locals>.<genexpr>z%s other: %.1f KiBc             s   s   | ]}|j V  qd S )N)r  )r0   r  r   r   r   r2     s    zTotal allocated size: %.1f KiB)Zfilter_tracestracemallocZFilterZ
statisticsr$   	enumerater~  r   sepr5   rc  r!   r  r  	linecachegetlinestripformatsumr   )ZsnapshotZkey_typelimitZ	top_statsr   r  framerc  lineZllotherr  Ztotalr   r   r   display_top  s*    

r  c          
   C   s   t jjjddd tjj| jtj	d}|sdd | j
ddD }tj|d	< tj|d
< tj|d< tjf |}|rd|_|jtj  d|_|jtj  |rd|_|jtjjdd t jj  |jdd W d Q R X t  |S Q R X d S )Nzcreate-current_person-lock
   )r  )loginr   c             S   s(   i | ] \}}| d s|dkr||qS )Zcmf_rl   )rb   )r0   r   r   r   r   r   
<dictcomp>  s   z+create_person_from_auth.<locals>.<dictcomp>T)rq   	cmf_owner
cmf_authorcmf_modified_byZServiceDeskClient)r|  )Z	only_data)ro   r   r   ZCmfLockr   r  rT   r  r   r  r{   r   r   r  r  r   ZCmfPersonGroupZsupport_groupr  Z
user_groupr  r  r  r  r  )authr  is_servicedeskr  Zperson_valuesr   r   r   create_person_from_auth  s*    


r  )forcelevelc             G   s6  t tdd s| s|r2|d k	r4t|trFt t|}n| r@tj}ntj}t }tt|t	j
 d d}tt|t	j d d}t	di dt }|dd}|dd}|d	d}	tjd
}
t	jd|
d| d| dd| d| d|	 d|| |	  ddf|}t|dddd |D  t t	_d S )NrF   i  rg   r   Zselect_countZselectr   r   insertmr   z(+z)mszs zu zi r   z%sr.   c             s   s   | ]}t |V  qd S )N)r/   )r0   partr   r   r   r2   #  s    zdebug.<locals>.<genexpr>)r   rE   r   r/   r3   INFOrF   timeroundr   debug_start	debug_nowrT   r<   r  r   
request_idlogr5   )r  r  messagesr   r   rq  ZscZscsZscuZscir  partsr   r   r   r4     s,    
$
r4   c              C   s   t jd} t jdr6| r6tt| jdrdS ntt jdrFdS t jds^t jdrbdS t jdst jdst jd	rd
S t jdrdS t jdrdS dS )Nr  z/files/z/servicedesksd_apiz/api/Zapiz/pub/z/docs/z/share/Zpub_apiz/auth/r  z/with-contextsystemZdeny)r  r  rT   rZ  rb   r/   r   )Zrefererr   r   r   set_api_scope'  s    $r  c              C   s  t jdkrdS t  t  t  dt_i t_	i t_
g t_tjddkt_ddlm}  ddlm} |  t_tjt_d	|d
ddt_dt_g t_g t_dt_dt_dt_dt_dt_dt_dt_ dt_!dt_"dt_#dt_$dt_%dt_&dt_'dt_(t) t_*dt_+dt_,t-j-.t-j/j0t_1dd t_.tj12 t_3dd t_2dt_4i t_5i t_6g t_7g t_8dt_9dt_:dt_;dt_<dt_=g t_>i t_?i t_@tA t_Bi t_Cg t_Di t_Ei t_Fg t_Gg t_HtIt_ItJjKL  tJjML  tNjOstPd dS t jQRdrdS d}d}t jQRdst jQRdrt jSd}|s`t jSd}|r`|Rdr\|tTdd }nd}|srt jUd}|rtJjVW|}tJjVj|dtXjYd}tId|dd  d| d|  |stZ[dt jSt jU t\ddd d!S t jQd"krtJj]j^tXjYd#}t jQRd$rd%}d&t j_kr&t j_d& }t`|}|sTtad&|i}tbtc  d'| }t jSd(d)|jSd*< d+|jSd,< d-|jSd.< |S d/}	|st jdd0}
t jdd1}|
rtJjef|
\t_t_,n|rtJjgh|t_tjr
tNjiotJjgjtjjjjd2}tNjir
|s
dt_tjrtjjjjt_d3d4tjjgg}tJjVj|tXjYd5}d6|j d7}	|r|jkrvtId6|j d8 d}n$|jlrd6|j d9}	tI|	 d}nN|rtm|tjjnd:}n6tjjnrtmtjtjjnd:}ntjojprtmtjdd;}t jQRd<pt jQRd=pt jQRd>}d?d@ }|rj|jjjt_tjrJtjjnt_tjjq t_ndt_|jr t_dt_tP| nN|sx| rtjs}tt  tj(rtju}dt_dt_tP| ndt_tPtjv tjp
t jQRdAp
t jQRdBp
t jQdCkp
t jQRdDp
t jQRdEp
t jQdFkp
t jQRdGp
t jQRdrJt j_dHdIkrJt jwdJkp
t jQRdKp
t jQdLkp
t jQRdMp
t jQRdNrt jwdJkp
t jQRdOrt jwdJkp
| rt jQRdPrtJjxy p
| rt jQRdQrtJjxy p
t jQRdRr tjp
tz{t jQ}tj|}tjv}tJjM}  |s0| r4dS tj*dSkrv|s^tjrVt~|	S t~|	S |js|jrst~ S nrtjr|st~|	S t jQd%kr|r|jrs|jrtbdTS tbdUS |r|jrstNjist~ S tjrt~ S tXjsdtX_t  tj,rtj, }|r|S dS )VuJ  
    Должны вернуть Response or None
    Особенности поведения:
      В случае web запроса:
        - response - view не выполняется, сразу отправляем response
        - None - выполняем view
        - Exception(в т.ч. и abort) - обработчик выводит трейс клиенту
      Системный контекст(shell, celery, socket, other with cmf_context):
        - None, Response - нет разницы
        - Exception - прерывает выполнение.
    ZOPTIONSNFZ
run_pytest1r   )r  )choicesrf   Z0123456789abcdef   )r   c               S   s   t jS )N)r   _nowr   r   r   r   <lambda>q      z before_request.<locals>.<lambda>c               S   s   t jS )N)r   _dater   r   r   r   r  s  r  Tz/memZOKz/api/z/files/zX-Eva-TokenZAuthorizationzBearer token)api_token_hashr  r   zAuth API Token(z...): hash=z	, person=z6Invalid API token: request.headers=%s, request.args=%szInvalid API tokeni  z
text/plain)r  z/pub/webhook)r   z/auth/not_authorizedr   next_urlzauth/signin?r  r   zAccess-Control-Allow-Originr  z Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headersul   Учётная запись заблокирована. Обратитесь к администраторуsession_tokenaccess_token)r  r  z==)filterr   u   Учётная запись uQ    заблокирована. Обратитесь к администраторуu    заблокирована.uo    заблокирована за неактивность, обратитесь к администратору)r  )r  z/pub/pub_apiz/docsz/sharec               S   s   t jdpt jdS )Nz/filesz/socket.io/)r  rZ  rb   r   r   r   r   is_allow_public	  s    z'before_request.<locals>.is_allow_publicz/health_check/z
/auth/sync)z/auth/invitez/auth/restore_passwordz
/auth/signz/servicedesk/auth/signz"/servicedesk/auth/restore_passwordz/auth/two-factormoderootz	127.0.0.1z/crm/forms/z/manifest.webmanifestz/app/assets/z/forms/z/js/z/pub/z/sso/z	/helpdeskr  z/servicedeskz/docs/)r  methodcheck_db_lockr   r   r  before_requestr   r   r   flagsremove_filesr   r   rT   Ztestr  r   r  r  r  r5   r  Zsave_only_data_hackalertnoter  r  Zis_guest_userZis_anonymousr  Zis_system_contextr  r  Zdisable_notifyZimport_modesession_tab_idZcomponent_idZinteractive_shellr  r  r  	api_scoper  sessionr   r   rd   rw   r  rL  r  Zrelaxed_bz_python_mode	emit_listsocket_eventsserver_eventsZdeferred_audit_listr  Zjscache_timelifeZTEXCOM_ENABLE_GROWCACHE_HACKr	  r-  r.  Zacquired_locksZacquired_lock_timignsr   r   Zfulltext_search_headlinesr<  Zproject_perm_browse_cacheZ%project_perm_timetrackerhistory_cacheZshow_bg_progressbarZapi_hack_fieldsr4   r   ZCmfDeferredJobZinit_contextCmfAccessListrE   r  r  rZ  rb   r  r   r   r  Z
hash_tokenr   r  r3   warningr   Z
CmfWebhookZget_token_personr   check_sso_redirectr   redirectauth_base_hrefZcookiesZ
CmfSessionZ
from_tokenCmfAuthZfrom_jwtZIS_AUTHORIZATORrr   r  r  r  Zjwt_is_supportr  Zservicedesk_allow_auth_guestsZjwt_is_match_orgr  r  r  r  r   Zremote_addrZ	CmfPluginZcheck_secretSTATIC_URL_REr  r  Zsetup_contextreject_responser  prepare_plan_cache_doneprepare_plan_cacheZtfa_check_two_factor)r  r  Zauth_personZ	real_authZ	api_tokenr   r  r   qsZerr_msgr  r  Z_filterZis_force_publicr  Zanon_personZis_allow_without_authr   r   r   r   r
  :  s   




$












 ""	

r
  c             C   s(   t jjdgd}|r$|js$|| S d S )Ndisabled)r   )r   ZCmfAuthOpenIdPluginrT   r   Zlogin_redirect)r  Zopenidr   r   r   r  	  s    
r  c             C   s   t dtjtjtjtjtj tj	ds@tj	ds@tjdkrRt
| pHddddS d	tji}| rh| |d
< t|}tjdkrtt  d| }nt }|stt  d| }tjdd|jd< d|jd< d|jd< |S d S )NzJRequest reject access: path=%s, auth=%s, login=%s, api_scope=%s, person=%sz/socket.io/z/api/z/pub/webhookznot authorizedi  z
text/plain)r  r  messager  zservicedesk/auth/signin?zauth/signin?r  r   zAccess-Control-Allow-Originr  z Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)r3   r  r  rZ  r   r  r  r  r  rb   r   r'   r   r  r  r  r  rT   )r!  paramsr  r   r   r   r   r  	  s(    




r  c               C   s   t   t  t  d S )N)r  r  emit_eventsemit_server_eventsr   r   r   r   commit_with_event	  s    r%  c           	   C   sR   t dsd S x8t j D ]*\} }td|d  |d|ddd qW i t _d S )Nr  zis_changed-r   r   r   private)	namespacer   )r   rT   r  r{   r   )r   r   r   r   r   emit_list_apply	  s
    
&r(  c             C   s,  x$|   D ]\}}x
|D ] }|d }|d= t|d }|d= |d  }y"t| t| t| W nD tk
r } z&td| d| d| d|  wW d d }~X Y nX t|ts|j	|f|d |d	|d	 i q|d
 r.|d
 dks.|d
 |d
< |j	|f|d |d	|d	 i q|
dr|d rd|d d krl||d d d  d|d d krx$|d d d D ]}|| qW xz|D ]r}	t|	tjjrtd|	 d| d| d|  |	jj}
nt|	}
|
|d
< |j	|f|d |d	|d	 i qW qW qW d S )Nsocket_clientr   r   uP   DEV: FATAL emit пришел с несериализуемыми данными z! socket_client:z; event_persons:z; event_param:r   r'  r   r&  r   event_current_personr   Zrelation_personsuY   DEV: INFO Кривой евент, в event_person попал объект, а не str: r.   )r{   r   copyrK   rL   ry   r$   r   rQ  rY   rb   r   ro   r   r9  rl   rr   r/   )Z
event_dictmsgZevent_param_listZevent_paramr)  r   Zemit_kwargsr   Zuser_idevent_personevent_persons_strr   r   r   emit_events_dict	  sF    

 
""

 
r/  c               C   s   t dd d S )Nr   )delay)emit_events_with_delayr   r   r   r   r#  
  s    r#  c              C   s\   dd l } tdsd S i }x4|  tjD ]$}|dr(tj| ||< tj|= q(W t| d S )Nr   r  Zproject_notify)r+  r   rT   r  rb   r/  )r+  r  r,  r   r   r   emit_project_events
  s    

r2  c                sL   t   tdpi i t_r< r< fdd}t| nrHt dS )u   Запускаемся в контексте, но отправляем в отдельном таске вне контекста, после паузы, чтобы не держать запрос.r  c                  s   t   t d S )N)rA  sleepr/  r   )r0  r  r   r   emitter
  s    
z'emit_events_with_delay.<locals>.emitterN)r(  r   rT   r  rA  rB  r/  )r0  r4  r   )r0  r  r   r1  
  s    r1  c              C   sT   t dpg } g t _x:| D ]2\}}t d| d|  tj|t| qW d S )Nr  zemit_server_events: z, )	r   rT   r  r4   r  rg  rJ   rK   rL   )r  r?  rC  r   r   r   r$  $
  s
    r$  c               C   s   t   i t_d S )N)r  Zrollback_all_dsr   r  r   r   r   r   rollback_purge_event,
  s    r5  c              C   s6   x*t dg D ]} tj| rt|  qW g t _d S )Nr  )r   rT   r   rZ  r   r   r  )rc  r   r   r   apply_deferred_remove_files2
  s    r6  c             C   s   t jrtjt j|  dS )u   Сессия может быть продлена через SSO, надо продлить куку

    Args:
        r (response): ответ браузеру в котором обновляем куки
    N)r   r  r   r  Zset_session_token)r   r   r   r   update_cookies:
  s    r7  c             C   sJ   t ddd t|  tjdd| jd< d| jd< d	| jd
< d| jd< | S )uk   
    Запускается только если небыло ошибок
    :param r:
    :return:
    Trg   )after_hooksevent_delayr  r   zAccess-Control-Allow-Originr  z Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-HeadersbyteszAccept-ranges)
cmf_commitr7  r  r  rT   )r   r   r   r   acaoE
  s    


r<  c           	   C   sN   ddl m}  tjsd S tjt_tjj	
  tjjj  W d Q R X |   d S )Nr   )spawn_server_event_listener)Zcmf.cmf_server_event_listenerr=  rE   r  ZDISABLE_PERMISSIONSr   disable_permissionsro   r   r   r  includer   r  Zload_acl_data)r=  r   r   r   app_init_aclW
  s    r@  c            	   C   s<   t tjjdsd S tjj  tjjj  W d Q R X d S )NCmfProjectPermScheme)	r}   ro   r?  r   r   r   r  rA  Zload_project_permission_datar   r   r   r   app_init_project_permissiond
  s    rB  c           z   C   sF  t tddkrd S tjj * tj } tjj	| d d}|
  W d Q R X tj	 }|r|  |  |ddddg |d	d
ddddg |ddddddddg |ddg |dddddddddd d!d"d#g |d$g |dddd%ddd&d'd(d)g
 |dd*d+d,g |d+d,g |d-d.d$g |d/g |d-d0d1g |d2d3d4ddd+d,d5g |d6d7dd8g |d9dg |dd:g |dd;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMd	d3dNdOdPdQd4ddRdSd6dTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddd&dddddddddddddddddddddddd5dgs |dddg |d;dddtdddddddddg |dddddddg |ddddddddddd d!dd"d#ddg |dg |ddd;d<d=d>d?d@dAdBdCdDdEdFdGdHdIddJddKdLdMd	d3dNdOdPdQd4ddRdSd6dTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddeddfdgdhdidjdkdldmdndodpdqdrddtdudvdwdxdyddzd{d|d}d~dddddddddddddddddddddddddddddddddddddddd5dgx xRdddgddddgdddggfD ].}|dddgg}tjj|dddddgdō q.W tj	 }|r|  |  |ddddg |ddddddg |d6ddddddg tj	 }|r"|  |  |ddg |ddddg |d	d3ddddddddddg tj	 }|rB|  |  d S )Nr[  z/opt/eva-apprl   )rl   r  rV  r   Z	scheme_wfr  ZdealZordernozparent.project_idrU  r  z
perm_acl.*zperm_acl.cmf_ownerz!perm_acl.object_ownerperm_inheritZperm_effective_acl_idZperm_has_aclZperm_inherit_acl_idZperm_parentZparent_logic_prefixz0parent.sl_allow_executor_change_nofatal_deadlinezparent.sl_deadline_shiftzparent.sl_deny_no_approvezparent.sl_only_owner_approvezparent.sl_task_need_approvezparent.sl_task_only_owner_closezworkflow.enable_sl_controlz2workflow.sl_allow_executor_change_nofatal_deadlinezworkflow.sl_deadline_shiftzworkflow.sl_deny_no_approvezworkflow.sl_only_owner_approvezworkflow.sl_task_need_approvez!workflow.sl_task_only_owner_closez'project.task_code_use_logic_type_prefixZperm_inheritZperm_policyZperm_policy_anonymousZperm_policy_guestZperm_policy_sharelinkZcmf_owner_assistantszparent.cmf_ownerzparent.cmf_owner_assistantszlogic_type.obj_code_prefixzproject.task_code_prefixz!parent.default_agile_story_pointszparent.task_code_prefixz&parent.task_code_use_logic_type_prefixZcache_status_typeZcmf_created_atr  Zwaiting_forr|  ZhrefZui_nameZop_gantt_taskZtree_parent_idZagile_story_pointsZ
alarm_dateZapprovedZattachmentszattachments.cmf_created_atzattachments.urlzattachments.url_previewzattachments.url_preview_imgZchild_taskszchild_tasks.activityzchild_tasks.agile_story_pointszchild_tasks.cmf_deletedzchild_tasks.is_checkedzchild_tasks.listszchild_tasks.logic_prefixzchild_tasks.parent_taskzchild_tasks.responsiblezchild_tasks.statusZcloned_fromr  Zcmf_locked_atZcmf_locked_byr   zcmf_owner.avatar_filenameZcmf_owner_idzcomments.cmf_authorzcomments.cmf_created_atzcomments.cmf_ownerzcomments.importantzcomments.likeszcomments.log_levelzcomments.parentzcomments.person_views.personzcomments.privatezcomments.spectatorszcomments.textzcomments.tree_parentZcompanyzcompany.is_internalZ
componentsZdeadlineZ	executorsZext_idZgantt_projectZgit_brancheszgit_branches.urlZgit_commitszgit_commits.urlZgit_merge_requestszgit_merge_requests.mergedzgit_merge_requests.urlZhas_child_tasksZin_tasksZ
is_checkedZis_milestoneZis_templateuA   link:/?popup=1&obj=${id}&uiModule=acl:Настройки правZlistszlists.logic_prefixzlists.parent.logic_prefixzlists.sys_typeZlocal_linksrW  zlogic_type.ui_colorZ	main_listZmarkZ
no_controlzop_gantt_task.actual_completeZ	out_tasksZoutline_numberzparent.logic_prefixzparent.logic_typezparent.main_gantt_projectZparent_taskz#parent_task.cache_branch_gantt_pathzparent_task.logic_typeZperiod_clear_checkboxZperiod_create_newZperiod_intervalZperiod_next_dateZperm_encryptZplan_end_dateZplan_start_datepriorityZremaining_estimateZresponsibleZresult_textZ
spectatorsstatusZstatus_closed_atZstatus_review_atZtagsz
tags.colorz%tags.tag_category.ui_separated_widgettextZtime_estimateZ
time_spentZtimetracker_historyZtimetracker_is_runningZtmplt_documentZtree_parentZui_view_formr  Zworkflowzparent.ui_form_schemezresponsible.namezstatus.status_codezstatus.status_typezcmf_author.user_localzcmf_owner.user_localzexecutors.user_localzparent.cmf_owner.user_localzresponsible.user_localzspectators.user_localzwaiting_for.user_localzparent.sl_readonly_closed_taskz workflow.sl_readonly_closed_taskz5workflow.sl_deny_closing_task_before_closing_subtasksu.   workflow.sl_сlose_task_after_closing_subtasksz9project.security_level_scheme.default_task_security_levelZaffected_versionszchild_tasks.logic_type.ui_colorzchild_tasks.priorityZfix_versionsu`   link:/?popup=1&obj=${id}&uiModule=acl:Настройки уровней безопасностиZperm_security_levelZcache_action=r  ORr$  Z	cmf_modelCmfTaskZjson_filterZjson_entry_pointZjson_actionZ	func_nameZ	json_data)r  r   r   Zsys_typezparent.codez	parent.idzparent.logic_type.namezparent.nameZ	log_levelzparent.activityzparent.logic_type_idzparent.scheme_wfZ	importantZlikeszperson_views.personr&  )r   rE   ro   r   r   r  r   rH  Zcreate_dummy_taskrT   Zdelete_dummy_taskZsave_prepareZ_load_perm_fieldsr*  Z
CmfTriggerrz   r  Z
CmfCommentZ	CmfNotify)Zdummy_task_dataZ
dummy_taskr   Z_fr  crq  r   r   r   r  l
  sl    

$",& 

"
r  c               C   s8   t   t  t  t  tjr(t  tj	r4t
  d S )N)r  before_first_requestr   preprocess_requestr@  rB  rE   WHATSAPP_MESSENGER_URLspawn_messenger_socketio_clientWHATSAPP_WEB_SOCKETspawn_whatsapp_socketio_clientr   r   r   r   rJ  
  s    rJ  c             C   s   t | d d S )N)r  )cmf_rollback)r  r   r   r   teardown_request
  s    rQ  c          	   C   s   |rt jsdS |dkr&|r tjntj}tjd|  d| d| d| |d |dk	rd|t j krddS |rdt	
 }td|  t| | tjkrtj|  dS )	u   
    Глобальная функция для оповещения фронта о предупреждениях
    :param msg:
    :return:
    Nzcmf_alert: msg=z abort=z debug_only=z devel_only=)r  r   zcmf_alert Stack:
)rE   rF   r3   ZWARNINGr  r   r4   
PRODUCTIONr5   r~  format_stackri  r  r   )r,  r   r   
devel_onlyr  Z	stack_strr   r   r   r   
  s    
&
r   c             C   sn   |rt jsdS |dkrtj}tjd|  d| d| |d |dk	rT|t j krTdS | tjkrjtj|  dS )u   
    Глобальная функция для оповещения фронта о предупреждениях
    :param msg:
    :return:
    Nzcmf_note: msg=z debug_only=z devel_only=)r  )	rE   rF   r3   r  r   r4   rR  r  r   )r,  r   rT  r  r   r   r   cmf_note
  s    
 
rU  r&  )r'  r)  r   r   c         
   O   s  |st }ydtkrt t_W n" tk
r> } zd S d }~X Y nX t|dkrfdtjr^tjjjp`d ig}t	|d tkrdtkrtj
|d d< nd|d d< tjrtjjjpd |d d< t||||d}t| ||d< d	}	xd
D ]}
| |
rd}	P qW |	rtdt   |s4tjg}|	s4tdt   g }x<|D ]4}t|tjjrb||jj n|t| q>W ||d< t|d  tj| g }||kr|| d S )Nr  r   rO   r  rf   r*  )r   r   r'  r   r)  F)
zevent-zinvaldebug-ztask-comment-zaudit-task-comment-znotify-person-zis_changed-zcomment-z	notify-osznotify-important-ZDEBUG_TuC   DEV: WARNING в cmf_emit_event не указали cmf_emit_event: u   DEV: FATAL!!!!!!!!!!!!!! Добавьте меня в спинт Баги реактивности. 10.10.2022 в cmf_emit_event не указали cmf_emit_event: r   )socketior   r<   r  ry   r   r  rl   rr   rm   r  rK   rL   rb   r$   localsr   r   ro   r   r9  r   r/   
setdefault)r,  r'  r)  r   r   r   r   r   Zevent_paramsZmutedZ
muted_debtr.  r-  Z
event_listr   r   r   r   
  sL    




r   c             C   s  |rd |nd}|rdnd}	|r&dnd}
d |	|| |
g}|rRddlm} | }tj|dtjtjd	}|r| \}}|r| }| }|j}|r|rt	d
| t	d| t	d| t
d| |g}|r|| || n||p| |r|| |  |S dS )u  
    :param command: собственно, команда которую необходимо выполнить
    :param sudo: необходимо ли команду выполнять от рута
    :param timeout: секунд на выполнение. Дальше команда получит SIGTERM.
    :param wait: True дождаться окончания выполнения команды, False запустить и забыть, вернёт (None, None)
    :param separate_out_and_err: отдельно stdout, отдельно stderr, иначе не ясно как это всё парсить
        False по умолчанию, чтобы никому ничего не сломать.
    :param do_decode: возвращать декодированные строки вместо байт
    :param do_raise: выбрасывать исключение в случае, если код возврата != 0 (удобно для логирования трэйсбэков)
    TODO: почему u''? Наследие python2 и биллинга или реальная необходимость?
    TODO: Можно перейти на f'{sudo}bash -c export BLA=BLA;{timeout}{cmd}{redirect}', читается лучше
    ztimeout -v {0} rf   zsudo z 2>&1z0{0} bash -c "export BOOTUP="noncolor";{1}{2}{3}"r   )r  T)shellr  rH   u6   Произошла ошибка при вызове %sz
STDOUT: %sz
STDERR: %su4   Произошла ошибка при вызове )NN)r  r  
subprocessPopenPIPEZcommunicaterS   
returncoder3   errorRuntimeErrorr   )ZcommandZsudor  waitZseparate_out_and_errZ	do_decodeZdo_raiseZmeasure_runtimeZtimeout_cmdZ_sudoZ	_redirectcmdr  Zpopen_startZprocessouterrZerrcoder6  r   r   r   run_bash_command/  sD    

rd  c             C   sL   t tj}t }||   ||}t	|
 }|  d| }|S )ua   
    Подписываем токен сертификатом
    :param jwt:
    :return:
    r   )r
   r)  r   rsa_private_keyr	   r   r   signbase64	b64encoderS   )jwtZsignerZdigestrf  r   r   r   r   rsa_sign_pack_jwtd  s    
rj  c             C   sH   ddd}t t|  }t t|   } | d|  S )uD   
    Создаем токен
    :param payload:
    :return:
    ZRS256ZJWT)Zalgtypr   )rg  rh  rK   rL   r   rS   )payloadheaderr   r   r   
create_jwts  s    
rn  c               C   s   t jS )u2   
    Текущая версия
    :return:
    )rE   ZCMF_VERSIONr   r   r   r   cmf_get_version  s    ro  c             C   s   | t jkrt j|  dS )ux   
    Удаления файлов после коммита транзакции
    :param filename:
    :return:
    N)r   r  r   )rc  r   r   r   cmf_remove_file  s    
rp  c             C   s   t j| d d S )N)r  )r  r  )r  r   r   r   rP    s    rP  c             C   sJ   t   | rFddlm} |j  t  t|d t  t	  t   d S )Nr   )r   )r0  )
r  r  cmf.includer   ZCmfAuditZapply_deferred_auditr2  r1  r$  r6  )r8  r9  r   r   r   r   r;    s    

r;  c               @   s,   e Zd Zd
ddddZdd Zdd	 ZdS )cmf_contextFN)r9   c             C   s   t d| _|| _d S )Nz/with-context)r   Ztest_request_contextctxinit_views_and_ds)r   rt  r   r   r   r     s    zcmf_context.__init__c             C   sD   ddl m} | rtd| j  | jr8t  t  t	
  d S )Nr   )has_app_contextu;   Контекст нельзя включать дважды)r]  ru  ry   rs  	__enter__rt  start_viewsr  Zinit_dsr   rK  )r   ru  r   r   r   rv    s    
zcmf_context.__enter__c             C   sJ   z|rt |d n
tdd W d |r4tjr4| j  | j||| X d S )N)r  T)r8  )rP  r;  r   Zpreserve_context_on_exceptionrs  r   __exit__)r   excrr   r~  r   r   r   rx    s    
zcmf_context.__exit__)F)r"   r    r,   r   rv  rx  r   r   r   r   rr    s   
rr  c              C   s   ddddddg} t jdd | D  }x|D ]\}}}|tjd	}|d
r*xd|D ]\}|dsj|drR|dsRddd |dD }t	j
|d |dd  d d qRW q*W tjddtd tjddtd tjddtd tjddtd t  d S )Nz	cmf/viewszcmf/modulescommonmoduleszcustom/commonzcustom/modulesc             S   s&   g | ]}t jtj d | ddqS )r   T)followlinks)r   walkrE   r[  )r0   Z
search_dirr   r   r   r     s   zstart_views.<locals>.<listcomp>rf   z/viewsz.pyz.pycz__init__.pyr   c             s   s   | ]}|r|V  qd S )Nr   )r0   r   r   r   r   r2     s    zstart_views.<locals>.<genexpr>r   r   )packager  )r   Z	view_funcz/<path:req_filename>Zdistz/static/<path:req_filename>Zstaticz,/plugins/<plugin>/static/<path:req_filename>Zplugins_static)	itertoolschainrx   rE   r[  r   rb   r5   r!   	importlibimport_moduler   r#   re  app_before_run)rb  Zsearch_iterdirnameZdirnames	filenamesrc  r&   r   r   r   rw    s"    


(rw  c               C   s   d S )Nr   r   r   r   r   r    s    r  c             K   s,   | dd ||d< ||d< | jf | d S )NZ	countdownrg   r   r   )rX  Zapply_async)Zjobr   r   r(   r   r   r   schedule_deferred_job  s    r  c              C   s"   dd } t jrtj| dgd d S )Nc             S   s2   i }t jdd rdtji}tjtj| |d d S )NZSOCKETIOr   )
namespacesr  )r   r   rT   rE   ORG_NAMEwhatsapp_sioconnectrL  )r  r  r   r   r   messenger_connect  s
    
z:spawn_messenger_socketio_client.<locals>.messenger_connectz	/whatsapp)r  )rE   rL  rA  rB  )r  r   r   r   rM    s    rM  c               C   s   t tjtj d S )N)rA  rB  whatsapp_go_sior  rE   rN  r   r   r   r   rO    s    rO  c              C   s@   dd l } tddtj dtj  | jtjtjdddd d S )Nr   z%suY   Подключаемся к удаленной отладке config.REMOTE_DEBUG_SERVER=z config.REMOTE_DEBUG_PORT=TF)ry  ZstdoutToServerZstderrToServerZsuspend)pydevd_pycharmr3   inforE   ZREMOTE_DEBUG_SERVERZREMOTE_DEBUG_PORTsettrace)r  r   r   r   cmf_pycharm_debug  s    r  )r9   c              C   sH   t tjtjttt ttt d tjj	dd} t
| }t|S )N<   Zguid)ZissZorg_nameZiatZexpr  Zjti)r<   rE   APP_FQDNr  r/   rs   r  r   r  rr   rn  rj  )rl  ri  r   r   r   gen_eva_app_token  s    r  )urirC  c       
      C   s   ddl m} tjrtjdkrPttj|d }|dg }|di }|||}n| }ddd	d
|_t	  |  }t
 |d< |j|t|d}	|	jdkrtd| d|	j d|	j |	 }|rd|krtd| t| |S )Nr   )r  Falser  r   r   zapplication/jsonz
text/plainzutf-8)zContent-typeZAcceptzContent-EncodingZeva_app_token)rC     u9   Не удалось отправить запрос, url=z, status_code=z, res=r^  u(   Сервер вернул ошибку: )Zrequestsr  rE   ZEVA_ACCOUNT_USEr   r   r  rT   r  r  r  ZpostrK   rL   r  ry   Zcontentr   r4   )
r  rC  r  r  Zmethod_argsZmethod_kwargsresultr   r'   r   r   r   r   call_eva_account  s*    



r  Zeva_db_upgrade_runningc             C   s6   | st t } tjjt| ddds2tdt dS )u   Запускается перед миграций БД. Информирует приложение, что не следует открывать транзакции.r  T)exZnxzCannot lock N)r/   r   r=  r  rg  r   _DB_LOCK_KEYCmfError)rr   r   r   r   app_db_upgrade_start5  s    r  c               C   s   t jt dS )u   Запускается после миграций БД. Информирует приложение, что можно продолжать работать.N)r  rg  rW   r  r   r   r   r   app_db_upgrade_stop=  s    r     c             C   sb   dd }d}t   }xH| r\| r0t   | |krH|rDtdt ndS |d7 }t d qW dS )u   Проверяем не заблокировано ли использование БД, если заблокировано, то можем дождаться разблокировки.c               S   s,   t rt t  dkr(tjtat a tS )uW   используем кеш 1sec, чтобы часто не ходить в редисra   )_db_lock_cache_tsr  r  rg  rT   r  _db_lock_cacher   r   r   r   
check_lockD  s    z!check_db_lock.<locals>.check_lockr   z
DB locked Fra   T)r  r  r  r3  )r`  r  Zraise_errorr  rM   startr   r   r   r	  B  s    r	  c              C   s>   dd l } tjrd}ntj}| j|dd |  }|| d S )Nr   rF   z:%(asctime)s %(process)d %(name)s %(levelname)s %(message)s)r  r  )Zlogging.handlersrE   rF   Z	LOG_LEVELZbasicConfigZ	getLoggerZsetLevel)r3   r  ru  r   r   r   init_loggingY  s    r  httpsc             C   sR   t jpd}|ds|d7 }| rNt jr2dt j nd}| dt j | | S |S )Nr   rj   rf   z://)rE   	BASE_HREFr   EXTERNAL_PORT_HTTPSr  )Zfull_urlZprotocol	base_href	port_specr   r   r   app_base_hrefi  s    

r  c             C   sl   t jrt j}nH| rD|rd}qHt jr.dt j nd}dt j | }nd}|t jpRd7 }|dsh|d7 }|S )Nzhttp://127.0.0.1:8080rj   rf   zhttps://r   )rE   ZAUTH_SERVER_URLr  r  r  r   )ZabsoluteZinternalr  r  r   r   r   r  s  s    
r  )rf   N)r  r  )FF)N)N)r   )N)FFNN)FNN)TNTFFFF)T)Tr   )NN)N)Tr  T)Fr  )FF)r:  r  r3   rG   Zfcntlrg  r   rU   rZ  r  r~  r%  r   r   Zpathlibr   Zurllib.parser   r   r   r   rA  r   r  ZCrypto.Hashr	   ZCrypto.Signaturer
   r]  r   Z
flask.jsonr   Zwerkzeug.exceptionsr   ro   r   rq  Zcmf.data_providersr   r  Zcmf.system_datar  compiler  r   r7   objectr8   rI  rJ  r"   rE   r[  r   Zjson_encoderr  r  ra  r>  Zcache_in_project_roler  Z
rpc_modelsZclean_attributesZflask_socketiorQ  rR  rV  rS  rT  rg  rX  r/   rY  re  rf  r  r}   rt  r+  Zcfgr   rs  r   r   rT   ry   rF   Zsocketio_kwargsrv  r'   rw  rz  Zengineio.payloadr{  Zmax_decode_packetsr  r  rZ  r   openr%   readr  r  r   ZREDIS_DB_IDZREDIS_DB_ID_TIMERZerrorhandlerr  Zregister_error_handlerZprivate_key_pathZpublic_key_pathZCrypto.PublicKeyr  Z
import_keyZ
read_bytesre  Zrsa_public_keyr  r  r  r  r  r  r   r  r  r  propertyrm   r   r   r   r  r  r  r  r4   r  r
  r  r  r%  r(  r/  r#  r2  r1  r$  r5  r6  r7  Zafter_requestr<  r@  rB  r  rJ  rQ  r   rU  r   rd  rj  rn  ro  rp  rP  r;  rr  rw  r  r  rM  rO  r  r  r<   r  Zcache_notify_scheme_ruleZcache_person_notify_optZcache_cust_field_config_schemer0  r  r  r  r  r  r	  r  r  r  r   r   r   r   <module>   s  
          [

; 


 


"


c	 "

  i

0
D

: 
4

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

