B
    f                 @   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   sj   t jrt t j dk rt jS t jd} | sNttt }t jjd|dd n| 	 }|t _t t _t jS )N   redis_idT)Znx)
APPREDIS_DB_IDr	   ZREDIS_DB_ID_TIMERZREDIS_DBgetstrintsetdecode)Zraw_redis_idr    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_roomz%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_regisrtyA   s    r1   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)   z%szhandle_user_join_room: 	room_namer&   )r'   r,   zUser r+   z	 join to participants)r,   z
Joined to 	user_name
user_login)r3   r4   r5   r+   )r-   r)   r   r    r.   servermanagerget_participantslenlistr/   )r0   r)   r3   ZparticipantsSizer   r   r   handle_user_join_roomK   s    ,r;   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*   z%szhandle_user_leave_room: r2   r&   )r'   r,   zUser leave roomr3   )r,   )r-   r*   r   r    r.   r6   r7   r8   r/   r9   r:   )r0   r*   r3   r   r   r   handle_user_leave_room\   s
    r<   document_broadcastc             C   s   t jd| | d tjjd d S )Nr=   r2   )r,   Zskip_sid)r.   r/   flaskr   Zsid)r0   r   r   r   handle_document_broadcastd   s    r?   Z	user_pingc             C   sF   ddl m}m} tdd|   | dd }|rBtd|  d S )Nr   )r)   r*   z%szhandle_user_ping: r+   Z
user_pong_)r-   r)   r*   r   r    r   r.   r/   )r0   r)   r*   r+   r   r   r   handle_user_pingi   s
    r@   c                s   i  fdd}|S )Nc                 s4   t | t| f}|kr, | ||< | S )N)pickler   sorteditems)r#   r$   hash)funcmemoryr   r   memox   s    zmemoized.<locals>.memor   )rE   rG   r   )rE   rF   r   memoizedu   s    rH   c             C   s   dt krt t _|t j| < d S )Nprofiler_data)r!   r   rI   )keymsr   r   r   set_call_time   s    rL   z******c                   s  e Zd ZdZd5dd fddZd6ddZd7dd	Zd8d
