U
    4f                     @   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
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# Z0e*j+d$ddd%d& Z1d'd( Z2d)d* Z3d+Z4G d,d- d-ej5j6Z7d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   logginginfo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_message:   s    r*   Zuser_regisrtyc                 C   sR   ddl m}m} tdd|   | dd }|r:|| tjd| |d d S )Nr   	join_room
leave_room%szhandle_user_regisrty: user_idzMe registered: roomflask_socketior,   r-   r   r    r   socketioemitparamsr,   r-   r/   r   r   r   handle_user_regisrty>   s    r8   r,   c                 C   s   ddl m} td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,   r.   zhandle_user_join_room: 	room_namer'   r(   r1   zUser r/   z	 join to participantsr0   z
Joined to 	user_name
user_login)r;   r<   r=   r/   )r3   r,   r   r    r4   servermanagerget_participantslenlistr5   )r7   r,   r;   ZparticipantsSizer   r   r   handle_user_join_roomH   s    ,rC   r-   c                 C   sh   ddl m} tdd|   || d  tjjjd| d d}tjdd	t	t
|i| | d d
 d S )Nr   )r-   r.   zhandle_user_leave_room: r9   r'   r:   zUser leave roomr;   r0   )r3   r-   r   r    r4   r>   r?   r@   r5   rA   rB   )r7   r-   r;   r   r   r   handle_user_leave_roomY   s
    rD   document_broadcastc                 C   s   t jd| | d tjjd d S )NrE   r9   )r1   Zskip_sid)r4   r5   flaskr   Zsid)r7   r   r   r   handle_document_broadcasta   s    rG   Z	user_pingc                 C   sF   ddl m}m} tdd|   | dd }|rBtd|  d S )Nr   r+   r.   zhandle_user_ping: r/   Z
user_pong_r2   r6   r   r   r   handle_user_pingf   s
    rH   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   memou   s    zmemoized.<locals>.memor   )rN   rO   r   rM   r   memoizedr   s    rP   c                 C   s   dt krt t _|t j| < d S )Nprofiler_data)r!   r   rQ   )keymsr   r   r   set_call_time}   s    rT   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)selfrW   	__class__r   r   rY      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   s8   t d|| d||dtdtjd}| j||dS )Nz%s, exception=%s2.0)codemessagealert)jsonrpcerrorri   callidrd   )r   rk   r!   r   
api_callidre   )r\   rg   rh   rd   rc   r   r   r   _error   s    zApiView._errorc                 C   sv   |sg }d|||t j|t dt dt d|t |t d}t jrPt j|d< |sh|sht jrht j|d< | j||dS )	Nrf   rQ   ri   note)rj   rc   metajsverrl   jsurlrQ   ri   rp   abortversion
invalidater   jscache_timelifeshow_bg_progressbarrm   )r!   rn   r   Zcmf_get_versionr   rw   rx   re   )r\   rc   rq   rr   rs   rv   rt   rd   r   r   r   _ok   s*    

zApiView._okc                 C   s   |  ddS )NiDzParse errorro   r\   r   r   r   parse_error   s    zApiView.parse_errorc                 C   s&   d}|  d|d kr|n| d| S )NzInvalid Requestiz: rz   )r\   rh   titler   r   r   invalid_request   s    zApiView.invalid_requestc                 C   s   |  ddS )NizMethod not foundrz   r{   r   r   r   method_not_found   s    zApiView.method_not_found c                 C   s   |  dd| S )NizInvalid params: rz   )r\   rh   r   r   r   invalid_params   s    zApiView.invalid_paramsc                 C   s   |  ddS )NizInternal errorrz   r{   r   r   r   internal_error   s    zApiView.internal_errorc                 C   s$   |t dddkst| j|||dS )Ni irm   )rangeAssertionErrorro   )r\   rg   rh   rd   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)rB   r   cmfmodelsZ	BaseModeldirr   getattrr_   
issubclass	api_allowZabstractinspectZgetattr_static
startswithr   r   
isinstanceZCmfDeferredJobWrapperclassmethodstaticmethodlowerfieldsrK   ZCmfM2MZCmfGenericM2MZCmfJsonr   )r\   rW   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   rZ      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)r[   r
   )Zrender_with_paramsr[   r
   r{   r   r   r   r   (  s    zApiView.getz9"(?P<attr>(cmf|doc|obj|approved)_version)":(?P<value>\d+)Fc              
   C   s  t jsD|sDt|tkrDt|dkrDtdt| dtj 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tj	d | |||||}|rt|}	t| jd|	 }	ndzt|ddd}	W n@ tk
