U
    [f                    @   s   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m	Z	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Zd dlZd dlmZ d dlT d dlmZ d dlmZ G d	d
 d
ejZdS )    N)deepcopy)Path)DictIterator)cached_property)*)cmf_plugin_csvcmf_contextc                   @   sz  e Zd ZU dZe ed< dZdd Ze	dd Z
edd	d
Ze	ee dddZdd Ze	eeef dddZdd ZeeedddZdd Zdd Zdd ZdJedddZdKedd d!Zd"d# Zd$d% Zed&d'd(Zd)d* Zd+d, Z d-d. Z!d/d0 Z"d1d2 Z#d3d4 Z$d5d6 Z%d7d8 Z&e'j(e'j)e*d9d:d;d<d= Z+dLd>d?Z,d@dA Z-dBdC Z.dDdE Z/dFdG Z0dHdI Z1dS )MCmfPluginCsvN_loggerr   c                 C   s   t  d | _| jjd| jd  ddd tjrBttj| j| _| jjdtj dd t	 j
}| jjdt|d  d	dd tt|d
 | j| _| jstdd S )N   z
cpu_count=u%   , надо не менее 2 ядерT)Z	anonymouszconfig.IMPORT_PROCESS=zavailable_memory=i   @u-   Гб, по 2 Гигабайта на ядроl        u   Ресурсов системы недостаточно для импорта, обратитесь в техподдержку для дополнительной информации.)multiprocessing	cpu_countmax_processes
cmf_importlogconfigZIMPORT_PROCESSminpsutilZvirtual_memoryZ	availableint	Exception)selfZavailable_memory r   +./modules/settings/models/cmf_plugin_csv.py_prepare_multiprocessing   s&    

z%CmfPluginCsv._prepare_multiprocessingc                  C   s   dt j t jjddt j t jjddt j t jjddt j t jjddt j t jjddt j	 t j	jddt j
 t j
jdd	t j t jjdd
t j t jjdg	} | S )uR   Собственный магазин при выборе импорта из Jirau#   Поля пользователей)captionfieldsiconu!   Поля контрагентовu   Поля задачu,   Оперативная гант-задачаu   Журнал работu!   Поля комментариевu   Поля проектовu"   Поля списков задачu   Поля групп)models	CmfPersonimport_shop_fieldsr   
CmfCompanyCmfTaskCmfGanttTaskCmfTimeTrackerHistoryZCmfTimeTracker
CmfComment
CmfProjectCmfListZCmfPersonGroup)resr   r   r   calc_models_settings6   s6    







z!CmfPluginCsv.calc_models_settings)returnc              	   C   s   |j }d}d}z | |}t|D ]\}}q"W n tk
rn   d| d| }| j| t|dd d}Y nb tk
r   | jd| d|  d}Y n4 tt	fk
r   | jd| d|  d}Y nX |S )	NFr   uK   Не корректный формат загружаемого файла :T)abort*   Приложен пустой файл CSVu5   Не удаётся прочитать строчку)
full_path_file	_get_file	enumerateUnicodeDecodeErrorr   	exceptionZ	cmf_alertStopIterationIOError
ValueError)r   
attachmentZ	file_path
have_errorZnum	file_read_msgr   r   r   _check_fileN   s&    

zCmfPluginCsv._check_filec              	   c   s   t | j}|jdkrLtt|}|d}| D ]}dd |D V  q4n~|jdkrt	t|}|j
}|jddD ]
}|V  qvnF|jdkrtd	 t|d
"}tj|dddD ]
}|V  qW 5 Q R X d S )N.xlsr   c                 S   s   g | ]
}|j qS r   )value).0itemr   r   r   
<listcomp>j   s     z*CmfPluginCsv._get_file.<locals>.<listcomp>.xlsxT)Zvalues_only.csvi r;")Z	delimiterZ	quotechar)r   r/   suffixxlrdZopen_workbookstrZsheet_by_indexZget_rowsopenpyxlZload_workbookZactiveZ	iter_rowscsvZfield_size_limitopenreader)r7   Zattachment_file_pathZworkbookZ	worksheetelfiler   r   r   r0   c   s"    






