U
    rwe                     @   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	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZ d dlZd d
lm Z m!Z! d dl"T d dl#m$Z$ dd Z%e&e'dddd Z(e)j*ddddd Z+e)j*ddddd Z,e)j*ddddd Z-e)j*ddddd  Z.e)j*d!ddd"d# Z/e)j*d$ddd%d& Z0d'd( Z1d)d* Z2d+Z3G d,d- d-ej4j5Z6dS ).    N)OrderedDict)deepcopy)is_dataclass)isclass
isfunctionismethod	signature)time)uuid4)Responserequest)dumpsloads)commit_all_dsrollback_all_ds)*)	CMF_CACHEc                  C   sd   t jrt t j dk rt jS t jdsDtt } t jjd| dd t jd	 t _t t _t jS )N   redis_idT)Znx)
APPREDIS_DB_IDr	   ZREDIS_DB_ID_TIMERZREDIS_DBexistsintsetgetdecode)r    r   ./modules/api/views/index.pyget_redis_id   s    
r   zCmfCache:flushdb)Zchannelc                  O   s   d t _td td d S )NzAPP.REDIS_DB_ID = NONE)r   r   printgdebugargskwargsr   r   r   flush_redis_id+   s    r%   zjshash-invalidate-confirm/)	namespacec                 O   s   t |  d S N)r   Zjshash_invalidate_confirm)Zconfirm_dictr#   r$   r   r   r   handle_message9   s    r)   Zuser_regisrtyc                 C   sN   ddl m}m} td|   | dd }|r6|| tjd| |d d S )Nr   	join_room
leave_roomzhandle_user_regisrty: user_idzMe registered: roomflask_socketior+   r,   r   r   socketioemitparamsr+   r,   r-   r   r   r   handle_user_regisrty=   s    r6   r+   c                 C   s   ddl m} td|   || d  tjjjd| d d}tt|}tj	d| d  d	| d  d
|i| d d tj	d| d  || d | d | d d| d d d S )Nr   )r+   handle_user_join_room: 	room_namer&   r'   r/   zUser r-   z	 join to participantsr.   z
Joined to 	user_name
user_login)r:   r;   r<   r-   )
r1   r+   r   r2   servermanagerget_participantslenlistr3   )r5   r+   r:   ZparticipantsSizer   r   r   handle_user_join_roomG   s    ,rB   r,   c                 C   sd   ddl m} td|   || d  tjjjd| d d}tjddtt	|i| | d d	 d S )
Nr   )r,   r7   r8   r&   r9   zUser leave roomr:   r.   )
r1   r,   r   r2   r=   r>   r?   r3   r@   rA   )r5   r,   r:   r   r   r   handle_user_leave_roomX   s
    rC   document_broadcastc                 C   s   t jd| | d tjjd d S )NrD   r8   )r/   Zskip_sid)r2   r3   flaskr   Zsid)r5   r   r   r   handle_document_broadcast`   s    rF   Z	user_pingc                 C   sB   ddl m}m} td|   | dd }|r>td|  d S )Nr   r*   zhandle_user_ping: r-   Z
user_pong_r0   r4   r   r   r   handle_user_pinge   s
    rG   c                    s   i  fdd}|S )Nc                     s4   t | t| f}|kr, | ||< | S r(   )pickler   sorteditems)r#   r$   hashfuncZmemoryr   r   memot   s    zmemoized.<locals>.memor   )rM   rN   r   rL   r   memoizedq   s    rO   c                 C   s   dt krt t _|t j| < d S )Nprofiler_data)r    r   rP   )keymsr   r   r   set_call_time|   s    rS   z******c                       s  e Zd ZdZd4dd fddZd5ddZd6dd	Zd7d
dZdd Zd8ddZ	dd Z
d9ddZdd Zd:ddZed;ddZdd Zejjdd ZedZd<d!d"Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd=ed/d0d1Z ejjd2d3 Z!  Z"S )>ApiViewr&   N)returnc                    s   t    | j|d| _d S )N)extra_models_list)super__init__get_rpcrpc)selfrV   	__class__r   r   rX      s    
zApiView.__init__c                 C   s   |rdd |j jD |d< |S )Nc                 S   s   g | ]
}|j qS r   )__name__).0Ze_clsr   r   r   
<listcomp>   s     z/ApiView._add_exception_info.<locals>.<listcomp>Zexception_types)r]   __mro__)r[   result	exceptionr   r   r   _add_exception_info   s    zApiView._add_exception_infoc                 C   s*   d||dt dt jd}| j||dS )N2.0)codemessagealert)jsonrpcerrorrh   callidrc   )r    r   
api_callidrd   )r[   rf   rg   rc   rb   r   r   r   _error   s    zApiView._errorc                 C   sV   |sg }d|||t j|t dt d|t |t d}t jrHt j|d< | j||dS )Nre   rP   rh   )ri   rb   metajsverrk   jsurlrP   rh   abortversion
invalidater   jscache_timeliferl   )r    rm   r   Zcmf_get_versionr   ru   rd   )r[   rb   ro   rp   rq   rt   rr   rc   r   r   r   _ok   s$    
zApiView._okc                 C   s   |  ddS )NiDzParse errorrn   r[   r   r   r   parse_error   s    zApiView.parse_errorc                 C   s&   d}|  d|d kr|n| d| S )NzInvalid Requestiz: rw   )r[   rg   titler   r   r   invalid_request   s    zApiView.invalid_requestc                 C   s   |  ddS )NizMethod not foundrw   rx   r   r   r   method_not_found   s    zApiView.method_not_found c                 C   s   |  dd| S )NizInvalid params: rw   )r[   rg   r   r   r   invalid_params   s    zApiView.invalid_paramsc                 C   s   |  ddS )NizInternal errorrw   rx   r   r   r   internal_error   s    zApiView.internal_errorc                 C   s$   |t dddkst| j|||dS )Ni irl   )rangeAssertionErrorrn   )r[   rf   rg   rc   r   r   r   server_error   s    zApiView.server_errorc                 C   s  i }|sg }nt |}|tjj tt|D ]}t|rR|}t|d|j}nDtt|d pjttj|d }t|svq0t	|tjjsq0|j
sq0|jrq0i }t|D ]}t||}t||}|drqt|st|st|tsq|tjjkr|dkrqt|t}	t|t}
t|t}|| |	|
|dd}|||d < qt	|tjjr|j D ]\}}g }t	|tjjtjjfrddd	d
g}nt	|tjjrddg}|D ]D}| d| }t||}||t|ddddd|| d| < qqV|||d}|||d < q0|S )N
class_name_)Zall_models_metaZpublic_all_models_metaZget_ui_full_pathZpublic_get_ui_full_pathZsdesk_get_ui_full_pathZpublic_noneZpublic_none_classmethodF)_methodnameis_class_methodis_static_methodis_taskis_field_methodr   appendremoveextendZ
all_nested.T)r   r   r   r   r   r   r   )_classr   methods)rA   r   cmfmodelsZ	BaseModeldirr   getattrr^   
issubclass	api_allowZabstractinspectZgetattr_static
startswithr   r   
isinstanceZCmfDeferredJobWrapperclassmethodstaticmethodlowerfieldsrJ   ZCmfM2MZCmfGenericM2MZCmfJsonr   )r[   rV   Z
rpc_modelsZ
model_nameclsZrpc_methodsZmethod_namemethodZmethod_attrr   r   r   Z
rpc_method
field_nameZ	field_clsZ
submethodsZ	submethodr   Z	rpc_modelr   r   r   rY      s~    




	
zApiView.get_rpcc                 C   s   |dkS )NZ	qweqweqwer   )r[   tokenr   r   r   check_token  s    zApiView.check_tokenc                 C   s   | j d| jtdS )Nz
index.html)rZ   r
   )Zrender_with_paramsrZ   r
   rx   r   r   r   r   !  s    zApiView.getz9"(?P<attr>(cmf|doc|obj|approved)_version)":(?P<value>\d+)Fc              
   C   s  t js>|s>t|tkr>t|dkr>tdt| dtj d t js|st|tkrt|dkrtj	
 t	dddkrtd	t| dtj d | |||||}|rt|}	t| jd
|	 }	n`zt|ddd}	W n< tk
r }
 ztd|
 d|  |
