U
    h                  	   @   s6  d Z ddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlmZ ddlmZ ddlmZ ddlmZ ejejeZededed	e ejd
 dd Ze  G dd dZe Ze  ddl T ddl!Z!dej"kre#  ne$e% ddl&m'Z' e'(  ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 dBddZ6dd Z7dd Z8dd Z9dd Z:ddl)m;Z; dd  Z<d!d" Z=d#d$ Z>dCd&d'Z?d(d) Z@d*d+ ZAd,d- ZBdDd.d/ZCd0d1 ZDd2d3 ZEd4d5 ZFd6d7 ZGd8d9 ZHeId:d;d<ZJdEeIeIeId=d>d?ZKd@dA ZLdS )Fu   Magage.py занимается построением аппликейшена и не переопределяет функции и не создает функции в апп    N)OrderedDict)Path)fields)init_system_datazrunning:inz	from cwd:filec                  C   s@   t jt  d} t jt  d}t j| s<t||  d S )Nzcustom/config.pyzcustom/config.py.example)ospathjoingetcwdexistsshutilcopy)Zconfig_pathZexample_path r   ./cmf/manage.pycheck_config   s    r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )WorkModelFileu  
    Почему бы не создать целый класс для одного файла, гг?
    Захотел прибить гвоздями весь код, работающий с ним в одно место, а не размазывать по manage.py
    c                 C   s,   t t d| _| jd | _| jd | _d S )NZtmpz__autogen_models_tmp.pyz__autogen_models.py)r   r	   r   app_tmpfilepath	orig_pathselfr   r   r   __init__+   s    zWorkModelFile.__init__c                 C   s   | j jdd | jd dS )    Зануляем файл чтобы иметь объект модуля-заглушки для Чёрной Магии (тм) T)exist_okz# clean
N)r   mkdirr   
write_textr   r   r   r   	clean_tmp0   s    zWorkModelFile.clean_tmpc                 C   s   | j jdd dS )r   T)
missing_okN)r   unlinkr   r   r   r   clean_models5   s    zWorkModelFile.clean_modelsc                 C   sH   | j | j j dt  }|| j  || j  t	
| dS )uw  
        Закидываем в заглушку настоящую модель (тупо копируем всё из __autogen в __autogen_tmp) и реимпортим в память
        _models, а не models чтобы ясно было что его на момент объявления ещё нет и он передаётся аргументом
        .N)r   	with_namenamer	   getpidr   r   	read_textrename	importlibreload)r   Z_modelsZmodels_tmp_tmp_pathr   r   r   fill9   s    zWorkModelFile.fillN)__name__
__module____qualname____doc__r   r   r!   r*   r   r   r   r   r   &   s
   r   )*autogen)RelationCache)APPcmf_contextapp_init_aclapp_init_project_permissionspawn_messenger_socketio_clientspawn_whatsapp_socketio_clientinit_logging
cmf_commit)init_dsinit_dbrollback_all_dsc              
   K   s   ddl m}m} t  tjtj	tj
td  tt t  t  t  z"t  t  t  W 5 Q R X W n. tjk
r } ztjrn W 5 d }~X Y nX i }| rd| krd|d< |f | d S )Nr   )deferred_job_workerRedisMonitor/config_load.pyz--single_queueTsingle_queue)cmf.cmf_deferred_jobr=   r>   install_traceback_email_notifyr2   configfrom_pyfiler	   r
   dirnameabspath__file__socketioZinit_appr8   start_viewsr:   r3   r4   r5   redisConnectionErrorZCACHE_REDIS_FAILOWER)Zcmd_args_kwargsr=   r>   eZ
job_kwargsr   r   r   start_job_workerb   s*    
rN   c                  O   s  t   tjtjtjtd  dt_	dt_
t  i }d|d< d| krTd|d< d}d| krdd}d}d| ksxd| kr|d}d	}| D ]}d
|krt|dd }qt  tjj  t  tjrdtjd< |rddlm} tj|dd tjt_t  tjtfd||d| d S )Nr?   FZuse_reloaderz--auto-reloadTz--no-debuggerz--with-celeryz--with-jobsi  z--port=   1ZSOCKETIOr   )r=   )r@   z0.0.0.0)hostportdebug) rB   r2   rC   rD   r	   r
   rE   rF   rG   Zdisable_permissionsZfirst_request_init_skiprI   intsplitr:   cmfappREDIS_SETTINGS_MANAGER
