U
    ^h                    @   sF  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Zd dl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# e$ Z%G dd dej&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)*fields
cmf_import
log_configwrapsc                   @   s   e Zd Zdd ZdS )AnonymousFilterc                 C   s   t |ddS )N	anonymousF)getattr)selfrecord r   ./common/models/cmf_import.pyfilter!   s    zAnonymousFilter.filterN)__name__
__module____qualname__r   r   r   r   r   r       s   r   c                       s  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
dZeedddZedd Zed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deeeeeed#d$d%Zd&d' Zedd(d)Zd*d+ Ze dd,d-Z!d.d/ Z"e#d0d1 Z$d2d3 Z% fd4d5Z&d6d7 Z'd8d9 Z(d:d; Z)e#dd=d>Z*ed?d@ Z+e#dAdB Z,e#dCdD Z-edEdFdGZ.dHdI Z/de dJdKdLZ0dMdN Z1ddOdPZ2dQdR Z3dSdT Z4eddUdVZ5dWdX Z6dYdZ Z7d[d\ Z8d]d^ Z9e#ded_d`daZ:e#dddbdcZ;ddde Z< fdfdgZ= fdhdiZ>djdk Z?e
ddldmZ@dndo ZAdpdq ZBdrds ZCe edtdudvZDdwdx ZEdydz ZFd{d| ZGdd~dZHdd ZIedddZJdd ZKe#eLdddddd ZMe#deedddZN  ZOS )	CmfImport)CSV_SETTING_NAMEcsv_import_settings_fieldslogger_last_stats	threadingqueuethreading_max_forksdownload_threading_max_forksmax_processesimport_settingsworker_flag_file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CSVNz/tmp/eva_import_worker.flagreturnc                 C   s
   | j  S N)r,   existsclsr   r   r   worker_here<   s    zCmfImport.worker_herec                 C   s   | j   d S r<   )r,   touchr>   r   r   r   create_worker_flag@   s    zCmfImport.create_worker_flagc                 C   s   | j  r| j   d S r<   )r,   r=   unlinkr>   r   r   r   remove_worker_flagD   s    
zCmfImport.remove_worker_flagc                 C   s.   | j s(| dg dd | jd D | _ | j S )Njson_settingsc                 S   s   i | ]}|d  |qS namer   ).0sr   r   r   
<dictcomp>M   s      z-CmfImport.import_settings.<locals>.<dictcomp>r+   )_import_settingsload_fieldsrE   r   r   r   r   r+   I   s    zCmfImport.import_settingsc           	      C   sx  t jrtjntj}tjjd| d}|sPtjd| d}|  |jsP|j	ddd tjjd| d}|stjd| d}|  |js|j	ddd t
j|jddd	d
d}|| |tt
j t
j|jddd	d
d}|| |tt
j |t  t }|| |t
  tjt|||}|  td| j }|| d|_|jst|tjt |S )uE    Журнал логирования процесса импорта data.logrG   parent    F)Zmake_previewzanonymous_data.logutf-8Di@KL    )filenameencodingZwhenZmaxBytesZbackupCountimport_)configDEBUGloggingINFOmodelsCmfAttachmentgetsavefile_existsZupload_filer   ZMyLogsHandlerfull_path_fileZsetLevelZsetFormatterZ	FormatterZ	FORMATTERZ	addFilterr   ZStreamHandlerZCustomFormatterhandlersZQueueListener	log_queuer6   	getLoggeridZ	propagateZ
addHandlerZQueueHandler)	r   levelattachment_logZattachment_log_anonZfile_handlerZanonymous_handlerZconsole_handlerZlistenerr$   r   r   r   r$   P   s`    



zCmfImport.loggerFmsgrf   c                 K   s&   | j j||fd|i|dd| dS )uI  Логируем как обычные лог для веб так и со скрытыми данными для возможности отправки в СТП

        Args:
            msg (str): сообщение
            level (int, optional): уровень логирования. Defaults to logging.INFO.
        r      )Zextraexc_info
stacklevelN)r$   log)r   ri   rf   r   rk   kwargsr   r   r   rm      s    zCmfImport.logERR-0001process)ri   
error_codeobj_typeext_href	dump_path
error_typec           	   
   C   sv   | j |tjd tj||| |||t |d}|rd|j|_|j	|_
| jrd| j||_| j||_|  t  dS )u7  Логируем ошибки и записываем их в базу

        Args:
            msg (str): текст ошибки
            error_code (int, optional): Код ошибки для нахождения возможного решения или группировки. Defaults to 1.
        rh   )textcoder   rt   ru   rr   	tracebackrs   N)rm   rZ   ERRORr\   CmfImportErrorrx   
format_excrG   title
class_namerr   pluginZcalc_ext_hrefrs   Zcalc_dump_pathrt   r_   
cmf_commit)	r   ri   rq   objrr   rs   rt   ru   Zimport_errorr   r   r   	log_error   s$    	zCmfImport.log_errorc                 C   s   t j| _t j| _d S r<   )rX   ZIMPORT_THREADSr(   ZIMPORT_DOWNLOAD_THREADSr)   rM   r   r   r   _prepare_multiprocessing   s    z"CmfImport._prepare_multiprocessingc                 C   s   ddl }ddl}| }|d }| jd| ddd | j}t|d }| jd	| d
dd tjrtt	tj|}| jdtj ddd t	t|d |}| jd| ddd |st
d| d| d|S )u.  
        Рассчитывает максимальное количество процессов
        для создания нескольких независимых процессов

        Returns:
            int: максимальное количество процессов
        r   N   u4   Количество ядер системы (CPU): u    (не менее 2)T)r      @u%   Доступно памяти (RAM): u!    ГБ (по 2 ГБ на ядро)u/   Количество процессов (MAX): uB    (в параметре 'IMPORT_PROCESS' конфигурации)rj   u    (итоговое)uY   Недостаточно системных ресурсов для импорта (CPU: z, RAM: uq    ГБ). За дополнительной информацией обратитесь в техподдержку)multiprocessingpsutil	cpu_countrm   virtual_memoryZ	availableintrX   ZIMPORT_PROCESSmin	Exception)r   r   r   r   r*   Zavailable_memoryZavailable_memory_gbr   r   r   get_max_processes   s:    



zCmfImport.get_max_processesc                 O   sF   t jjd| dgd}|s.t jd| d}|  |js@| jd |jS )uK   
        Возвращает путь текущему файлу
        rN   url)rG   rP   r   rO   u   Начало)r\   r]   r^   r_   r`   r$   infor   )r   argsrn   rg   r   r   r   r2      s    zCmfImport.get_log_filenamec                    s:   t d  jddd  fddt D }|S )u   
        Список файлов после logrotate, чтобы можно было загрузить историю
        T)parentsexist_okc                    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)rH   fdir_pathr   r   r   