W 5 d }
~
X Y nX t| jd
|	}	t js~|s~t|	dkr~tdt|	 dtj d | j||||||ddS t js|st|	dkrtj	
 t	dddkrtdt|	 dtj d | j||||||ddS t|	ddS )Ni  u}   Разработчик внимание! Критически много строк через API. Используй slice z, z...i,  i  r      uw   Разработчик внимание! Слишком много строк через API. Используй slice z"\g<attr>":"\g<value>"r   F)indentZensure_asciizJson dumps error: e=z
 response=i   uw   Разработчик внимание! Критически большой размер данных через API.  T)orjson_rt   	recursioni   uq   Разработчик внимание! Слишком большой размер данных через API. zapplication/json)Zmimetype)configZ
PRODUCTIONtyperA   r@   	cmf_alertr    
api_methoddatetimedateZtodayrv   cmfutilZ	cmf_dumpsresub_BIG_INT_JSON_HACK_REr   r   	TypeErrorr   sys	getsizeofresponse_okr   )r[   result_dictro   rp   rq   r   rt   r   ZresponseZ	json_dataer   r   r   r   (  s:    


zApiView.response_okc                 C   s   t jr
d S tjdrd S |ds2t d d S tj 	dd d t j
jjd}t|t|rzt d |d S t d	 d S )
NNO_CACHEjshash:z$api_cache_add failed, invalid jshash%Y%m%d%H%M%S%f)rp   Zcurrent_person_idzapi_cache_add endrp   zapi_cache_add failed)r    Zno_jscache_forceosenvironr   r   r!   r   utcnowstrftimecurrent_personidvaluer   Z_obj_dict_setrH   r   )r[   rK   Z	res_cacher   r   r   api_cache_addO  s    


zApiView.api_cache_addc                 C   sL   t jdrd S |dsd S t|}|s0d S t|}td|  |S )Nr   r   zAPI CACHE HIT )	r   r   r   r   r   _obj_dict_getrH   r   r   )r[   rK   Z_resresr   r   r   api_cache_get`  s    


zApiView.api_cache_getc                 O   s   | j |f||S r(   full_cache_validationr[   jshash_list_args_kwargsr   r   r   public_full_cache_validationl  s    z$ApiView.public_full_cache_validationc                 O   s   | j |f||S r(   r   r   r   r   r   sdesk_full_cache_validationp  s    z#ApiView.sdesk_full_cache_validationc                 O   sn   dt j  dd d i}|D ]6}|ds0q t|}|r t|}|d||< q | j	|d d t
jddS )Notherr   r   r   rp   T)ro   rp   rq   r   )r   r   r   r   r   r   rH   r   r   r   r    rq   )r[   r   r   r   rb   jshashZ
redis_data
cache_datar   r   r   r   t  s    


zApiView.full_cache_validationc                 C   s   t jrt jt jkrdS dS )u;   
        Проверяем доступ к апи
        FT)r    r   Zanonymous_userrx   r   r   r   _check_access  s    zApiView._check_access)r   c                 C   s   z|j ddd\}}W n tk
r,   Y dS X || jkr<dS | j| }|d }d}|dkrr|jsr|srd| }d	}||d
 krdS |d
 | }||d< ||d< |S )u  
        Поиск метода rpc

        находит метод в rpc_json
        проверяет его разрешенность
        возвращает указатель на функцию

        Возвращает не метод, а структуру из self.get_rpc + доп.поля:
         - use_simple - когда решили использовать slist или sget
         - _class - указатель на модель
        r   r   maxsplitNr   F)r   rA   sTr   _use_simple)split
ValueErrorrZ   disable_simple)r[   r   r   Zproc_cls_nameproc_methodZproc_clsr   
use_simpler   r   r   rpc_prepare_method  s$    


zApiView.rpc_prepare_methodc           ;      C   sv  d t _|  s| ddS t jjrPt jjtjkrP| ddt jj dtj dS t dt j	j
j d tj }ttj}t dtj d	tj d
| d t|ts|  S |dt _|dt _|dt _t jstddd t t _d|kr| dS |d t _|dd}|t _|dp,i }|d}d|ksXt|trnd|krntjdkrn| dS |dp|g }|d}|dkr2|dpi }|r||d< |dd }	|	r|	|d< |d d }
|
r|
|d < |d!d }|r||d!< |d"d }|r||d"< |d#d }|r2||d#< |dg t _d$d%d&d'd(d)d*d+d,d-h
}t jD ]6}||krv| | |d. |kr^| |d.  q^|t _!|d/i t _"t j"d0rt#j$%  |d1d }|r||d1< | d2S |d3}|d4d }|d5}|d }g }|d6kr(| j&||S |d7kr>| j'||S |d8krT| j(||S d }|d9d }| )||}|s~| * S |d: }|d; }|d< }d=}d>D ]}||d krd}d=t _+t j,-|j. d?|d krhd=}|dkr|r|d@ dAkrt|dB t/rt01|dB  d}|r>dA|kr>t01|dA  d}|r`dC|kr`t01|dC  d}|rd|kr|d d@ dAkrt|d dB t/rt01|d dB  d}|d d@ dCkrt|d dB t/rt01|d dB  d}|rdD|d@ krt01|d@  d}dE|d krdFdGdHdIdJg}|D ]}||d kr.d} qNq.|sht dK|d    qrqdF|d krd=}|r|dLrd=}t2|dMd=rd=}|dN} |dO}!|!t _3|r|!d krtdP| dd d=}|r|rt dQ n| rtj }t dR | 4|!}"t5dStj | j6dT  t dU |"r| |"dNkr|rrt78|}t dV | j9d d |"dN |||dWS t dX |dY sX|dZ sX|d[ rn|d\| }#t j:d]d^ d_k}$|dkrXt d` d|krvdA|d krv|d d@ dAkrvt da t }%|d |%d< dAg|%d< |$|%db< |jf |%}t;|d dckrV|d= n|dAs|rt da |j|dAg||$dd}n|rdA|kr|#rt01|dA t }%dAde|dAg|%d< dAg|%d< |$|%db< |jf |%}|<dAd nB|rJ|= }%g |%d< dAg|%d< |$|%db< |jf |%}n| dfdgS nt;|d@kstdD|d@ kr| dfdhS |<d@}&|#rt01|& t }%dAde|&g|%d< dAg|%d< |$|%db< |di djkrt j>?t/|& |jf |%}|di djk	rtt@|D ]r}'|jA|'}(|(	r |(jB	s:tdk|' dl |<|' n6tC|jA|' tDjAjE	r ||' tFk	r tdm |<|' 	q |	r|#	rt01|jGj tH|dC	r|j
jI	st01|j
j |	st dn tJ  | jKd i d |dodpS t|tDj#jL	o|jMj})t|tDj#jN
o
|jOj}*t|tDj#jN
o"|jPj}+t|tDj#jL
o:|jQjR},t#j$jS|)|j.|*|jGj|+|dq|,d=dr	
st ds t#jTjUdq|j.|dtdu tJ  | jKd i d |dvtV dwS t dx d]|di krJ|di j:d]dydz\}}-t#j$jS|)|j.||*|jGj|+|dq|,d=d{
s4t d| t#jTjUdq|j.|dtdu tJ  | jKd i d |d}tV dwS t2||}.t2|.|-}nt2||di }t5d~tj | j6dT  tj }t d|d   z(|d[ r|jW||d}/n
|||}/W n tXk
r> }0 zftY|0 tZ[d t/|0}1tt2|0dd t@t\frd]dd |0j^D }1| jKd i d ||1|0dw W Y S d }0~0X Y nh t_k
r }0 zHt`ja[d tY|0 d|d  d}2|2tbc 7 }2| jdd|2|0d W Y S d }0~0X Y nX t d t5dtj | j6dT  tj }|r|jert d z|f  W n tXk
r~ }0 zftY|0 tZ[d t/|0}1tt2|0dd t@t\frTd]dd |0j^D }1| jKd i d ||1|0dw W Y S d }0~0X Y nX t d t5dtj | j6dT  tj }tY  t5dtj | j6dT  tj }|di dkr|/o|/jGj}/n"|di djkrtH|/dAr|/jGj}/t0jg|/|d}3t d |r@|3h  n|3:  t5dtj | j6dT  |3ji|3jj }4}5|di dkr|5rd}6t|5tr|5ddkrdt}6|j.dks|6dtkrt|5trt#jTjUdq|j.|5dA |6du n.tk|5r
t#jTjUdq|j.|5jG|6du n
tl|5d|di dkrd}6d=}7d=}8|5D ].}9t|9trZ|9dd dkrZd}7nd}8q2|7rt|8rtd}6n
|7r~dt}6|j.dks|6dtkrt#jTjUdq|j.|6d t5d|3jm t d tj }|rt2t dd s| n|!} |rt78|}z| j9|5|4| |||d}:W n< tok
rL }0 zt d| d|5   W 5 d }0~0X Y nX t5dtj | j6dT  t d |:S )Ni  u   Нет правu>   Версия Eva отличается от версии БД: z != u   . Вероятно была запущен несовместимый образ Eva, либо были проблемы во время обновления и патчи применились частично.zAPI request start ()zrequest.remote_addr=z request.url=z
 json_res=r   session_tab_idcomponent_idrk   zAPI: No callid specifiedT)Z
devel_onlyr   zNo method specifiedrq   r}   r$   save_kwargsZ	only_dataz	127.0.0.1uM   SPEC0 Использование only_data через API запрещено.r#   ri   re   filterr   sliceorder_bygroup_byinclude_deletedperm_effective_acl_idZperm_inherit_acl_idZperm_parent_idZperm_parent_owner_idZ
user_localZvacation_endZvacation_startZperm_encryptZimport_original%perm_security_level_allowed_ids_cacheZ_idflagsZ
admin_modeno_cacheu)   no_cache запрещен go to spec0 osv
no_jscacheno_metacache_idzCache.full_cache_validationz"Cache.public_full_cache_validationz!Cache.sdesk_full_cache_validationr   r   r   r   F)z.getZ_getz.listZ_listz.selectZ_selectz.sumZ_sumz.count_countz.maxZ_maxz.minZ_minr   r   r      rf   :zCmfPersonVar.getZget_current_userZget_settingsZCmfRFilezCmfPersonVar.get_metaZCmfMenuTreez+Possible cache return invalid_data: method=Zsearch_stringZTEXKOM_no_cacherp   r   ur   ошибка на frontend методы list get и тп должны быть с jshash, кроме тестов z$api_cache_get skip due to no_jscachezapi_cache_get startr   i  zapi_cache_get endzapi_cache_get hit!)r   ro   rp   rq   r   rt   zapi_cache_get jsver mismatch!r   r   r   
for_updater   r   ZrestorezAPI object get startu~   deprecated id объекта нужно передавать в kwargs или может вообще параметром RPCcmf_deleted   )r   r   r   r   z==i  u   Необходимо указать filter или kwargs для получения объекта перед вызовом его методаu1   Необходимо указать id в args[0]r   updateu	   Поле u1    не доступно для изменения.uB   Не задано новое значение для пароля.zAPI object get Noneu>   Объект не найден, возможно удалён.)rb   ro   rp   rq   rr   read)	initial_acl_keyobject_modelobject_owner_id	object_idobject_parent_idobject_instanceaccess_levelperm_security_level_allowed_idsraise_errorzAPI object access prohibitedZfail)operatecmf_model_nameparentresult_statusuE   Объект недоступен: недостаточно прав.)rb   ro   rp   rq   rr   rc   zAPI object get endr   r   )
r   r   Zobject_fieldr   r   r   r   r   r   r   z"API object field access prohibiteduQ   Поле объекта не доступно: недостаточно прав.ZpreparezAPI method start r"   zUserError Trace:c                 S   s   g | ]}t |qS r   strr_   ir   r   r   r`     s     z ApiView.post.<locals>.<listcomp>	Exceptionu/   Ошибка выполнения метода z