zCmfPluginCsv._get_filec              	   C   s  |j | _|jsd S tjjdgdd|jgdgd}dg d}tjj|dd	d
ddggdgdgd}| |}|rpg S | 	|}| 
 }t|D ].\}}	|dkr|jd s qn|dkr qt|	D ]\}
}d}|dkr~|r^|jd r^t|jd D ]b}d|krd|kr q^|d dkr(q|d D ]*}|d |kr0|d | d} qq0q|s|d |d d d d q|d |
 }||d }||d< |r||d< |d |d< qq|d s| jd g S |gS )N-cmf_modified_atidz!=json_settings)order_byfilterr   ZCSV)namer   	file_typeINrC   r=   rB   urlparentrT   rS   r   r   	first_rowr   Fimport_settingsrU   r   titleT)r]   file_valmodel_fieldr   r^   r_   r   r.   )loggerr   Zattachmentsr   	CmfImportgetrQ   CmfAttachmentr<   r0   _default_mapping_csvr1   rR   r   appendr3   )r   r   Zprev_settingssettingsr7   r8   r9   default_mappingirowjvalfoundZprev_setZ
prev_fieldZrow_settingsr_   r   r   r   calc_import_settingsw   sh    




 

z!CmfPluginCsv.calc_import_settingsc               &   C   s  d} d}d}d| dd| dd| dd| dd	| dd
| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd| dd|dd|dd|dd|dd|dd|ddddddddddd ddd!ddd"ddd#ddd$dddd%dd&$}i }t j D ]}|||d' < q@| D ]P\}}|d(d)}|d*d)}	tt |}
||	| d+|	 |
jd,|
jd-||< q\|S ).ug    Структура сопоставления полей из файла CSV по умолчанию. r#   r'   r(   ext_id)
field_name
model_namerU   
logic_typeZcmf_modified_atcmf_created_atcmf_modified_bycodetextstatusZ
alarm_dateZdeadlinepriorityzresponsible.namezresponsible.emailzcmf_author.namezcmf_author.emailzexecutors.namezexecutors.emailparent_taskzparent_task.codezchild_tasks.codeZtask_code_prefixactivityactual_workr$   sched_start_datesched_finish_date
sched_workagregat_workactual_myself_workZactual_completeZactual_finish_dater&   )$u/   Ид внешней системы задачиu   Тема задачиu   Тип задачиu(   Дата изменения задачиu&   Дата создания задачиu*   ФИО изменившего задачуu   Код задачиu   Описание задачиu   Статус задачиu   Будильник задачиu$   Крайний срок задачиu   Важностьu   ФИО исполнителяu   Email исполнителяu   ФИО автораu   Email автораu!   ФИО соисполнителяu    Email соисполнителяu%   Родительская задачаu$   Код основной задачиu$   Код дочерней задачиu   Название проектаu   Код проектаu   Префикс задачu   Тип проектаu   Вид деятельностиu   Список задачu/   Фактические трудозатратыu&   Плановая дата началаu,   Плановая дата окончанияu/   Планируемые трудозатратыu2   Сумма дочерних трудозатратui   Фактические трудозатраты по собственным ресурсам задачиu-   Фактический % завершенияu   Дата финишаu   Комментарийr   rp    ro   .T)r   ro   field_qualnamer   requiredverbose_name)r   r#   r!   itemsrb   getattrr   r   )Zname_cmf_taskZname_cmf_projectZname_cmf_epicrg   Zdefault_local_attrs_mappingZshop_fr]   Zvalue_modelrp   Z	name_attrmodelr   r   r   rd      sr    '
z!CmfPluginCsv._default_mapping_csvc                 C   s<  g }ddg g d}d}t jj|ddddd	ggd
gd}|sH| jjd | |}|jd rdt| t	|D ]\}}|dkr qg }	|d 
|	 t	|jD ]l\}
}|d sq|d d dd }|s|dkrd}|dkr|dkr|d 
|d d  |	
||
  qql|d r"|
| |s8d|d< d|d< |S )Nu   СделкиZ	handshake)r]   r   titlesrowsFrV   rW   rC   r=   rB   rP   )rZ   rT   rS   u)   Не найден файл импортаr[   r   r   r_   r   r   r   CmfDealT)r   r#   r   r   u   Задачиr]   zcalendar-todayr   )r   rc   rb   r   r`   errorr0   rR   nextr1   re   Zcsv_import_settings_fieldssplit)r   r   resultZdealsZis_dealZattachr9   rh   ri   Zdata_rowrj   rf   rp   r   r   r   preview   sD    



