B
    f7x              	   @   s  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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.m/Z/ ddl0m1Z1m2Z2m3Z3 dd Z4dd Z5dd Z6dd Z7dd Z8ddl(m9Z9 dd  Z:d!d" Z;d#d$ Z<d?d&d'Z=d(d) Z>d*d+ Z?d,d- Z@d@d.d/ZAd0d1 ZBd2d3 ZCd4d5 ZDd6d7 ZEd8d9 ZFeGd:d;d<ZHd=d> ZIdS )Au   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 )u    Зануляем файл чтобы иметь объект модуля-заглушки для Чёрной Магии (тм) T)exist_okz# clean
N)r   mkdirr   
write_text)r   r   r   r   	clean_tmp/   s    zWorkModelFile.clean_tmpc             C   s(   y| j   W n tk
r"   Y nX dS )u    Зануляем файл чтобы иметь объект модуля-заглушки для Чёрной Магии (тм) N)r   unlinkFileNotFoundError)r   r   r   r   clean_models4   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   Z	with_namenamer   getpidr   r   Z	read_textrename	importlibreload)r   Z_modelsZmodels_tmp_tmp_pathr   r   r   fill;   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)init_dsinit_dbrollback_all_dsc           	   O   sp   t   tjtjtjtd  t	
t t  t  t  t  t  W d Q R X ddlm} |  d S )Nz/config_load.pyr   )deferred_job_worker)install_traceback_email_notifyr-   configfrom_pyfiler   r	   dirnameabspath__file__socketioZinit_appstart_viewsr4   r.   r/   r0   cmf.cmf_deferred_jobr7   )Z_argsZ_kwargsr7   r   r   r   start_job_workern   s    
rA   c              O   s  t   tjtjtjtd  dt_	t
  i }d|d< d| krNd|d< d}d| kr^d}d}d| ksrd| krvd}d	}x&| D ]}d
|krt|dd }qW t  t  tjrdtjd< |rddlm} tj|dd tjt_tjtfd||d| d S )Nz/config_load.pyFZuse_reloaderz--auto-reloadTz--no-debuggerz--with-celeryz--with-jobsi  z--port=   1ZSOCKETIOr   )r7   )Zsingle_queuez0.0.0.0)Zhostportdebug)r8   r-   r9   r:   r   r	   r;   r<   r=   Zdisable_permissionsr?   intsplit	CMF_CACHEflushdbr4   ZWHATSAPP_MESSENGER_URLenvironr@   r7   geventZspawnZIS_BOX_VERSIONZcache_optimizer>   run)argskwargsoptionsrF   Z	with_jobsrE   argr7   r   r   r   start~   s6     

rR   c           	   C   sL   t d8 ddlm}  t  t  t  t  |   t	  W d Q R X d S )N/r   )before_request)
r-   test_request_contextcmf.apprT   r?   r4   r5   rI   rJ   r   )rT   r   r   r   cmf_init_db   s    rW   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)getattrr9   logginginfoZraven.contrib.flaskrY   Zraven.handlers.loggingrZ   Z
raven.confr[   r-   rX   ZclientZsetLevelZERROR)rY   rZ   r[   ZsentryZ	l_handlerr   r   r   install_sentry_hook   s    

r_   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          
      sx  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| }	x$|	D ]}
|d|
||
f  qW d
|d
 }|d}||d<  |d< d|d< |d}|| ||}|| y|ddd}W n2 tk
rP } zt| | 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   )Ztimeout)	tracebackZflaskrf   Zsmtplibrg   Zemail.mime.multipartrh   Zemail.mime.textri   formatmethodZurlstr
format_excappendrK   sortedkeysgetr
   ZattachOSErrorprintZehloZsendmailZ	as_stringquit)Z	exceptionrl   Z	__requestrg   rh   ri   ZsubjectZmsg_contentsrK   ZenvironkeyskeyZbodyZmsg_rootZmsg_alternativeZplainZsmtpe)	mail_frommail_tosubject_prefixr   r   traceback_exception   sH    






z;install_traceback_email_notify.<locals>.traceback_exception)r\   r9   r]   r^   rc   
isinstancelisttupleAssertionErrorrd   re   r-   Zregister_error_handler	Exceptioncmf_exception_mail)r   r}   r   )rz   r{   r|   r   r8      s&    
0r8   )CustomJSONEncoderc              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   zUTF-8zNeed to pull)r]   rF   r   r	   r   r^   stattimest_mtime
subprocessPopenPIPEcommunicatedecodestripr   Z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.sh)r   r   zUTF-8z./.cmf_need_update)r]   r^   r   r   r   r   r   r   r	   r   remove)r   r   r   r   r   
cmf_updateI  s    

