B
    fB                @   s(  d dl Z d dlmZmZ d dlmZ d dlmZmZ d dlmZ d dl	Z	d dl
Z
d dlmZ d dlmZmZ d dlZd dlZd dlm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T d dlmZ d dlmZ d dlmZ d dl Z d dl!Z!d dl"m#Z# G dd dej$Z$dd Z%G dd dZ&dS )    N)copydeepcopy)Decimal)datetimetimezone)Logger)Path)DictIterator)cached_property)commit_all_ds)*)fields)
cmf_import)
log_config)wrapsc                   sb  e Zd Zejjd Zejjdddddddd	d
ddddg ZdZdZdZ	e
edddZeedddZejddfeedddZdzeeeeeedddZdd  Zd!d" Zedd#d$Zd%d& Zed'd( Zd)d* Z fd+d,Zd-d. Zd/d0 Z d1d2 Z!ed{d4d5Z"ed6d7 Z#ed8d9 Z$ed:d; Z%d<d= Z&d|ed>d?d@Z'dAdB Z(dCdD Z)dEdF Z*dGdH Z+e,ddIdJZ-dKdL Z.dMdN Z/dOdP Z0dQdR Z1edSdT Z2edddUdVZ3dWdX Z4 fdYdZZ5 fd[d\Z6d]d^ Z7e8dd_d`Z9dadb Z:dcdd Z;dedf Z<eedgdhdiZ=djdk Z>d}dmdnZ?dodp Z@eddqdrZAdsdt ZBeeCdududvdwdxdy ZD  ZES )~	CmfImport)
CSV_SETTING_NAMEcsv_import_settings_fieldslogger_last_stats	threadingqueuethreading_max_forksdownload_threading_max_forksmax_processesimport_settingscalc_import_settingscancelcheck_projectsdelete_dumpget_all_logs_by_zipget_log_filenameget_log_filenames
pg_restorepreviewstartstoptake_import_statstmplt_import_settingsZCSVN)returnc             C   s.   | j s(| dg dd | jd D | _ | j S )Njson_settingsc             S   s   i | ]}||d  qS )name ).0sr-   r-   ./common/models/cmf_import.py
<dictcomp>6   s    z-CmfImport.import_settings.<locals>.<dictcomp>r   )_import_settingsload_fieldsr+   )selfr-   r-   r0   r   2   s    zCmfImport.import_settingsc       	      C   sj  G dd dt j}t j}tjr$t j}tjjd| d}|s^tjd| d}|  |j	s^|
d tjjd| d}|stjd| d}|  |j	s|
d t |jj}|| d|_|jsftj|jdd	d
dd}|| |t tj || tj|jdd	d
dd}|| |t tj ||  || t tj}|t  || |S )uE    Журнал логирования процесса импорта c               @   s   e Zd Zdd ZdS )z)CmfImport.logger.<locals>.AnonymousFilterc             S   s   t |ddS )N	anonymousF)getattr)r4   recordr-   r-   r0   filter=   s    z0CmfImport.logger.<locals>.AnonymousFilter.filterN)__name__
__module____qualname__r8   r-   r-   r-   r0   AnonymousFilter<   s   r<   zdata.log)r,   parent    zanonymous_data.logFzutf-8Di@KL    )filenameencodingZwhenZmaxBytesZbackupCount)loggingZFilterINFOconfigDEBUGmodelsCmfAttachmentgetsavefile_existsZupload_file	getLoggeridvalueZsetLevelZ	propagatehandlersr   ZMyLogsHandlerZfull_path_fileZsetFormatterZ	FormatterZ	FORMATTERZ
addHandlerZ	addFilterZStreamHandlersysstdoutZCustomFormatter)	r4   r<   levelattachment_logZattachment_log_anonZapp_logZfile_handlerZanonymous_handlerZconsole_handlerr-   r-   r0   r   9   sR    







zCmfImport.loggerF)msgrR   c             K   s$   | j j||fd|i|d| dS )uI  Логируем как обычные лог для веб так и со скрытыми данными для возможности отправки в СТП

        Args:
            msg (str): сообщение
            level (int, optional): уровень логирования. Defaults to logging.INFO.
        r5   )Zextraexc_infoN)r   log)r4   rT   rR   r5   rU   kwargsr-   r-   r0   rV   i   s    zCmfImport.logERR-0001process)rT   
error_codeobj_typeext_href	dump_path
error_typec       	   
   C   sz   | j |tjd tj||| |||t |d}|rd|j|_|j	|_
| jrd| j||_| j||_|  |j  dS )u7  Логируем ошибки и записываем их в базу

        Args:
            msg (str): текст ошибки
            error_code (int, optional): Код ошибки для нахождения возможного решения или группировки. Defaults to 1.
        )rT   rR   )textcoder   r]   r^   r[   	tracebackr\   N)rV   rC   ERRORrG   CmfImportErrorra   
