U
    T8f                     @   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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                       s0  e Zd Zejjd 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dkeeeeeedddZdd Zdd ZedddZdd Zdd Z fddZdd Zd d! Zd"d# Zedld%d&Z ed'd( Z!ed)d* Z"ed+d, Z#d-d. Z$dmed/d0d1Z%d2d3 Z&d4d5 Z'd6d7 Z(d8d9 Z)e*dd:d;Z+d<d= Z,d>d? Z-d@dA Z.dBdC Z/edDdE Z0edddFdGZ1dHdI Z2 fdJdKZ3 fdLdMZ4dNdO Z5e6ddPdQZ7dRdS Z8dTdU Z9dVdW Z:eedXdYdZZ;d[d\ Z<dnd^d_Z=d`da Z>e
ddbdcZ?ddde Z@eeAdfdfdgdhdidj ZB  ZCS )o	CmfImport)
CSV_SETTING_NAMEcsv_import_settings_fieldslogger_last_stats	threadingqueuethreading_max_forksdownload_threading_max_forksmax_processes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>$   s      z-CmfImport.import_settings.<locals>.<dictcomp>r!   )_import_settingsload_fieldsr$   selfr'   r'   r*   r!       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)r/   recordr'   r'   r*   filter+   s    z0CmfImport.logger.<locals>.AnonymousFilter.filterN)__name__
__module____qualname__r3   r'   r'   r'   r*   AnonymousFilter*   s   r7   data.logr&   parent    zanonymous_data.logF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)	r/   r7   levelattachment_logZattachment_log_anonZapp_logZfile_handlerZanonymous_handlerZconsole_handlerr'   r'   r*   r   '   sV    







zCmfImport.loggerFmsgrP   c                 K   s$   | j j||fd|i|d| dS )uI  Логируем как обычные лог для веб так и со скрытыми данными для возможности отправки в СТП

        Args:
            msg (str): сообщение
            level (int, optional): уровень логирования. Defaults to logging.INFO.
        r0   )Zextraexc_infoN)r   log)r/   rS   rP   r0   rT   kwargsr'   r'   r*   rU   W   s    zCmfImport.logERR-0001process)rS   
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.
        rR   )textcoder   r\   r]   rZ   	tracebackr[   N)rU   rA   ERRORrE   CmfImportErrorr`   
format_excr&   title
class_namerZ   pluginZcalc_ext_hrefr[   Zcalc_dump_pathr\   rH   dpcommit)	r/   rS   rY   objrZ   r[   r\   r]   Zimport_errorr'   r'   r*   	log_error`   s$    	zCmfImport.log_errorc                 C   s   dd l }dd l}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)r0   zconfig.IMPORT_PROCESS=zavailable_memory=   @u-   Гб, по 2 Гигабайта на ядроl        u   Ресурсов системы недостаточно для импорта, обратитесь в техподдержку для дополнительной информации.)r   r   multiprocessingpsutilrC   ZIMPORT_THREADSr   ZIMPORT_DOWNLOAD_THREADSr   	cpu_countr    rU   ZIMPORT_PROCESSminvirtual_memoryZ	availableint	Exception)r/   r   r   rm   rn   Zavailable_memoryr'   r'   r*   _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   
        Возвращает путь текущему файлу
        r8   url)r&   r:   r   r9   u   Начало)rE   rF   rG   rH   rI   r   inforu   )r/   argsrV   rQ   r'   r'   r*   get_log_filename   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_pathr/   r'   r*   
<listcomp>   s    z/CmfImport.get_log_filenames.<locals>.<listcomp>)r   rz   listdir)r/   rw   rV   Z	file_listr'   r   r*   get_log_filenames   s    
zCmfImport.get_log_filenamesc              	   O   s   dd l }t| d}|d}tj|r6t| ||d,}| 	 D ]}|
dtj}|| qLW 5 Q R X tjd|  dS )Nr   Tall_logs.zipw/filesry   )zipfiler	   r   joinpathrz   r{   existsremoveZipFiler   replacerC   
UPLOAD_DIRwriter}   )r/   rw   rV   r   r   zip_pathmyzip	file_pathr'   r'   r*   get_all_logs_by_zip   s    