<listcomp>  s    z/CmfImport.get_log_filenames.<locals>.<listcomp>)r	   r   mkdirr   listdir)r   r   rn   Z	file_listr   r   r   r3     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/filesr   )zipfiler	   r   joinpathr   r   r=   removeZipFiler3   replacerX   
UPLOAD_DIRwriter   )r   r   rn   r   r   zip_pathmyzip	file_pathr   r   r   r1     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   r\   
CmfProjectr   Zregex	fullmatchZshort_str_enc)keyr   r   r   r   r   get_correct_key  s
    zCmfImport.get_correct_keyc           
   	   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   r   r   )r   pathlibr	   r   r   r   nowstrftimer3   r   r   rX   r   r   r   r   r   r   )
r   r   rn   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_statusrM   	__class__r   r   r   6  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   Поля групп)rE   r~   Zcalc_models_settingstypeappendr\   	CmfPersonZimport_shop_fieldsr   CmfTaskZ
CmfCommentr   CmfListZCmfPersonGrouprM   r   r   r   _calc_models_settings;  s>    

zCmfImport._calc_models_settingsc                 K   sz   |  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< d	| jd< | j| _|   d S )NrE   attachmentsr   r~   r+   r   Tsend_invitesFremove_conflict_projects
add_suffix	pg_backupmerge_identic_names)rL   rE   r~   r-   r_   r   rn   r   r   r   r-   V  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d
| jd< | jj| d| jd< | j| _|   d S )NrE   r   r   r~   r+   r   Tr   r   Fr   r   r   )rL   rE   valuer^   r~   r9   r_   r   r   r   r   r9   e  s    
zCmfImport.tmplt_import_settings c                 C   s4   d|  d d} td|  d|  t|  d S )Nu1   Ошибка при импорте данных. .ue   . Проверьте загружаемый файл и повторите попытку снова.zCmfImportError: : )striprZ   error	cmf_alert)ri   er   r   r   
_log_errorr  s    zCmfImport._log_errorc                 C   s:   |  dg | jd D ]}|d | jkr|d   S qg S )NrE   r+   rG   r   )rL   rE   r"   )r   settingsr   r   r   r#   x  s
    z$CmfImport.csv_import_settings_fieldsc                 O   s&   t j  t jd|  t j  dS )uJ   
        Запускаем в фоне импорт данных
        r6   N)r\   ZCmfAccessListZactivate_admin_moder!   
run_workerrB   	import_id_args_kwargsr   r   r   r6     s    
zCmfImport.startc                 O   s   t jd|  dS )uR   
        Останавливаем в фоне импорт данных
        r7   N)r\   r!   r   r   r   r   r   r7     s    zCmfImport.stop)entity_typec                 C   sd   |  dg d}||kr:| jjjdkr:td| ddd d|i}tjjd	| j|d
 tj	  dS )u   
        Запускает отдельную обработку сущностей (фильтры, связи, ссылки и др.)

        Args:
            entity_type (str): тип сущности (filters, relations, links, etc.)
        r~   filtersZ	relationsCmfPluginJirau4   Запуск отдельной обработки 'u?   ' возможен только для импорта из JiraTabortr   process_entityparamsN)
rL   r~   r   r}   r   r\   r!   r   re   rB   )r   r   Zjira_entitiesr   r   r   r   r     s    
zCmfImport.process_entityc                 O   s&   dd l }|  }| r"|| d S )Nr   )shutilget_download_pathr=   rmtree)r   r   rn   r   download_pathr   r   r   r0     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   rw   ORrG   ==z**r   r   ZRUunionT)rw   r   include_deleted)rG   r   _z%Y%m%d-%H%M%S)r   	enumerater#   splitr}   strr   r   r^   
issubclassZCmfRelationZCmfGenericRelationZrelated_modelssetattrZ
CmfRelBaseZCmfPhonephonenumbersparseZformat_numberZPhoneNumberFormatZINTERNATIONALZ
CmfNumericr   rE   rw   rG   r   r   r   utcr_   )r   r   model_filterr   result_fieldsisettingZnew_objZnew_coder   ZfieldZrel_objZ	rel_modelvalZphonerw   r   r   r   _process_obj  sp    

zCmfImport._process_objc                 C   s   | j ddS )um   
        Ручка фронта для проверки конфликтующих проектов
        T)as_msg)get_conflict_projectsrM   r   r   r   r/     s    zCmfImport.check_projectsc              	   C   s  |  dg | jjjdkrdS g }ddd}| jd d d	 }d