init_redis	CMF_CACHEflushdbZWHATSAPP_MESSENGER_URLenvironrA   r=   geventZspawnZIS_BOX_VERSIONZcache_optimizer8   rH   run)argskwargsoptionsrT   Z	with_jobsrS   argr=   r   r   r   start~   s<     
rd   c               	   C   sN   t ddd8 t  tjj  t  ddlm	}  |   t
  W 5 Q R X d S )NTF)Zpreprocess_requestr   before_request)r3   r;   rW   rX   rY   rZ   r[   r\   cmf.apprf   r   re   r   r   r   cmf_init_db   s    rh   c                  C   sj   t tdd rftd ddlm}  ddlm} ddlm	} | t
tjd}||j}|tj || d S )N
SENTRY_DSNzInstall sentry hookr   )Sentry)SentryHandler)setup_logging)Zdsn)getattrrC   logginginfoZraven.contrib.flaskrj   Zraven.handlers.loggingrk   Z
raven.confrl   r2   ri   ZclientsetLevelZERROR)rj   rk   rl   ZsentryZ	l_handlerr   r   r   install_sentry_hook   s    

rq   c                     s   dd } t tdd sd S td tjtttfs>tdt tdd sRtdtj	 t tdd sltd	tj
 fd
d}tt| |t_d S )Nc                 S   s   d S Nr   )xr   r   r   <lambda>       z0install_traceback_email_notify.<locals>.<lambda>TRACEBACK_EMAIL_NOTIFYzInstall traceback email notifyuC   Параметр TRACEBACK_EMAIL_NOTIFY - это список emailTRACEBACK_EMAIL_NOTIFY_FROMu*   Укажите TRACEBACK_EMAIL_NOTIFY_FROM%TRACEBACK_EMAIL_NOTIFY_SUBJECT_PREFIXu4   Укажите TRACEBACK_EMAIL_NOTIFY_SUBJECT_PREFIXc              
      sz  dd l }ddlm} ddlm} ddlm} ddlm} d	|j
|j}dt| dd	| g}|d
 |d |d	 |j}t| }	|	D ]}
|d|
||
f  qd
|d
 }|d}||d<  |d< d|d< |d}|| ||}|| z|ddd}W n8 tk
rR } zt| | W Y d S d }~X Y nX |  | |  |  d S )Nr   )request)SMTP)MIMEMultipart)MIMETextz{} Cmf traceback {} {}u,   Проблема на веб-сервере:z
Traceback:zP================================================================================
zRequest Information:z%s: %sZrelatedZSubjectZFromz, ZToZalternativezsmtp.carbonsoft.ru:25251   )timeout)	tracebackZflaskry   Zsmtplibrz   Zemail.mime.multipartr{   Zemail.mime.textr|   formatmethodurlstr
format_excappendr]   sortedkeysgetr   ZattachOSErrorprintZehloZsendmailZ	as_stringquit)	exceptionr   Z	__requestrz   r{   r|   ZsubjectZmsg_contentsr]   ZenvironkeyskeyZbodyZmsg_rootZmsg_alternativeZplainZsmtprM   Z	mail_fromZmail_toZsubject_prefixr   r   traceback_exception   sP      




z;install_traceback_email_notify.<locals>.traceback_exception)rm   rC   rn   ro   rv   
isinstancelisttupleAssertionErrorrw   rx   r2   Zregister_error_handler	Exceptioncmf_exception_mail)r   r   r   r   r   rB      s<    
     0rB   )CustomJSONProviderc                  C   s   t d tjdr$t d d S d} tj| rTt| }t |j dk rTd S t d t	j