zCmfImport.get_all_logs_by_zipc           
   	   O   s   dd l }ddlm} || d}|t d d}|  }|r|	|d6}|  D ]&}	|	
dtj}	||	 t|	 q^W 5 Q R X tjd|  d	S d S )
Nr   r   Tz
%Y%m%d%H%Mz_all_logs.zipr   r   ry   r   )r   pathlibr	   r   r   r   nowstrftimer   r   r   rC   r   r   rz   r   r{   r}   )
r/   rw   rV   r   r	   r   r   Zlog_file_pathsr   r   r'   r'   r*   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_statusr.   	__class__r'   r*   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$   rf   Zcalc_models_settingstypeappendrE   	CmfPersonZimport_shop_fieldsr   CmfTaskZ
CmfComment
CmfProjectCmfListZCmfPersonGroupr.   r'   r'   r*   _calc_models_settings   s>    

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   rf   r!   r   Tsend_invitesFremove_conflict_projects	pg_backupmerge_identic_names)r-   r$   rf   calc_import_settingsrH   r/   rV   r'   r'   r*   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   rf   r!   r   Tr   r   r   Fr   )r-   r$   rL   rG   rf   tmplt_import_settingsrH   r   r'   r'   r*   r      s    
zCmfImport.tmplt_import_settings c                 C   s4   d|  d d} td|  d|  t|  d S )Nu1   Ошибка при импорте данных. .ue   . Проверьте загружаемый файл и повторите попытку снова.zCmfImportError: : )striprA   error	cmf_alert)rS   er'   r'   r*   
_log_error   s    zCmfImport._log_errorc                 C   s:   |  dg | jd D ]}|d | jkr|d   S qg S )Nr$   r!   r&   r   )r-   r$   r   )r/   settingsr'   r'   r*   r     s
    z$CmfImport.csv_import_settings_fieldsc                 O   s   t jd|  dS )uJ   
        Запускаем в фоне импорт данных
        startNrE   r   
run_worker	import_id_args_kwargsr'   r'   r*   r     s    zCmfImport.startc                 O   s   t jd|  dS )uR   
        Останавливаем в фоне импорт данных
        stopNr   r   r'   r'   r*   r     s    zCmfImport.stopc                 O   s&   dd l }|  }| r"|| d S )Nr   )shutilget_download_pathr   rmtree)r/   rw   rV   r   download_pathr'   r'   r*   delete_dump  s    zCmfImport.delete_dump)rowc              	   C   s4  d}|dkr|j }|sg }i }t| jD ]Z\}}|d r(|| r(|d d dd |jkr^q(|d d |kr(|| ||d d < q(|s|S || d}	tt|	d	}
|D ]}|j|}t	|tj
st	|tjr,d}| D ]8}|jd
dd|| gd	d|| ggdgd}|r qq|r,t|	|| qt	|tjr<qt|	|||  || }t	|tjr~t|d}t|tjj}t	|tjrq||d|g q| jd r|j|dgd}|s0|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_namer   r_   ORr&   ==z**r3   r   ZRUunionT)r_   r   include_deleted)r&   r   _z%Y%m%d-%H%M%S)r   	enumerater   splitre   strr1   r   rG   
issubclassZCmfRelationZCmfGenericRelationZrelated_modelssetattrZ
CmfRelBaseZCmfPhonephonenumbersparseZformat_numberZPhoneNumberFormatZINTERNATIONALZ
CmfNumericr   r$   r_   r&   r   r   r   utcrH   )r/   r   model_filterkeyresult_fieldsisettingZnew_objZnew_coder   ZfieldZrel_objZ	rel_modelvalZphoner_   r'   r'   r*   _process_obj!  sp    