zCmfPluginCsv.preview)	row_arrayrf   r+   c           	      C   s   t  }t|d d D ]\}}|| s(q|d s4qn|d d |jkrHq|d d d}t||d }t|tjjrt	|dkr|d || i||d < qd|| i||d < q|j
d	kr| || ||d < q|| ||d < q|S )
Nr   r   r_   r   ro   r   r   rn   rw   )dictr1   r   r   r   
issubclassZcmfr   Z
CmfRelBaselen
class_nameZcalc_priority)	r   r   rf   r   r)   idxZfield_settingsZfield_partsZfieldr   r   r   _map_object  s$    
zCmfPluginCsv._map_objectc                 C   s   d }|  || jjd tj}|rg }dddg}|D ]N}||d}|r2|dkrl|d|d|gdd|gg n||d|g  qq2|rtjj|d}|S )	Nr\   rn   rt   rU   r   OR==rT   )r   r   rR   r   r'   rb   re   )r   ri   project_objproject_filteruniq_fields
uniq_fielduniq_field_valuer   r   r   _get_project/  s    
zCmfPluginCsv._get_projectc           
      C   s   d }|  || jjd tj}|rg }dddg}|D ]N}||d}|r2|dkrl|d|d|gdd|gg n||d|g  qq2|rtjj|dd	}	|d
d|gdd|	gg tjj|d}|S )Nr\   rn   rt   rU   r   r   r   sprinttree_parentZsys_typerZ   r   r   )	r   r   rR   r   r(   rb   re   	CmfFolderextend)
r   ri   r   
sprint_objr   r   r   r   r   sprint_folderr   r   r   _get_sprintD  s"    
zCmfPluginCsv._get_sprintc                 C   sx   t jjdd|gd}|stt jjdd| gd}t|dkrh| jjd| dt| d	d
dd td|rt|d }|S )Nrt   r   r   rU   ILIKEr   u<   Компаний с одинаковым названием z > uF   , укажите код компании вместо названияzERR-0071r"   Zobj_typeu]   Найдено несколько компаний с одинаковым названиемr   )	r   r"   rb   liststripr   r   	log_errorr   )r   rn   company	companiesr   r   r   _get_company[  s    zCmfPluginCsv._get_company)r   c                 C   s   |D ]}d|d< | j jd|  | | j tj|\}}|j  |rt|j	j
dkrtjjdd|j
gddd	ggd
}|j| |  qd S )NTZservicedesk_allowu1   Пытаемся создать компанию project.servicedesk:defaultzparent.coder   zproject_role.code=zsdesk-client:defaultr   )r   r`   infoprocess_any_table_fieldsr   r"   dpcommitrI   rq   rt   ZCmfProjectRoleAssignrb   membersre   save)r   r   r   r   Zcompany_objis_newZrole_assignr   r   r   _process_companieso  s    

zCmfPluginCsv._process_companies)personsc           	      C   s   |D ]}d }| dr2|d  d}| ||d< | jjd|  | | jtj|\}}|j	  |rt
|jjdkr|jjst
|j}| j|t }|r|jr|jjtjs||jj qd S )Nr   rn   u9   Пытаемся создать пользователя r   )rb   r   r   r`   r   r   r   r    r   r   rI   rq   rt   Z
user_localr>   rQ   person_emails
setdefaultsetZemailendswithr   Z
ORG_DOMAINadd)	r   r   r   personZ
project_idZcompany_ext_idZ
person_objZperson_is_newZproject_person_emailsr   r   r   _process_persons  s*    


zCmfPluginCsv._process_personsc                 C   s>  d|d j  d|d j  }d|d j d|d j }tjjdd|gd	}|s| jjd
 tjjdd|d j	dd  dgd	}|stjjdd}tj||| jdd}||_|j