ddgt	jd	}| d
 d}t |  | dkrtd  t|   d S )Nu:   Проверяем, нужно ли подпулить cmfz./cmf/.cmf_need_updatez+Cmf need update! Run ./manage.py cmf_updatez./cmf/.cmf_last_check_updatei  u<   Проверяем, нужно ли cmf обновитьсяz ./cmf/bin/git_check_need_pull.shz./cmfstdoutr   UTF-8zNeed to pull)rn   rT   r	   r
   r   ro   stattimest_mtime
subprocessPopenPIPEcommunicatedecodestripr   touch)Zlast_check_filenameZstatbufprocessoutputr   r   r   check_cmf_need_update  s&    



 r   c                   C   s   dS )u   Не нужно сейчас.
     Считаем, что когда в проект будут копироваться сложные файлы, которые нужно обновлять - доделаемNr   r   r   r   r   check_project_need_update_cmf-  s    r   c                  C   sR   t d tjdgtjd} |  d d}t | tj	drNt
d d S )Nu   Обновляем cmfz./cmf/bin/cmf_update.shr   r   r   z./.cmf_need_update)rn   ro   r   r   r   r   r   r	   r
   r   remove)r   r   r   r   r   
cmf_updateQ  s    

r   Tc              	   C   s  d }|st dd}z\|r"|  ddlm} ddlm} ddl	m
} dd l}dd l}	dd l}
|
j}t |	jj |s| stj }|rdat|t t  tW S | r`tjd}|fdd	}tj|rt| t| td
 td td td td t t!"t j# |r6dt$_%t&dtj'd |j(t d |rn|  nt&dtj'd W 5 |r|jt   X d S )NTZinit_views_and_dsr   r<   commit_with_eventtimeitz~/.cmf_historyc                 S   s   t |  d S rr   )readlinewrite_history_file)Zhistory_pathr   r   r   save_historyz  s    zcmf_shell.<locals>.save_historyztab: completezset show-all-if-ambiguous onzset show-all-if-unmodified onzset completion-query-items 200z set colored-completion-prefix onshell#!!! Use commit() to commit changes.r   )localzNothing to exec))r3   __exit__sysexc_info	__enter__cmf.data_providers.baser<   rg   r   cmf.cmf_profiler   codecmf.includepprintlocalsupdateZinclude__dict__stdinreadZretcodeexecglobalsr	   r
   
expanduserr   r   read_history_fileatexitregisterparse_and_bindZset_completerrlcompleterZ	CompleterZcompleteginteractive_shellr   stderrZinteract)interactivescriptr`   without_contextZ_cmf_contextrollbackcommitr   Z__coderW   r   ppZ__history_pathr   r   r   r   	cmf_shellZ  sR    








r   c            	   	      s   ddl m}  ddlm} ddlm  ddlm} ddlm	} dd l
}ddlm} d|_td	d
  fdd}|j
}| }d|j_tdd* dt_tdtjd | |d    W 5 Q R X d S )Nr   )embed)
get_configr   r   r   )	VerboseTBz
bg:#039dfcZparsoZWARNINGc                      s"      t tjtjftj d S rr   )r	   execvr   
executableargvr   r   r   r   r)     s    zipython.<locals>.reloadZneutralTr   ishellr   r   )rC   )ZIPythonr   Ztraitlets.configr   r   r<   rg   r   r   r   r   ZIPython.core.ultratbr   Z_tb_highlightrn   Z	getLoggerrp   ZInteractiveShellEmbedZcolorsr3   r   r   r   r   r   )	r   r   r   r   r   r   r)   r   cr   r   r   ipython  s$    
r   c              	   C   s8   t d& dtjd< ddlm} ||  W 5 Q R X dS )u|   
    :param email: почта админа созданная на этапе acrm_assign.sh --admin=test@carbonsoft.ru
    TrQ   NO_CACHEr   )	demo_dataN)r3   r	   r]   rW   r   Zcreate)emailr   r   r   r   init_demo_data  s    