zCmfImport._process_objc                 C   s$   |  dg ddd |  D S )Nrf   
c                 S   s   g | ]\}}|qS r'   r'   )r(   r   dr'   r'   r*   r   q  s     z,CmfImport.check_projects.<locals>.<listcomp>)r-   r}   get_confict_projectsr.   r'   r'   r*   check_projectso  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 }|D ]}tjjd	d
d|d
 gdd|d gggdddddgd}|rJd }|jr|jdg |jj	}| j j j
}| j jjdkr@|jjdkr||d| d|j d| df nH|jr|jr||d| df n ||kr||d| df qJ| j jjdkrJ|jjdkr| jd  d d! d"kr||d#| d|j d$|d
  d%| d&	f qJ|jr|jr||d| df qJ||krJ||d| df qJ|S )'NCmfPluginCsvplugin.plugin.source_hashZselectedObjectsrL   r   c                 S   s$   g | ]}|d  r|d r|d  qS )ri   Z	isCheckedr'   )r(   r   r'   r'   r*   r   {  s       z2CmfImport.get_confict_projects.<locals>.<listcomp>Zchildrenr   r&   ZILIKEtask_code_prefixr   r   Tlogic_prefixr   cmf_deleted)r3   r   r   ext_idCmfPluginJirazproject.wikiu4   В системе уже есть Wiki-проект u    с кодом «uj   ». Измените префикс кода задач и код проекта у Wiki-проекта «u[   » в системе и запустите импорт Agile-проекта ещё раз.uI   В системе обнаружен одноименный проект u   . Для запуска импорта необходимо удалить данный проект (проект будут удалён безвозвратно) или отменить его выбор.u  , импортированный из другого источника. Для запуска импорта необходимо удалить данный проект (проект будут удалён безвозвратно) или отменить его выбор.ZCmfPluginConfluenceproject.agileZimport_typerK   projectu5   В системе уже есть Agile-проект uB   ». Для объединения Wiki-пространства «u   » с Agile-проектом u    запустите импорт ещё раз с опцией «Импортировать в Документы Agile проекта» на втором шаге импорта.)rf   rL   re   r-   r!   rE   r   rG   r   r   source_hashr   r   r   r   )r/   r   rootZselected_projectsZprjdupZdup_shZself_shr'   r'   r*   r   s  sB    
$ 

&
0zCmfImport.get_confict_projectsc                 C   sB   t j D ]&}| jj |kr
t jj|d  S q
tddd d S )NZbackup_nameu   Бекап для данного импорта не существует. Воспользуйтесь функционалом "Отмена".T)abort)rE   CmfGlobalSettingsZpg_backup_lsr_   rL   lower
pg_restorer   )r/   Zbk_namer'   r'   r*   r     s    zCmfImport.pg_restorec           
      C   s&  |  dddg d}| jrdzzLt	
 8 | jjdrVtjj| jj d | jjdr|  }|r|D ]4\}}| jd	| tjd
 |jdd |j  qtdtjd< d| _d| _| jjjj| _|   | j  dtjd< | jD ]P}| j| D ]@}d}|dkr0t | ! " r0| j| | }| #||| qqtj$j%dd| gd | jj&| d}W 5 Q R X W nl t'k
r } zL| j(  t)| dt*+|j,d  }	| -d |	| _.| j/j0dd| _1W 5 d}~X Y nX W 5 |  | _|   tjj  |  S X  | j2dkr"| 3 S dS )u9   
        Импортируем файл в бд
        r   plugin.plugin.*zplugin.*FNr   r   r   u7   Удаляем конфликтующий проект rP   T)TEXKOM_db_deleter   ZNO_CACHEr   1