r   Tc          	   C   s  d }|st dd}zX|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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! |r2dt"_#t$dtj%d |j&t d |rj|  nt$dtj%d W d |r|j't(   X d S )NT)init_views_and_dsr   )r6   )commit_with_event)timeitz~/.cmf_historyc             S   s   t |  d S )N)readlinewrite_history_file)Zhistory_pathr   r   r   save_historyr  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shellz#!!! Use commit() to commit changes.)r   )ZlocalzNothing to exec))r.   	__enter__cmf.data_providers.baser6   rV   r   cmf.cmf_profiler   codecmf.includepprintlocalsupdateZinclude__dict__sysstdinreadZretcodeexecglobalsr   r	   
expanduserr   r   read_history_fileatexitregisterparse_and_bindZset_completerrlcompleterZ	CompleterZcompleteginteractive_shellrv   stderrZinteract__exit__exc_info)interactivescriptrN   without_contextZ_cmf_contextrollbackcommitr   Z__codecmfr   ppZ__history_pathr   r   r   r   	cmf_shellR  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
} fdd}|j
}| }d	|j_td
d* dt_tdtjd | |d    W d Q R X d S )Nr   )embed)
get_config)r6   )r   )r   c                  s"      t tjtjftj d S )N)r   execvr   
executableargvr   )r   r   r   r$     s    zipython.<locals>.reloadZneutralT)r   ishellz#!!! Use commit() to commit changes.)r   )r9   )ZIPythonr   Ztraitlets.configr   r   r6   rV   r   r   r   r   ZInteractiveShellEmbedZcolorsr.   r   r   rv   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 dQ R X dS )u|   
    :param email: почта админа созданная на этапе acrm_assign.sh --admin=test@carbonsoft.ru
    TrD   NO_CACHEr   )	demo_dataN)r.   r   rK   r   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   Zresolver   rv   ZabsoluteZCrypto.PublicKeyr   ZgenerateZwrite_bytesZ
export_keyZ	publickey)Zproj_dirZrsa_private_pathZrsa_public_pathr   rx   r   r   r   generate_rsa_keypair  s    

r   c          	   C   s   dt jd< t  t  g }xbttD ]V}|dkr2q$tt| }t|sJq$t|t	jj
sZq$d|jkrpd|jkrpq$|| q$W t }x|D ]}||}qW | rt| d}|tj|tdd W d Q R X nttj|tdd d S )	NrD   r   )ZCmfRFilerightleftzw+   )clsindent)r   rK   r?   r4   varsmodelsinspectZisclass
issubclassr   Z	BaseModelr   rq   r   Zdump_data_dictopenwritejsondumpsr   rv   )	file_pathZ
all_models
model_namemodelresfr   r   r   dump_db  s,    


"r   c          	      sZ   dt jd< t  t  t| d}t|  W d Q R X d fdd	}|  |d d S )	NrD   r   rFc                s*  x" D ]}yt t| }W n   t| d wY nX d }xЈ | D ]}td |j|j}||jj|d k }|rtd |d }| sqLntd |dd}x"|D ]}|d	krtd
 q|	|ddkrqt
||std| d| d qt||}tt|tjs$q|	|d kr>|js>qt|tjsjt|tjrr|jsj|jrr| srqt|tjr
x|| D ]z}	yPtj|	d }
|
j|
j}||
jj|	d k }|r||d  W n"   td|	d   wY nX qW qt|tjr,|	|d sqqt|tjr|jsJ|jryt||jd d ||  W n,   td| d|j d|j  wY nX qt|tjr|| d krq||| |_q|| |_qW |	ddd kr|dkrtd|j  qL|jdd qLW |r|j   qW 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 задача без кода )	only_data)!r   r   rv   dpZquery_deprecatedZdp_modelfilterr   allrt   hasattrr\   r   typer   ZCmfTypeZnullabler~   Z
CmfRelBaseZCmfTUUIDZforeign_keyZforeign_keysZ
CmfM2MBaseZget_cls_by_tuuid_strrq   ZCmfRelationBasesetattr
class_nameZ_valueZCmfDateTimecastsaver   )Zwith_relr   r   ZinstZ	inst_dictqZinstsrx   ZfielditemZ
list_model)r   r   r   r     s    