irl   zAPI method endZcall_method_mszAPI save startc                 S   s   g | ]}t |qS r   r  r  r   r   r   r`   =  s     zAPI save endsaveZcommit)ZcreateZupsertZcreate_from_template)r   zAPI json dump startZresult_to_dict_ms)r   sgetokZ_acl_objZdenyCmfAuditz$get result must be dict or dataclass)rA   ZslistZ	partially)r   r   r  number_of_objectszAPI json dump endZcache_store_error)rt   r   uQ   Ошибка конвертации результата запроса json_res=z result_dict=Zresult_to_response_mszAPI request end)pr    rm   r   rn   Zglobal_settingsZeva_versionr   ZEVA_VERSIONr!   r   rf   r   r   Znowr   r   dataZremote_addrZurlr   dictry   r   r   r   r   r
   r{   r   rq   r~   Z
api_fieldsr   api_hack_fieldsr   r   ZCmfAccessListZactivate_admin_moder   r   r   r   r|   Zin_memory_cacheZin_memory_cache_skip_modelsr   r   r  r   Zcache_obj_lock_getr   r   r   rS   Zmicrosecondsr   Zjshash_invalidate_confirm_listr   r   r@   popcopyZskipcache_select_for_updateaddrA   r   r   r   r   ZCmfPassword_PASSWORD_MASKr   hasattrZvirtualr   rv   Z	CmfEntityr   ZCmfModelZcmf_owner_idZ	parent_idr   oldZcheck_accessr  Zaudit_eventZCmfPermissionErrorZapply_asyncZCmfUserErrorr   Zloggingrc   tuplejoinr#   r  r   logger	traceback
format_excr   Z
is_changedr  ZCmfResultSplitterZsplit_simplero   rb   r   r   r  r   r   );r[   Z
start_dateZjson_resrq   r$   r   r#   Zjsonrpc_verZ_filterr   r   r   r   r   r  r   r   r   r   r   r   Zinvalidate_listobjr   r   r   r   Zapi_use_cacher   Zcache_lock_okZ_cachelock_skip_methodsmrp   r   r   r   r   Z
tmp_kwargsr   argZfieldr   Zobj_owner_idZobj_parent_idr   Zfield_methodZ	obj_fieldrb   r   Z	abort_msgmsgZsplitterro   r   Zcheck_result_statusZcheck_result_have_denyZcheck_result_have_okZ_objZrespr   r   r   post  sL    

"




 


       










.&&
   









 


*







$
        
    
     
    



     	&



     




  
  





zApiView.post)N)N)N)NNN)N)r}   )N)N)FNF)F)#r^   
__module____qualname__Z__url__rX   rd   rn   rv   ry   r{   r|   r~   r   r   rO   rY   r   r   viewsactionr   r   compiler   r   r   r   r   r   r   r   r  r   r  __classcell__r   r   r\   r   rT      s6   

	



X


'	(rT   )7ZdecimalZ	ipaddressr   r   rH   stringZrandomr   r  collectionsr   r  r   Zdataclassesr   r   r   r   r   r   r	   Zuuidr
   rE   r   r   Zujsonr   r   Z
cmf.modelsr   Zcmf.data_providers.baser   r   Zcmf.includeZcmf.appr   r   r   Zon_server_eventr%   r2   Zonr)   r6   rB   rC   rF   rG   rO   rS   r  r"  ZBaseViewrT   r   r   r   r   <module>   sP   

	