downloadedr   r   r3   r   r   u(   Ошибка работы импортаimport-errorstatus_coder   )4r-   rf   get_redis_import_statsimport_statsrH   cmfapp	CMF_CACHEflushdbcmfutilenable_import_moder$   rL   rG   rE   r   r   r_   r   r   rU   rA   WARNINGdeleterg   rh   rz   environZimported_object_countprogressr   r   listr   Ziterdirinc_statrb   Zbulk_deleteprocess_importrs   Zrollbackr   r`   	format_tb__traceback__rj   	error_msgr   r   r   r   _process_import_excel)
r/   r   Zprojectsr   r   obj_nameopr   err
error_textr'   r'   r*   r    sR    






&
zCmfImport.process_importc           4      C   sd  ddl m} | jr| jd s dS d}zi }i }i }i }i }i }i }	|  }
t|
D ]&\}}|dkrr| jd rrqTi }i }d}d}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rP|dkr2|||d < q||i }|| ||d < nZ|dkrt|dkrt|
|| }n6|dkr||| }n|dkrd||| i}|||< |||< q|di }|dd}||d}|s|| tj|\}}|||d< || tj|\}}|di }|drD|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 < |rH||g }!|!|  |!||< |rt||d g }"|"| |"||d < |d&i d'd}#|#r|# d(|jj }$||$i }%||%d!< |#|%d'< |%d)g }&|&|  |&|%d)< |%||$< ||d}'|'sft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 qT| 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},|,  |+d) D ]} |,| _!| jd7d8 q q| D ]>\}}-||}.|.rF|-D ]}/|/j!"  |.|/_!|/  qbqF| D ]N\}}0||}.|.r|0D ].}1||1}/|/r|/j!"  |.|/_!|/  qqW n~ t#k
r^ }2 z^t$|2 d9| d:|2 d;t%&|2j'd<  }3| j()|3 |3| _*| j+j,d=d>| _-|   W Y dS d?}2~2X Y nX d7S )@u   
        Запуск импорта из CSV

        :return: Истина в случае успешного импорта
        r   )CmfPluginImportMixinr!   FZ	first_rowr   r   r   r   r   parent_taskZchild_tasksrk   	executorsr   r   priorityr   r   r   r_   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_idr   r   r&   r   tasksZtree_parent_idZSprintsr  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Z	only_datau   Строка r   r   r  r  r  N).Z%common.models.cmf_plugin_import_mixinr  r   r$   Z	_get_filer   r   r   rG   lenZget_logic_prefixZget_priorityZget_status_type
setdefaultZprocess_any_table_fieldsrE   r   r   CmfWorkflowZcalc_workflowZCmfActivityrK   r   r  r   rH   r_   rL   Z	CmfFolderr   ZCmfListCmfTaskitemsZCmfLogicTyper  r   rs   r   r`   r  r  r   	exceptionr  r   r   r   )4r/   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   rL   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'   r*   r    sL   








 




 




"zCmfImport._process_import_excelc                 C   s>  |  |tj}|r|sdS d}| jD ] }|d r$|d d dkr$|}q$|dg tjj|jt|d |j	jdgd}|stj|t|d |j	| d	}|
  |jjd
d t|jjD ]*}|jj| jkrq|  |jj| q| j |tjtjjdd|jgdd|jggd}|ddg ||_||_|jr:|
  |S )u;   
        Импорт товара в сделку
        Nr   r   zCmfProduct.pricescurrencyfile_valprice)
product_idr7  Zcurrency_idr   )productr7  r5  r   T)forceZdeal_idr   r8  )r   r   r9  Zsales_order)r   rE   Z
CmfProductr   r-   ZCmfPricerG   rK   r   r5  rH   Zpricesr   r   Z
deal_itemsrL   r   r  r   ZCmfDealItemsr   dealr9  
is_changed)r/   r   r;  r9  Zprice_settingr   r7  itemr'   r'   r*   _process_product  s@    
 zCmfImport._process_productc           	      C   s  |s|r|j sd S d }| jD ] }|d r|d d dkr|}q|sFd S g }tjj|d d}|sxt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.pipeliner6  r%   Zpipeline_idr   Z