r|jdd tjj|d d d}|sdd|d d gddd gg}tjj|d	}|s,tj|d d | jdd}|d d |_|d}|sV|d d }| |}	|	|_|d d |_|j
r|jdd |j  d|d d  }
tjj|
d}|stjjdd|gdd|ggd	}|stjjdd|d d gdd|ggd	}|s&| jjd tj|| j|dd}|
|_|d d |_||_|	|_|j
rZ|jdd d|d j  }d|d d  }tjj|d}|stjjd d}tj||| jdd}||_t|d jd!kr||_|j
r|jdd tjj|d ||d"d#}|s4|d |d"|| jdd$}tjf |}|jdd |||fS )%NzCSV::rZ   ::rq   u   БП для проекта u    и типа rn   r   r   u/   Не нашли БП, создаем новыйrt   LIKEr,   r   %zdefault.system:defaultrt   T)rn   templater   import_originalZsave_importrv   rn   rU   r   )rU   r   r   cache_status_typeworkflowstatus_codeu7   Не нашли статус, создаем новый)r   r   r   r   u%   CSV-схема для проекта softdev:default)task.agile:defaulttask.base:defaultr#   )rq   Ztarger_workflow	scheme_wfcmf_model_name)rq   Ztarget_workflowr   r   r   r   )rQ   rU   r   CmfWorkflowrb   r   r`   r   rt   r   
is_changedr   CmfStatusCodern   Zcalc_status_typestatus_type	CmfStatusr   CmfSchemeWfrI   Zdefault_task_workflowZCmfSchemeWfRule)r   taskrn   rU   r   r   Zcmf_status_coder   r   r   status_ext_idtask_statusZscheme_ext_idZscheme_nameZschemeZruleZ	rule_dictr   r   r   _process_workflow  s    *


 zCmfPluginCsv._process_workflowc           	      C   s  d }d }d }d }| dr8|d  dr8|d d  }|rtjj ddd| dgd}|s| jjd| d tjj d	d