d |d D }|D ]@}| |d }|dpx|d }| jjj d|d  }	tj	j
ddd|	gddd|	 dggddddgd}
|
r| jjjdkr|
jdksT|
jd |kr|
jd |krqTtj	jddd|gd d|ggddd d!d"gd}|D ]d}d}t|joR|jj| jjjk}| jjjdkr|jd#krd$|j d%|j d&|d'< |}n| jjjdkr|jd#kr|jdkr| jd( d d d)kr֐q.|jsd*|d+< d,| d%|  d&|d'< |}n|jr|js|r |}|r.|j d-|j d.}|jdkrP|d/7 }n|jd#krd|d07 }|jrv|d17 }n|r|d27 }|||f q.qTd3}|rd4d3d5d6 |D  d7d3d8d6 | D  d9}|r|S d:d |D S );u  
        Возвращает список конфликтующих проектов или текст сообщения для предупреждения

        Args:
            as_msg (bool, optional): возвращать в виде текста для сообщения. Defaults to False.

        Return:
            list, str: список проектов или текст сообщения
        plugin.plugin.source_hashCmfPluginCsvNu^   отменить выбор аналогичных импортируемых проектовu   удалить существующие проекты (проекты и все их данные будут безвозвратно удалены))r.   deleteZselectedObjectsr   r   c                 S   s$   g | ]}|d  r|d r|d  qS )r   Z	isCheckedr   )rH   r  r   r   r   r     s       z3CmfImport.get_conflict_projects.<locals>.<listcomp>childrenr   original_namerG   ::re   r   ext_id=LIKE%::::%T--logic_prefiximport_raw_json)r   r   r   CmfPluginConfluenceproject.agileILIKEr   zcmf_import.ext_idcmf_deletedzproject.wikiu   добавить суффикс 'Wiki' к названию или коду существующих Wiki-проектов (пример: 'z Wiki' (zWIKI))r   Zimport_typeprojectu   объединить с существующими Agile-проектами, запустив импорт с опцией 'Импортировать в Документы Agile проекта'Zcombineu   импортировать с добавлением 'Wiki' к названию или коду проекта (пример: ' ()u    <em>Agile-проект</em>u    <em>Wiki-проект</em>u(    <em>удален в корзину</em>uI    <em>импортирован из другого источника</em>r   u               <p><strong>В системе уже существуют проекты с аналогичными названиями или кодами:</strong></p>
            <ul>c                 s   s   | ]\}}d | dV  qdS z<li>z</li>Nr   )rH   project_namer   r   r   r   	<genexpr>  s     z2CmfImport.get_conflict_projects.<locals>.<genexpr>u   </ul>
            <br />
            <p><strong>Для продолжения импорта вы можете:</strong></p>
            <ul>c                 s   s   | ]}d | dV  qdS r  r   )rH   actionr   r   r   r     s     z</ul>
            c                 S   s   g | ]\}}|qS r   r   )rH   r   r  r   r   r   r     s     )rL   r~   r   r}   r+   r   r^   source_hashr\   r   sgetr  r  listboolr   r  rG   r   r  upperr   r   values)r   r  Zconflicting_projectsactionsrootZselected_projectsZprjZselected_project_keyZselected_project_nameZselected_project_ext_idr  Zmatching_projectsZmatching_projectZconflicting_projectZother_sourcer  ri   r   r   r   r  	  s    

	


zCmfImport.get_conflict_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   Бекап для данного импорта не существует. Воспользуйтесь функционалом "Отмена".Tr   )r\   CmfGlobalSettingsZpg_backup_lsrw   r   lowerr4   r   )r   Zbk_namer   r   r   r4     s    zCmfImport.pg_restorec           	      C   s  |  dddg d}| jrdzz@t	
 , | jjdrVtjj| jj d | jjdr|  }|r|D ],}| jd	| tjd
 |jdd t  qtdtjd< d| _d| _| jjjj| _|   t  dtjd< | jD ]P}| j| D ]@}d}|dkr$t|   ! r$| j| | }| "||| qqtj#j$dd| gd | jj%| d}W 5 Q R X W n^ t&k
r } z>t'  t(| dt)*|j+d  }| ,d|  || _-W 5 d}~X Y nX W 5 |  | _|   tjj  |  S X  | j.dkr| / S dS )u9   
        Импортируем файл в бд
        r   plugin.plugin.*zplugin.*FNr   r*  r   u7   Удаляем конфликтующий проект rf   T)TEXKOM_db_deleter   ZNO_CACHEr   1
downloadedr   r   r   r   
u*   Ошибка работы импорта: r   )0rL   r~   get_redis_import_statsimport_statsr_   cmfapp	CMF_CACHEflushdbcmfutilenable_import_moderE   r   r^   r\   r+  r   rw   r,  r  rm   rZ   ZWARNINGr  r   r   environZimported_object_countprogressr"  r  r$  r   iterdirinc_statrz   Zbulk_deleteprocess_importr   cmf_rollbackr   rx   	format_tb__traceback__r   	error_msgr   _process_import_excel)	r   r  Zprojectsr  obj_nameopr  err
error_textr   r   r   rA    sP    




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_tasksr   	executorsr  r   priorityr   r   r  rw   r   
cmf_authorZ	cmf_ownerzproject.basez
task.base%baserw   )Z	cmf_modelprefixZactivityztask.agile:softdev%Zsoftdevr   r  rP   ZANDZ	parent_idr   r   rG   r   tasksZtree_parent_idZSprintsr2  u
   ДоскаZkanban)rG   rP   tree_parentZ	list_type)r   r   
obj_fields
filter_obj)leftrightZEpicsr  z	task.epicztask.epic:default)rP   rT  rG   Z
logic_typeTZ	only_datau   Строка r   r3  r4  import-errorstatus_codeN).Z%common.models.cmf_plugin_import_mixinrK  r   rE   Z	_get_filer   r#   r   r^   lenZget_logic_prefixZget_priorityZget_status_type
setdefaultZprocess_any_table_fieldsr\   r   r   CmfWorkflowZcalc_workflowZCmfActivityre   r   rM  r   r_   rw   r   	CmfFolderr   ZCmfListCmfTaskitemsZCmfLogicTyperL  r   r   rB  rx   rC  rD  r$   	exceptionrE  r   r   r   )4r   rK  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   r   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_folderrV  rU  dataZepic_objrS  rL  Zsub_taskZ
tasks_codeZsub_task_coderI  rJ  r   r   r   rF    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_idri  Zcurrency_idr   )productri  rg  r   T)forceZdeal_idr   rj  )r   r   rk  Zsales_order)r  r\   Z
CmfProductr#   rL   ZCmfPricer^   re   r   rg  r_   Zpricesr   r   Z
deal_itemsr   r   r  r   ZCmfDealItemsr   dealrk  
is_changed)r   r   rm  rk  Zprice_settingr   ri  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.pipelinerh  rF   Zpipeline_idr   Z
company_idcompanypipeline)rq  r#   r\   ZCmfPipeliner^   r_   r   re   r  ZCmfDealrL   rr  rn  )	r   r   Zcontactrq  Zpipeline_settingr   r   rr  rm  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   ipzIP unavailabler   )r4  r   r   ZmemoryZdiskzSTATS )timer   socketr%   dictZAF_INETZ
SOCK_DGRAMZconnectZgetsocknamecloseOSError
getloadavgr   
disk_usager   r$   r   )r   rw  r   rx  statsrI   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r|  t  | jd|d	d
 dS |j