format_excr,   title
class_namer[   pluginZcalc_ext_hrefr\   Zcalc_dump_pathr]   rJ   dpcommit)	r4   rT   rZ   objr[   r\   r]   r^   Zimport_errorr-   r-   r0   	log_errorr   s"    zCmfImport.log_errorc             C   s   dd l }dd l}tj| _tj| _| d | _| j	d| jd  ddd tj
r`ttj
| j| _| j	dtj
 dd | j}| j	dt|d	  d
dd tt|d | j| _| jstdd S )Nr      z
cpu_count=u%   , надо не менее 2 ядерT)r5   zconfig.IMPORT_PROCESS=zavailable_memory=i   @u-   Гб, по 2 Гигабайта на ядроl        u   Ресурсов системы недостаточно для импорта, обратитесь в техподдержку для дополнительной информации.)multiprocessingpsutilrE   ZIMPORT_THREADSr   ZIMPORT_DOWNLOAD_THREADSr   	cpu_countr   rV   ZIMPORT_PROCESSminvirtual_memoryZ	availableint	Exception)r4   rm   rn   Zavailable_memoryr-   r-   r0   _prepare_multiprocessing   s    
z"CmfImport._prepare_multiprocessingc             O   sF   t jjd| dgd}|s.t jd| d}|  |js@| jd |jS )uK   
        Возвращает путь текущему файлу
        zdata.logurl)r,   r=   r   )r,   r=   u   Начало)rG   rH   rI   rJ   rK   r   inforu   )r4   argsrW   rS   r-   r-   r0   r"      s    zCmfImport.get_log_filenamec                s(    d  fddt D }|S )u   
        Список файлов после logrotate, чтобы можно было загрузить историю
        Tc                sB   g | ]:}t jt j |rtd |rt jd |qS )z%(?:data|anonymous_data)\.log(\.\d+)?$files)ospathisfilejoinrematchget_files_dir)r.   f)dir_pathr4   r-   r0   
<listcomp>   s    z/CmfImport.get_log_filenames.<locals>.<listcomp>)r   ry   listdir)r4   rw   rW   Z	file_listr-   )r   r4   r0   r#      s    
zCmfImport.get_log_filenamesc          	   O   s   dd l }t| d}|d}tj|r6t| ||d0}x(| 	 D ]}|
dtj}|| qNW W d Q R X tjd|  dS )Nr   Tzall_logs.zipwz/filesrx   )zipfiler   r   joinpathry   rz   existsremoveZipFiler#   replacerE   
UPLOAD_DIRwriter|   )r4   rw   rW   r   r   zip_pathmyzip	file_pathr-   r-   r0   r!      s    

zCmfImport.get_all_logs_by_zipc             C   s6   ddl m} tjjd }|j| s2|j| dd} | S )Nr   )cmf_hashlibtask_code_prefixZABCDEFGHIJKLMNOPQRSTUVWXYZ)Z	enc_table)Zcmf.utilr   rG   
CmfProjectr   Zregex	fullmatchZshort_str_enc)keyr   r   r-   r-   r0   get_correct_key   s
    zCmfImport.get_correct_keyc       
   	   O   s   dd l }ddlm} || d}|t d d}|  }|r|	|d:}x2|  D ]&}	|	
dtj}	||	 t|	 q`W W d Q R X tjd|  d	S d S )
Nr   )r   Tz
%Y%m%d%H%Mz_all_logs.zipr   z/filesrx   zall_logs.zip)r   pathlibr   r   r   r   nowZstrftimer#   r   r   rE   r   r   ry   r   rz   r|   )
r4   rw   rW   r   r   r   r   Zlog_file_pathsr   r   r-   r-   r0   zip_all_logs   s    
zCmfImport.zip_all_logsc                s(   | j  s| jjdd| _ t   d S )NZOPEN)status_type)statusloadworkflowget_default_statussuper_calc_status)r4   )	__class__r-   r0   r      s    
zCmfImport._calc_statusc             C   s  | j d rd S | jr(| j | j d< d S | jdkr6d S | j d dtj tjjd | j d dtj	 tj	jd | j d dtj
 tj
jd | j d dtj tjjd | j d dtj tjjd | j d d	tj tjjd d S )
NZmodels_fieldsexcelu   Поля контактов)Zcaptionr   iconu   Поля задачu   Поля заметокu   Поля проектовu"   Поля списков задачu   Поля групп)r+   rg   Zcalc_models_settingstypeappendrG   	CmfPersonZimport_shop_fieldsr   CmfTaskZ
CmfCommentr   CmfListZCmfPersonGroup)r4   r-   r-   r0   _calc_models_settings   s2    

zCmfImport._calc_models_settingsc             K   sp   |  ddddg | jd r d S | jj| d| jd< d| jd< d	| jd
< d| jd< d	| jd< | j| _|   d S )Nr+   attachmentsr   rg   r   )r   Tsend_invitesFremove_conflict_projects	pg_backupmerge_identic_names)r3   r+   rg   r   rJ   )r4   rW   r-   r-   r0   r     s    




zCmfImport.calc_import_settingsc             K   s   |  ddddg | jd r d S | jjdd| jd< | jjdd| jd< | jjd	d| jd	< | jjd
d| jd
< | jj| d| jd< | j| _|   d S )Nr+   r   r   rg   r   r   Tr   r   r   F)r   )r3   r+   rN   rI   rg   r)   rJ   )r4   rW   r-   r-   r0   r)     s    
zCmfImport.tmplt_import_settings c             C   s4   d|  d d} td|  d|  t|  d S )Nu1   Ошибка при импорте данных. .ue   . Проверьте загружаемый файл и повторите попытку снова.zCmfImportError: z: )striprC   error	cmf_alert)rT   er-   r-   r0   
_log_error  s    zCmfImport._log_errorc             C   s:   |  dg x(| jd D ]}|d | jkr|d S qW g S )Nr+   r   r,   r   )r3   r+   r   )r4   settingsr-   r-   r0   r   #  s
    z$CmfImport.csv_import_settings_fieldsc             O   s   t jd|  dS )uJ   
        Запускаем в фоне импорт данных
        r&   N)rG   r   