zrestore_db.<locals>.processT)F)r   rK   r?   r4   r   r   loadsr   )r   r   r   r   )r   r   
restore_db  s    
Rr   c           	      s   dt jd< t  t  t  ddlm  ddlm}  t	d |   t
jjdd}t
jjd	d} fd
d}| }x`tdD ]T}|j| |  |d tdt|jjd d |j| |  |d q~W |  W d Q R X d S )NrD   r   r   )r   )rT   rS   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 )N)rv   )s)nowr   r   r   wrapK  s    z&prod_test.<locals>.timer.<locals>.wrapc                  s   t d   S )Nend)rv   r   )rR   r   r   r   ra   P  rb   z*prod_test.<locals>.timer.<locals>.<lambda>)r   )r   )r   )r   )r   rR   r   timerG  s
    zprod_test.<locals>.timer
   rq   
all_nested)r   r   )r   rK   r?   r4   r5   r   rV   rT   r-   rU   r   r   rt   Z
CmfProjectrangeZ	executorsrq   Z_test_save_commitrv   lenr   r   r   )rT   ZtaskZprojectr   tir   )r   r   	prod_test9  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 d 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_z/patch/z.pyzpatch.jinja2)
patch_name	file_namezw+u#   Сгенерирован файл: u7   Команда для запуска: python3 -m patch.)jinja2EnvironmentFileSystemLoaderr   r	   r
   r9   PROJECT_DIRZpoliciesZcmfutilZtranslit_stripdatetimer   strftimeget_templaterenderr   r   rv   )r    Z	jinja_envr  r   Z
patch_textr   r   r   r   	new_patche  s    
r  c           	      s    fdd} t   g }tjtj ds0dS x:ttj dD ]$}t	d|rD|
|dd  qDW |  |std dS td	d
 tjjdgdgd}|s|d  |   xX|D ]" tjj dstj d  qW n,t|jjd}x|D ]  |kr|   qW W d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	  yPt
|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sgetrv   r9   r  r   run_bash_commandr   r   )r  cmdZerrcodeouterr)r    r   r   apply_patchx  s    
zpatch.<locals>.apply_patchz/patch/Nz[0-9]+_.*\.pyr   r   u0   Не найдено ни одного патчаT)r   r    r*   )Zorder_byr   r   )r    Z202306050000)rI   rJ   r   r	   r   r9   r  listdirrematchrq   rH   sortrv   r.   r   r  rt   r  r   maxr    value)r  ZpatchesfilenameZfirst_patchZfrom_patch_limitr   )r    r   patcht  s0    

r  c           	   C   s@   t   tdd$ tj } tj| _| j	dd W dQ R X dS )u?  
    Команда для системы обновления. Сохраняет eva_version в CmfGlobalSettings
    Если версии будут отличаться, в случае запуска образа с несовместимой версией БД,
    система вернет ошибку
    T)r   )r   N)
rI   rJ   r.   r   ZCmfGlobalSettingsrt   r9   ZEVA_VERSIONZeva_versionr   )Zgsr   r   r   save_version_to_db  s
    
r  )r    c          	   C   s   i }t tjtjdg}||d< t jf |}tj dtj	 
d d}t|d$}|d}||d| i W d Q R X td	|  d S )
Nzcmf/contribr   z/tests/test_z%Y%m%d%H%M%Sz.pyzw+ztest.py.tmplr    u#   Сгенерирован файл: )r  r  r   r	   r
   r9   r  r  r  r   r	  r   r
  r   r  rv   )r    Z_optionsZ_loaderZ
_jinja_envr   r   templater   r   r   new_test  s    
r!  c        	   	   C   sH  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| np|jdkrtd| nT|jdkrt  n>|jdkrt  n(|jdkrF|js8tdt|j n|jdkr\t  n|jdkrtt|  n|jdkrt|  n|jdkrPd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 rHt$d!d"d# |  n|jd$krt%t&j'( d%||j)d&}|rDt*| n|jd'krt|d + }|, }W d Q R X t%t&j'( |||j)d( nr|jd)krt-  n^|j.d*s|j.d+rt/0|j n4|jd,kr&t12  nt3d-t&j4dt&j5 t*d. d S )/Ncommandzrun command)r   helpz--emailu"   Почта (для init_demo_data)z--without-context
store_trueu4   Не инициализировать app и context)actionr#  rR   )Zcelery_workerZ
job_workerr   r5   r   r   r!  r  r  r   us   Нужно указать почту владельца CRM для инициализации демо-данныхr   r   r   r+   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)r  r   rj   )r   r   r   r   )r   r   rN   r   )r   r   zbin.zsbin.Zcache_flushdbu$   Команда не найдена:    )6r_   argparseArgumentParseradd_argumentro   parse_known_argsr3   r"  rR   rA   r   rW   r   r  r
   r!  r  r  r   r   r   r   r   r   Zcmf.make_modelsr'  r   r9   r  r   r   r	   r   ZmoveZrmtreer"   r  r   r   r   isattyr   exitr   r   r   
startswithr#   import_modulerI   rJ   rv   r   r   )	parserrN   Zunknown_argsr'  Zdir_pathZdst_pathr   Zscript_filer   r   r   r   main  s~    












 


r2  )TNNN)N)Jr)   Zcmf.monkey_patchr   r  r   r   r   r   r   r   r   r   collectionsr   Zpathlibr   r   Zcmf.system_datar   r	   r;   r<   r=   ZCUR_DIRrv   r   r   r   r   Z
work_modelr   r   rL   r   r   r%   r   Zcmf.fields.cmf_relation_cacher,   Zbuild_fields_cacherV   r-   r.   r/   r0   r1   r2   r3   r   r4   r5   r6   rA   rR   rW   r_   r8   r   r   r   r   r   r   r   r   r   r   r   r  r  r  ro   r!  r2  r   r   r   r   <module>   sf   !

$+J$	
:
_,2