jdks|jdkrd|_
|jr|  t  | jd dS t  |   dS )Nr   r   r   cache_status_typere   r   
   rZ  u8   Импорт прерван, место на диске z.2fz	Gb < 10GbTimport-stoppingIN_PROGRESSimport-pauseduA   **** Импорт остановлен пользователемF)r   r;  r<  Zimport_heartbeatr   r}  r\   r!   r^   re   r   rn  r_   r   r$   r   rw   r  warningr  )r   r   r   totalusedfreeZfree_gbr   r   r   r   	is_cancel  s.    
zCmfImport.is_cancelr   c              	   C   s   ddl }d| dg}t|trH| D ]\}}|| d| d q(d|}|jdddd	|  d
| dgddtddtddd dS )ul  
        Запускает выполнение метода импорта в отдельном процессе 

        Args:
            method (str): метод импорта
            import_id (str): ID импорта (CmfImport)
            params (dict, optional): параметры запускаемого метода. Defaults to None.
        r   N"z=",/usr/bin/python3	manage.pyshellzHfrom common.models.cmf_import import CmfImportWorker; CmfImportWorker().(r  T"/var/log/eva-import-subprocess.loga+&/var/log/eva-import-subprocess.err.logZ	close_fdsZstart_new_sessionstdoutstderr)
subprocess
isinstancery  ra  r   r   Popenopen)methodr   r   r  Zparams_lkvr   r   r   r     s"    


  zCmfImport.run_workerc                  O   s    t jd|d  t j  dS )/   
        Отменяем импорт
        r.   re   N)r\   r!   r   rB   )r   rn   r   r   r   r.   +  s    zCmfImport.cancelc                 O   s    |  ddddg | jj| dS )uk   
        Предварительный просмотр получившихся объектов
        rE   r   r   r~   r   )rL   r~   r5   r   r   rn   r   r   r   r5   4  s    zCmfImport.previewc                    s   t   ddddg S )NrE   r   r   r~   )r   save_preload_fieldsrM   r   r   r   r  ;  s    zCmfImport.save_preload_fieldsc                    s   |    t jf |S r<   )r   r   r_   r   r   r   r   r_   >  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:defaultrQ  zimport.system:default)r   r~   r}   r\   r_  r^   rM   r   r   r   _calc_workflowB  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)r   r   )rL   r	   rX   r   r   r~   Zui_namer,  r"  r   r   )r   resr   r   r   r   J  s    zCmfImport.get_download_pathc                 C   s   | j |  d S r<   )r~   download_datarM   r   r   r   r  R  s    zCmfImport.download_datac                 C   s   | j |  d S r<   )r~   download_filesrM   r   r   r   r  U  s    zCmfImport.download_filesc           	      C   s   dd l }dd l}|jdddgd}| jdtjd |D ]0}| jd|jd |jd |jd tjd q6| jd	tjd |d
dg}|	d}|
 }|D ]}| j|tjd qd S )Nr   pidrG   usernameattrsz==============ps auxr.  z{:<10d} {:<20s} {:<10s}z==============netstat -panZnetstatz-panrR   )r   r  Zprocess_iterrm   rZ   rY   formatr   Zcheck_outputdecode
splitlines)	r   r   r  Z	processesrp   outputZ
output_strlinesliner   r   r   
log_detailX  s    
zCmfImport.log_detail)api_urlsr;   c                    s  ddl m} ddlm  d dfddd dfdd}d dfd	d
}d dfdd}ttddd} fdd}	d}
|dd  rq| }|dkrqztj	|dddddddddg	d}j
d| d |j d! |jjpd"} |d#}|jrv|| jjjd$kr\|jd%kr\||| ||| ||| |	| d"d&d' |jjD |_jjjd$kr|jd(kr|jr||jj|jj|_|jrt|dr|jd)d* n|jd)d+ |jD ]r}|jd,krq|jjpd"} |d#}|jsq|| d"d-d' |jjD |_|jr|jd)d+ qW q   jd.d/|d0 |
d17 }
Y qX qW 5 Q R X ||
 d S )2Nr   cmf_context)BeautifulSoupr:   c                    s  | dd D ]x}|d}|s4j|  d qjjj d| }tjj|d}|stj|  d| d q|tj	