run_worker)	import_id_args_kwargsr-   r-   r0   r&   +  s    zCmfImport.startc             O   s   t jd|  dS )uR   
        Останавливаем в фоне импорт данных
        r'   N)rG   r   r   )r   r   r   r-   r-   r0   r'   2  s    zCmfImport.stopc             O   s&   dd l }|  }| r"|| d S )Nr   )shutilget_download_pathr   Zrmtree)r4   rw   rW   r   download_pathr-   r-   r0   r    9  s    zCmfImport.delete_dump)rowc          	   C   s>  d}|dkr|j }|sg }i }xht| jD ]Z\}}|d r*|| r*|d d dd |jkr`q*|d d |kr*|| ||d d < q*W |s|S || d}	tt|	d	}
 x|D ]}|j|}t	|tj
st	|tjr4d}x@| D ]4}|jd
dd|| gd	d|| ggdgd}|rP qW |r4t|	|| qt	|tjrDqt|	|||  || }t	|tjrt|d}t|tjj}t	|tjrq||d|g qW | jd r|j|dgd}|s:|d	}|r|j|dgdd}|r|
|	_|j|	jdgd}|r.|	j dttjd|	_|	}|  |S )u  
        Импортируем объект

        :param list row: Строка из файла
        :param models.* model: Модель для создания объекта
        :param list _filter: Для фильтрации объекта
        :param str key: Ключевое имя для сопоставления модели

        :return: Новый или найденный объект
        :rtype: Optional[models.*]
        Nmodel_fieldfield_qualnamer   r   verbose_name
field_name)r   r`   ORr,   z==z**)r8   r   ZRUunionT)r`   r   include_deleted)r,   r   _z%Y%m%d-%H%M%S)r   	enumerater   splitrf   strr6   r   rI   
issubclassZCmfRelationZCmfGenericRelationZrelated_modelssetattrZ
CmfRelBaseZCmfPhonephonenumbersparseZformat_numberZPhoneNumberFormatZINTERNATIONALZ
CmfNumericr   r+   r`   r,   r   r   r   utcrJ   )r4   r   model_filterr   result_fieldsisettingZnew_objZnew_coder   ZfieldZrel_objZ	rel_modelvalZphoner`   r-   r-   r0   _process_obj@  sh    

zCmfImport._process_objc             C   s$   |  dg ddd |  D S )Nrg   
c             S   s   g | ]\}}|qS r-   r-   )r.   r   dr-   r-   r0   r     s    z,CmfImport.check_projects.<locals>.<listcomp>)r3   r|   get_confict_projects)r4   r-   r-   r0   r     s    zCmfImport.check_projectsc       	      C   s  g }| j jjdkr|S | dg | jd d d }dd |d D }x|D ]}| |d	 }tjjd
dd|d gdd|gggdddddgd}|rNd }|j	r|j	dg |j	j
}|r| j j jnd }| j jjdkrd|jjdkr||d| d|j d| df nT|j	r|jr6||d| df n,|r|r||kr||d| df qN| j jjdkrN|jjdkr| jd  d d! d"kr||d#| d|j d$|d  d%| d&	f qN|j	r|jr||d| df qN|rN|rN||krN||d| df qNW |S )'NCmfPluginCsvzplugin.plugin.source_hashZselectedObjectsrN   r   c             S   s$   g | ]}|d  r|d r|d  qS )rj   Z	isCheckedr-   )r.   r   r-   r-   r0   r     s    z2CmfImport.get_confict_projects.<locals>.<listcomp>Zchildrenr   r   r,   ZILIKEr   z==Tlogic_prefixr   cmf_deleted)r8   r   r   ext_idCmfPluginJirazproject.wikiu4   В системе уже есть Wiki-проект u    с кодом «uj   ». Измените префикс кода задач и код проекта у Wiki-проекта «uv   » и его название в системе и запустите импорт Agile-проекта ещё раз.uI   В системе обнаружен одноименный проект u   . Для запуска импорта необходимо удалить данный проект (проект будут удалён безвозвратно) или отменить его выбор.u  , импортированный из другого источника. Для запуска импорта необходимо удалить данный проект (проект будут удалён безвозвратно) или отменить его выбор.ZCmfPluginConfluencezproject.agileZimport_typerM   projectu5   В системе уже есть Agile-проект uB   ». Для объединения Wiki-пространства «u   » с Agile-проектом u    запустите импорт ещё раз с опцией «Импортировать в Документы Agile проекта» на втором шаге импорта.)rg   rN   rf   r3   r   r   rG   r   rI   r   r   source_hashr   r   r   r   )	r4   r   rootZselected_projectsZprjZproject_keydupZdup_shZself_shr-   r-   r0   r     s@     &0zCmfImport.get_confict_projectsc             C   sB   x0t j D ]"}| jj |krt jj|dS qW tddd d S )N)backup_nameu   Бекап для данного импорта не существует. Воспользуйтесь функционалом "Отмена".T)abort)rG   CmfGlobalSettingsZpg_backup_lsr`   rN   lowerr$   r   )r4   Zbk_namer-   r-   r0   r$     s    zCmfImport.pg_restorec       
   
   C   s  |  dddg d}| jr zyZt F | jjdrTtjj	| j
j d | jjdr|  }|rx<|D ]4\}}| jd| tjd	 |jd
d |j  qtW dtjd< d| _d| _| jjjj| _|   | j  dtjd< x`| jD ]V}xP| j| D ]B}d}|dkr6t|   r6| j| | }| ||| qW qW tjj dd| gd | jj!| d}W dQ R X W n\ t"k
r } z<| j#  t$| dt%&|j'd  }	| (d |	| _)W dd}~X Y nX W d| * | _|   t+j,j-.  |S | j/dkr| 0 S dS )u9   
        Импортируем файл в бд
        r   zplugin.plugin.*zplugin.*Fr   )r   r   u7   Удаляем конфликтующий проект )rR   T)TEXKOM_db_deleter   ZNO_CACHEr   1