|gdgd}|s| jjd| d tjj dd|gdgd}|r|jrd| |j |_nd| d|_|jdd |r|d d  }| jjd| d d	d
|gddd gg}tj	j |d}|rldd
|gdd
|gg}tj
j |d}|sdd
|gd	d
|gg}tj
j |d}|s| jjd| d dd
|gdd|gg}tj
j |d}|s| dr| |\}}}n| jjd ||d< ||d< |S )Nr   rn   r   %::::%r   u   Ищем БП по коду "rF   rt   r   rT   r   u   Ищем БП по имени "rU   r   r   Tr   rv   u-   Ищем статус в БП по коду "r   r   u/   Ищем статус в БП по имени "rq   ut   Невозможно создать БП и статус, не указан логический тип задачи)rb   r   r   r   r   r`   r   rn   r   r   r   r   Zwarning)	r   r   workflow_schemeZworkflow_ext_idr   r   r   Zfilter_r   r   r   r   _calc_workflow  sZ    zCmfPluginCsv._calc_workflow)projectsc                 C   s  |  D ]}|d }|ds&d|d< |dsDtjjdd|d< n| |d|d< |dsptjjd	d|d< |d
r| ||d
< | | jtj	|\}}|j
  |r| |d |}|r||_|  | |d | | |d | | |d | qd S )NdataZproject_typer   rq   project.agile:defaultr   r'   r   r   ry   	workflowssprintsr   r   )valuesrb   r   CmfLogicType_process_logic_typer   _process_activityr   r   r'   r   r   _process_workflowsr   r   _process_sprintsr   r   )r   r   r   project_datar   r   r   r   r   r   _process_projects7  s*    




zCmfPluginCsv._process_projectsc                 C   sd   t jjdd}|D ]L}t jj|dd}||d< ||d< ||d< | | jt j|\}}|j  qd S )Nzlist.agile_sprint:defaultr   r   r   rZ   r   rq   )	r   r   rb   r   r   r   r(   r   r   )r   r   r   Zsprint_logic_typer   r   r   r   r   r   r   r   Q  s    zCmfPluginCsv._process_sprintsc                 C   sH   d }|D ]:}||d< | dr.| |d|d< | dr| |}q|S )NrZ   rq   r#   rv   )rb   r   r   )r   r   r   r   r   r   r   r   r   [  s    

zCmfPluginCsv._process_workflowsc                 C   s  |  || jjd tj}|rzdddddddddddddddddddd	}dddddddddd
	}|drb|d}|d   }||}|dkr||d< n|dkrd|d< d |d< ||d< ||d< n|dkr|dkr||d< n d|d< d |d< ||d< ||d< nRd|d< dd tjjj	
 D }	| jjd| dd|	 ddd |  jd7  _|dr|d dkr|d   }
||
|d< |d dkrdd tjjj	
 D }	| jjd|
 dd|	 ddd |  jd7  _dD ]&}||rt|| d  ||< q|d!d |D  |D ]}t|jj|||  q6|d"s|d#d$d%d&g |jjr|jjrtjj|j |jjj|jjj|jjjd'}||j_|jjjd(d) W nH tk
r   t  | jjd*| d+| d,dd |  jd7  _Y nX d S )-Nr\   0-const1-early2-latter3-after4-before2-before1-after)   фиксированнаяu   как можно раньшеu   как можно позже   не раньше   не позжеu    начало не позднееu   начало не ранее&   окончание не позднее"   окончание не ранее'   фиксированное начало-   фиксированное окончание   фн   фоu   кмрu   кмпu   ннрu   ннп   онр   онп)	u   фиксированныйr   r   r   r   r   r   r   r   constrain_start_typeconstrain_start_date)r   r   r   r   )r   r   constrain_finish_typeZconstrain_finish_date)r   r   r   c                 S   s   g | ]}d | d qS rF   r   r?   tr   r   r   rA     s     z/CmfPluginCsv._process_gantt.<locals>.<listcomp>uG   Не найден тип ограничения даты начала "u,   ". Укажите один из типов: , zERR-0082r$   r   r   )r   r   r   c                 S   s   g | ]}d | d qS r  r   r  r   r   r   rA     s     uM   Не найден тип ограничения даты окончания "zERR-0083)r}   Z
const_workr~   rz   r   <   c                 S   s   g | ]}d | qS )zop_gantt_task.r   )r?   keyr   r   r   rA     s     sched_durationzop_gantt_task.sched_start_datezop_gantt_task.sched_finish_datezop_gantt_task.sched_durationzop_gantt_task.const_duration)ZcalendarZfrom_dtZto_dtZforce_include_endsTr   u:   Не удалось импортировать Гантт u    для задачи zERR-0072)r   r   rR   r   r$   rb   r   lowerr  choicesr   r   join_has_errorsr  floatZload_fieldssetattrZop_gantt_taskr>   r{   r|   ZCmfCalendarZget_duration_minutesZ_get_calendarZconst_durationr
  r   r   commit_with_event)r   ri   task_objZganttZconstrain_start_type_mappingZconstrain_finish_type_mappingr  Zconstrain_start_type_rawr  typesZconstrain_finish_type_rawr	  Zcalendar_durationr   r   r   _process_gantth  s    







zCmfPluginCsv._process_ganttc                 C   sl  dddddddddddddddddddd	dd
ddd
ddddddddddddddddddddd}| j jd|d   |d d|d d }||}|r.tjjdd|d gdgd}|jr||jkrd| |j |_nd| d|_|jr*|j	dd |S tjjddd | d!gd"}|rT|S | j jd#| d$ tjjdd|gdgd}|stjjdd%|gdgd}|r|jr||jkrd| |j |_nd| d|_|jr|j	dd |S | j jd& |d'krd}n|d(kr d}tjjdd|gd"}t
d| d|||d)}	| | j tj|	\}}
t  |S )*N   Подзадачаztask.sub:defaultrU   rt   Z	UserStoryztask.userstory:defaultz
Task Agiler      Задачаr   Bugztask.bug:defaultEpicztask.epic:defaultu&   Проект. Классическийzproject.base:defaultu   Проект. Agiler   u   Проект. Service Deskr   )zSub-taskZSubtaskr  ZStoryu   ИсторияZTaskr  r  u   Багu   Эпикr  u   КлассическийZAgilezService DeskZServiceDesku   Логический тип rq   rn   rU   rt   r   r   r   Tr   r   r   r   r   uF   Ищем логический тип по коду или имени ''r   uF   Не нашли, создаем новый логический типr#   r'   )rn   rU   r   r   )r   r`   r   rb   r   r   r   rn   r   r   r   r   r  )r   objrp   	name2codern   Zlogic_type_dictrq   Ztemplate_coder   Zlogic_type_paramsr   r   r   r   r     sx    


z CmfPluginCsv._process_logic_typec                 C   s  ddddddddddd	dd
ddddddddddddddd	}| j jd|d   |d d|d d}||}|rtjjdd|d gdgd}|jr||jkrd| |j |_nd| d|_|jr|jdd |S tjjddd | d!gd"}|r|S | j jd#| d$ tjjdd|	 gdgd}|sltjjdd%|	 gdgd}|r|jr||jkrd| |j |_nd| d|_|jr|jdd |S | j jd& t
d| d|	 d'}| | j tj|\}}t  |S )(u"    Виды деятельности   БизнесZbusinessr     ПродажиZsales   МаркетингZ	marketing   ПроизводствоZ
production   ПоддержкаZhelpdesk   БухгалтерияZfinance!   ИТ инфраструктураZservicedesk%   Хозяйственная частьZ	household   Разработка ПОZsoftdev)	r  r  r  r   r!  r"  r#  r$  r%  u    Вид деятельности ry   rn   rU   rt   r   r   r   Tr   r   r   r   r   uJ   Ищем вид деятельности по коду или имени 'r  r   uJ   Не нашли, создаем новый вид деятельности)rn   rU   )r   r`   r   rb   r   ZCmfActivityrn   r   r   r   r   r   r  )r   r   r  rn   Zactivity_dictry   Zactivity_paramsr   r   r   r   r   *  sZ    