| q|j d	d
idD ]}d }|d}|sj|  d qtjjddd| dgdgd}|D ]}|jd |kr|} qq|s$j|  d| d q|tj	
| q| dD ]}|jdrZqB|jd}	|	sj|  dtjt|  qBztj|	}
W nJ tk
r } z*j|  d|	 d|  W Y qBW 5 d }~X Y nX |
js|
jr|
jdrB|
j krBd }d }|d}|d}|dkrJ|d krJjjj d| }tjj|dgd!}|stjjd"dd#jjj d$gddd%| dggd&}|sȈj|  d'|  qB|jt|jkst|tjr|j}|d(rtj|d( d)}| d*| }d+|jd< |jd |jd,< ||jd< qBn|d-kr|rtjjd"dd#| d$gdgd}|sj|  d.|  qBd+|jd< |jd |jd,< |j|jd< qBnd/|jd krvt d0|jd D ]@}jjj d|d1d   }tjj|dgd!}|r q,q|sRj|  d2|jd   qB|s̈j|  d'|  qBnVd3|jd krRt!d4|jd }|sj|  d5|jd   qBtjjddd|"d6d1d   dgdgd}|D ].}|jd |"d6d1d  kr|} q q|s̈j|  d7|"d6d1d    qBnzd8|jd kr4t!d9|	}|sxqB|"d1}tj|"d:}tjjd;d|gd<d=d ggdd>gd}|D ]&}t|j#jd |kr|} qq|sj|  d?|d6   qBd+|jd< |jd |jd,< |j|jd< qBnd@|	krBt!dA|	}|sTqB|"d1}tjjjjj d| d}|sj|  dB|	  qBd+|jd< |jd |jd,< |j|jd< qBnqB|tj	
| qBd S )CNc                 S   s
   |  dS )Ndata-issue-id)Zhas_attr)tagr   r   r   <lambda>x  rQ   z@CmfImport.obj_check_links.<locals>.check_links.<locals>.<lambda>r  uT   : Не удалось найти id задачи в атрибуте 'data-issue-id'r  r  u;   : Не удалось найти задачу по ext_id ''zdata-macro-nameZjirar  zdata-jira-keyuX   : Не удалось найти код задачи в атрибуте 'data-jira-key'r  r  %"key":""%r   r   u=   : Не удалось найти задачу по коду "r  acmf_convertedhrefu#   : Ссылка без адреса u9   : Не удалось разобрать URL-адрес 'z': httpzdata-linked-resource-typezdata-linked-resource-idpage)NZnull)r  r   r  r  r  %"homepage":{"id":"r2  u<   : Не удалось найти документ по ид zdata-anchor#z##TZ	href_origspaceuD   : Не удалось найти пространство по ид z/wiki/z\/\d+r   u<   : Не удалось найти ид документа в z/browse/z	\/\w+-\d+u8   : Не удалось найти код задачи в r   u<   : Не удалось найти задачу по коду z	/display/z+/display/([~]?[A-Za-z0-9]+)+(?:/)?([^?#]*)?rj   rG   r   !=zparent.import_raw_jsonuD   : Не удалось найти документ по ссылке z/pages/viewpage.action$/pages/viewpage.action\?pageId=(\d+)uE   : Не удалось найти документ по ссылке: )$find_allr^   r$   r  r~   r"  r\   r   Zreplace_withr
  Zcreate_tag_linkr$  r  r  urllibr   unquote_plusr   urlparser   schemenetloc
startswithCmfDocumentr   stringrG   r  r  quotelstripr   findallsearchgrouprP   )main_objsoupr  Zissue_idZissue_ext_idZtaskr   Ztask_keyrS  r   Z
parsed_urlexcr  Zresource_typeZresource_idZtag_hrefZanchor_nameZext_codeobjsr   r   Z	space_key	page_nameZdocsdocpage_id)r  r   r   r   check_linksv  sj   




 










z.CmfImport.obj_check_links.<locals>.check_linksc                    s  |j ddidD ]}|jdr"q|jd}|sJ j|  d|  q|jd} jjj d| }tjj|d	}|stj	jd
dd jjj dgddd| dggd}|rt
|}|jj|d< |jj|d< t
||d< d|d< |d= q j|  d|  qdS )uz   
            Заменяет ссылку на корневую страницу в макросе Page Tree
            data-macrosz	page-treer  r  data-macro-parametersu5   : Макрос Page Tree без параметров Zroot_page_originalr  r  r  r  r  r  r  r  r  r2  r)  Z
rootLocaletrueug   : В макросе Page Tree не удалось найти корневую страницу по ID N)r  r  r^   r$   r  r~   r"  r\   r  r   jsonloadsre   r   rG   dumps)r  r  r  Zdata_macro_parametersZroot_page_idZroot_page_ext_idZpagetree_rootZmacro_paramsrM   r   r   check_pagetree_rootL  s4    
z6CmfImport.obj_check_links.<locals>.check_pagetree_rootc                    s   |j dddgidD ]}|d}|dp4|d}tjjdd	d
 jjj dgddd| dggd}|s j|  d| d qtjj||d}|rt	|j