downloadedr   z==)r8   )r   Nr   u(   Ошибка работы импортаr   )1r3   rg   cmfutilenable_import_moder+   rN   rI   rG   r   r   r`   r   r   rV   rC   WARNINGdeleterh   ri   ry   environZimported_object_countprogressr   r   rJ   import_statslistr   Ziterdirinc_statrc   Zbulk_deleteprocess_importrs   Zrollbackr   ra   	format_tb__traceback__rk   	error_msgget_redis_import_statscmfapp	CMF_CACHEflushdbr   _process_import_excel)
r4   r   Zprojectsr   r   obj_nameopr   err
error_textr-   r-   r0   r     sP    





zCmfImport.process_importc       4      C   s  ddl m} | jr| jd s dS d}yi }i }i }i }i }i }i }	|  }
x<t|
D ].\}}|dkrv| jd rvqXi }i }d}d}x>t| jD ].\}}|d r|| sq|d d d	d }||i }|d d
 d	}|d }|| }|dkr|}qn|dkr|}qt	|dkrZ|dkr<|||d < q||i }|| ||d < nZ|dkr~|dkr~|
|| }n6|dkr||| }n|dkrd||| i}|||< |||< qW |di }|dd}||d}|s|| tj|\}}|||d< || tj|\}}|di }|drP|d |d< |di }|r|	|}|s|dkrtjjddtjjddd}ntjjddtjjddd}||	|< ||d < ||d< ||d!< ||d"< d#d$d%|jgdd%|d gg}|| tj||\} }| j| |   | ||d < |rT||g }!|!|  |!||< |r||d g }"|"| |"||d < |d&i d'd}#|#r|# d(|jj }$||$i }%||%d!< |#|%d'< |%d)g }&|&|  |&|%d)< |%||$< ||d}'|'srtjjd#d*d%|jgd'd%d+ggd,}(d#d*d%|(jgd'd%d-gg})d-||(d.d/}*|j| tj|*|)d0\}'}|'||d< || tj|'| d1 qXW x| D ]\}$}+tjjd#d*d%|+d! jgd'd%d2ggd,}(d#d*d%|(jgd'd%|+d' gdd3d4gg})tjj|)d,},|,s(tj|+d! |(|+d' tj jd5dd6},|,  x$|+d) D ]} |,| _!| jd7d8 q2W qW xN| D ]B\}}-||}.|.r^x&|-D ]}/|/j!"  |.|/_!|/  q|W q^W x^| D ]R\}}0||}.|.rx6|0D ].}1||1}/|/r|/j!"  |.|/_!|/  qW qW W nx t#k
r~ }2 zXt$|2 d9| d:|2 d;t%&|2j'd<  }3| j()|3 |3| _*| j+j,d=d>| _-|   dS d?}2~2X Y nX d7S )@u   
        Запуск импорта из CSV

        :return: Истина в случае успешного импорта
        r   )CmfPluginImportMixinr   FZ	first_rowr   r   r   r   r   parent_taskZchild_tasksrl   	executorsr   r   priorityr   r   zproject.agiler`   r   Z
cmf_authorZ	cmf_ownerzproject.basez
task.base%base)r`   )Z	cmf_modelprefixZactivityztask.agile:softdev%Zsoftdevr   r   r=   ZANDZ	parent_idz==r   r,   r   tasksZtree_parent_idZSprints)r8   u
   ДоскаZkanban)r,   r=   tree_parentZ	list_type)r   r   
obj_fields
filter_obj)leftrightZEpics=z	task.epicztask.epic:default)r=   r  r,   Z
logic_typeT)	only_datau   Строка z: r   r   zimport-error)status_codeN).Z%common.models.cmf_plugin_import_mixinr  r   r+   Z	_get_filer   r   r   rI   lenZget_logic_prefixZget_priorityZget_status_type
setdefaultZprocess_any_table_fieldsrG   r   r   CmfWorkflowZcalc_workflowZCmfActivityrM   r   r  r   rJ   r`   rN   Z	CmfFolderr   ZCmfListCmfTaskitemsZCmfLogicTyper  r   rs   r   ra   r   r   r   	exceptionr   r   r   r   )4r4   r  Z
number_rowZall_parent_taskZall_child_tasksZall_epic_tasksZ	all_tasksZ
cash_boardZcash_projectZcash_workflow_taskZ	file_readr   executorr   Zparent_task_codeZchild_tasks_codeidxr   
model_nameZ_rowZfields_namer   rN   Zproject_fieldsr   r   r   Zexecutor_objZtask_fieldsZvalue_statusr   Zfilter_taskZtask_objZtmp_parent_tasksZtmp_child_tasksZ	epic_nameZepic_keyZtmp_dataZ	tmp_tasksZlist_objZparent_folderr
  r	  dataZepic_objr  r  Zsub_taskZ