r   c                  C   st   t   } | d }| d }| r6td| d d S ddlm} |d}||	d ||
 	d d S )	Nztmp/jwt_rsaztmp/jwt_rsa.pubZFilezalready existsr   )RSAi   ZPEM)r   resolver   r   absoluteZCrypto.PublicKeyr   Zgeneratewrite_bytesZ
export_keyZ	publickey)Zproj_dirZrsa_private_pathZrsa_public_pathr   r   r   r   r   generate_rsa_keypair  s    

r   c              	   C   s   dt jd< t  t  g }ttD ]V}|dkr0q"tt| }t|sHq"t|t	jj
sXq"d|jkrnd|jkrnq"|| q"t }|D ]}||}q| rt| d}|tj|tdd W 5 Q R X nttj|tdd d S )	NrQ   r   )ZCmfRFilerightleftw+   )clsindent)r	   r]   rI   r:   varsmodelsinspectZisclass
issubclassrW   Z	BaseModelr   r   r   Zdump_data_dictopenwritejsondumpsr   r   )	file_pathZ
all_models
model_namemodelresfr   r   r   dump_db  s,    

"r   c              	      sf   dt jd< t  t  tjj  t| d}t	
|  W 5 Q R X d fdd	}|  |d d S )	NrQ   r   rFc                    s   D ]}zt t| }W n   t| d Y qY nX d } | D ]}td |j|j}||jj|d k }|rtd |d }| sqFntd |dd}|D ]}|d	krtd
 q|	|ddkrqt
||std| d| d qt||}tt|tjsq|	|d kr2|js2qt|tjs^t|tjrf|js^|jrf| sfqt|tjr|| D ]|}	zPtj|	d }
|
j|
j}||
jj|	d k }|r||d  W n$   td|	d   Y q|Y nX q|qt|tjr|	|d sqqt|tjr|js<|jrzt||jd d ||  W n.   td| d|j d|j  Y qY nX qt|tjr|| d krq||| |_q|| |_q|	ddd kr|dkrtd|j  qF|jdd qF|r|j   qd S )Nu    больше нетz&======================================idZ	HHHHHHHHHr   zHHHHHHHHH newT)emptyZis_newu+   WARNING: служебное поле is_newu   WARNING: Поля u    нет в модели !u3   Не возможно создать связь с Z_idu,   WARNING не удалось задать FK z = u    для обьекта r   z-1CmfTasku%   WARNING задача без кода Z	only_data)!r   r   r   dpZquery_deprecatedZdp_modelfilterr   allr   hasattrrm   r   typer   ZCmfTypeZnullabler   Z
CmfRelBaseZCmfTUUIDZforeign_keyZforeign_keysZ
CmfM2MBaseZget_cls_by_tuuid_strr   ZCmfRelationBasesetattr
class_name_valueZCmfDateTimecastsaver   )Zwith_relr   r   instZ	inst_dictqZinstsr   ZfielditemZ
list_modelr   r   r   r     s    





zrestore_db.<locals>.processT)F)r	   r]   rI   r:   rW   rX   rY   rZ   r   r   loadsr   )r   r   r   r   r  r   
restore_db  s    
Rr  c               	      s   dt jd< t  t  tjj  t  ddl	m	  ddl
m}  td |   tjjdd}tjjd	d} fd
d}| }tdD ]T}|j| |  |d tdt|jjd d |j| |  |d q|  W 5 Q R X d S )NrQ   r   r   r   re   /z
DEV-004234)r   z/cmfproject-6597795c-95ce-11ea-9023-6f4fdd48682bc                     s0      d fdd	} fdd| _ | S )N c                    s   t |       d S rr   r   )s)nowr   r   r   wrap]  s    z&prod_test.<locals>.timer.<locals>.wrapc                      s   t d   S )Nendr  r   )rd   r   r   r   rt   b  ru   z*prod_test.<locals>.timer.<locals>.<lambda>)r  )r  )r  r  )r  rd   r   timerY  s
    zprod_test.<locals>.timer
   r   