|d< q j|  d| d qdS )u\   
            Добавляет ID документа в макрос "Include"
            r  zinclude-excerptzinclude-pager  zdata-param-projectkeyzdata-param-pagenamezdata-param-page-labelr  r  r  r  r  r  r  r  r2  u`   : В макросе "Include" не удалось найти пространство по key "uA   ". Возможно оно еще не импортированоrO   zdata-param-pageidu_   : В макросе "Include" не удалось найти страницу по имени "u@   ".Возможно она еще не импортированаN)r  r^   r\   r   r~   r"  r$   r  r  r   re   )r  r  r  Z
projectkeyr  r  Zexcerpt_pagerM   r   r   check_includer  s&    
z0CmfImport.obj_check_links.<locals>.check_includec                    s  |j ddidD ]}|ddkr&qd}d}d}d}|d}|rtdd	 |d
D }|dr|d }|dkr~| j}n$d|kr|dd\}}n
| j}|}|rtjjddd jjj dgddd| dggd}|s j	
|  d| d q|r.tjj||d}|s. j	
|  d| d q|p6|}	|	r|jdd}
d|	j |
_|d }t|}t|	j|d!< tj|d"d#d$|d < d|d< qdS )%u   
            Добавляет ID документа в параметр 'Родительская страница' макроса 'Отображение дочерних'
            r  zchildren-docsr  r  r  Nzoriginal-data-macro-parametersc                 s   s.   | ]&}t |d ddkr|d dV  qdS )r  r   rj   N)r]  r   )rH   Zparamr   r   r   r     s   zFCmfImport.obj_check_links.<locals>.check_childpages.<locals>.<genexpr>|r  /:r   r  r  r  r  r  r  r  r  r2  u   : При конвертации макроса 'Отображение дочерних' не найдено пространство с ключем 'uA   '. Возможно оно еще не импортированоrO   u   : При конвертации макроса 'Отображение дочерних' не найдена страница 'u9   '.Возможно она не импортированаzextension-object-name)class_z | r  Z
documentIdF)r  r  )Zensure_asciiZ
separators)r  r^   ry  r   rP   r\   r   r~   r"  r$   r  r  findrG   r  r  r  r   re   r  )r   r  r  r  ZdocumentZspacekeyZpagenameZoriginal_macro_parametersr  Zparent_pageZspan_object_nameZmacro_parametersr   rM   r   r   check_childpages  sf    





z3CmfImport.obj_check_links.<locals>.check_childpages)task_raw_datalocal_linksc                 S   s   |pg }|  dg D ]}|d }|d }| ddks| ddks| dd	rRqtd
|d }|r|d}tjj ddd| gd}|sq||kr|| d|d< q|S )NZremotelinksobjectZapplicationr   zcom.atlassian.confluenceZrelationshipz	Wiki Page	processedFr  r   r   r  r  r  r2  T)r^   r   r  r  r\   r  r   )r  r  Z
remotelinkZremotelink_objZremotelink_appr   r  r  r   r   r   check_remotelinks  s*    



z4CmfImport.obj_check_links.<locals>.check_remotelinksc                    s   | j s
dS | j d }| D ]n}|s&q| D ]Z\}}|s<q.tjdtjd}||sXq. |d}| | ddd |jj	D ||< q.qd|i| _ d|i| _
dS )	u   
            Конвертирует ссылки, которые могут быть в макросе "Свойства страницы"
            Ndetailsz
<a .+?</a>)flagslxmlr   c                 S   s   g | ]}t |qS r   r   rH   xr   r   r   r     s     zFCmfImport.obj_check_links.<locals>.check_macros_db.<locals>.<listcomp>)	macros_dbr'  ra  r   compileIr  r   bodyr  macros_db_draft)r   r  Zdetailr   r   patternZ
value_soup)r  r  r   r   check_macros_db  s"    



 
z2CmfImport.obj_check_links.<locals>.check_macros_dbF)Zinit_views_and_dsDONErP   rv   zcomments.log_levelzcomments.textZ
text_draftr  r  r  r  r   u5   Конвертируем ссылки объекта r  r  r   r  r  r  c                 S   s   g | ]}t |qS r   r  r  r   r   r   r   3  s     z-CmfImport.obj_check_links.<locals>.<listcomp>r   T)Zsave_importrY  rj   c                 S   s   g | ]}t |qS r   r  r  r   r   r   r   M  s     uV   Не удалось конвертировать перекрестные ссылкиzERR-0034)rq   r   r   )cmf.appr  Zbs4r  ry  r$  r  r^   r;  Zget_obj_by_idr$   debugrw   rv   r   Zhtmlr~   r}   r   r  r  r  r  rn  hasattrr_   ZcommentsZ	log_levelr   put)r   r  	obj_queueobj_queue_errorsr  r  r  r  r  r  
has_errorsZobj_idr   Zobj_textr  ZcommentZcomment_textr   )r  r  r  r   r   obj_check_linksr  s     W& I







zCmfImport.obj_check_linksc                 C   s  ddl m} dd l}t Z t D t . |   d}tt	| }t	j
jddddddggd	gd
}g }	|D ]$}
|
jsqx|	tj|
jjj qx| d|j d| d|  t }t }g }| d| j  |j }t| jD ]F}tj| jd| |||	dd}|| |  | d|  qd}ddd gdddgg}|j|ddg||| gd}|D ]*}|  r q|d7 }| |j! qv|D ]}| d q| d|j  |D ]}|"  q|j | }| d||#   d d}|$ s$||% 7 }q
| d |j 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   r  r   INr  r   ZCmfPluginTrackerApiZCmfPluginYouTrackext_urlr   u)   Конвертируем ссылки в uB    на локальные задачи и документы start=z limit=uJ   Обрабатываем ссылки в несколько тредов: r  )r   r  r  )targetrG   rn   u.   Параллельный обработчик r   r  import_originalr   Tr  re   )r   r   slicer   r  u,   Ждем обработки ссылок в u*   ------------------------ скорость u#    обьектов в секундуu6   Закончили обработку ссылок в u   . Ошибок: )&r  r  r   r;  disable_acldisable_notifyr<  r   varsr\   Z	CmfPluginr$  r  r   r  r   r  r   r  rm   r   r'   Queuer(   r   ranger&   Threadr  r6   Zslistr  r  re   r   Ztotal_secondsemptyr^   )r   re  r6   limitr  r   r  r   Zpluginsr  r~   r   r  Zobj_processrI   r  procZcntr   r  r   Zdiffr   r   r   process_cross_links_by_modelZ  s|    $ 	
	



z&CmfImport.process_cross_links_by_modelc                 C   st   dd l }|jdddd| j d| d| dtj d		gd
d
tddtddd}| jd|j d| d| d |S )Nr   r  r  r  z&cmf_import = models.CmfImport.get(id='z,');cmf_import.process_cross_links_by_model('z', z, z);Tr  r  r  r  u1   Запущен process_cross_links_by_model (pid=z model_name=z start=r  )	r  r  re   rX   IMPORT_OBJ_CNTr  r$   r   r  )r   re  r6   r  r  r   r   r   _execute_cross_links  s        zCmfImport._execute_cross_linksc              
   C   s  d}z|   | _W n: tk
rL } z| d|  | W Y S d}~X Y nX t }dddgdddgg}d	D ]f}tt| }|j|d
}|sqnt	  | j
d|j d| d| j  t }d}	g }
t| jD ]2}| ||	}|
| |	tj7 }	|	|kr qq|   |	|k rtd t|
D ]R}| }|dk	r,||7 }|
| | ||	}|
| |	tj7 }	|   q,qt|
D ] }|  |jr||j7 }qt | }| j
d| d|dd qnt | }| j
d|dd|  |S )u   
        Обработка ссылок на задачи и документы в тексте импортированных объектов
        r   u.   Ошибка обработки ссылок: Nr   r  r  r   T)r   r  r   r`  r2  u5   Обработка ссылок в объектах 'z' (u,   ) в несколько процессов: r   u$   Обработка ссылок в 'u   ' завершена за z.3fu    сек.uA   Обработка всех ссылок завершена за u    сек. Ошибок: )r   r*   r   r   rw  	monotonicr  r\   countr   r$   r   r   r  r  r   rX   r  r  sleepr$  Zpollr   Zcommunicate