tasks_codeZsub_task_coder   r   r-   r-   r0   r     s2   



















"zCmfImport._process_import_excelc             C   sF  |  |tj}|r|sdS d}x*| jD ] }|d r&|d d dkr&|}q&W |dg tjj|jt|d |j	jdgd}|stj|t|d |j	| d	}|
  |jjd
d x:t|jjD ]*}|jj| jkrq|  |jj| qW | j |tjtjjdd|jgdd|jggd}|ddg ||_||_|jrB|
  |S )u;   
        Импорт товара в сделку
        Nr   r   zCmfProduct.pricescurrencyfile_valprice)
product_idr  Zcurrency_idr   )productr  r  r   T)forceZdeal_idz==r  )r   r   r  Zsales_order)r   rG   Z
CmfProductr   r3   ZCmfPricerI   rM   r   r  rJ   Zpricesr   r   Z
deal_itemsrN   r   r   r   ZCmfDealItemsr   dealr  
is_changed)r4   r   r  r  Zprice_settingr   r  itemr-   r-   r0   _process_product  s8    zCmfImport._process_productc       	      C   s  |s|r|j sd S d }x*| jD ] }|d r|d d dkr|}qW |sJd S g }tjj|d d}|s|tj|d d}|  |dd|jg |r|dd|jg n|dd|j jg | |tj	|}|
d	d
g |j s|r||_ n|j |_ |js||_|jr|  |S )Nr   r   zCmfDeal.pipeliner  )r,   Zpipeline_idz==Z
company_idcompanypipeline)r#  r   rG   ZCmfPipelinerI   rJ   r   rM   r   ZCmfDealr3   r$  r   )	r4   r   Zcontactr#  Zpipeline_settingr   r   r$  r  r-   r-   r0   _process_deal  s8    zCmfImport._process_dealc             C   s   dd l }dd l}dd l}| jr4|  | j dk r4d S |  | _t }y6||j|j}|d | d |d< |	  W n t
k
r   d|d< Y nX y| |d< W n t
k
r   d|d< Y nX | |d< ||  |d	< | jd
|  d S )Nr      )z8.8.8.8P   ZipzIP unavailabler   )r   r   r   ZmemoryZdiskzSTATS )timern   socketr   dictZAF_INETZ
SOCK_DGRAMZconnectZgetsocknamecloseOSError
getloadavgrq   
disk_usager   r   rv   )r4   r(  rn   r)  Zstatsr/   r-   r-   r0   	get_stats  s*    

zCmfImport.get_statsc             C   s   dd l }tj  |  }||\}}}|d }tjj| j	ddgd}|dk rd|_
|jrj|  t  | jd| d	 d
S |   |j
jdks|jdkrd|_
|jr|  t  | jd d
S dS )Nr   i   @r   cache_status_type)rM   r   
   zimport-erroru8   Импорт прерван, место на диске z < 10GbTzimport-stoppingIN_PROGRESSzimport-pauseduA   **** Импорт остановлен пользователемF)r   r   r   Zimport_heartbeatr   r.  rG   r   rI   rM   r   r   rJ   commit_with_eventr   r   r/  r`   r0  warning)r4   r   r   ZtotalZusedZfreeZfree_gbrj   r-   r-   r0   	is_cancel  s,    
zCmfImport.is_cancelc          	   C   sB   dd l }|jdddd|  d| dgddtd	d
tdd
d d S )Nr   z/usr/bin/python3z	manage.pyshellzHfrom common.models.cmf_import import CmfImportWorker; CmfImportWorker().z("z")Tz"/var/log/eva-import-subprocess.logza+z&/var/log/eva-import-subprocess.err.log)Z	close_fdsZstart_new_sessionrQ   stderr)
subprocessPopenopen)methodr   r8  r-   r-   r0   r   )  s    zCmfImport.run_workerc              O   s   t jd|d  dS )u/   
        Отменяем импорт
        r   rM   N)rG   r   r   )rw   rW   r-   r-   r0   r   0  s    zCmfImport.cancelc             O   s    |  ddddg | jj| dS )uk   
        Предварительный просмотр получившихся объектов
        r+   r   r   rg   )r   )r3   rg   r%   )r4   rw   rW   r-   r-   r0   r%   8  s    zCmfImport.previewc                s   t   ddddg S )Nr+   r   r   rg   )r   save_preload_fields)r4   )r   r-   r0   r<  ?  s    zCmfImport.save_preload_fieldsc                s   |    t jf |S )N)r   r   rJ   )r4   rW   )r   r-   r0   rJ   B  s    zCmfImport.savec             C   s@   | j r
d S | jr,| jjdkr,tjjdd| _ tjjdd| _ d S )Nr   zimport.system.jira:default)r`   zimport.system:default)r   rg   rf   rG   r  rI   )r4   r-   r-   r0   _calc_workflowF  s
    zCmfImport._calc_workflowc             C   sZ   |  dg ttj| jj  d}| jjjj	rH|| jjjj	}|j