r( }
 z tdd|
 d|  |
W 5 d }
~
X Y nX t| jd|	}	t js|st|	dkrtdt|	 dtj dtj	d | j||||||ddS t js|st|	dkrt
j t
ddd	krtdt|	 dtj dtj	d | j||||||ddS t|	ddS )Ni  u    !!!Блокирующая задача критикал баг! Обратитесь в техком!!!. Используй slice z, z...leveli,  i        uw   Разработчик внимание! Слишком много строк через API. Используй slice z"\g<attr>":"\g<value>"r   F)indentZensure_asciir.   zJson dumps error: e=z
 response=i   uh   !!!Блокирующая задача критикал баг! Обратитесь в техком!!!  T)orjson_rv   	recursioni   uq   Разработчик внимание! Слишком большой размер данных через API. zapplication/json)Zmimetype)configZ
PRODUCTIONtyperB   rA   	cmf_alertr!   
api_methodr   WARNINGdatetimedateZtodayry   cmfutilZ	cmf_dumpsresub_BIG_INT_JSON_HACK_REr   r   	TypeErrorrk   sys	getsizeofresponse_okr   )r\   result_dictrq   rr   rs   r   rv   r   ZresponseZ	json_dataer   r   r   r   /  sR    


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)rr   Zcurrent_person_idzapi_cache_add endrr   zapi_cache_add failed)r!   Zno_jscache_forceosenvironr   r   r"   r   utcnowstrftimecurrent_personidvaluer   Z_obj_dict_setrI   r   )r\   rL   Z	res_cacher   r   r   api_cache_addb  s    