zCmfPluginCsv._process_activityc              
   C   s  | j jd t| j}d}t }| jD ]<}| j  r@ d S | j j| d|  |d7 }ddd|gdd|gg}tj	j
|d}|s| j jd	| d
dd |  jd7  _q*| j| D ]}zjddd|gdd|gg}tj	j
|dddgd}	||	_|	jjds|	jjdr|	j|	_|	jdd W q tk
rd   | j jd| ddd |  jd7  _Y qX qq*t | }
| j jd|
dd d S )Nu5   Привяжем подзадачи к задачамr       из r   rn   r   rt   r   uE   Не удалось найти родительскую задачу zERR-0073r#   r   rx   r   rq   r   ztask.subprojectz	task.epicTr   u4   Не удалось привязать задачу zERR-0074u<   Обработка подзадач выполнена за .3f    сек.)r   r`   r   r   subtaskstime	monotonic	is_cancelr   r#   rb   r   r  rx   rq   rt   
startswithr   r   r   )r   totalrh   t1parent_ext_idr   rx   Zchild_ext_idZ_filter_childr   t2r   r   r   _process_subtasksb  sL    

zCmfPluginCsv._process_subtasksc           
   	   C   s  | j jd t| j}d}t }| jD ]}zj| j  rFW  d S | j j| d|  |d7 }tj	j
|d d}|stj	j
dd|d gd}|s| j jd	|d  d
ddd |  jd7  _W q*tjj
dd|d gd}|s| j jd|d  ddd |  jd7  _W q*tjj
dd|d gd}|s`| j jd|d  ddd |  jd7  _W q*tjj
|||d}|stj|||| j dd}|jdd W q*   | j jd| ddd |  jd7  _Y q*X q*t | }	| j jd|	dd d S ) Nu&   Создадим связи задачr   r&  typer   rU   r   r   u2   Не удалось найти тип связи "rF   zERR-0075CmfRelationTyper   rn   in_linku=   Не удалось найти входящую задачу zERR-0076r#   out_linku?   Не удалось найти исходящую задачу zERR-0077)relation_typer5  r6  T)r7  r5  r6  r   r   r   u.   Не удалось создать связь zERR-0078CmfRelationOptionu8   Обработка связей выполнена за r'  r(  )r   r`   r   r   	relationsr*  r+  r,  r   r4  rb   r   r  r#   r8  r   )
r   r.  rh   r/  relation_datar7  r5  r6  Zrelation_optionr1  r   r   r   _process_relations  s|    