ddd |S )Nzplugin.plugin.source_hashZ	_raw_dataT)exist_okparents)r3   r   rE   r   r   rg   Zui_namer   r   rN   mkdir)r4   resr-   r-   r0   r   N  s    zCmfImport.get_download_pathc             C   s   | j |  d S )N)rg   download_data)r4   r-   r-   r0   rB  V  s    zCmfImport.download_datac             C   s   | j |  d S )N)rg   download_files)r4   r-   r-   r0   rC  Y  s    zCmfImport.download_filesc       	   	   C   s   dd l }dd l}|jdddgd}| d x2|D ]*}| d|jd |jd |jd  q2W | d |d	d
g}|d}| }x|D ]}| | qW d S )Nr   pidr,   Zusername)attrsz==============ps auxz{:<10d} {:<20s} {:<10s}z==============netstat -panZnetstatz-panzutf-8)	rn   r8  Zprocess_iterrV   formatrv   Zcheck_outputdecode
splitlines)	r4   rn   r8  Z	processesrY   outputZ
output_strlinesliner-   r-   r0   
log_detail\  s    

*


zCmfImport.log_detail)api_urlr*   c       
   
      s\  ddl m} ddlm  td fdd}d}|dd
 x  rNP | }|d	kr`P y| tj	|d
dddgd}t
|dr||jj|_|jr|  |  n ||jj|_|jr|jdd x:|jD ]0}	|	jdkrq||	jj|	_|	jr|	jdd qW W qD   jd| tjddd |d7 }Y qDX qDW W d Q R X || d S )Nr   )cmf_context)BeautifulSoup)r_   c                s  | s| S  | d}x| dD ]}|jdr4q |jddr d }d|jd krtd|jd }|sjd|jd  tjd	 q j	j	j
 d
|ddd   }tjj|dgd}|sވjd| tjd	 q nd|jd kr td|jd }|s$jd|jd  tjd	 q tjjddd|ddd   dgdgd}x2|D ]*}|jd |ddd  krX|}P qXW |sjd|ddd   tjd	 q nq |tj| q W t|S )Nzhtml.parseraZcmf_convertedZhrefr   z/wiki/z\/\d+u:   Не удалось найти ид документа в )rR   z::r   rl   )r   r   u:   Не удалось найти документ по ид z/browse/z	\/\w+-\d+u4   Не удалось найти ид задачи в import_raw_jsonZLIKEz%"key":"z"%)r8   r   r   u:   Не удалось найти задачу по коду )Zfind_allrE  rI   
startswithr}   searchrV   rC   r   rg   r   grouprG   ZCmfDocumentr   r   rQ  Zreplace_withr   Zcreate_tag_linkr   )r_   Zsouptagrj   r   Zext_codeobjsr   )rO  rM  r4   r-   r0   check_linksv  sH    
"

$z.CmfImport.obj_check_links.<locals>.check_linksF)Zinit_views_and_dsDONEr_   zcomments.log_levelzcomments.text
text_draft)r   T)r     uZ   Не удалось конвертировать перекрестные ссылки в )r5   rU   rl   )cmf.apprN  Zbs4rO  r   r5  rI   rV   r   Zget_obj_by_idhasattrr_   rN   rY  r   rJ   Z
do_approveZcommentsZ	log_levelrC   rb   put)
r4   rM  	obj_queueobj_queue_errorsrN  rW  
has_errorsZobj_idrj   commentr-   )rO  rM  r4   r0   obj_check_linkss  s@    '



zCmfImport.obj_check_linksc             C   s  ddl m} dd l}t  t  t  |   d}tt	| }| 
d|j d| d|  t }	t }
g }| 
d| j  |j }xTt| jD ]F}tj| jd| |	|
|dd	}|| |  | 
d
|  qW d}ddd gdddgg}|j|ddg||| gd}x.|D ]&}|  r>P |d7 }|	|j q.W x|D ]}|	d q^W | 
d x|D ]}|  qW |j | }| 
d||   d d}x|
 s||
 7 }qW | 
d|  |S Q R X W d Q R X W d Q R X d S )Nr   )rN  u)   Конвертируем ссылки в uB    на локальные задачи и документы start=z limit=uJ   Обрабатываем ссылки в несколько тредов: rb  )r^  r_  rM  )targetr,   rW   u.   Параллельный обработчик r   z!=Zimport_originalz==Tz--rM   )r8   r   slicerl   rX  u(   Ждем обработки ссылокu*   ------------------------ скорость u#    обьектов в секундуuA   Закончили обработку ссылок, ошибок )r[  rN  r   r   disable_acldisable_notifyr   rt   varsrG   rV   r   r   ZQueuer   r   ranger   ZThreadrb  r   r&   Zslistr5  r]  rM   r|   Ztotal_secondsemptyrI   )r4   rM  r  r&   limitrN  r   r`  r   r^  r_  Zobj_processr/   r   procZcntr   rV  rj   Zdiffr-   r-   r0   process_cross_links  sP    $






zCmfImport.process_cross_linksr   c             C   s6  d|krt dd}| d| d| j }tj}| j d| d}|jj|dd}|  zr|j ^}	|	| jj	| |d k	r|	j
|||d n&||r|	| n|	j
|d|d |	  W d Q R X W d y|  W nH tjjk
r" }
 z$td	|
 d