returncode)r   errorsr  Ztotal_t1r   re  r   Zobj_cntZmodel_t1r6   rp   r   r  r  Znew_procZmodel_t2Ztotal_t2r   r   r   process_cross_links  sb    








zCmfImport.process_cross_linksr1  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 )exr   r1  zdownloaded-)r   re   APPREDIS_DBredislockacquirerelease
exceptionsZ	LockErrorgr  rG   r  rr  Zsaddr   setr=   ZincrZexecuter6  r^   )r   rG  rH  r   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smembersre   r   r  r^   r   ry  )r   r(  r  r   r   rH  rG  r   r   r   r   r5  ,  s    


z CmfImport.get_redis_import_statsc                 C   s(   |  ddg | jdkr | jjS |  S )Nr  r6  r  )rL   r  r6  r   r5  rM   r   r   r   r8   9  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 st }| sd}| j	|t
jd	 || _| jjd
d| _|   |   dS dS )Nr   rE  r  r   r  import-plannedFu   Импорт прерван по неизвестной причине. Проверьте системные требования.r.  rZ  r[  T)rL   r  r   rw   r;  r<  Zimport_is_runningCmfImportWorker
is_runningrm   rZ   ry   rE  r   r   r_   rD   )r   ZworkerrE  r   r   r   r,  @  s    
zCmfImport.is_runningTz	@minutely)Z	only_onceZ
system_jobZschedulec                  C   s`   t j sd S td t jjdddgdddgggdd	dd
gdD ]} |  sBtd|  qBd S )Nz&cmf_deferred_job: CmfImport.cron_checkr  r   r  zstatus.codezNOT INr*  r   rE  r   r   uH   Импорт прерван по неизвестным причинам)	r\   r!   r@   r&  r  r$  r,  r;  Zadmin_alert)r   r   r   r   
cron_checkQ  s    




zCmfImport.cron_checkreport.json)project_identifierreport_file_namec                 C   sp  t jjdddd|  dgdd| gdd| gdd| ggd	d
dggddgd}|s\td|  d|jsrtd| d|jj}|jjd}|s|jjd}|std| dt|	 std| d| dt
 }||}t
 }|| }	t||}
t|
d}t|| W 5 Q R X t|tjr|D ]p}|d }|d }|d }|d }|d }|| d | d!| d"| d# |r4|d$|  d%|  q4|d&|	d'd(td)d* t|
tjd+ d |d, nd-d.lm} d/d0 }g }|D ]}||| q d1d2d3d4g}t|||d5d6 td&|	d' td7td)d* t|
tjd+ d dS )8u  
        Собирает статистику количества сдампленных и обработанных объектов
        по проекту

        Args:
            project_identifier (str): ext_id, код, префикс кода задач или название проекта
            report_file_name (str, optional): имя файла отчета. Defaults to "report.json".
            stdout (Logger, optional): вывод данных отчета.
        r   r  r  %rw   r  r   rG   r   r  Nzcmf_import.pluginr  r   u   Проект 'u   ' не найденu   Проект u.    не содержит данных дампаproject_dirr   u*   В данных дампа проекта uA    отсутствует путь до каталога дампаu@   Отсутствует каталог дампа проекта z: 'r  zw+entitydumpedr  r   unprocessedu,    (сдамплено/обработано): z / r  r  u   Необработанные r   u   Выполнено за z.4fu,   . Ссылка на файл отчета: 'T)Zfull_urlzrdisk/file/z2--------------------------------------------------r   )tabulatec                 S   s   dd |   D S )Nc                 S   s   g | ]\}}|d kr|qS ))r3  r4  r  r   r   )rH   r  r  r   r   r   r     s   z>CmfImport.project_stats.<locals>.data_list.<locals>.<listcomp>)ra  )Z
stats_datar   r   r   	data_list  s    z*CmfImport.project_stats.<locals>.data_listr   u   Сдампленоu   Обработаноu   РезультатZgrid)headersZtablefmtu*   Ссылка на файл отчета: ')r\   r   r^   r   r  r   r~   r   r	   r=   rw  perf_counterproject_statsr   r  r  dumpr  rZ   r   r   r  r,  Zapp_base_hrefr   r   rX   r   r6  r   print)r/  r0  r  r  r~   r2  Z
start_timer~  Zend_timeZelapsed_timeZreport_filer   Zentity_statsr3  r4  r  r   r5  r6  r7  rf  r8  r   r   r   r:  b  sz    

"*"zCmfImport.project_stats)ro   NNNNrp   )r   )NN)F)N)r1  N)r.  N)Pr   r   r    r   r!   Zui_meta_skipZapi_methodsr"   r%   rK   r	   r,   classmethodr%  r@   rB   rD   propertyry  r+   r   r   r$   rZ   r[   r   r   rm   r   r   r   r2   r$  r3   r1   staticmethodr   r   r   r   r-   r9   r   r#   r6   r7   r   r0   r  r/   r  r4   rA  rF  rp  rs  r  r  r   r.   r5   r  r_   r  r   r  r  r  r  r  r  r  r@  r5  r8   r,  Zcmf_deferred_jobr-  r:  __classcell__r   r   r   r   r!   $   s   

@    
 5


	
N
 2 B!#   kHI
,  r!   c                    s   t   fdd}|S )Nc                    sT   z0 | f||}t   | jd t  |W S    t  | jd Y nX d S )Nu*   Импорт завершил работуu&   Ошибка работы демона)r   r$   r   r!   rD   rB  rb  )r   r   rn   r  fnr   r   wrapped  s    z!catch_exceptions.<locals>.wrappedr   )rB  rC  r   rA  r   catch_exceptions  s    
rD  c                   @   s   e Zd ZdddZdd Zdd Zdd	d
dZdd Ze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   rZ   r   r	   rd   r$   Zinit_loggerr[   r  )r   r8  r   rZ   r	   r   r   r   __init__  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rX|s|j d |jjdd|_	|
  n:|j	jdkrX|j d| d |jjdd|_	|
  tjjd|d}t|jtjd}tjj||j |j!d|j dt"#t$j%dd | d!d"d# d S )$Nu   Импорт запущенr   re   r   rw   r   r   r>  r-  r   u%   ***Запускаем импорт***r  import-startedr   r\  r   r  r   r2  u2   ***Импорт успешно завершен***import-completedr[  CLOSEDu6   ***Импорт завершен с ошибками: u,   . Подробности в отчете.***rZ  rN   rO   /files/u   Импорт данных 'u   ' завершен %d.%m.%Y %H:%Mz (UTC), <a href=(   >Журнал логирования</a>Tr   ZpersonrG   ri   Zforce_notify_current_person)&r$   r   r\   r!   r^   r   rm   r   r   r   r_   r   r;  r	  r
  r<  rA  geventr  re   rz   r  rw   r   r]   r   ra   r   rX   r   	CmfNotifyplace_notifyrO  rG   r   r   r   r   )r   r   r   r  r  Zlog_filelog_pathr   r   r   run  sD    

(


"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   re   r   rw   r   r   r>  r-  r   u!   ***Запускаем дамп***r  rH  rI  r   r2  u.   ***Дамп успешно завершен***rK  r   u2   ***Дамп завершен с ошибками: z***rZ  r[  r   rL  u'   Дамп данных завершен rM  z
, <a href=rN  TrO  )"r$   r   r;  r	  r
  r<  r\   r!   r^   rm   r   r   r   r_   r   r  r  rz   r  r   rb   ZbaseFilenamer   rX   r   rQ  rR  r&  Zcurrent_personrG   r   r   r   r   )r   r   r   r  Zres2r  rS  r   r   r   	dump_data   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   t  |d7 }|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&   t  |d7 }|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 } z8t| |j d|  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   re   r   rw   r   r   T)r   r   r   zimport-cancelingr[  r   Nu#   ***** Отменяем импортr   )r   r   u   Удаляем )r/  rl  r   u#   Не удалось удалить uW   , видимо обьект использовали вне данных импортаimport_objectsuy   Не удалось удалить, видимо обьект использовали вне данных импортаzimport-canceledu,   Успешно отменили импортu#   Количество ошибок: rZ  u   Ошибка удаления )r$   r   r;  r	  r
  r<  r\   r!   r^   r   r   r   r_   r   r7  r8  r9  r:  r   r$  r  rB  rb  rV  r   r   r   rE  )r   r   r   r  r   r   r   r   r   _cancel_import   s^    $ 
 


&zCmfImportWorker._cancel_importc           
      C   s  t jjddd|gdd|ggddddgd	}d
d|jdi}|jjjdkrd|jj|dddd|jj|dddd}|| ||}|s|j	
d| d d S |d }|di }|jjddd|_|  t  | j	|d  d t B t . t  |f | 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|	s|jjd"d#|_|  n&|jjd$kr|jjd%d#|_|  tjj  | j	|d  d& d S )'Nr   re   r   rw   r   r   r>  r-  r   Zlinksu   Обработка ссылок)rG   r  r   u   Импорт фильтровZ_process_filters)r   Zprocess_method)rG   r  rn   u3   Обработка связей всех задачZ_process_relationsr   uC   Конфигурация для запуска обработки 'u   ' не найденаr  rn   r  rH  rI  rG   u    запущенаr   r  r   r2  rJ  r[  rK  rZ  u    завершена) r\   r!   r^   r  r~   r   r}   r   updater$   r   r   r   r   r_   r   r   r;  r	  r
  r<  rP  r  re   rz   r  rw   r   r7  r8  r9  r:  )
r   r   r   r   Zprocess_configsZprocess_jira_configsZprocess_configr  Zmethod_kwargsr  r   r   r   _process_entityR  s    	


(	
zCmfImportWorker._process_entityc                 G   s>   | j  rtd| j tt  | j|  | j   d S Nu"   Импорт уже запущен)	r  r=   r   
write_textr   r   getpidrT  rC   r   r   r   r   r   r6     s
    

zCmfImportWorker.startc                 G   s>   | j  rtd| j tt  | j|  | j   d S rZ  )	r  r=   r   r[  r   r   r\  rU  rC   r]  r   r   r   r;    s
    

zCmfImportWorker.dumpc                 G   s>   | j  rtd| j tt  | j|  | j   d S rZ  )	r  r=   r   r[  r   r   r\  rW  rC   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 )Nr  r   r  r   r   r>  r-  r   uQ   Пытаемся остановить импорт, таймаут 1 минутаr  r[  <   r   r  u"   Импорт уже прерванr  u<   Импорт остановлен пользователемu    Импорт не запущенu'   Останавливаем импортuK   Не удалось завершить процесс, он запущен?)r\   r!   r^   r,  r$   r  r   r   r   r_   r   r  rP  r  re   r  r   r  r=   r   killr   	read_textsignalSIGTERMrb  rC   )r   r   r   r  r   r   r   r7     s4    


zCmfImportWorker.stopc                 O   s@   | j  rtd| j tt  | j|| | j   d S rZ  )	r  r=   r   r[  r   r   r\  rY  rC   r  r   r   r   r     s
    
zCmfImportWorker.process_entityc                 C   s0   | j  r,tt| j  r"dS | j   d S )NT)r  r=   r;  Zcheck_process_runningr   r`  rC   rM   r   r   r   r,    s    
zCmfImportWorker.is_running)rE  )r   r   r    rG  rT  rU  rW  rY  rD  r6   r;  r.   r7   r   r,  r   r   r   r   r+    s    
% 2U




r+  )+Zcsvr   r   decimalr   r   r   rZ   r   sysrx   r   r	   typingr
   r   r!  r   r   ZxlrdZopenpyxlrw  r&   r'   r  Zcmf.includer7  r   Zcommon.fieldsr   rF  r   r   ra  	functoolsr   r  rc   ZFilterr   r!   rD  r+  r   r   r   r   <module>   sV                  .