company_idcompanypipeline)r?  r   rE   ZCmfPipelinerG   rH   r   rK   r   ZCmfDealr-   r@  r<  )	r/   r   Zcontactr?  Zpipeline_settingr   r   r@  r;  r'   r'   r*   _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 }z6||j|j}|d | d |d< |	  W n t
k
r   d|d< Y nX z| |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   )r/   rD  rn   rE  Zstatsr)   r'   r'   r*   	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   rl   r   cache_status_typerK   r   
   r  u8   Импорт прерван, место на диске z < 10GbTimport-stoppingIN_PROGRESSimport-pauseduA   **** Импорт остановлен пользователемF)r   r  r  Zimport_heartbeatr   rJ  rE   r   rG   rK   r   r<  rH   commit_with_eventr   r   rK  r_   rL  warning)r/   r   r   totalusedfreeZfree_gbri   r'   r'   r*   	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_sessionrO   stderr)
subprocessPopenopen)methodr   rZ  r'   r'   r*   r   
  s      zCmfImport.run_workerc                  O   s   t jd|d  dS )/   
        Отменяем импорт
        cancelrK   Nr   )rw   rV   r'   r'   r*   r_    s    zCmfImport.cancelc                 O   s    |  ddddg | jj| dS )uk   
        Предварительный просмотр получившихся объектов
        r$   r   r   rf   r   )r-   rf   preview)r/   rw   rV   r'   r'   r*   r`    s    zCmfImport.previewc                    s   t   ddddg S )Nr$   r   r   rf   )r   save_preload_fieldsr.   r   r'   r*   ra     s    zCmfImport.save_preload_fieldsc                    s   |    t jf |S N)r   r   rH   r   r   r'   r*   rH   #  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:defaultr"  zimport.system:default)r   rf   re   rE   r.  rG   r.   r'   r'   r*   _calc_workflow'  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 )Nr   Z	_raw_dataT)exist_okparents)r-   r	   rC   r   r   rf   Zui_namer   r   rL   mkdir)r/   resr'   r'   r*   r   /  s    zCmfImport.get_download_pathc                 C   s   | j |  d S rb  )rf   download_datar.   r'   r'   r*   rh  7  s    zCmfImport.download_datac                 C   s   | j |  d S rb  )rf   download_filesr.   r'   r'   r*   ri  :  s    zCmfImport.download_filesc           	   	   C   s   dd l }dd l}|jdddgd}| d |D ]*}| d|jd |jd |jd  q0| d |d	d
g}|d}| }|D ]}| | qd S )Nr   pidr&   Zusername)attrsz==============ps auxz{:<10d} {:<20s} {:<10s}z==============netstat -panZnetstatz-panr<   )	rn   rZ  Zprocess_iterrU   formatrv   Zcheck_outputdecode
splitlines)	r/   rn   rZ  Z	processesrX   outputZ
output_strlinesliner'   r'   r*   
log_detail=  s    
(

zCmfImport.log_detail)api_urlr#   c           
   
      sV  ddl m} ddlm  td fdd}d}|dd  rLq>| }|d	kr`q>z| tj	|d