|j d|j  W d d }
~
X Y nX X |dkr2|s2d| d| j }| d}|jj|dd}|  zn||sd| jj	|i kr|j 8}	|	| jj	| |	j
|| j| d |d |	  W d Q R X W d y|  W nH tjjk
r. }
 z$td	|
 d
|j d|j  W d d }
~
X Y nX X d S )N-uA   Нельзя использовать "-" в obj_name: {obj_name}i:	 z.lock   )timeout)exrl   zlock release error z, lock_name z
, timeout r   zdownloaded-)rs   rM   APPREDIS_DBredislockacquirer$  ZsaddrN   setr   ZincrZexecuterelease
exceptionsZ	LockErrorgdebugr,   ro  r   rI   )r4   r   r   rN   Zttlr   redis_dbZlock_keyrt  piper   r-   r-   r0   r     sH    
4
"zCmfImport.inc_statc             C   sn   t j}i }x^|j| jjD ]J}| }||}|d^}}}||sVt	 ||< | || |< qW |S )Nrm  )
rq  rr  rs  ZsmembersrM   rN   rG  rI   r   r*  )r4   r{  r   r   rN   r   r   r   r-   r-   r0   r     s    


z CmfImport.get_redis_import_statsc             C   s(   |  ddg | jdkr | jjS |  S )Nr0  r   r2  )r3   r0  r   rN   r   )r4   r-   r-   r0   r(   #  s    
zCmfImport.take_import_statsc             C   s~   |  ddddg | jdks(| jjdkr,dS tj szt }| szd}| j	|t
jd	 || _| jjd
d| _|   dS dS )Nr   r   r0  r   r2  zimport-plannedFu   Импорт прерван по неизвестной причине. Проверьте системные требования.)rR   zimport-error)r  T)r3   r0  r   r`   r   r   Zimport_is_runningCmfImportWorker
is_runningrV   rC   rb   r   r   r   rJ   )r4   Zworkerr   r-   r-   r0   r~  *  s    
zCmfImport.is_runningTz	@minutely)Z	only_onceZ
system_jobZschedulec              C   sJ   t d x:tjjdddgddddgdD ]} |  s*td	|  q*W d S )
Nz&cmf_deferred_job: CmfImport.cron_checkr0  z==r2  r   r   r   )r8   r   uH   Импорт прерван по неизвестным причинам)ry  rz  rG   r   r   r~  r   Zadmin_alert)rj   r-   r-   r0   
cron_check:  s
    
zCmfImport.cron_check)rX   NNNNrY   )r   )NN)r   N)Fr9   r:   r;   r   r   Zui_meta_skipZapi_methodsr   r   r2   propertyr*  r   r   r   r   rC   rD   r   rr   rV   rk   rt   r"   r   r#   r!   staticmethodr   r   r   r   r   r)   r   r   r&   r'   r    r   r   r   r$   r   boolr   r"  r%  r/  r5  r   r   r%   r<  rJ   r=  r   r   rB  rC  rL  rb  rl  r   r   r(   r~  Zcmf_deferred_jobr  __classcell__r-   r-   )r   r0   r      s   /	 
N%2 B!#J,
-r   c                s   t   fdd}|S )Nc                sJ   y& | f||}t   | jd |S    | jd t  Y nX d S )Nu*   Импорт завершил работуu&   Ошибка работы демона)r3  r   rv   r  rollback_purge_event)rj   rw   rW   rA  )fnr-   r0   wrappedF  s    z!catch_exceptions.<locals>.wrapped)r   )r  r  r-   )r  r0   catch_exceptionsE  s    
r  c               @   sl   e Zd ZdddZdd Zdd Zdd	d
dZedd Zedd Z	edd Z
edd Zdd ZdS )r}  eva-import-workerc             C   sb   ddl m} dd l}ddlm} ||| _|j| j|d| d|jd |d| d| _	d S )	Nr   )r   )r   z/var/logz.log)rR   z	/var/run/z.pid)
cmf.modules.logsr   rC   r   r   rL   r   Zinit_loggerrD   rD  )r4   r   r   rC   r   r-   r-   r0   __init__T  s     zCmfImportWorker.__init__c             C   s  | j d tjjddd|gdd|ggdddd	gd
}|  |d |jjddd|_	|
  t  t @ t , t  | }td W d Q R X W d Q R X W d Q R X tjj|jdddd	gd}tjjdd|gd}|j	jdkrX|s|j d |jjdd|_	|
  n:|j	jdkrX|j d| d |jjdd|_	|
  |j jd jtjd}tjj|tj |j!dt"#t$j%dd| dd d! d S )"Nu   Импорт запущенr   rM   z==r`   r   r   r   zplugin.plugin.*)r8   r   u%   ***Запускаем импорт***r2  zimport-started)r   r  rl   )rM   r   r   )r8   u2   ***Импорт успешно завершен***zimport-completed)r  CLOSEDu6   ***Импорт завершен с ошибками: u,   . Подробности в отчете.***zimport-errorr   z/files/u+   Импорт данных завершен z%d.%m.%Y %H:%Mz