zApiView.api_cache_addc                 C   sN   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_getrI   r   r   r    )r\   rL   Z_resresr   r   r   api_cache_gets  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_validation  s    z$ApiView.public_full_cache_validationc                 O   s   | j |f||S r)   r   r   r   r   r   sdesk_full_cache_validation  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   rr   T)rq   rr   rs   r   )r   r   r   r   r   r   rI   r   r   r   r!   rs   )r\   r   r   r   rc   jshashZ
redis_data
cache_datar   r   r   r     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_userr{   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   rB   sTr   _use_simple)split
ValueErrorr[   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   s  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tjd tt t _d|kr
| dS |d t _|dd}|t _ |dp4i }|d}d|ks`t|trvd|krvtjdkrv| !dS |dpg }|d}|dkr:|dpi }|r||d< |dd }	|	r|	|d< |d d }
|
r|
|d < |d!d }|r||d!< |d"d }|r ||d"< |d#d }|r:||d#< |dg t _"d$d%d&d'd(d)d*d+d,d-h
}t j"D ]6}||kr~|#| |d. |krf|#|d.  qf|t _$|d/i t _%t j%d0rt&j'(  |d1d }|r||d1< | !d2S tj)r|t j*|d ||+ t j%d3}|d , D ]H\}}t|trt-|d4krd5t-| d|d d6  |d |< qt.d7t/0|  |d8}|d9d }|d:}|d }g }|d;kr| j1||S |d<kr| j2||S |d=kr| j3||S d }|d>d }| 4||}|s| 5 S |d? }|d@ }|dA }dB}dCD ]}||d kr4d}dBt _6t j78|j9 dD|d krdB} |dkr|r|dE dFkrt|dG trt:;|dG  d} |rdF|krt:;|dF  d} |rdH|krt:;|dH  d} |r~d|kr~|d dE dFkrBt|d dG trBt:;|d dG  d} |d dE dHkr~t|d dG tr~t:;|d dG  d} |rdI|dE krt:;|dE  d} dJ|d krdKdLdMdNdOg}!|!D ]}"|"|d krd}  qq| st dP|d    qq4dK|d krdB}|r0|dQr0dB}t<|dRdBrBdB}|dS}#|dT}$|$t _=|r|$d krtdU| dtjd dB}|r:|rt dV n|#r:tj }t dW | >|$}%t?dXtj | j@dY  t dZ |%r:|#|%dSkr0|rtAB|}t d[ | jCd d |%dS |||d\S t d] |d^ s|d_ s|d` r\n|da| }&t jDdbdc ddk}'|dkrt de d|krdF|d kr|d dE dFkrt df t }(|d |(d< dFg|(d< |'|(dg< |jf |(}t-|d dhkr|d= n|dFsB|rBt df |j|dFg||'di}n|rdF|kr|&rht:;|dF t }(dFdj|dFg|(d< dFg|(d< |'|(dg< |jf |(}|EdFd nB|r|+ }(g |(d< dFg|(d< |'|(dg< |jf |(}n| dkdlS nt-|dEk	sdI|dE k	r| dkdmS |EdE})|&	r4t:;|) t }(dFdj|)g|(d< dFg|(d< |'|(dg< |dn dok	rxt jFGt|) |jf |(}|dn dok
rtH|D ]~}*|jI|*}+|+	r|+jJ	stdp|* dqtjdr |E|* n<tK|jI|* tLjIjM	r||* tNk	rtdstjdr |E|* 	q|
rX|&
rXt:;|jOj tP|dH
rX|j
jQ
sXt:;|j
j |
st dt tR  | jSd i d |dudvS t|tLj&jT
o|jUj},t|tLj&jV
o|jWj}-t|tLj&jV
o|jXj}.t|tLj&jT
o|jYjZ}/t&j'j[|,|j9|-|jOj|.|dw|/dBdx	sFt dy t&j\j]dw|j9|dzd{ tR  | jSd i d |d|t^ d}S t d~ db|dn kr|dn jDdbdd\}}0t&j'j[|,|j9||-|jOj|.|dw|/dBd
st d t&j\j]dw|j9|dzd{ tR  | jSd i d |dt^ d}S t<||}1t<|1|0}nt<||dn }t?dtj | j@dY  tj }t d|d   z(|d` rR|j_||d}2n
|||}2W n t`k
r }3 zfta|3 tbd t|3}4tt<|3dd tHtcfrdddd |3jeD }4| jSd i d ||4|3d} W Y S d }3~3X Y nh tfk
rJ }3 zHtgjhbd ta|3 d|d  d}5|5tij 7 }5| jkd|5|3d W Y S d }3~3X Y nX t d t?dtj | j@dY  tj }|r0|jlr0t d z|m  W n t`k
r$ }3 zfta|3 tbd t|3}4tt<|3dd tHtcfrdddd |3jeD }4| jSd i d ||4|3d} W Y S d }3~3X Y nX t d t?dtj | j@dY  tj }ta  t?dtj | j@dY  tj }|dn dkr|2o|2jOj}2n"|dn dokrtP|2dFr|2jOj}2t:jn|2|d}6t d |r|6o  n|6D  t?dtj | j@dY  |6jp|6jq }7}8|dn dkr|8rd}9t|8trN|8ddkrNdz}9|j9dksd|9dzkrt|8trt&j\j]dw|j9|8dF |9d{ n.tr|8rt&j\j]dw|j9|8jO|9d{ n
ts|8d|dn dkrNd}9dB}:dB};|8D ].}<t|<tr |<dd dkr d}:nd};q|:r|;rd}9n
|:r$dz}9|j9dks:|9dzkrNt&j\j]dw|j9|9d t?d|6jt t d tj }|rt<t dd s| u|$}#|rtAB|}z| jC|8|7|#|||d}=W n< tvk
r }3 zt d| d|8   W 5 d }3~3X Y nX t?dtj | j@dY  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_idrl   zAPI: No callid specifiedT)Z
devel_onlyr   r   zNo method specifiedrs   r   r%   save_kwargsZ	only_dataz	127.0.0.1uM   SPEC0 Использование only_data через API запрещено.r$   rj   rf   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)loginr   r$   r%   r      zLONG_STRING    z
API_TRACE 
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      rg   :zCmfPersonVar.getZget_current_userZget_settingsZCmfRFilezCmfPersonVar.get_metaZCmfMenuTreez+Possible cache return invalid_data: method=Zsearch_stringZTEXKOM_no_cacherr   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   rq   rr   rs   r   rv   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    не доступно для изменения.r   uB   Не задано новое значение для пароля.zAPI object get Noneu>   Объект не найден, возможно удалён.)rc   rq   rr   rs   rt   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   Объект недоступен: недостаточно прав.)rc   rq   rr   rs   rt   rd   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   ra   A  s     z ApiView.post.<locals>.<listcomp>	Exceptionu/   Ошибка выполнения метода z

irm   zAPI method endZcall_method_mszAPI save startc                 S   s   g | ]}t |qS r   r  r  r   r   r   ra   _  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)rB   ZslistZ	partially)r	  r
  r  number_of_objectszAPI json dump endZcache_store_error)rv   r   uQ   Ошибка конвертации результата запроса json_res=z result_dict=Zresult_to_response_mszAPI request end)wr!   rn   r   ro   Zglobal_settingsZeva_versionr   ZEVA_VERSIONr"   r   rg   r   r   Znowr   r   dataZremote_addrZurlr   dictr|   r   r   r   r   r   r   r  r
   r~   r   rs   r   Z
api_fieldsr   api_hack_fieldsr   r   ZCmfAccessListZactivate_admin_modeZ	API_TRACEr   copyrK   rA   printZjsonr   r   r   r   r   r   Zin_memory_cacheZin_memory_cache_skip_modelsr   r   r   Zcache_obj_lock_getr   r   r   rT   Zmicrosecondsr   Zjshash_invalidate_confirm_listr   r   popZskipcache_select_for_updateaddrB   r   r   r   r   ZCmfPassword_PASSWORD_MASKr   hasattrZvirtualr   ry   Z	CmfEntityr   ZCmfModelZcmf_owner_idZ	parent_idr   oldZcheck_accessr  Zaudit_eventZCmfPermissionErrorZapply_asyncZCmfUserErrorr   rd   tuplejoinr$   r  r   logger	traceback
format_excr   Z
is_changedr  ZCmfResultSplitterZsplit_simplerq   rc   r   r   r  r   r   )>r\   Z
start_dateZjson_resrs   r%   r   r$   Zjsonrpc_verZ_filterr   r   r   r   r   r  r   r   Z
trace_datakvr   r   r   r   Zinvalidate_listobjr   r   r   r   Zapi_use_cacher   Zcache_lock_okZ_cachelock_skip_methodsmrr   r   r   r   r   Z
tmp_kwargsr   argZfieldr   Zobj_owner_idZobj_parent_idr   Zfield_methodZ	obj_fieldrc   r   Z	abort_msgmsgZsplitterrq   r   Zcheck_result_statusZcheck_result_have_denyZcheck_result_have_okZ_objZrespr   r   r   post  sf    

"
 



 


       




(





.&&
   



 





 


*







$
        
    
     
    



     	&



     




  
  





zApiView.post)N)N)N)NNN)N)r   )N)N)FNF)F)#r_   
__module____qualname__Z__url__rY   re   ro   ry   r|   r~   r   r   r   r   rP   rZ   r   r   viewsactionr   r   compiler   r   r   r   r   r   r   r   r  r   r,  __classcell__r   r   r]   r   rU      s6   






X


3	(rU   )8decimalZ	ipaddressr   r   r   rI   stringZrandomr   r$  collectionsr   r  r   Zdataclassesr   r   r   r   r   r   r	   Zuuidr
   rF   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&   r4   Zonr*   r8   rC   rD   rG   rH   rP   rT   r  r/  ZBaseViewrU   r   r   r   r   <module>   sR   

	