dddgd}t
|dr||jj|_|jr|  |  n ||jj|_|jr|jdd |jD ]0}	|	jdkrq||	jj|	_|	jr|	jdd qW q@   jd| tjddd |d7 }Y q@X q@W 5 Q R X || d S )Nr   cmf_context)BeautifulSoup)r^   c                    s  | s| S  | d}| dD ]}|jdr0q|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}|D ].}|jd |ddd  krR|} qqR|sjd|ddd   tjd	 qnq|tj| qt|S )Nzhtml.parseraZcmf_convertedZhrefr   z/wiki/z\/\d+u:   Не удалось найти ид документа в r   z::r   rk   )r   r   u:   Не удалось найти документ по ид z/browse/z	\/\w+-\d+u4   Не удалось найти ид задачи в import_raw_jsonZLIKEz%"key":"z"%r   r   u:   Не удалось найти задачу по коду )Zfind_allrk  rG   
startswithr~   searchrU   rA   r  rf   r   grouprE   ZCmfDocumentr   r  rx  Zreplace_withr   Zcreate_tag_linkr   )r^   Zsouptagri   r   Zext_codeobjsr   rv  rs  r/   r'   r*   check_linksW  sJ    
"
$z.CmfImport.obj_check_links.<locals>.check_linksF)Zinit_views_and_dsDONEr^   zcomments.log_levelzcomments.text
text_draftr   Tr+     uZ   Не удалось конвертировать перекрестные ссылки в )r0   rT   rk   )cmf.appru  Zbs4rv  r   rW  rG   rU   r  Zget_obj_by_idhasattrr^   rL   r  r<  rH   Z
do_approveZcommentsZ	log_levelrA   ra   put)
r/   rs  	obj_queueobj_queue_errorsru  r  
has_errorsZobj_idri   Zcommentr'   r~  r*   obj_check_linksT  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|  | j }	| j }
g }| 
d| j  |j }t| jD ]H}| jj| jd| |	|
|dd	}|| |  | 
d
|  qd}ddd gdddgg}|j|ddg||| gd}|D ]*}|  rB qZ|d7 }|	|j q.|D ]}|	d q^| 
d |D ]}|  q~|j | }| 
d||   d d}|
 s||
 7 }q| 
d|  |W  5 Q R  W  5 Q R  W  5 Q R  S Q R X W 5 Q R X W 5 Q R X d S )Nr   rt  u)   Конвертируем ссылки в uB    на локальные задачи и документы start=z limit=uJ   Обрабатываем ссылки в несколько тредов: r  )r  r  rs  )targetr&   rV   u.   Параллельный обработчик r   z!=Zimport_originalr   Tz--rK   )r3   r   slicerk   r  u(   Ждем обработки ссылокu*   ------------------------ скорость u#    обьектов в секундуuA   Закончили обработку ссылок, ошибок )r  ru  r   r  disable_acldisable_notifyr  rt   varsrE   rU   r   r   ZQueuer   r   ranger   Threadr  r   r   ZslistrW  r  rK   r}   Ztotal_secondsemptyrG   )r/   rs  r3  r   limitru  r   r  r   r  r  Zobj_processr)   r   procZcntr   r}  ri   Zdiffr'   r'   r*   process_cross_links  sV    $







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 5 Q R X W 5 z|  W nH tjj	k
r" }	 z$t
d|	 d|j d	|j  W 5 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 5 Q R X W 5 z|  W nH tjj	k
r. }	 z$t
d|	 d|j d	|j  W 5 d }	~	X Y nX X d S )N-uA   Нельзя использовать "-" в obj_name: {obj_name}i:	 z.lock   )timeoutzlock release error z, lock_name z
, timeout )exrk   r   zdownloaded-)rs   rK   APPREDIS_DBredislockacquirerelease
exceptionsZ	LockErrorgdebugr&   r  r@  ZsaddrL   setr   ZincrZexecuter  rG   )r/   r  r  rL   Zttlr   redis_dbZlock_keyr  r   piper'   r'   r*   r    sH    
4
"zCmfImport.inc_statc                 C   sj   t j}i }|j| jjD ]J}| }||}|d^}}}||sTt	 ||< | || |< q|S )Nr  )
r  r  r  ZsmembersrK   rL   rm  rG   r   rF  )r/   r  r   r   rL   r  r  r   r'   r'   r*   r    s    