zCmfPluginCsv._process_relationsc                 C   s   |  || jjd tj}|r| jjd|  d|d< | j|d< d|d< |drntjj|d d	 d
|d< |drtj	j|d d	 d|d< tjf |}|j
r|jr|j
jtj|jjd |_|jdd d S )Nr\   u   Грузим журнал closedrv   r   Tr   
cmf_authorrn   ZloginrZ   r   )Zminutesr   )r   r   rR   r   r%   r`   r   rb   r    r#   Z
start_dateZ
time_spentr>   datetimeZ	timedeltaZend_dater   )r   ri   Ztimetracker_historyhistoryr   r   r   _process_timetracker  s*    







z!CmfPluginCsv._process_timetracker
      )Z	max_triesZmax_timec                 C   s  | j jd }| ||tj}| |}|r|r|dsDtd||d< |drf| |d|d< |drz| 	| |dr|d |d	< |d	r|ds|d	= d
D ]J}||}|r|drtj
j|d d}ntj
jf |}|r|||< q| j d|  dd| j jgdddgdd|d gg}| j jjdd }	|drdd}	dd|d g}n.|drd}	ddd|d gdd|d gg}|	st|d|dd |dd d   }
| jjj|
dd}|" | j| j tj|||	d\}}W 5 Q R X n| j| j tj|||	d\}}|rtjd| jj d| jj d| j j dd|| j dd }|jdd! |j  | j d"| d#|d d$|d d%|d d&	 n8| j d'| d#|d d$|d d%|d d&	 | || | ||}|r |j !  |j "| |j#r4|jdd! |j  | ||tj}|r|d(r|d)r||d< | | j tj|\}}n&|r| j j$d*d+dd, |  j%d-7  _%| &| | j j  d S ).Nr\   rU   u:   Не указано наименование задачи!rZ   rq   r#   rv   epicrx   )r=  Z	cmf_ownerrs   ZresponsibleZwaiting_forrn   r>  u_   Пытаемся создать или обновить задачу по параметрам zcmf_import.pluginr   r   TZmerge_identic_namesFrt   r   r   z.lockx   )timeout)Z
filter_objdont_updateuB   Задача импортирована из файла: <a href="z" target="_blank">z</a> ()   )ru   Z	log_levelrZ   r   r   r   u'   Создали новую задачу z ext_id=z code=z name='r  u   Нашли задачу rr   ru   u   Невозможно импортировать задачу без проекта, создайте проект и укажите ID в файлеzERR-0079r   r   )'r   rR   r   r   r#   r   rb   r   r   r   r    r   pluginr>   hashlibZsha256encodeZ	hexdigestredis_dbZredislockr   r&   import_filerX   rU   rt   r   r   r   r  r   Zlistsloadre   r   r   r  rA  )r   ri   r\   r   r   r	  rk   r   r   rG  Zlock_keyrN  r  Ztask_is_newZcommentr   Zcomment_objZcomment_is_newr   r   r   _process_task  s    








(

"
..



zCmfPluginCsv._process_taskc                 C   s   d}t dd tj| _| j r$q| \}}|d krH|||f qz(| jj	d| d|  | 
| W q tk
r } z<|d7 }| jjd| d| d	| d
dd | jj  W 5 d }~X Y qX qW 5 Q R X || d S )Nr   F)Zinit_views_and_dsu   Импорт строки r&  r   u<   Не удалось импортировать строку z: z. zERR-0041r#   r   )r
   ZAPPZREDIS_DBrM  r   r,  rb   putr`   r   rQ  r   r   r   Zrollback)r   	row_queuerow_queue_errors
total_rowserrorsZrow_numZrow_dataexcr   r   r   _process_task_workerx  s*    
*z!CmfPluginCsv._process_task_workerc              
   C   s  ddl m} d}t  t  tjj|dgd}|| _tj	j|ddddd	ggd