, <a href=u(   >Журнал логирования</a>T)rj   personr,   rT   force_notify_current_person)&r   rv   rG   r   rI   r   rV   r   r   r   rJ   r3  r   re  rf  r   r   geventsleeprM   rc   countr`   r   rO   baseFilenamer   rE   r   	CmfNotifyplace_notifyry  current_personr,   r   r   r   r   )r4   r   rj   rA  errorslog_pathr-   r-   r0   run\  s<    
(

zCmfImportWorker.runc             C   s  | j d t . t  t  tjjddd|gdd|ggdddd	gd
}|	d |j
jddd|_|  t  | }| }tjjdd|gd}|r|r|s|j d |j
jdd|_|  n:|jjdkr|j d| d |j
jdd|_|  |j jd jtjd}W d Q R X W d Q R X W d Q R X tjj|tj|jdtt j!dd| ddd d S ) Nu   Дамп запущенr   rM   z==r`   r   r   r   zplugin.plugin.*)r8   r   u!   ***Запускаем дамп***r2  zimport-started)r   r  r   )r8   u.   ***Дамп успешно завершен***r  )r   u2   ***Дамп завершен с ошибками: z***zimport-error)r  r   z/files/u'   Дамп данных завершен z%d.%m.%Y %H:%Mz
, <a href=u(   >Журнал логирования</a>T)rj   r  r,   rT   r  )"r   rv   r   re  rf  r   rG   r   rI   rV   r   r   r   rJ   r3  rB  rC  rc   r  r   rO   r  r   rE   r   r  r  ry  r  r,   r   r   r   r   )r4   r   rj   rA  Zres2r  r  r-   r-   r0   	dump_data  s4    $

6zCmfImportWorker.dump_dataN)r*   c             C   sx  | j d t X t B t , tjjddd|gdd|ggddgdd	}|j	j
d
d|_|  t  zƐyfd}d}|j d xxtjjdd|gddD ]^}y*|j d|  |jddd t  W q   |d7 }t  |j d| d Y qX qW tjjddd|gdd|ggdddgdd	}xb|jD ]X}y*|j d|  |jddd t  W n&   |d7 }t  |j d Y nX q>W |s|j	j
dd|_|j d n"|j d|  |j	j
dd|_W nX tk
r: } z8|j d|  t| t||_|j	j
dd|_W dd}~X Y nX W d|  tjj  X W dQ R X W dQ R X W dQ R X dS )u/   
        Отменяем импорт
        u   Отмена запущенаr   rM   z==r`   r   r   T)r8   r   r   zimport-canceling)r  r   Nu#   ***** Отменяем импортr   )r8   r   u   Удаляем )r   r  rl   u#   Не удалось удалить uW   , видимо обьект использовали вне данных импортаimport_objectsuy   Не удалось удалить, видимо обьект использовали вне данных импортаzimport-canceledu,   Успешно отменили импортu#   Количество ошибок: zimport-erroru   Ошибка удаления )r   rv   r   re  rf  r   rG   r   rI   r   r   r   rJ   r3  r   r   r   r  r  r  r   rs   r   r   r   r   r   r   r   )r4   r   rj   r  r   r   r-   r-   r0   _cancel_import  sV    $


&zCmfImportWorker._cancel_importc             G   s>   | j  rtd| j tt  | j|  | j   d S )Nu"   Импорт уже запущен)	rD  r   rs   
write_textr   ry   getpidr  unlink)r4   rw   r-   r-   r0   r&     s
    

zCmfImportWorker.startc             G   s>   | j  rtd| j tt  | j|  | j   d S )Nu"   Импорт уже запущен)	rD  r   rs   r  r   ry   r  r  r  )r4   rw   r-   r-   r0   dump  s
    

zCmfImportWorker.dumpc             G   s>   | j  rtd| j tt  | j|  | j   d S )Nu"   Импорт уже запущен)	rD  r   rs   r  r   ry   r  r  r  )r4   rw   r-   r-   r0   r     s
    

zCmfImportWorker.cancelc             G   s4  t jjdddgddddgd}|r|  r|jd	 |jjd
d|_|	  t
  xJtdD ]0}td t jj|jddgd}|jdkr^P q^W n|jd |jjdd|_|	  t
  |jd | j s| jd d S | jd ytt| j tj W n   | jd Y nX | j  d S )Nr0  z==r2  r   r   r   zplugin.plugin.*)r8   r   uQ   Пытаемся остановить импорт, таймаут 1 минутаzimport-stopping)r  <   rl   )rM   r   u"   Импорт уже прерванzimport-pausedu<   Импорт остановлен пользователемu    Импорт не запущенu'   Останавливаем импортuK   Не удалось завершить процесс, он запущен?)rG   r   rI   r~  r   r4  r   r   r   rJ   r3  rh  r  r  rM   r0  rv   rD  r   ry   killrr   	read_textsignalSIGTERMr  r  )r4   rw   rj   r   r-   r-   r0   r'     s4    


zCmfImportWorker.stopc             C   s0   | j  r,tt| j  r"dS | j   d S )NT)rD  r   r   Zcheck_process_runningrr   r  r  )r4   r-   r-   r0   r~    s    
zCmfImportWorker.is_running)r  )r9   r:   r;   r  r  r  r  r  r&   r  r   r'   r~  r-   r-   r-   r0   r}  S  s   
$ 2r}  )'Zcsvr   r   decimalr   r   r   rC   r   rP   ra   r   r   typingr	   r
   rs  r   r   ZxlrdZopenpyxlr   r   Zcmf.data_providers.baser   Zcmf.includer   r   Zcommon.fieldsr   r  r   ry   r  	functoolsr   r   r  r}  r-   r-   r-   r0   <module>   sB           2