dZdd Zd9ddZ	dd Z
d:ddZdd Zd;ddZed<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 d0d1d2Z!ejjd3d4 Z"  Z#S )?ApiViewr&   N)returnc                s   t    | j|d| _d S )N)extra_models_list)super__init__get_rpcrpc)selfrO   )	__class__r   r   rQ      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)rU   __mro__)rT   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=%sz2.0)codemessagealert)jsonrpcerrorr_   callid)r[   )r   ra   r!   r   
api_callidr\   )rT   r]   r^   r[   rZ   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 )	Nz2.0rI   r_   note)r`   rZ   metajsverrb   jsurlrI   r_   re   abortversion
invalidater   jscache_timelifeshow_bg_progressbar)r[   )r!   rc   r   Zcmf_get_versionr   rl   rm   r\   )rT   rZ   rf   rg   rh   rk   ri   r[   r   r   r   _ok   s(    


zApiView._okc             C   s   |  ddS )NiDzParse error)rd   )rT   r   r   r   parse_error   s    zApiView.parse_errorc             C   s&   d}|  d|d kr|n| d| S )NzInvalid Requestiz: )rd   )rT   r^   titler   r   r   invalid_request   s    zApiView.invalid_requestc             C   s   |  ddS )NizMethod not found)rd   )rT   r   r   r   method_not_found   s    zApiView.method_not_found c             C   s   |  dd| S )NizInvalid params: )rd   )rT   r^   r   r   r   invalid_params   s    zApiView.invalid_paramsc             C   s   |  ddS )NizInternal error)rd   )rT   r   r   r   internal_error   s    zApiView.internal_errorc             C   s$   |t dddkst| j|||dS )Ni i)r[   )rangeAssertionErrorrd   )rT   r]   r^   r[   r   r   r   server_error   s    zApiView.server_error)rO   c             C   s\  | s
g } nt | } | tjj ddd | D }tj|rJtj| S i tj|< xt	t| D ]}t
|r|}t|d|j}n<tt|d pttj|d }t
|sqdt|tjjsqd|jrqd|dkrtdddd	d
dddddg
}n|jsqdn
t|j}i }tt	||@ }xd|D ]\}t||}t||}t|t}	t|t}
t|t}|| |	|
|dd}|||d < qW t|tjjr0x|j D ]\}}g }t|tjjtjjfrddddg}nt|tjjrddg}xL|D ]D}| d| }t||}||t|ddddd|| d| < qW qW |||d}|tj| |d < qdW tj| S )Nrs   c             S   s   g | ]}t |qS r   )r   )rW   objr   r   r   rX      s    z#ApiView.get_rpc.<locals>.<listcomp>
class_name	BaseModelZall_models_metaZget_metaZget_ui_full_pathZubql2bqlZpublic_get_ui_full_pathZpublic_all_models_metaZpublic_noneZpublic_none_classmethodZsdesk_get_ui_full_pathZsdesk_all_models_metaF)_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)r:   r   cmfmodelsr|   joinr   Z
rpc_modelsr   dirr   getattrrV   
issubclassZabstractr   	api_allowZapi_methodsinspectZgetattr_static
isinstanceclassmethodstaticmethodZCmfDeferredJobWrapperlowerfieldsrC   ZCmfM2MZCmfGenericM2MZCmfJsonr   )rO   rJ   Z
model_nameclsZapi_methods_setZrpc_methodsZmethod_namemethodZmethod_attrr   r   r   Z
rpc_method
field_nameZ	field_clsZ
submethodsZ	submethodr~   Z	rpc_modelr   r   r   rR      s    










"zApiView.get_rpcc             C   s   |dkS )NZ	qweqweqwer   )rT   tokenr   r   r   check_token>  s    zApiView.check_tokenc             C   s   | j d| jtdS )Nz
index.html)rS   r
   )Zrender_with_paramsrS   r
   )rT   r   r   r   r   A  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|	 }	ndyt|ddd}	W n@ tk
r( }
 z tdd|
 d|  |
W d 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_asciiz%szJson dumps error: e=z
 response=i   uh   !!!Блокирующая задача критикал баг! Обратитесь в техком!!!  T)orjson_rk   	recursioni   uq   Разработчик внимание! Слишком большой размер данных через API. zapplication/json)Zmimetype)configZ
PRODUCTIONtyper:   r9   	cmf_alertr!   
api_methodr   WARNINGdatetimeZdateZtodayrn   cmfutilZ	cmf_dumpsresub_BIG_INT_JSON_HACK_REr   r   	TypeErrorra   sys	getsizeofresponse_okr   )rT   result_dictrf   rg   rh   r   rk   r   ZresponseZ	json_dataer   r   r   r   H  sH    






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_CACHEzjshash:z$api_cache_add failed, invalid jshashz%Y%m%d%H%M%S%f)rg   Zcurrent_person_idzapi_cache_add endrg   zapi_cache_add failed)r!   Zno_jscache_forceosenvironr   
startswithr"   r   utcnowstrftimecurrent_personidvaluer   Z_obj_dict_setrA   r   )rT   rD   Z	res_cacher   r   r   api_cache_add{  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   zjshash:zAPI CACHE HIT )
r   r   r   r   r   _obj_dict_getrA   r   r   r    )rT   rD   Z_resZresr   r   r   api_cache_get  s    


zApiView.api_cache_getc             O   s   | j |f||S )N)full_cache_validation)rT   jshash_list_args_kwargsr   r   r   public_full_cache_validation  s    z$ApiView.public_full_cache_validationc             O   s   | j |f||S )N)r   )rT   r   r   r   r   r   r   sdesk_full_cache_validation  s    z#ApiView.sdesk_full_cache_validationc             O   sr   dt j  dd d i}x>|D ]6}|ds2q"t|}|r"t|}|d||< q"W | j	|d d t
jddS )Notherz%Y%m%d%H%M%S%fr   zjshash:rg   T)rf   rg   rh   r   )r   r   r   r   r   r   rA   r   r   r   r!   rh   )rT   r   r   r   rZ   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_user)rT   r   r   r   _check_access  s    zApiView._check_access)r   c             C   s   y|j ddd\}}W n tk
r*   dS X || jkr:dS | j| }|d }d}|dkrp|jsp|spd| }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   r:   sTr   _use_simple)split
ValueErrorrS   disable_simple)rT   r   r   Zproc_cls_nameproc_methodZproc_clsr   
use_simpler   r   r   rpc_prepare_method  s$    


zApiView.rpc_prepare_methodc       A      C   sp  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 _|dt _t jstddtjd tt t _d|kr| dS |d t _ t jrFt!dt j  dt j" d |dd}|t _#|dpfi }t$|% }|dpi }t$|% }dddh}|&|s|&|rtjdkr| 'd| d S |d!pg }	|d"}
|
d#kr|d$pi }|r||d$< |d%d }|r,||d%< |d&d }|rF||d&< |d'd }|r`||d'< |d(d }|rz||d(< |d)d }|r||d)< |d%g t _(d*d+d,d-d.d/d0d1d2d3h
}x@t j(D ]6}||kr|)| |d4 |kr|)|d4  qW |t _*|d5i t _+t j+d6r(t,j-.  |d7d }|rL||d7< | 'd8S tj/rt j0|d |	|1 t j+d9}xX|d 2 D ]H\}}t|tr~t3|d:kr~d;t3| d|d d<  |d |< q~W t4d=t56|  |d>}|d?d }|d@}|d }g }|dAkr | j7|	|S |dBkr6| j8|	|S |dCkrL| j9|	|S d }|dDd }| :||}|sv| ; S |dE }|dF }|dG } dH}!xdID ]}"|"|d krd}!dHt _<t j=>|j? dJ|d krddH}#|
d#kr|r|dK dLkrt|dM trt@A|dM  d}#|r:dL|kr:t@A|dL  d}#|r\dN|kr\t@A|dN  d}#|rd$|kr|d$ dK dLkrt|d$ dM trt@A|d$ dM  d}#|d$ dK dNkrt|d$ dM trt@A|d$ dM  d}#|	r
dO|	dK kr
t@A|	dK  d}#dP|d krdQdRdSdTdUg}$x"|$D ]}%|%|d kr,d}#P q,W |#sdt dV|d   P qW dQ|d kr~dH}!|r|dWrdH}!tB|dXdHrdH}!|dY}&|dZ}'|'t _C|!r|'d krtd[| dtjd dH}!|!r|rt d\ n|&rtj }t d] | D|'}(tEd^tj | jFd_  t d` |(r|&|(dYkr|rptGH|}t da | jId d |(dY || |dbS t dc |dd sf|de sf|df rn|dg|! })t j Jdhdi djk}*|
d#k	rVt dk d$|krtdL|d$ krt|d$ dK dLkrtt dl t }+|d$ |+d$< dLg|+d%< |*|+dm< |jf |+}t3|d$ dnk	rT|d$= n|dLs|rt dl |j|dLg||*do}n|	rdL|k	r|)rt@A|dL t }+dLdp|dLg|+d$< dLg|+d%< |*|+dm< |jf |+}|KdLd nB|	rH|1 }+g |+d$< dLg|+d%< |*|+dm< |jf |+}n| dqdrS nt3|	dKk	srdO|	dK k	r~| dqdsS |	KdK},|)	rt@A|, t }+dLdp|,g|+d$< dLg|+d%< |*|+dm< |dt duk	rt jLMt|, |jf |+}|dt duk
rxtN|D ]~}-|jO|-}.|.
r |.jP
s@tdv|- dwtjdx |K|- n<tQ|jO|- tRjOjS
r ||- tTk
r tdytjdx |K|- 
q W |
r|)
rt@A|jUj tV|dN
r|j
jW
st@A|j
j |
st dz tX  | jYd i d |d{d|S t|tRj,jZo |j[j}/t|tRj,j\o|j]j}0t|tRj,j\o0|j^j}1t|tRj,jZoH|j_j`}2t,j-ja|/|j?|0|jUj|1|d}|2dHd~	st d t,jbjcd}|j?|dd tX  | jYd i d |dtd dS t d dh|dt krX|dt jJdhdd\}}3t,j-ja|/|j?||0|jUj|1|d}|2dHd
sBt d t,jbjcd}|j?|dd tX  | jYd i d |dtd dS tB||}4tB|4|3}ntB||dt }tEdtj | jFd_  tj }t d|d   y(|df r|je|	|d}5n
||	|}5W n tfk
rD }6 z^tg|6 thd t|6}7ttB|6d!d tNtifr"djdd |6jkD }7| jYd i d ||7|6dS d }6~6X Y n` tlk
r }6 z@tmjnhd tg|6 d|d  d}8|8top 7 }8| jqd|8|6dS d }6~6X Y nX t d tEdtj | jFd_  tj }|r|jrrt d y|s  W n~ tfk
rt }6 z^tg|6 thd t|6}7ttB|6d!d tNtifrRdjdd |6jkD }7| jYd i d ||7|6dS d }6~6X Y nX t d tEdtj | jFd_  tj }tg  tEdtj | jFd_  tj }|dt dkr|5o|5jUj}5n"|dt dukrtV|5dLr|5jUj}5t@jt|5|d}9t d | r6|9u  n|9J  tEdtj | jFd_  |9jv|9jw }:};|dt dkr
|;r
d}<t|;tr|;ddkrd}<|j?dks|<dkr
t|;trt,jbjcd}|j?|;dL |<d n.tx|;r t,jbjcd}|j?|;jU|<d n
ty|;d|dt dkrd}<dH}=dH}>x6|;D ].}?t|?trR|?dd dkrRd}=nd}>q*W |=rn|>rnd}<n
|=rxd}<|j?dks|<dkrt,jbjcd}|j?|<d tEd|9jz t d tj }|!rtBt dd s| {|'}&|rtGH|}y| jI|;|:|&||| d}@W n< t|k
rF }6 zt d| d|;   W d d }6~6X Y nX tEdtj | jFd_  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_idrb   TECHCOM_HACK3441zAPI: No callid specifiedT)Z
devel_onlyr   r   zNo method specifiedz%sz TECHCOM_HACK3441rh   rs   r$   save_kwargsZ	only_dataZauditZnotifyz	127.0.0.1u!   SPEC0 Использование u#    через API запрещено.r#   r`   z2.0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      r]   :zCmfPersonVar.getZget_current_userZget_settingsZCmfRFilezCmfPersonVar.get_metaZCmfMenuTreez+Possible cache return invalid_data: method=Zsearch_stringZTEXKOM_no_cacherg   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   rf   rg   rh   r   rk   zapi_cache_get jsver mismatch!r   r   r   
for_updater   rv   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>   Объект не найден, возможно удалён.)rZ   rf   rg   rh   ri   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   Объект недоступен: недостаточно прав.)rZ   rf   rg   rh   ri   r[   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#   r$   zUserError Trace:c             S   s   g | ]}t |qS r   )r   )rW   ir   r   r   rX   d  s    z ApiView.post.<locals>.<listcomp>	Exceptionu/   Ошибка выполнения метода z

i)r[   zAPI method endZcall_method_mszAPI save startc             S   s   g | ]}t |qS r   )r   )rW   r   r   r   r   rX     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)r:   ZslistZ	partially)r   r   r   number_of_objectszAPI json dump endZcache_store_error)rk   r   uQ   Ошибка конвертации результата запроса json_res=z result_dict=Zresult_to_response_mszAPI request end)}r!   rc   r   rd   Zglobal_settingsZeva_versionr   ZEVA_VERSIONr"   r   r]   r   r   Znowr   r   dataZremote_addrZurlr   dictro   r   r   r   r   r   r   r   r   r
   rq   r   r    Zcurrent_userrh   r   keysintersectionrt   Z