gdgd| _
tdd | | j
D }tjdd}t }	g }
t| jD ]N}tj| jd|d  ||	|dd}|
| |  | jjd|  qt| | j
D ]f\}}| j r qj|jd r6|dkr6q||k rDq||krT qj||d |f q|d |
D ]}|  qx|	 s||	 7 }qW 5 Q R X W 5 Q R X |S )Nr   r	   r   )rQ   r   rV   rW   rC   r=   rB   rP   rX   rY   c                 S   s   g | ]}d qS r   r   r?   r:   r   r   r   rA     s     z2CmfPluginCsv.process_task_fork.<locals>.<listcomp>i  )maxsizez_process_task_worker r   )rS  rT  rU  )targetrU   kwargsu.   Параллельный обработчик r[   )NN)cmf.appr
   ZcmfutilZdisable_aclZdisable_notifyr   ra   rb   r   rc   rO  r   r0   queueZQueuerangeZthreading_max_forks	threadingThreadrX  re   startr`   r   r1   r,  rR   rR  r  empty)r   Zcmf_import_idstart_index	end_indexr
   rV  r   rU  rS  rT  threadsrh   threadri   r   r   r   process_task_fork  sV    	




$zCmfPluginCsv.process_task_forkc                 C   s   dd l }|jdddd| jjj d| jj d| d| d		gd
d
tddtddd}| jd|j d| d|  | j  |S )Nr   z/usr/bin/python3z	manage.pyshellz%plugin = models.CmfPluginCsv.get(id="z'");retcode = plugin.process_task_fork("z", r  z);Tz"/var/log/eva-import-subprocess.logza+z&/var/log/eva-import-subprocess.err.log)Z	close_fdsZstart_new_sessionstdoutstderru,   Запустили подпроцесс PID u)    для обработки строк с u    по )	
subprocessPopenr   rJ  rQ   rL   r   pidZ
log_detail)r   re  rf  rm  procr   r   r   _execute_task  s      & 
zCmfPluginCsv._execute_taskc                 C   s   | j }tdd | | jD }|| }|| }t }g }t|D ]H}|| }|| }	|d |k rn|	d8 }	n|	|7 }	| ||	}
||
 qD|D ]"}
|
	  |
j
r|  j|
j
7  _qt | }| jjd|dd d S )Nc                 S   s   g | ]}d qS rY  r   rZ  r   r   r   rA     s     z/CmfPluginCsv._process_tasks.<locals>.<listcomp>r   u.   Импорт задач выполнен за r'  r(  )r   r   r0   rO  r*  r+  r`  rq  re   Zcommunicate
returncoder  r   r`   r   )r   r   rU  Z
chunk_sizeZ	remainderr/  Z	processesrh   re  rf  rp  r1  r   r   r   _process_tasks  s(    
zCmfPluginCsv._process_tasksc                 C   s  | j jd }t| | jD ]\}}| j  r6 q| j jd rL|dkrLq| ||tj}| ||tj	}| ||tj
}|rxdddg}|D ].}||d}	|	r| j|	i }
||
d<  qq|
d	g }| ||tj}|r||kr|| ||
d	< |
d
g }| ||tj}|r|d}|s6|d}|drN|d |d< |d}|r|ds|d= |d}|s|d }| j|g }|r|| n,|  jd7  _| j jd|d  dddd || j|< | ||tj}|r|rd}|dr|d d }|drd|d d }|dD ]*}|||d}|| jkr8| j| q8|dr|d d }|dD ]*}|||d}|| jkr| j| qn,|  jd7  _| j jd|d  dddd |d|d|dd}||kr|| ||
d
< |
dg }|r@||kr@|| ||
d< |
d g }|rn||krn|| ||
d < q|r|| jkr| j| |r|| jkr| j| qd!S )"u   
        Из строк файла собирает данные проектов, спринтов, БП, компаний и пользователей для последующего импорта
        r\   r[   r   rn   rt   rU   r   r   r   r   rD  rx   r   u   Строка u   : Невозможно создать связь с Epic или родительской задачей. Укажите код или ИД задачи в файлеzERR-0080r#   r   zsystem.finish:startr7  r5  rE   )r3  r5  r6  r6  uy   : Невозможно создать связи задач. Укажите код или ИД задачи в файлеzERR-0081r   rv   rq   )r   rv   rq   r   r   N)r   rR   r1   r0   rO  r,  r   r   r"   r    r'   rb   r   r   r(   re   r#   r)  r  r   r8  r   r9  r   r   )r   r\   rh   ri   Zcompany_dataZperson_datar   r   r   r   r   Zproject_sprintsZsprint_dataZproject_workflowsr   Ztask_ext_idrx   r0  r)  r:  r7  Zrelated_tasksZrelated_taskZrelationr   Zproject_companiesZproject_personsr   r   r   _prepare_import_data   s    












z!CmfPluginCsv._prepare_import_datac                 C   sB  || _ |   g | _g | _i | _i | _i | _g | _tj	j
|dddddggdgdgd| _|   | | j | | j | | j |   |   |   | j jj
d	d
r| j D ]b\}}|sq| j jdt| d|  |rtjjj|t|gd qtjjjt|gd q| jr:| j d| j  | j S )NrV   rW   rC   r=   rB   rP   rX   rY   Zsend_invitesTu,   Отправляем приглашения u    пользователям: )argsu#   Ошибок обнаружено: ) r   r   r   r   r   r   r)  r9  r   rc   rb   rO  rt  r   r   r   rs  r2  r;  rR   r>   r   r`   r   r   r    Zregister_sdesk_clientZapply_asyncr   Zregister_personsr  r   )r   r   r   r   r   r   r   process_importz  s@    	zCmfPluginCsv.process_import)N)N)NNr   )2__name__
__module____qualname__r   ZloggingZgetLoggerClass__annotations__r  r   staticmethodr*   boolr<   r   r   r0   rm   r   rI   rd   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r2  r;  rA  backoffZon_exceptionZexpor   rQ  rX  ri  rq  rs  rt  rv  r   r   r   r   r      sV   

=?%b>
 B8*H
 
9zr   )rK   Zmathcopyr   r?  rK  pathlibr   typingr   r   r}  r   ra  r_  r   r*  rJ   rH   r   Zcmf.includeZmodules.settings.fieldsr   r^  r
   r   r   r   r   r   <module>   s&   