all_nested)r  r   )r	   r]   rI   r:   rW   rX   rY   rZ   r;   r   rg   rf   r2   Ztest_request_contextr   r  r   Z
CmfProjectrangeZ	executorsr   Z_test_save_commitr   lenr   r   r  )rf   ZtaskZprojectr  tir   r  r   	prod_testJ  s,    

r%  c              	   C   s   t jt tjtjdgdd}ddd|jd< t	
| } tj d d|  }tj d	| d
}|dj| |d}t|d}|| W 5 Q R X td|  td|  d S )Nzcmf/templatesT)loaderZkeep_trailing_newlineF)Zensure_asciiZ	sort_keyszjson.dumps_kwargsz
%Y%m%d%H%M_/patch/.pyzpatch.jinja2)
patch_name	file_namer   #   Сгенерирован файл: u7   Команда для запуска: python3 -m patch.)jinja2EnvironmentFileSystemLoaderr	   r
   r   rC   PROJECT_DIRZpoliciesZcmfutilZtranslit_stripdatetimer  strftimeget_templaterenderr   r   r   )r$   Z	jinja_envr+  r   Z
patch_textr   r   r   r   	new_patchw  s    
r5  c               	      s   fdd} g }t jtj ds(dS t tj dD ]$}td|r:||	dd  q:|
  |sxtd dS td	d
 t  tjjdgdgd}|s|d  |   |D ]" tjj dstj d  qn(t|jjd}|D ]  |kr|   qW 5 Q R X dS )u?   
    Накладываем патчи по очереди
    c                    s   t j  tjj dr,td  d d S dtj d|  d}tj d	  zPt
|ddddd	\}}}td
  d|  td
  d|  tjj  W n   td |   Y nX d S )Nr$   u	   Патч u    уже примененz(cd z; python3 -m patch.)FT)sudoZseparate_out_and_errZdo_raiseZ	do_decodezPatch z	 stdout: z	 stderr: uI   Произошла ошибка накатывания патча %s (%s))r   r   flushr   CmfPatchsgetr   rC   r0  r  run_bash_commandr  r   )r*  cmdZerrcodeouterrr6  r   r   apply_patch  s"    
 zpatch.<locals>.apply_patchr(  Nz[0-9]+_.*\.pyr"   r   u0   Не найдено ни одного патчаTr   r$   r/   )Zorder_byr   r  r6  Z202306050000)r	   r
   r   rC   r0  listdirrematchr   rV   sortr   r3   r[   r\   r   r:  r   r;  r  maxr$   value)r@  ZpatchesfilenameZfirst_patchZfrom_patch_limitr   r6  r   patch  s0    rH  c               	   C   sL   t dd8 tjj  t  tj	 } t
j| _| jdd W 5 Q R X dS )u?  
    Команда для системы обновления. Сохраняет eva_version в CmfGlobalSettings
    Если версии будут отличаться, в случае запуска образа с несовместимой версией БД,
    система вернет ошибку
    Tr   r  N)r3   rW   rX   rY   rZ   r[   r\   r   ZCmfGlobalSettingsr   rC   ZEVA_VERSIONZeva_versionr  )Zgsr   r   r   save_version_to_db  s    
rI  )r   c              	   C   s   i }t tjtjdg}||d< t jf |}tj| rPt	d|  d d S tj
| \}}|
dd }tj|st| t| d$}|d}||d	|i W 5 Q R X t	d
|   d S )Nzcmf/contribr&  u	   Тест u    уже существуетr)  r   r   ztest.py.tmplr$   r,  )r-  r/  r	   r
   r   rC   r0  r.  r   r   rV   isdirmakedirsr   r3  r   r4  )r   Z_optionsZ_loaderZ
_jinja_envZfolderr$   r   templater   r   r   new_test  s    

rM  )ext_smtploginpasswordc              	   C   s   t d tj }|ddddddg dtjdd	d
 }| sTd| d} |sbd| }| |j	_