api_fieldsr   api_hack_fieldsr   r   ZCmfAccessListZactivate_admin_modeZ	API_TRACEr   copyrC   r9   printZjsonr   r   r   r   r   rr   Zin_memory_cacheZin_memory_cache_skip_modelsr   r{   r   Zcache_obj_lock_getr   r   r   rL   Zmicrosecondsr   Zjshash_invalidate_confirm_listr   r   popZskipcache_select_for_updateaddr:   r   r   r   r   ZCmfPassword_PASSWORD_MASKr   hasattrZvirtualr   rn   Z	CmfEntityr   ZCmfModelZcmf_owner_idZ	parent_idr   oldZcheck_accessr   Zaudit_eventZCmfPermissionErrorZapply_asyncZCmfUserErrorr   r[   tupler   r#   r   r   Zlogger	traceback
format_excry   Z
is_changedr   ZCmfResultSplitterZsplit_simplerf   rZ   r   r   r  r   r   )ArT   Z
start_dateZjson_resrh   r$   Z
kwargs_setr   Zsave_kwargs_setZblock_kwargsr#   Zjsonrpc_verZ_filterr   r   r   r   r   r  r   r   Z
trace_datakvr   r   r   r   Zinvalidate_listrz   r   r   r   r   Zapi_use_cacher   Zcache_lock_okZ_cachelock_skip_methodsmrg   r   r   r   r   Z
tmp_kwargsr   argZfieldr   Zobj_owner_idZobj_parent_idr   Zfield_methodZ	obj_fieldrZ   r   Z	abort_msgmsgZsplitterrf   r   Zcheck_result_statusZcheck_result_have_denyZcheck_result_have_okZ_objZrespr   r   r   post  s    

"












*





.&&












*







$













 













zApiView.post)N)N)N)NNN)N)rs   )N)N)FNF)F)$rV   
__module____qualname__Z__url__rQ   r\   rd   rn   ro   rq   rr   rt   ru   ry   r   r:   rR   r   r   viewsactionr   r   compiler   r   r   r   r   r   r   r   r   r   r  __classcell__r   r   )rU   r   rM      s2   






m

3	(rM   )8decimalZ	ipaddressr   r   r   rA   stringZrandomr   r  collectionsr   r  r   Zdataclassesr   r   r   r   r   r   r	   Zuuidr
   r>   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%   r.   Zonr(   r1   r;   r<   r?   r@   rH   rL   r  r  ZBaseViewrM   r   r   r   r   <module>   sD   