z CmfImport.get_redis_import_statsc                 C   s(   |  ddg | jdkr | jjS |  S )NrL  r  rP  )r-   rL  r  rL   r  r.   r'   r'   r*   take_import_stats  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  rL  r   rP  zimport-plannedFu   Импорт прерван по неизвестной причине. Проверьте системные требования.r   r  r  T)r-   rL  r   r_   r  r  Zimport_is_runningCmfImportWorker
is_runningrU   rA   ra   r  r   r   rH   )r/   Zworkerr  r'   r'   r*   r    s    
zCmfImport.is_runningTz	@minutely)Z	only_onceZ
system_jobZschedulec                  C   sF   t d tjjdddgddddgdD ]} |  s(td	|  q(d S )
Nz&cmf_deferred_job: CmfImport.cron_checkrL  r   rP  r   r  r   r   uH   Импорт прерван по неизвестным причинам)r  r  rE   r   r  r  r  Zadmin_alert)ri   r'   r'   r*   
cron_check  s    


zCmfImport.cron_check)rW   NNNNrX   )r   )NN)r   N)Dr4   r5   r6   r   r   Zui_meta_skipr   r   r,   propertyrF  r!   r   r   r   rA   rB   r   rr   rU   rj   rt   rx   r  r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r  boolr  r>  rA  rK  rW  r   r_  r`  ra  rH   rc  r	   r   rh  ri  rr  r  r  r  r  r  r  Zcmf_deferred_jobr  __classcell__r'   r'   r   r*   r      s   /	    
 



N$3 B!#
J,
-r   c                    s   t   fdd}|S )Nc                    sL   z( | f||}t   | jd |W S    | jd t  Y nX d S )Nu*   Импорт завершил работуu&   Ошибка работы демона)rR  r   rv   r0  rollback_purge_event)ri   rw   rV   rg  fnr'   r*   wrapped'  s    z!catch_exceptions.<locals>.wrappedr   )r  r  r'   r  r*   catch_exceptions&  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.logr   z	/var/run/z.pid)
cmf.modules.logsr   rA   r   r	   rJ   r   Zinit_loggerrB   rj  )r/   r	  r   rA   r	   r'   r'   r*   __init__5  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 5 Q R X W 5 Q R X W 5 Q R X tjj|jdddd	gd}tjjdd|gd}|j	jdk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}tjj|tj |j!dt"#t$j%dd| dd d! d S )"Nu   Импорт запущенr   rK   r   r_   r   r   r  r   r   u%   ***Запускаем импорт***rP  import-startedr   r  rk   rM  r   r  u2   ***Импорт успешно завершен***CLOSEDr   u6   ***Импорт завершен с ошибками: u,   . Подробности в отчете.***r  r  r   /files/u+   Импорт данных завершен %d.%m.%Y %H:%M
, <a href=(   >Журнал логирования</a>Tri   Zpersonr&   rS   Zforce_notify_current_person)&r   rv   rE   r   rG   r   rU   r   r   r   rH   rR  r  r  r  r  r  geventsleeprK   rb   countr_   r   rM   baseFilenamer   rC   r   	CmfNotifyplace_notifyr  current_personr&   r   r   r   r   )r/   r   ri   rg  errorslog_pathr'   r'   r*   run=  sB    

(


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 5 Q R X W 5 Q R X W 5 Q R X tjj|tj|jdtt j!dd| ddd d S ) Nu   Дамп запущенr   rK   r   r_   r   r   r  r   r   u!   ***Запускаем дамп***rP  r  r  r   r  u.   ***Дамп успешно завершен***r  r   u2   ***Дамп завершен с ошибками: z***r  r  r   r  u'   Дамп данных завершен r  r  r  Tr  )"r   rv   r  r  r  r  rE   r   rG   rU   r   r   r   rH   rR  rh  ri  rb   r  r   rM   r  r   rC   r   r  r  r  r  r&   r   r   r   r   )r/   r   ri   rg  Zres2r  r  r'   r'   r*   	dump_dataa  s8    $


6zCmfImportWorker.dump_dataNr"   c                 C   sp  | j d t P t : t $ tjjddd|gdd|ggddgdd	}|j	j
d
d|_|  t  zz^d}d}|j d tjjdd|gddD ]^}z*|j d|  |jddd t  W q   |d7 }t  |j d| d Y qX qtjjddd|gdd|ggdddgdd	}|jD ]X}z*|j d|  |jddd t  W n&   |d7 }t  |j d Y nX q8|s|j	j
dd|_|j d n"|j d|  |j	j
dd|_W nX tk
r2 } z8|j d|  t| t||_|j	j
dd|_W 5 d}~X Y nX W 5 |  tjj  X W 5 Q R X W 5 Q R X W 5 Q R X dS )r^  u   Отмена запущенаr   rK   r   r_   r   r   T)r3   r   r   zimport-cancelingr  r   Nu#   ***** Отменяем импортr   )r3   r   u   Удаляем )r   r:  rk   u#   Не удалось удалить uW   , видимо обьект использовали вне данных импортаimport_objectsuy   Не удалось удалить, видимо обьект использовали вне данных импортаzimport-canceledu,   Успешно отменили импортu#   Количество ошибок: r  u   Ошибка удаления )r   rv   r  r  r  r  rE   r   rG   r   r   r   rH   rR  r  r	  r
  r  r   r  r  r  r0  r  r   rs   r   r   r  )r/   r   ri   r  r   r   r'   r'   r*   _cancel_import  s^    $ 
 


&zCmfImportWorker._cancel_importc                 G   s>   | j  rtd| j tt  | j|  | j   d S Nu"   Импорт уже запущен)	rj  r   rs   
write_textr   rz   getpidr  unlinkr/   rw   r'   r'   r*   r     s
    

zCmfImportWorker.startc                 G   s>   | j  rtd| j tt  | j|  | j   d S r  )	rj  r   rs   r  r   rz   r  r  r  r  r'   r'   r*   dump  s
    

zCmfImportWorker.dumpc                 G   s>   | j  rtd| j tt  | j|  | j   d S r  )	rj  r   rs   r  r   rz   r  r  r  r  r'   r'   r*   r_    s
    

zCmfImportWorker.cancelc                 G   s2  t jjdddgddddgd}|r|  r|jd	 |jjd
d|_|	  t
  tdD ]2}td t jj|jddgd}|jdkr\ qq\n|jd |jjdd|_|	  t
  |jd | j s| jd d S | jd ztt| j tj W n   | jd Y nX | j  d S )NrL  r   rP  r   r   r  r   r   uQ   Пытаемся остановить импорт, таймаут 1 минутаrO  r  <   rk   rM  u"   Импорт уже прерванrQ  u<   Импорт остановлен пользователемu    Импорт не запущенu'   Останавливаем импортuK   Не удалось завершить процесс, он запущен?)rE   r   rG   r  r   rS  r   r   r   rH   rR  r  r  r  rK   rL  rv   rj  r   rz   killrr   	read_textsignalSIGTERMr0  r  )r/   rw   ri   r   r'   r'   r*   r     s4    


zCmfImportWorker.stopc                 C   s0   | j  r,tt| j  r"dS | j   d S )NT)rj  r   r  Zcheck_process_runningrr   r  r  r.   r'   r'   r*   r    s    
zCmfImportWorker.is_running)r  )r4   r5   r6   r  r  r  r  r  r   r  r_  r   r  r'   r'   r'   r*   r  4  s   
$ 2



r  )%Zcsvr   r   decimalr   r   r   rA   r   rN   r`   r   r	   typingr
   r   r  r   r   ZxlrdZopenpyxlZcmf.data_providers.baser   Zcmf.includer  r   Zcommon.fieldsr   r  r   rz   r  	functoolsr   r   r  r  r'   r'   r'   r*   <module>   s>           