||j	_||j	_d|j	_d|j	_d
|j	_|j	  t  W 5 Q R X d
S )u`   Настраиваем в ножницах локальный почтовый сервер
    Tzplugin.ext_smtpzplugin.loginzplugin.passwordzplugin.use_tlszplugin.verify_sslzplugin.ext_portr"   rP   Nzmailserver.z:25zuser@F)r3   r   ZCmfPluginMailBoxZget_local_mailboxZload_fieldsr   rC   ZAPP_FQDNrV   ZpluginrN  rO  rP  Zuse_tlsZ
verify_sslZext_portr  r9   )rN  rO  rP  Zmail_boxdomainr   r   r   set_local_mailserver  s$    



rR  c            	   	   C   st  t   t } | jdtdd | jdtdd | jdddd	 |  \}}t  |jd
krft|  n
|jdkr|t	| n|jdkrt
  n|jdkrt  n|jdkrt  n|jdkrtd| n|jdkrtd| n|jdkrt|  nh|jdkrt  nR|jdkr4t  n<|jdkr^|jsPtdt|j n|jdkrtt  n|jdkrt|  n|jdkrt|  n|jdkrjddlm} ttj d}ttj d}| r>tj tj dr>| r,t!"tj d| d  t!#| n|$tj d tj tj d!r`t%d"d#d$ |  n|jd%krt&t'j() d&||j*d'}|rpt+| n|jd(krt|d , }|- }W 5 Q R X t&t'j() |||j*d) n|jd*kr t.  np|j/d+s|j/d,r*t01|j nF|jd-krRt2  t3j4j56  t78  nt9d.t'j:dt'j; t+d/ d S )0Ncommandzrun command)r
  helpz--emailu"   Почта (для init_demo_data)z--without-context
store_trueu4   Не инициализировать app и context)actionrT  rd   )Zcelery_workerZ
job_workerr   r;   r%  r5   rM  rR  rH  rI  r   us   Нужно указать почту владельца CRM для инициализации демо-данныхr   r   r  r0   r   )make__autogen_modelsz/custom/modules/servicedeskz/custom/modules/taskz./custom/modules/servicedesk/fields/cmf_task.pyz/fields/cmf_task.pyz'/custom/modules/task/fields/cmf_task.pya@  sed -i 's/class CmfTask(modules.servicedesk.models.cmf_task.CmfTask):/class CmfTask(modules.task.models.cmf_task.CmfTask):/' /opt/eva-app/custom/modules/task/fields/cmf_task.py; sed -i 's/import modules.servicedesk.models.cmf_task/import modules.task.models.cmf_task/' /opt/eva-app/custom/modules/task/fields/cmf_task.pyF)r8  r   r}   )r   r   r   r   )r   r   r`   r   )r   r   zbin.zsbin.Zcache_flushdbu$   Команда не найдена:    )<rq   argparseArgumentParseradd_argumentr   parse_known_argsr8   rS  rd   rN   r   rh   r%  r5  r   rM  rR  rH  rI  r   r   r   r   r   r  Zcmf.make_modelsrX  r   rC   r0  r   r	   r
   r   movermtreer'   r<  r   r   r   isattyr   exitr   r   r   
startswithr(   import_moduler:   rW   rX   rY   rZ   r[   r\   r   r   r   )	parserr`   Zunknown_argsrX  Zdir_pathZdst_pathr   Zscript_filer   r   r   r   main  s    












 


   
re  )N)TNNN)N)NNN)Mr.   rJ   Zcmf.monkey_patchrW   r1  r   r   r   r	   r   r   r   r   collectionsr   pathlibr   r   Zcmf.system_datar   r
   rE   rF   rG   ZCUR_DIRr   r   r   r   r   Z
work_modelr   r   r^   r   r!   r*   r   Zcmf.fields.cmf_relation_cacher1   Zbuild_fields_cacherg   r2   r3   r4   r5   r6   r7   r8   r9   r   r:   r;   r<   rN   rd   rh   rq   rB   r   r   r   r   r   r   r   r   r   r  r%  r5  rH  rI  r   rM  rR  re  r   r   r   r   <module>   sj   

(
/J$	
:
`-2