U
    he                    @   s   d dl mZ d dlT d dlZd dlZd dlZd dlmZ d dlZd dl	m
Z
 d dlZd dlmZmZmZmZmZmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dl m!Z! eee"j# ee"j$ ee"j% f Z&ej'G dd dZ(dd Z)G dd de!Z*dS )    )cmf_context)*N)Path)TemporaryDirectory)DictOptionalListCallableUnionTypeIterator)BeautifulSoup)cached_property)commit_all_dsinit_ds)	BaseModel)CmfPluginImportMixin)JiraApi)JiraBaseImportc                   @   s:   e Zd ZU dZeed< eed< eed< dd Zdd Zd	S )
EpicDatauD    Данные используемые при создании epic namekeyproject_keyc                 C   s
   t | jS N)hashr   self r   ./modules/jira/api_import.py__hash__    s    zEpicData.__hash__c                 C   s   | j |j kS r   )r   )r   otherr   r   r   __eq__#   s    zEpicData.__eq__N)__name__
__module____qualname____doc__str__annotations__r   r!   r   r   r   r   r      s   
r   c                    s    fdd}|S )Nc                    s    fdd}|S )Nc                    s   zD| j d  | j  r$W dS  | f||}| j j  |W S  tk
r   | j j  |  jd7  _| j d  Y dS X d S )Nz================== r      u   Ошибка )	
cmf_importlog	is_canceldpcommit	Exceptionrollback
has_errors	log_error)objargskwargsres)funcr   r   r   wrapper)   s    
z3catch_exception.<locals>.decorator.<locals>.wrapperr   )r6   r7   r   )r6   r   	decorator(   s    z"catch_exception.<locals>.decoratorr   )r   r9   r   r8   r   catch_exception'   s    r:   c                       s  e Zd ZU dZeed< eeef ed< e	dd fddZ
eeeef dd	d
Zdd Zdd Zeeeeee  dddZdd Zeeeef  dddZedd Zedd Zdd ZedddZee ddd Zee dd!d"Zee ed#d$d%Zdd(d)Zed*d+d, Zed-d.d/ Z ed0eed1d2d3Z!d4d5 Z"ed6dee#d7d8d9Z$dd:d;Z%ed<d=d> Z&ed?d@dA Z'e(j)ddBdCZ*dDdE Z+dFdG Z,dHdI Z-edJdKdL Z.eedMdNdOZ/dPdQ Z0dRdS Z1edTdUdV Z2edTdWdX Z3edYdZd[ Z4ed\d]d^ Z5d_d` Z6dadb Z7e8dcdddeZ9edfedgdhdiZ:edjedgdkdlZ;edmdndo Z<dpdq Z=edrddsdtZ>edudvdw Z?edxdydz Z@ed{ed|d}d~ZAeddd ZBeddd ZCeddd ZDeddd ZEeddd ZFdd ZGededddZHedddZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdddZTedgddZUedgddZVedgddZWedgddZXedgddZYdd ZZdd Z[edee8edddZ\dd Z]ddÄ Z^eedĜddƄZ_ddȄ Z`ddʄ Zadd̄ Zbdd΄ ZcddЄ Zddd҄ ZeddԄ Zfddք Zgdd؄ Zhddڄ Ziedۜdd݄Zjdd߄ Zkeddd Zldd Zm  ZnS )JiraAPIImportu;   Класс загрузки объектов через APIr0   _JiraAPIImport__jira_fieldsN)jirareturnc                    s   t  j|| || _d| _| jjjr*d| _tjjdd| _	i | _
i | _i | _i | _g | _g | _d| _td}| jjj|_|| jjj |   d | _d S )Nr   	accountIdsoftdevcoder   zatlassian.rest_client)super__init__r=   user_keyconncloudmodelsCmfActivitygetdefault_activityjira_global_settingsZepicsissue_relationssubtasksboardsselected_projectsr0   loggingZ	getLoggerr)   loggerZhandlersZsetLevellevel_prepare_multiprocessingr<   )r   r=   r3   r4   rR   	__class__r   r   rD   A   s$    

zJiraAPIImport.__init__)r>   c              	   C   s|   | j r| j S | j d}| rFt|}t|| _ W 5 Q R X n0| j	 | _ t|d}t
| j | W 5 Q R X | j S )Nfields.jsonw+)r<   r)   get_download_pathjoinpathexistsopenjsonloadr=   Z
get_fieldsdump)r   	file_pathfr   r   r   jira_fieldsW   s    
zJiraAPIImport.jira_fieldsc              	   C   sl   dd l }|| _| j d}| j dt  }t|d}t	| j| W 5 Q R X |
|| d S )Nr   rW   zfields.json.rX   )shutilr<   r)   rY   rZ   osgetpidr\   r]   r_   move)r   fieldsrc   r`   file_path_tmpra   r   r   r   update_jira_fieldsf   s    z JiraAPIImport.update_jira_fieldsc                 C   s(   | j  D ]}|d |kr
|  S q
d S )Nr   )rb   values)r   r   fieldr   r   r   _get_field_by_nameo   s    z JiraAPIImport._get_field_by_name)model
field_namer>   c                 C   s&   |sd S | j |gd}|r"|d S d S )N)Zfields_namer   )import_shop_fields)rm   rn   r5   r   r   r   _get_field_namet   s    zJiraAPIImport._get_field_namec                 C   s   dd l }dd l}dd l}dd l}|| _ || _tj| _tj| _|	 d | _
| jjd| j
d  ddd tjr~ttj| j
| _
| jjdtj dd | j}| jjdt|d	  d
dd tt|d | j
| _
| j
stdd S )Nr   r(   z
cpu_count=u%   , надо не менее 2 ядерT)	anonymouszconfig.IMPORT_PROCESS=zavailable_memory=i   @u-   Гб, по 2 Гигабайта на ядроl        u   Ресурсов системы недостаточно для импорта, обратитесь в техподдержку для дополнительной информации.)	threadingqueuemultiprocessingpsutilconfigZIMPORT_THREADSZthreading_max_forksZIMPORT_DOWNLOAD_THREADSdownload_threading_max_forks	cpu_countmax_processesr)   r*   ZIMPORT_PROCESSminZvirtual_memoryZ	availableintr.   )r   rr   rs   rt   ru   Zavailable_memoryr   r   r   rT   |   s     
 z&JiraAPIImport._prepare_multiprocessingc              	   C   sn   g }ddddddddd	}d
ddd}| j  D ]8\}}d| ||d }|||d||d q0|S )uO    Сопоставление настроек для модели models.CmfTaskr   textprioritystatusZ
alarm_dateZdeadlinecmf_modified_atcmf_created_at)Zsummarydescriptionr}   r~   Zcustomfield_10015Zduedateupdatedcreatedz.namez.watchCountz.votes)r}   ZwatchesZvoteszfields. N)model_field	json_path	ext_field)rb   itemsrJ   append)r   Zissue_settingsZdefault_local_attrs_mappingZadditional_json_pathZcustom_field_keyZcustom_fieldr   r   r   r   _get_issue_import_settings   s,    

z(JiraAPIImport._get_issue_import_settingsc                  C   s    dddddddddg} | S )Nr   displayNamer   r   emailemailAddressdoes_not_workactiver   )Zuser_settingsr   r   r   _get_user_import_settings   s
    z'JiraAPIImport._get_user_import_settingsc                  C   s    dddddddddg} | S )Nr   r   r   
cmf_authorauthorr|   renderedBodyr   )Zcomment_settingsr   r   r   _get_comment_import_settings   s
    z*JiraAPIImport._get_comment_import_settingsc                 C   sX   dddddddd}||kr$|| S | d	}t|d
kr>dS | j|d
 i ddS )N   ИмяZEmailu   Активныйu   Созданоu
   Автор
   Текстu   Ключ)r   r   r   r   r   bodyr   .r(   r   r   )splitlenrb   rJ   )r   Zjsonpathmappingr   r   r    _get_setting_title_from_jsonpath   s    	
z.JiraAPIImport._get_setting_title_from_jsonpathTc                 C   s  |sd S | dD ](}t| ts& d S | |} | s d S q|rvt| trvdddg}|D ]}|| krX| |   S qXdS |rt| trg }| D ]f}d|kr||d d  qd|kr||d d  qd|kr||d  q|r|t| qd|S | S )	Nr   r   r   r   r   inwardIssueoutwardIssue,)r   
isinstancedictrJ   listr   r&   join)r2   r   to_strrn   Z
str_fieldsZ	str_fieldresultZrelated_objr   r   r   _get_file_val   s6    



zJiraAPIImport._get_file_valc                    sV  g  t ttt f tg tt f ttd fdd}jdg j 	d}d}|
 r D ]$}|d D ]} qqz|rh qqhdD ]} qq|sd	d
 jjddD }|r|d }dd
 jdD d }|std||jtj |std||jtj ddddddg}||jtj  dg d  S )u-    Инициализация настроек )objssettings_funcrm   r>   c                    sz   | D ]p}| }|D ]H} ||d |d< ||d |d< |d |d< |j|d< q |j|d |  S d S )Nr   Zfile_valr   titleicon)r   rg   )r   rp   r   r   r   verbose_name)r   r   rm   r2   Zobj_settingssettingr   r   r   r   _get_settings   s    z:JiraAPIImport.tmplt_import_settings.<locals>._get_settingszplugin.plugin.*projectsNidusersc                 S   s   g | ]}|qS r   r   .0r2   r   r   r   
<listcomp>  s     z7JiraAPIImport.tmplt_import_settings.<locals>.<listcomp>r(   limitr   c                 S   s   g | ]}|qS r   r   r   r   r   r   r     s     uS   Не найдено ни одной задачи, импорт невозможенua   Не найдено ни одного пользователя, импорт невозможенz2022-05-22T15:22:22.593+0300r   u!   Электронная почта)r   r   r   )r   r   r   selectedObjects)r   value)r
   r   r   r   r	   	TypeModelr)   load_fieldsrY   rZ   r[   _get_projectsget_project_tasks_simple_getr=   
get_issues	get_usersr.   r   rH   CmfTaskr   	CmfPersonr   
CmfCommentr   )r   r   Zdump_dirtaskprojectusertasksZcomment_exampler   r   r   tmplt_import_settings   sJ      z#JiraAPIImport.tmplt_import_settingsc                 C   s   |  | jjd }ddg g gdg}| jjddD ]}t|tjj d D ]f\}}|d s\qJ| 	||d	 }| 
|d d
 |}|d d |d d  |d d d | qJq2|S )Nimport_settingsu   Задачиzcalendar-today)r   r   titlesrows   r   rg   r   r   rn   r   r   captionr   )Z_normalize_settingsr)   json_settingsr=   r   	enumeraterH   r   r   r   _normalize_jira_valuer   )r   settingsr   issueZnumr   r   r   r   r   preview/  s    zJiraAPIImport.preview)r   r>   c                 C   s\   i }|D ]N}|d sq| j ||d dd}| |d d ||d}|||d d < q|S )uC    Преобразование настроек для модели r   r   F)r   rn   r   )r   r   rJ   )r   r2   r   Znormalized_objr   r   r   r   r   _normalize_obj>  s    zJiraAPIImport._normalize_objsprintkanbanc           
      C   s   dd|j gg}|dr*|dddg n|dd|g tjj|d}| jjjj d|d  }tj	| jtj
|d	 ||||d
|d|ddd|gd\}}	|	r|d	 |_|jdd |S )NZtree_parent_id==completeDatesys_typearchivefilter::r   r   	startDateendDate)r   parenttree_parent	list_typeplan_start_dateplan_end_dateext_idr   Z
filter_objTZsave_import)r   rJ   r   rH   	CmfFolderr)   pluginsource_hashr   process_any_table_fieldsCmfListr   save)
r   r   r   Zparent_sys_typer   _filterr   r   Zlist_objnewr   r   r   _process_listJ  s*    


zJiraAPIImport._process_listu8   Обработка наблюдателей задачиc                 C   s   |  |D ]j}| jjjr(| |d }n| |d }|sHtd| ||jks
||jks
||jkrhq
|j	
| q
t  dS )u;   Добавляем наблюдателей в задачуr?   r   uI   _process_watchers: Не найден наблюдатель задачи N)_get_issue_watchersr=   rF   rG   _get_personCmfErrorresponsibler   	cmf_owner
spectatorsr   commit_with_event)r   	issue_objr   watcherpersonr   r   r   _process_watchersc  s    
zJiraAPIImport._process_watchersu#   Обработка вложенийc                 C   s  ddl m} dd l}t|d  d}d}| r||}| D ]}zz|	drlW W qJ|d d D ]}	|	d	 |krx qqxt
j|}
t
jj|
|d
dddgd}|st
j| j|d|
d}|jrl|	r| |	d | j |_|	d |_||d}|jdd || |jdd |	rX|j|	d ksXtd|j d|	d  d|j  W 5 Q R X W nx tk
r   | jjd| dd|d |j  |d7 }Y n8   | jjd| d|d | jj  |d7 }Y nX W 5 | jdd X qJW 5 Q R X | |D ]}zzt
j|d }
t
jj|
|d }|sTt
j| j|d|
d}|jr|jdd |  t |d! |j! t
j"jj#$ }|%|j&}|'  |j  W n8   | jjd| d|d | jj  |d7 }Y nX W 5 | jdd X q|S )"Nr   )RDisk
issue_pathz /attachments/all_attachments.zip
attachment	processed/rg   filenameimport_originalurlZurl_preview_imgZurl_preview)r   r   rg   T)r)   r   r  r   r   r   r   sizeu   Текущий размер z != u    из метыu7   Обранужена проблема вложения uI   , размер файла не совпадает с метой из JIRAzERR-0034r2   r(   :   Не удалось обработать вложение zERR-0035	file_name)r   r   r`   )(Zrdisk.rdiskr   zipfiler   r[   ZipFileZnamelistr)   inc_statendswithrH   CmfDocument_get_filenameCmfAttachmentrJ   r  r   rE   r   r   r\   r   Zupload_stream_filest_sizeAssertionErrorr,   r-   r1   r/   _get_issue_attachmentsZ
upload_dirrc   copyZfull_path_fileZCmfRFileZdata_driverZget_rdZ	get_rfileZ
_file_namemake_preview)r   r   
jira_issuer   r  Zall_attach_zip_patherrorsZmyzipZzip_attach_nameattach_infoZattach_namer   Zattach_fattachment_infoZrdiskZrfiler   r   r   _process_attachmentss  s    






, 
   z"JiraAPIImport._process_attachmentsuB   Обработка упоминаний пользователей)r|   r>   c                 C   st  ddl m}m} |sdS t|d}|jddidD ]6}z|jdrX| |jd }n||jd	r| |jd	 }|jd
 |jd< |jd	 |jd< n>||jd }||j}	| 	|	d d 
 }
| |
| j }|jd |jd< |j|jd< d|jd< |jj|jd
< |jj|jd	< W q2 tk
rh } z0|  jd7  _| jjd| d| d|d W 5 d}~X Y q2X q2t|S )u]   
        Упоминания пользователей
        confluence-userlink
        r   )urlparseparse_qsNhtml.parserclass
user-hoverattrsdata-account-iddata-usernamezdata-linked-resource-idzdata-linked-resource-id_origzdata-username_orighrefr   	href_origTcmf_convertedr(   u)   Ошибка обработки тега : zERR-0036r  )Zurllib.parser  r  r   find_allr  rJ   r   query_get_user_info_from_dumplowerrE   r"  r   r   loginr.   r0   r)   r1   r&   )r   r   r|   r  r  doc_souptagr   Z
parsed_urlr'  	user_infoer   r   r   _process_mentions  s8    


 zJiraAPIImport._process_mentionsc                 C   s   t jj}|| jj d| }|d k	r2t|S | dD ]T}|| j	|krX|  S |dd
 |krt|  S |dd
 |kr<|  S q<td| d S )N:user:r   r   r   usernameuQ   Не нашли информацию по пользователю в дампе )APPREDIS_DBredisrJ   r)   r   pickleloadsr   rE   r)  r.   )r   user_idredis_dbr-  r   r   r   r(    s    

z&JiraAPIImport._get_user_info_from_dumpu#   Конвертация ссылок)r|   r   c                    s  |s|S t |}|dd D ]x}|jdrF| jjd|  q|drv|jd drv| jjd|  q| jjd|  |dr|jd }n
|jd	 }t	j
|d
d dd }tdt	j
|dd }	|	r(|	d  |d d }
tt fdd|
d }|r(|d }tj|}tjj|dg|d}|r|d	r|jd	 |jd< |j|jd	< d|jd< t|jd	 }|r|d r|d drd|_d|jd< d|jd< d|jd< |dr|jd |jd< |j|jd< d|jd< | jjd|j  qd|jdd kr|jd d
d dd }| |}|r|jd |jd< |j|jd< d|jd< | jjd|j  qt|S )!Nc                 S   s   |  dp|  dS Nr"  srchas_attrr,  r   r   r   <lambda>      z.JiraAPIImport._process_links.<locals>.<lambda>r$  u   Уже обработали r"  #u   Это якорь u&   Обрабатываем ссылку r:  r   ?r   (/attachment(?:/content)?/(\d+)(?:/)?(.*)r(   rg   r   c                    s   |  d kS Nr   rJ   itemZ	attach_idr   r   r>    r?  r  r  )r   rg   r   Zsrc_origTZvideoZcontrolsz100%widthZheightr#  u   Заменили на z/people/r   )r   r&  r  rJ   r)   rR   infor<  
startswithurllibparseunquoter   researchnextr   rH   r  r  r  sgetr  	mimetypes
guess_typer   r   r"  r&   )r   r|   r   r  r  Z	text_soupr,  r  r  	url_matchattachmentsattachZ
attach_obj	mime_type
account_idr   r   rH  r   _process_links  sd    

 
 





zJiraAPIImport._process_linksc                 C   s  | j jd|  | jjjrB|d dkrB| j jd|d   | || jt	j
j d }d| j jjj d|| j  d}|d d}t|d	kr|d
 nd|d< t|d	kr|d	 n|d
 |d< ddg}t	j
jdd|d g|d}|s~t	j
jddd| dg|d}|s~t	j
jdd|d g|d}	t|	d	krr| j jd|d  dt|	 ddd |  jd	7  _g }	|	sdd|d g}
t	j
j|
|d}	|	st|d	krdd|d
 g}
nHt|d	krddd|d
 gdd|d	 ggdd|d	 gdd|d
 ggg}
t	j
j|
|d}	t|	d	krT|  jd	7  _| j jd|d  dt|	 ddd |	rd|	d
 }n| j d|d  tj d }|s"|rd!}d	}|d }t	j
jdd| g|dr| j d"| d#tj |d d$\}}| d%| d$| }|d	7 }qt	j
||| j d!d&}nd |fS |r|jrL|D ]}t||||  q4|jrr||jkrx|j | |_n||_t	j }t	j }|j !| |j !| d!|_"|d' d( D ]}| jjjrd|d)  d}nd|d  d}d| j jjj | }t	jjddd| dgdgd}|sBt	jjdd|d gdgd}|sbt	j|| j d!|d |d*}|jrt|d |_#|js||_n||jkr|j | |_|j$d!d+ |j !| q|j%r|j$d!d+ ||fS ),Nu0   Импортируем пользователя ZaccountTypeZ	atlassianu   Неизвестный тип rg   r   r    r(   r   r   Z
first_name	last_namer   rg_member_ofr*  ILIKEr   r   rg   r   LIKE%u+   Пользователей с почтой z > zERR-0037r   obj_typer   ORu+   Пользователей с именем uM   Не нашли пользователя среди существующих FTuQ   Обнаружена учетная запись с дублирующим email u   , добавляем цифру@+)r   r*  r)   r  groupsr   groupId)r   r)   r  r   import_raw_jsonr   )&r)   rR   rJ  r=   rF   rG   warningr   r   rH   r   r   r   r   rE   r   r   rJ   r   r1   r0   r*   rQ   INFOr)  WARNINGr  setattrr   CmfPersonGroup
jira_group
user_groupr]  r   Z
user_localr   r   
is_changed)r   r   ZcreateupdateZ	user_dictr   r   rg   r   Zpersonsr   
is_creatednr*  Zprefix_emaildomainr   ro  rp  Z
group_infogroupr   r   r   _process_person'  s        
 

   
zJiraAPIImport._process_personu-   Обработка пользователейc              	   C   s   | j jjdds(| j jdtjd d S t }| dD ]}z^| j 	 rPW  d S | 
|\}}| j  jd7  _|jr|js|jds|r||jj W q8   |  jd7  _| j jd| d	d
d Y q8X q8|r| j jjddrttjjt|gd d S )N
load_usersTuA   Не грузим пользователей из-за опцийrS   r   r(   z.evateam.ruu@   Не удалось загрузить пользователя zERR-0038r   rb  Zsend_invites)r3   )r)   r   r   rJ   r*   rQ   rl  setr   r+   rw  imported_object_countr   r   r  addr0   r1   Zschedule_deferred_jobrH   r   Zregister_personsr   )r   Znew_user_emailsr   r   rs  r   r   r   _process_users  s,    
 zJiraAPIImport._process_usersu#   Обработка статусовc                 C   s   |  dD ]}| j r dS | jjjr2|d }n|d d }| jjjj d|d  }tj	j
|d}|sdd|d gd	ddgg}tj	j
|d
}|stj	|d | jd}||_t||_|d |_|jdd | jj  | j jd7  _q
dS )uc   
        Грузим статусы из Jira и сопостовляем с нашими
        statusesNstatusCategoryr   r   r   r   r   r   r   )r   r)   Tr   r(   )r   r)   r+   r=   rF   rG   r   r   rH   CmfStatusCoderJ   r   r   get_status_typestatus_typer   r   r,   r-   r{  )r   r~   r  r   Zcmf_status_coder   r   r   r   _process_statuses  s*    




zJiraAPIImport._process_statusesc                 C   s  t  }d}d}| |d D ]}| jjjj d|d  d|d  }d|d  d|d  }tjjdd	|gd
}|d dkrd}	n|d dkrd}	nd}	|stjj|	d}
tj||
| jd}||_|j	dd |s|d dkr|}|s|d dkr|}d| jjjj d|d  d}|||< | j
|d dD ]6}|d r.|d |d d d kr.| || q.tjjdd|gdddggdgdD ]@}tjjdd|jgdd|gdddggd
sq|jdd qq| jjjj d|d  }d|d  }tjj|d}|s(tjjd d}
tj||
| jd}||_||_||_|j	dd tjj|d!D ]}|  qT| D ]b\}}| j r qtjjdd"d#| d#gd
}||d$|| jd%}tjf |}|j	dd ql|S )&u)  
        У простого проекта воркфлоу привязан к issue type 1 к 1
        Поэтому надо получит все типы привязанные к проекту, на каждый тип создать WF и замапить через схему
        Nr   
::SIMPLE::r   (   Simple-схема для проекта r       и типа r   =r   hierarchyLevelr(   task.epic:defaultr   task.agile:defaultdefault.system:defaultrA   r   templater)   Tr   rA  
project_idZusagesZ
issueTypesworkflowr   r  r_  !=forcer  softdev:default	scheme_wfr`  ra  r   
logic_typeZtarget_workflowcmf_model_namer  r)   )r   _get_issue_types_for_projectr)   r   r   rH   CmfWorkflowrJ   r   r   _get_statuses_for_project_create_status	CmfStatusr   r  deleteCmfSchemeWfdefault_task_workflowZ!default_subtask_workflow_workflowCmfSchemeWfRuler   r+   CmfLogicType)r   Zjira_project_info	issue_mapZdefault_task_wfZdefault_subtask_wf
issue_typeworkflow_ext_idworkflow_namer  rB   r  issue_type_ext_idjira_statusr~   Zscheme_ext_idZscheme_nameschemerulelogic_type_ext_idr  	rule_dictr   r   r   #_create_schemewf_for_simple_project  sx    $$
 
 z1JiraAPIImport._create_schemewf_for_simple_projectc                 C   s0  | j jjj d|j d|d  }| j jjj d|d  }tjj|d}t|d }|srtj||d | j d}||_	|j
dd tjjd	d
|gd}|stjjdd|gdd|ggd}|stjjdd
|d gdd
|ggd}|stj|| j |d}||_|d |_|d |_||_||_	|j
|j d |S )Nr   r   r  r  r   )r   r   r)   Tr   r   r   r   r  r  status_code)r  r)   r  r   Z	only_data)r)   r   r   r   rH   r  rJ   r   r  r  r   r  r   r   r|   r  is_new)r   Zjira_status_datar  status_ext_idr   r  r  r~   r   r   r   r    s6    "

zJiraAPIImport._create_statusc                 C   s<  | j jjj d|d d  }tjj|d}|d d }|sztjjdd}tj|d ||d	d
|| j |d}|jdd t }| j|d dD ],}d|d kr| j jjj d|d  d|d  }d|d  d|d  }	tj	jdd|gd}
d| j jjj d|d  d}|
sxtj
jddd| dgd}tj	j|jdd  dd}|sftj	jdd}tj	||| j d}
|	|
_|
jdd |
||< |d D ]"}|d d  |d< | ||
 qqtjj|d!D ]}|  q| D ]P\}}
tj
jddd| dgd}||
d"|| j d#}tjf |}|jdd q|S )$Nr   jira_workflow_schemer   r  rJ  r  rA   r   r   r   )r   r   r|   ri  r)   r  Tr   r  	issuetyper   r  r  r  r   r  r   r`  ra  :r   z:defaultr  r  r~  r  r   r  r   r  )r)   r   r   rH   r  rJ   r   r   r  r  r  rB   r   r   r  r  r   r  r   )r   project_infor   Z	wf_schemeZwf_scheme_infor  r  r  r  r  r  r  r  r  r  r  r  r   r   r   _process_wf_scheme-  sZ    

$  z JiraAPIImport._process_wf_schemec              	   C   sV   d}t dd4 | j rq>| }|dkr.q>|| |7 }qW 5 Q R X || d S )Nr   FZinit_views_and_dsDONE)r   r)   r+   rJ   _process_issueput)r   Zissue_queueZissue_queue_errorsr  r   r   r   r   _process_issue_thread[  s    
z#JiraAPIImport._process_issue_threadu   Обработка теговc           
      C   s,  ddl m} t }| j|d | |d dD ]4}| j rB d S |d dr.||d d }q.|D ]}|	dd	d	d
}||ddd}z\dddd| dgdd|gddd| dgg}t
jj|d}|st
j|d}|jdd W qh tk
r$ }	 ztd| d|	  W 5 d }	~	X Y qhX qhd S )Nr   )translitr   r   rg   labelsr[  _r@  r   ruT)Zlanguage_codereversedrd  aliasr^  "z"%r   r   r8   r   u*   Не удалось создать тег r%  )Ztransliterater  rz  r   _count_project_tasksr)   r+   rJ   unionreplacerH   ZCmfTagr   r.   rQ   rj  )
r   r  r  tagsr   Ztag_nameZ
name_aliasr   Ztag_objr.  r   r   r   _process_tagsg  s,     
zJiraAPIImport._process_tags)project_structr  c                 C   s  t jjdd|d gddgd}|r|jj|d ksF|jr|j|d kr|d  d|d  d|d< | jjd|j	 d	|d   n|js|d |_|
  d
|d< t jj| jjjjd|d< t jj|d | d}|st j| j|d |d d
d}|jr,|D ]}t||||  q|dr,d|_|j}|
  |rbt jj|dD ]}|jd
d qN| |d D ]L}| jjjj d|d  }t jj|d}	|	st jjddd gdd|d ggd}	|	st j|d | jd
d}	||	_|d |	_	|d|	_|	j
d
d t jj||	d}
|
s2t j||	| jd}
g |
_|
j
d
d |dg D ]\}|d dkr| jjjr| |d  d! }nFz| |d" }W n2   | jjd#|	 d$|d"  d%|d& d }Y nX |r|
j | n| jjd'|  n|d d(kr| jjjr$d|d) d*  d}nd|d  d}d| jjjj | }t j!jdd+d,| d,gd}|rz|
j | n(| jjd-| d.d/|d& |  j"d07  _"nt#d1qP|
j
d
d qp| $  | %| | &| | $  | j'|d2 | (||_)t*|d3  d4}t+|}t,-|}W 5 Q R X |r\| jjjj d|d  }t j.j|d|_/|j
d
d | 0| | j1 rd S t2  | 3| | $  | 4| | j j5d07  _5| $  |S )5Nr   r   r  r   r_  z ()u   Проект с именем u8    уже существует! Переименуем в TZtask_allow_multiple_sprints)Zexit_idui_form_schemer   rg   )r)   r   r   r  	isPrivateprivate)r   )ZTEXKOM_db_deleter   r   r  r   )r   r)   r  r   r   )r   project_role)r   r  r)   actorstypeatlassian-user-role-actorr-  r?   r   uX   Не удалось найти и добавить пользователя в роль u    проекта:: zERR-0039r  uR   Не удалось привязать пользователя к проекту zatlassian-group-role-actorZ
actorGrouprh  r`  ra  u<   Не найдена группа пользователей u#    для проектной ролиzERR-0040r(   u&   Неизвестный тип ролиr  project_dir/issue_security_scheme.json)6rH   
CmfProjectrJ   r  r   r   r)   rR   rj  r   r   CmfUiFormSchemer   r   keysr  rm  Zperm_policyr  r   r   r  _get_project_rolesCmfProjectRoler|   ZCmfProjectRoleAssignmembersr=   rF   rG   r   r1   r   rn  r0   r.   _calc_progress_process_versions_process_componentsr  _process_permissionsZproject_perm_schemer   r\   r]   r^   CmfSecurityLevelSchemesecurity_level_scheme_process_tasksr+   r   _process_boards_process_sprintsr{  )r   r  r  project_objr   r  r   	role_infor   roleZrole_assignactorr   Z	sub_group	dump_filera   r  r   r   r   _process_project  s    "
 "
 
 





zJiraAPIImport._process_projectc                 C   s   dd l }|jdddd| jjj d| jj d|d  d	| d
tj dgddtddtddd}| jd|j	  | j
  |S )Nr   /usr/bin/python3	manage.pyshellz&plugin = models.CmfPluginJira.get(id="z(");retcode = plugin.process_issue_fork("", "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Popenr)   r   r   rv   IMPORT_OBJ_CNTr\   r*   pid
log_detail)r   r  doner  procr   r   r   _execute_task  s    
2  
zJiraAPIImport._execute_taskc           
      C   s  dd l }| jjd| j  d}| |d }g }t| jD ]0}| ||}|tj	7 }|
| ||kr> qpq>||k r|d t|D ]L}| }|d k	r|  j|7  _|| | ||}	|tj	7 }|
|	 qqpt|D ]"}|  |jr|  j|j7  _q| jjd d S )Nr   uD   Грузим задачи в несколько процессов: r   r(   u0   Закончили обработку задач)timer)   rR   rJ  ry   r  ranger  rv   r  r   sleepr   pollr0   removecommunicate
returncode)
r   r  r  r  Ztask_cntprocessr  r   r  new_procr   r   r   r     s4    




zJiraAPIImport._process_tasksu#   Обработка проектовc              
   C   s  t jjddjj}|  D ]}zv|d dd | jD kr@W qd }| j r\t	  W  d S |di }|r~| 
|| j }n
ddd	}|d
 dkrt jjdd}nL|d
 dkrt jjdd}n0|d
 dkrt jjdd}ntd|d
  d| jjjj d|d  |d< |d |jj|d ||d ||d |d}|d }|rZ| |}	|	|d< n0| jjjj d|d d  }
t jj|
d|d< | ||}W q tk
r   t  |  jd7  _| jjd| dd d! Y qX qd S )"Nr@   rA   r   c                 S   s   g | ]}|d  qS r   r   r   r   r   r   r   )  s     z3JiraAPIImport._process_projects.<locals>.<listcomp>leaddefault_import_jira@evateam.comdefault_import_jirar   r   projectTypeKeybusinessproject.base:defaultsoftwareproject.agile:defaultservice_deskproject.servicedesk:defaultu$   ERROR! Проекты с типом 3    временно не поддерживаютсяr   r   r   r   r   r   r  r|   activityZtask_code_prefixr   r   ri  
simplifiedr  r  r  r(   <   Не удалось импортировать проект ERR-0041r  rb  )rH   rI   rJ   r   r   r   rP   r)   r+   r   r   rE   r  r.   r   r   r  r  r  Zrollback_purge_eventr0   r1   )r   r  r  r  project_leadr   r  r  Zproject_simplifiedr  r   r   r   r   _process_projects$  s`    


 zJiraAPIImport._process_projectsc              
   C   s  d }t jjddjj}|  D ]r}z(| j r:W  d S |d dd | jD krVW q| jj	j	j
 d|d  |d< |di }|r| || j }n
d	d
d}|d dkrt jjdd}nL|d dkrt jjdd}n0|d dkrt jjdd}ntd|d  d|d |jj|d ||d ||d |d}| ||d< | ||}W q tk
r   t  |  jd7  _| jjd| ddd Y qX qd S )Nr@   rA   r   c                 S   s   g | ]}|d  qS r  r   r   r   r   r   r   k  s     z7JiraAPIImport._process_projects_box.<locals>.<listcomp>r   r   r  r  r  r  r  r  r  r  r  r  r  u$   ERROR! Поректы с типом r  r   r   r   r  r  r(   r  r  r  rb  )rH   rI   rJ   r   r   r   r)   r+   rP   r   r   r   rE   r  r.   r  r  r   r0   r1   )r   r  r  r  r  r   r  r  r   r   r   _process_projects_boxc  sT    
 z#JiraAPIImport._process_projects_boxu   Обработка досокc           
   
   C   s  |  |d D ]}z| j r*W  dS tjj|d d}| jjjj d|d  |d< tjj|d dddd	gd
}|stj|d | jd}|d |_	|d |_
||_||_|jdd |j  |jr|jD ]}|  q|j  |d d d D ]}ztj|d || jdd}|jdd |d D ]P}| jjjj d|d  }tjj|d}	|	sntd| d|j|	 q,|jdd |j  W q tk
r   |j  | jjd| d|d Y qX q| j jd7  _W q   | jj  | jjd| d|d Y qX qdS )z
        https://bcrm.carbonsoft.ru/desk/favorites/Document/DOC-007367#spec-006348-b
        https://developer.atlassian.com/cloud/jira/software/rest/api-group-board/#api-rest-agile-1-0-board-boardid-quickfilter-get
        r   Nr   r  r   kanban_board_columnsri  r   r   r  r   r)   r   rJ  Tr   ZcolumnConfigcolumns)r   r   r)   r  r~  u   Не найден статус u    для колонкиuD   Не удалось создать колонку для доски zERR-0042r  r(   u:   Не удалось импортировать доску zERR-0043)_get_project_boardsr)   r+   rH   r  rJ   r   r   ZCmfKanbanBoardr   ri  r   r   r   r,   r-   r  r   r  ZCmfKanbanBoardColumnr  r  Zmapped_status_codesr   r/   r1   r{  )
r   r  boardr   Z	board_objcolZ	board_colr~   r  Zstatus_globalr   r   r   r    sd    
 





 
  zJiraAPIImport._process_boardsu#   Обработка спринтовc                 C   s  t jj|d d}t jjdd|gdddggd}t jjdd|gdddggd	gd
}t jjdd}| |d D ]}| j r d S | jjjj	 d|d  }t j
j|dddddddddg	d}|st j
|d| j|d}|jr||_|d |_|d|_|d|_|jr|jdd |d dkrZ||_|jsJd|_|jdd |jd|_n"||_|d dkr||jd |_|jr|jdd t  | jjd!|j d"t|d#   |d# D ],}	| jjjj	 d|	 }
t jj|
d$dd%gd}|r|d&r| jjjj	 d'|j }t jj|d(d)d*gd}|sJt j|| jd+}d,|_d-|j d.|j d/|_ ||_!|jr|j|j" d0 |j#dkrt|j$d1kr|j%&| n|j%&| n0|  j'd17  _'| jj(d2|	 d3|d  d4|d5 q|jdd t  | j j)d17  _)qnd S )6Nr   r  r   r   r   r   r   r   tree_node_is_branchr_  zlist.agile_sprint:defaultrA   r   r   r   r  r  r  r   r   r~   r  T)r   r  r)   r  r   r   r   stateclosedCLOSEDr   ZIN_PROGRESSu0   Добавляем задачи в спринт r%  issueslistscache_status_typer   z::comment-sprint:	log_levelr|   r   r!     uB   Задача была в архивном спринте <a href="" target="_blank"></a>r  r(   u-   Неизвестная задача issue_id=u    в спринте zERR-0044r  )*rH   r  rJ   r   r  _get_all_sprintsr)   r+   r   r   r   r  r  r   r   r   rq  r   r   r&  r  Zget_default_statusr~   r   rR   rJ  r   r   r   r   r-  r"  r|   r   r  r,  r+  r  r   r0   r1   r{  )r   r  r   Zsprint_folderarchive_folderZsprint_logic_typer   r   Z
sprint_objZissue_idZissue_ext_idr   comment_ext_idcommentr   r   r   r    s    "
     
$ 
zJiraAPIImport._process_sprintsc                 C   s$   |sd}|sd}| d| d| S )Nu   Не указаноr%  u    ➔ r   )r   r   	old_valueZ	new_valuer   r   r   _simple_html_diff  s
    zJiraAPIImport._simple_html_diffc                 C   s   |dkrd S z|  |}W n,   | jjd| dddd tj Y S X | |dd\}}|s| jjjdrt	j
j| jjd d	}| jjd| d
| tjd n.| jjd| dddd tj}|  jd7  _|S )Nunknownu6   Не найден пользователь user_id = "u9   ", в дампе, указываем системногоzERR-0045ZCmfUserrb  FZdefault_user_idr  uA   ", ставим пользователя по умолчанию ry  uc   ", указываем системного , в дампе, указываем системногоr(   )r(  r)   r1   gZsystem_userrw  r   r   rJ   rH   r   r*   rQ   rl  r0   )r   r7  r   r   r  r   r   r   r   
  s,       zJiraAPIImport._get_person)	dump_pathc                 C   s   z|  |W S  tk
r   z|d}| rt|dB}|D ]6}t|}||| j kr@|  W  5 Q R  W  Y S q@W 5 Q R X | j	|}|rt|d}|
t|d  W 5 Q R X |W  Y S W n$   | jjd| tjd Y nX Y nX d S )N
users.jsonrr  
uM   Неудалось сдампить пользователя по ключу ry  )r(  r.   rZ   r[   r\   r]   r6  rE   r=   Zget_user_infowritedumpsr)   r*   rQ   rl  )r   r7  r9  Z
users_pathra   rowr2   r-  r   r   r   _get_user_info   s$    

&zJiraAPIImport._get_user_infou,   Обработка журнала работ)r   c                 C   s*  dd l }| jjd | |D ]}t }d|d< | j|d< | |d | j |d< |d |d< | |d	 | j |d
< ||d< |d |d< |d d |d< |dd|d< | jj	j	j
 d|d  |d< ||d< d|d< tjj|d d}|s tjf |}|jj|j|jjd |_|jdd q d S )Nr   u*   Загружаем журнал работr(  r~   r)   r   r   r   updateAuthorcmf_modified_byr   started
start_dateZtimeSpentSeconds<   
time_spentr4  r   r|   r   r   r   ri  Zremaining_estimater  )ZminutesTr   )datetimer)   rR   rJ  _get_issue_worklogsr   r   rE   rJ   r   r   rH   ZCmfTimeTrackerHistoryrD  r   Z	timedeltarF  Zend_dater   )r   r   r   rG  worklogZtimetracker_historyhistoryr   r   r   _process_issue_worklog5  s.    


z$JiraAPIImport._process_issue_worklogu8   Обработка комментариев задачиc           	      C   s  d}d}|  |D ]}|d7 }| jjjj d|d  }tjj|d}|rl|jsl| jjd| d|d q|stj||| jd	d
}| 	|d | j
 |_|j|_| 	|d | j
 |_|d |_|d |_||_| ||d |_| |jj|||_||_|drz|d7 }|d d dkrNtjj|d d d}|j| d	|_n,| jjd|d  d|d |  jd7  _q|jd	d | jdd q| jd| d|  d S )Nr   r(   r   r   r  uN   Комментарий уже есть, и правился в системе zERR-0046r  T)r   r   r)   r  r   rA  r   r   r   Z
visibilityr  r  r   r8   uL   Ошибка обработки приватного комментария zERR-0047r   r4  r   u   Обработано u:    комментариев, из них приватных )_get_issue_commentsr)   r   r   rH   r   rJ   r  r1   r   rE   r   r   rB  r   r   r   r/  r|   rZ  r   ri  r  r   r   r  r0   r   r
  r*   )	r   r   r   cntZprivate_cntr4  r   Zcmf_commentr  r   r   r   _process_issue_commentsN  sL    
 

 z%JiraAPIImport._process_issue_commentsu0   Обработка плагинов задачиc           	      C   s   |j jp
d}| |D ]}|d dkr|d rt|d}|jdddid	}|d d
D ]N}|sbqX|drx|d}n|jdddid	}||dd   || qX|| t||j _q|j	r|j
dd d S )Nr   r   z&com.railsware.SmartChecklist.checklistr   r  Zulr  ztox-checklistr  r<  -liztox-checklist--checkedr(   Tr   )r|   r   _get_issue_propertiesr   Znew_tagr   rK  r   r&   rq  r   )	r   r   r   r|   Zissue_propertyZsoupZ	checklistvalrP  r   r   r   _process_propertiesv  s"    


z!JiraAPIImport._process_propertiesc              	   C   sb  dd | j tjj d D }|d d D ]2}| jjjj d|d  }d }|drl| |d | j	 }n| jj
d	|  |d
 |d|d}|d D ]h}|d }	||d }
|
r|
d rd}	| |	|d |d }d|kr||d< q|d  d| |d< qtjj|ddddddgd}|s8tj| jd|d}|D ]}t||||  q<|  q(d S )Nc                 S   s   i | ]}|d  |qS )r   r   )r   rk   r   r   r   
<dictcomp>  s      z2JiraAPIImport._process_history.<locals>.<dictcomp>rg   	changelog	historiesz	::historyr   r   u   Аудит без автора r   r(   )r   r   r-  r   r   rk   r   r   Z
fromStringZtoStringr|   z<br>r)   r   r   r-  r   r  T)r)   r  r   )r   rH   r   r   r)   r   r   rJ   r   rE   rR   rj  r6  r   rm  r   )r   r   r   Zjira_map_fieldsrJ  r   r   r4  rG  r   rk   ZdiffZhistory_commentr   r   r   r   _process_history  s.    

zJiraAPIImport._process_historyu   Обработка задачиc                 C   s  d}| j jjj d|d d d  }tjj|d}|sRtd|d d d  | || jtj	j
 d }tjjd	d
| j jjj d|d d d  gdgd|d< |d j|d< | j|d< d|d< | j jjj d|d  |d	< |d |d< |d drp| j jjj d|d dd  }tjj|d|d< |d sp| j jd|d d ddd |  jd7  _| d}|r|d |d |d< |d dr.| |d d| j|d< |d s.|  jd7  _| j jd|d d d dd | j jd|d d| j tjddd! |d d"r| |d d"| j|d#< |d# s|  jd7  _| j jd$|d d" d dd | j jd$|d d"| j tjddd! |d d%r^| |d d%| j|d&< |d& s^|  jd7  _| j jd'|d d% d dd | j jd'|d d%| j tjddd! ||d(< |d) r|d* d+ |d)< ||d(< |pg }d| j jjj d|d d, d  d}	tjjd	d
d-|	 d-gd.|d/< | j jd0|  tj| j tj	|d	d1|d	 gd2\}
}|| |
|7 }| |
|
jj|
_|  |
jj|
||
_|d d3 d4 rd| !|
| | j"d5r|d d6 d4 r| #|
| |D ]}|
j$%| q|d d7g |d d8g  D ]h}| j jjj d9|d  }tj&j|d}|s"| j jd:| d;d<d |  jd7  _n|
j'%| q|d d=g D ]h}| j jjj d|d  }tj(j|d}|s| j jd>| d?d@d |  jd7  _n|
j)%| qB||
_*|
j+r|
j,ddA t-  | .|
| |d dBg }|rzt/| j |
| W n   | j j0dC Y nX | 1||
 | 2||
 | j jjj dD|d  }tj3j|d}|sttj3|| j dE}|
|_4| j5j6 dF|d  }dG| dH| dI|_dJ|_7|j,ddA |j89  | j :dKdL |S )Mu   
        Общая логика обработки которая потом разделяется на задачи и эпики
        r   r   rg   r   r   r  u$   Не проекта с ключем r   r   r`  %::r~   r  r_  r,  r  TZapprovedrB   ZsecurityZperm_security_levelu:   Не найден уровень безопасности zERR-0048r   rb  r(   zStory PointsZagile_story_pointsreporterr   u*   Не найден автор задачи zERR-0049)rq   exc_infocreatorr   u?   Не найден ответственный по задаче assigneer   u6   Не найден исполнитель задачи r   r|   renderedFieldsr   r  ra  r   r  u2   Пытаемся создать задачу из r   r   r4  totaltimeTrackingEnabledrI  ZfixVersionsZversions
::version:u!   Не найдена версия zERR-0050r   
componentsu%   Не найден компонент zERR-0051CmfComponentr   r  u/   Не удалось привязать тегиz
::comment:r!  zbrowse/u<   Задача импортирована из Jira: <a href="r/  r0  r.  r   r   );r)   r   r   rH   r  rJ   r   r   r   r   r   r  r  rK   CmfSecurityLevelr1   r0   rl   r   rE   r*   rQ   ZERRORr  rR   rJ  r   r   r  r/  r|   r   rZ  rN  rL   rK  r+  r   r   Zfix_versionsrb  ra  ri  rq  r   r   r   Zprocess_tagsZexcepionrS  rW  r   r   r=   r  r-  r,   r-   r
  )r   r   sprintsr  Zproject_ext_idr   Znormalized_issuer   Zstory_p_fieldr  r   r  r   versionZversion_obj	componentZcomp_objr  r3  r4  r"  r   r   r   r    s    ",

$
 
 
 . 
 . 
 .

& 
 $  
zJiraAPIImport._process_issueu&   Обработка всех задачc                 C   s2   | j  }|D ]}| j r" d S | | qd S r   )r=   r   r)   r+   r  )r   r*  r   r   r   r   _process_issues3  s
    

zJiraAPIImport._process_issuesu3   Обработка связей всех задачc              	   C   s  |   D ]b}| j|d | |d dD ]>}| j rB  dS |d d}| jjjj d|d  }|r| jjjj d|d  }| j|g }|	| || j|< |d dg }|D ]}| jjjj d|d  }	d|kr$d	|i|d
< | jjjj d|d d  |d d	< || j
|	< qd
|krd	|i|d< | jjjj d|d
 d  |d
 d	< || j
|	< qq*q| jdt| j  | jD ]z}| j r dS tjj|d}
| j| D ]H}tjj|dgd}|s| jjd|  q|
|_|jdd qq| jj  ddddd}| jjdt| j
   | j
 D ]\}}| j rf dS zB| jjjj d|d d  }||d d }|rtjj|d}ntjj|d}|stjjdd|d d gd}|s(tj|| j|d d d}|d d |_|d d |_|jdd | jjjj d|d  }tjj|d}|sftj|| jd }tjj|d
 d	 d|_tjj|d d	 d|_||_|jdd W n6   |  jd!7  _| jj d"|d  d#d$d% Y nX qJ| jj  dS )&uD   
        Постобработка связей задач
        r   r   Nrg   r   r   Z
issuelinksr   r   r   u   Подзадачи: r  parent_taskr  uq   Не удалось связать задачи, возможно задача не попала в импорт Tr   zsystem.finish:finishzsystem.duplicatezsystem.linkzsystem.clone)ZBlocksZ	DuplicateZRelatesZClonersu   Связи: r  r   rA   r   r   )r   r)   r   ZinwardZoutwardr!  r(   u.   Не удалось создать связь zERR-0052r   rb  )!r   r   r  r)   r+   rJ   r   r   rN   r   rM   r*   r   rH   r   rR   rj  rh  r   r,   r-   rJ  r  r   ZCmfRelationTypeZin_type_nameZout_type_nameZCmfRelationOptionZin_linkZout_linkrelation_typer0   r1   )r   r   r   Zissue_parentr   Zparent_ext_idZ	sub_tasksZissue_linksZ
issue_linkZlink_ext_idrh  Zchild_ext_idZ
child_taskZ	map_namesZrelation_ext_idZissue_relationZrelation_coderi  Z
rel_ext_idZrelation_optionr   r   r   _process_relations;  s    "



&&


 z JiraAPIImport._process_relationsu)   Обработка компонентовr  c              	   C   s   t jj|d ddgd}t jj|dddgd}|s@td	| | |d
 D ]}zp|jsld|_|  | j	 r~W  dS | jj
j
j d|d
  }t jj|ddddddgd}|st j|| jdd}||_|d |_||_|dr| |d | j |_|d dkr|j|_n.|d dkr2|j|_n|d dkrH|j|_|jrd|jrd|jdd |ddr|js|  d|j_|jjr|dd|j_|jjjdd | j jd7  _W qN   |  jd7  _| jjd| dd d! Y qNX qNdS )"uG  https://docs.atlassian.com/software/jira/docs/api/REST/1000.824.0/#api/2/project-getProjectComponents
        Пока грузим как списки, после доработки будут отдельные обекты

        Args:
            project_info (dict): проект из джиры как есть
        r   r   r   r  ra  Tr&  )r   r   Zinclude_systemrg   uV   Данный тип проекта не поддерживает компоненты r   Nr   descr_documentdefault_ownerdefault_responsibler  r   r   r   r)   r  r   r  ZassigneeTypeZPROJECT_DEFAULTZPROJECT_LEADZCOMPONENT_LEADr   r   r   r(   u3   Ошибка загрузки компонента ERR-0053rb  rb  )rH   r  rJ   r   r  _get_project_componentsr&  r   r)   r+   r   r   rb  r   r   r   r   rE   rl  r   rm  r   r  rq  rk  Zcreate_descr_documentZ
text_draftr   r{  r0   r1   )r   r  r  r   rf  r   Zcomponents_listr   r   r   r    s\    
  



 z!JiraAPIImport._process_componentsu   Обработка версийc              	   C   s  t jj|d dgd}t jjd|d}t jjd|d}| j|d dD ]T}z| j rbW  d S | jjjj d	|d  }t j	j|d
}|st j	|| jdd}t j
jdd|_||_|d |_|dd|_|jj|_|jr|jr|jdd |d r||_n||_|jr:|d s$|d r0|d n
|d |jrV|jrV|jdd | j jd7  _W qF   |  jd7  _| jjd| ddd Y qFX qFd S )Nr   z"scheme_wf.default_release_workflowr  release)r   r   r   r   r  r`  r  Trn  zlist.release:defaultrA   r   r   r   r   ZarchivedZreleasedr)  ZOPENr(   u+   Ошибка загрузки версии ro  r   rb  )rH   r  rJ   r   _get_project_versionsr)   r+   r   r   r   r  r  r   r   r|   r  Zdefault_release_workflowr  r  rq  r   r   Zset_default_statusr{  r0   r1   )r   r  r  Zrelease_folderr2  re  r   Zversion_listr   r   r   r    sD    




 zJiraAPIImport._process_versionsu   Обработка аудитаc                 C   s   dS )u)   
        Грузим аудит
        Nr   r   r   r   r   _process_audit  s    zJiraAPIImport._process_auditu2   Обработка логических типовc                 C   sr  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|  | j r dS | jjjj d|d  }tjj	ddd| dgd}|rqp|	|d }|r>tjj	dd|d gdgd}|j
r"d| |j
 |_
nd| d|_
|jdd qp| jjd|d  d tjj	dd|d  gdgd}|r|j
rd| |j
 |_
nd| d|_
|jdd qp| jjd  d}| jjjr|d! d"krd}n|d! d#kr
d}n|d$ r
d}tjj	dd|gd}td| d|d  |d% d&|d'}t| jtj| t  | j jd#7  _qpdS )(u$   Маппим issueType в logic_type   Подзадачаztask.sub:default)r   rB   Z	UserStoryztask.userstory:defaultz
Task Agiler  Bugztask.bug:defaultEpicr  )zSub-taskZSubtaskrt  ZStoryu   ИсторияZTasku   Задачаru  u   Багu   Ошибкаu   Эпикrv  issue_typesu-   Обрабатываем тип задачи Nr   r   r   r`  rX  ::%r   r   rB   r   r_  Tr  u   Ищем по имени "r  r^  u*   Не нашли, создаем новыйr  rA  r(   Zsubtaskr   r   )r   r   r|   r  r  )r   r)   rR   rJ  r+   r   r   rH   r  rJ   r   r   stripr=   rF   rG   r   r   r   r   r{  )r   Z	name2coder  r  r  Zlogic_type_dictZtemplate_coder  r   r   r   _process_issue_type  sz    


z!JiraAPIImport._process_issue_typeu2   Обработка бизнес-процессовc                    s  i }  dD ]}|||d < q  dD ]P} j r@ dS  jj|d d    jjjj d|d d  d|d d  }tjj	|dstjj	d	d
}tj|| jd|d _
|d d _jdd |d D ]} ||d   qtjjddgdddggdgdD ]@}tjj	dd|jgddgdddggdsPq|jdd q|d D ] } j r  dS  jjjj dj d|d  }tjj	|d}	|	stj| jd}	|d |	_|d |	_
 fdd|d D }
tjjdd|
gd|	_t|	jt|
ks*td jjjj dj d|d  }tjj	|d|	_|	jdd qh j jd 7  _q*dS )!u   Импортируем workflowr~  r   	workflowsNr   r   ZentityIdr  r  rA   r  r   Tr   r  r   r   r  r_  r  r   r  Ztransitions)r   r  )r   r  r)   c                    s*   g | ]"} j jjj d j d | qS )r   )r)   r   r   r   )r   str   r  r   r   r   n  s     z3JiraAPIImport._process_workflow.<locals>.<listcomp>fromINuN   DEV: Fatal Вероятно, сломали создание статусов!tor(   )r   r)   r+   rR   rJ  r   r   rH   r  rJ   r|   r   r   r  r  r   r  r  r   ZCmfTransZstatus_fromr   r  Z	status_tor{  )r   Zjira_statusesr  Zjira_workflowZworkflow_idZtemplate_workflowr~   Zjira_transitionZtransition_ext_idZ
transitionZstatus_from_ext_id_listZstatus_to_ext_idr   r}  r   _process_workflow>  sT    
,

 
"

"zJiraAPIImport._process_workflowu    Обработка схем БПc              
   C   s  |  dD ]}| j r  d S | jjjj d|d  }tjjdd| dgd}|sjtd|d  |d	 |d
d| jjjj d|d  ddi||d}t	
| jtj|dd|d g\}}|stjj|dD ]}|  q|d  D ]\}}	| j r  d S | jjjj d| }tjjddd| dgd}
tjjdd| jjjj d|	 dgd}|
|d|| jd}tjf |}|jdd q| j jd7  _q
d S )Nworkflow_schemer   ZdefaultWorkflowr   r`  rx  r   u+   Не импортировался workflow r   r   r   r   rB   r  )r   r|   r   r  r  Zdefault_subtask_workflowr   r  ZissueTypeMappingsrX  r   r  Tr   r(   )r   r)   r+   r   r   rH   r  rJ   r  r   r   r  r  r   r  r   r  r   r{  )r   r  Zdefault_task_workflow_ext_idr  Zscheme_dictZworkflow_scheme_objr  r  r  r  r  r  r  r   r   r   _process_workflow_schemev  sP    

 
(z&JiraAPIImport._process_workflow_schemec                 C   sH   t jj}| dD ]0}|| j}|| jj d| t	
| qd S )Nr   r0  )r2  r3  r4  r   rJ   rE   rz  r)   r   r5  r>  )r   r8  r-  r   r   r   r   _cache_all_users  s    zJiraAPIImport._cache_all_usersu   Простой дампr8   c              	   C   s   | j  | d}| j  | d}| r8d S t|d6}| D ](}| j  jd7  _|t|d  qJW 5 Q R X t	
|| | j jdd t  d S )N.jsonz.json.dirtyr  r(   r<  Tr  )r)   rY   rZ   r[   r\   json_object_countr=  r]   r>  rc   rf   r   r   )r   Zapi_funcr   r`   rh   ra   r?  r   r   r   _simple_dump  s    
 zJiraAPIImport._simple_dumpc              	   c   sN   | j  | d}| rJt|d}|D ]}t|V  q.W 5 Q R X d S )Nr  r+)r)   rY   rZ   r[   r\   r]   r6  )r   r   r`   ra   r?  r   r   r   r     s    zJiraAPIImport._simple_getc              
   c   sf   | j  d}| rbt|D ]>}|dr2q"t| d| dd}t	|V  W 5 Q R X q"d S )Nr   .dirtyr   
/info.jsonr  )
r)   rY   rZ   r[   rd   listdirr  r\   r]   r^   )r   r  r  ra   r   r   r   r     s    
zJiraAPIImport._get_projectsc                 C   s&   |   D ]}||d kr|  S qd S rD  )Zget_projects)r   r  r  r   r   r   get_project  s    zJiraAPIImport.get_projectc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /issue_types.jsonr  r)   rY   rZ   r\   r]   r6  r   r  r  ra   r?  r   r   r   r    s    z*JiraAPIImport._get_issue_types_for_projectc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /statuses.jsonr  r  r  r   r   r   r    s    z'JiraAPIImport._get_statuses_for_projectc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /roles.jsonr  r  r  r   r   r   r    s    z JiraAPIImport._get_project_rolesc              
   c   sV   | j  d|d}t|D ]2}t| d| dd}t|V  W 5 Q R X qd S )Nr   rO   r   r  r  r)   rY   rZ   rd   r  r\   r]   r^   )r   r  	board_dirZboard_idra   r   r   r   r#    s    z!JiraAPIImport._get_project_boardsc              
   c   sV   | j  d|d}t|D ]2}t| d| dd}t|V  W 5 Q R X qd S )Nr   rd  r   r  r  r  )r   r  sprints_dirZ	sprint_idra   r   r   r   r1    s    zJiraAPIImport._get_all_sprintsc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /versions.jsonr  r  r  r   r   r   rr    s    z#JiraAPIImport._get_project_versionsc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /components.jsonr  r  r  r   r   r   rp    s    z%JiraAPIImport._get_project_componentsc                 C   s0   | j  d|d}tdd t|D }|S )Nr   r   c                 s   s   | ]}| d  V  qdS )r  N)r  )r   entryr   r   r   	<genexpr>  s     z5JiraAPIImport._count_project_tasks.<locals>.<genexpr>)r)   rY   rZ   sumrd   r  )r   r  	tasks_dircountr   r   r   r    s    z"JiraAPIImport._count_project_tasksr     c              
   c   s   | j  d|d}tt|D ]\\}}||k r4q"|dr@q"||| krP qt| d| dd}t	|V  W 5 Q R X q"d S )Nr   r   r  r   r  r  )
r)   rY   rZ   r   rd   r  r  r\   r]   r^   )r   r  startr   r  iZtask_idra   r   r   r   r     s    
zJiraAPIImport.get_project_tasksc                 c   sB   |d  d}t |D ]$}|dkr&q|| d| dV  qd S )Nr   z/attachmentsall_attachments.zipr   )r  r`   )rd   r  )r   r   Zattachments_pathr  r   r   r   r    s
    z$JiraAPIImport._get_issue_attachmentsc              	   c   s>   |d  d}t |d}|D ]}t|V  qW 5 Q R X d S )Nr   z/comments.jsonr  )r\   r]   r6  )r   r   comments_file_pathra   r?  r   r   r   rL    s    z!JiraAPIImport._get_issue_commentsc              	   C   s6   |d  d}t |d}t|}W 5 Q R X |p4g S )Nr   z/worklog.jsonr  r\   r]   r^   )r   r   r  ra   r5   r   r   r   rH    s    z!JiraAPIImport._get_issue_worklogsc              
   C   s:   |d  d}t |d}t|W  5 Q R  S Q R X d S )Nr   z/properties.jsonr  r  )r   r   Zproperties_file_pathra   r   r   r   rQ    s    z#JiraAPIImport._get_issue_propertiesc              
   C   s:   |d  d}t |d}t|W  5 Q R  S Q R X d S )Nr   z/watchers.jsonr  r  )r   r   Zwatchers_file_pathra   r   r   r   r     s    z!JiraAPIImport._get_issue_watchersc              
   C   sD   | j  d}| r@t|d}t|W  5 Q R  S Q R X i S )Nglobal_settings.jsonr  )r)   rY   rZ   r[   r\   r]   r^   )r   global_settings_file_pathra   r   r   r   _get_jira_global_settings  s
    z'JiraAPIImport._get_jira_global_settingsc              	   C   s@   | j  }| j d}t|d}t|| W 5 Q R X d S )Nr  rX   )r=   Zget_jira_global_settingsr)   rY   rZ   r\   r]   r_   )r   Zglobal_settings_datar  ra   r   r   r   _dump_jira_global_settings%  s    
z(JiraAPIImport._dump_jira_global_settingsu/   Обработка ссылок в тексте)r|   attachments_dirr   c                    s  d}|s|S t |ddd D ]2}d}|dr8d}|j| }z|drh| jjd|  W q |d	stj	
| jj|}|| jjs| jjd
|  W q t|dd \}}	|s| jjd|  W q tdtj	|}
|
r`|
d  |
d dd} |d kr`|d d }tt fdd|d }|r`| jjd|  W q tj	|dd dd }tj|}||}tjj||d | jjjjd}|stj| j||d | jjjjd}||_||_d|_|   |j!"  W q  t#k
rR } z2| jj!$  | jjd| d|  |d7 }W 5 d }~X Y q X q t |d}|jddid D ]P}|jd!r| %|jd! |d"  n$|jd#rp| %|jd# |d"  qp|S )$Nr   Zlxmlc                 S   s   |  dp|  dS r9  r;  r=  r   r   r   r>  1  r?  z+JiraAPIImport._dump_links.<locals>.<lambda>r:  r"  zmailto:u   Это почта: ZhttpuH   Это внешняя ссылка, оставляем как есть: rB  u   Это не файл: rC  r(   r.  r  rg   r   c                    s   |  d kS rD  rE  rF  rH  r   r   r>  J  r?  uE   Этот файл уже обработан во вложениях: r   rA  r   r"  
obj_ext_idr   r)   r"  r  r   Fu0   Не удалось скачать ссылку r%  r  r  r  r  r   r   r!  )&r   r&  r<  r  rK  r)   rR   rj  rL  rM  Zurljoinr=   r  rS  rT  r   rO  rP  rN  rQ  r   rH   r  r  rZ   CmfImportDownloadrJ   r   r   pathr   
downloadedr   r,   r-   r.   r/   r@  )r   r|   r  r   r0   r,  r   r  rX  encodingrU  Zattach_filenamerV  rW  r  r`   download_jobr.  r+  r   rH  r   _dump_links+  sx    



 



zJiraAPIImport._dump_linksc                 C   s   | j |d }| jD ]}| j| d s*q|d |s:q|d | d}|r|D ]}|dsz| jd| tj qT| j jj	r| j| dg D ]*}|d |d kr|dr|d |d< qqT|| j| d krT| j| d 
| qTq| | j d	S )
u   На коробке только через мету задачи можно получить варианты выбора полей

        Args:
            issue (dict): задача
        r   customrg   ZallowedValuesr   u   Выбор без id: optionschildrenN)r=   Zget_issue_metarb   rJ   r)   r*   rQ   rl  rF   rG   r   ri   )r   r   metarn   r  optionZcur_optr   r   r   _get_field_optionsk  s(    



z JiraAPIImport._get_field_optionsc                  C   sX  t ddB || _d}| jjd| d|  z| j|d ||D ]}zzz| j r|W W  W W 5 Q R  dS | jjd|d	  d
 |	t
|d }	|	 rW W FqJ| | |	t
|d d }
|
jdd |
|d< |		d}|d d rv| jjdt|d d   ztj| jjd|d  d}| jjjrptj| jjd|d  d}d}|	|}| jjjj d|d  }tjj||| jjjjd}|stj| j||| jjjjd}||_||_d|_|  |j  W nD tk
r> } z$| jjdt d| dddd W 5 d }~X Y nX |d d D ](}|d rL|  |d  | j! |
 qL| j"d!r|
	d"}| rt#| t$|d#Z}| j%|d }|D ]2}|  |d  | j! |
 |  |d$ | j! |
 qt&'|| W 5 Q R X |d% d& D ](}|d r|  |d  | j! |
 q|d d'rp|  |d d'| j!|
 |d d(r|  |d d(i | j!|
 |d d)i r|  |d d)i | j!|
 |  j(| )|d* d+ ||7  _(|
	d,}| rt#| | jjd- t$|d.}| j*|d D ]~}|  |d  | j! |
 |  |d$ | j! |
 |+t&,|d/  | j j-d7  _-| j.d0 |  j(| )|d1 ||7  _(q:W 5 Q R X | j/|d }|
	d2}t$|d#}t&'|| W 5 Q R X | j0|d }|D ]}|  || j! |
 q|
	d3}t$|d#}t&'|| W 5 Q R X t12|
|	 |jdd |		d4}t
|	3dd5|d< t$|d#.}t&'|| | j j-d7  _-| j.d6 W 5 Q R X W n(   |d7 }| jj4d7|  Y nX W 5 | jj  X qJW n.   | jj4d8|d9  d: |d7 }Y nX |5| W 5 Q R X d S );NFr  r   u   Задачи с u    до r   r(   u   Задача 'r   'r  Texist_okr   rV  rg   r   u%   Обработка вложений: zsecure/attachmentzip/z.zipzsecure/issueAttachments/r  r   r  r  r  r%  zERR-0054r   r_   rc  Z
error_typer   r_  zworklog.jsonrX   rA  rU  rV  rY  r[  r\  r]  r   zcomments.jsonu#   Дампим комментарииr  r<  r4  r   zproperties.jsonzwatchers.json	info.jsonr   r   u0   Не удалось скачать задачу u2   Не получить задачи проекта r   u    с сервера)6r   r=   r)   rR   rJ  Zget_all_project_issuesr,   r-   r+   rZ   r&   r[   r  mkdirr   rd   r  r   r  rF   rG   r   r   rH   r  rJ   r   r  r   r.   r1   r  r@  rE   rL   r  r\   Zissue_get_worklogr]   r_   r0   r  Zget_commentsr=  r>  r  r
  Zget_issue_propertiesZget_watchersrc   rf   r  	exceptionr  ) r   r  maxr  r  r=   tasks_that_are_doner  r   Ztask_dirZtask_dir_tmpr  r"  r  Zattach_file_pathr   r  r.  r  Zworklog_file_namera   ZworklogsrI  rJ  Zcomments_file_namer4  Z
propertiesZproperties_fileZwatchersr   Zwatchers_fileZ	info_pathr   r   r   _dump_task_part  s    



 


  


   


*


zJiraAPIImport._dump_task_partr  rM  c                 C   s  t jj}t|d  d}|jdd | j }d}t|| j d }|sNd}d}g }	d}
||
kr|| | }
|
|kr||}
| j	j
| jd| || |
||t| jj| jj| jj| jj| jj| jjjd	|d
d}|	| |  | jjd|  |d7 }qZ|d }| jjd| d |	D ]8}|j|d | r$| jjddddd tdq$| jjd | s|| 7 }ql| jjd|  | j |d | !|d dD ]}| j" r|  S t|d #d}| j$ #d}| j$ #d}|% rt&'|| t(|d}t(|dx}t(|db}|D ]V}||kr@|)| t*+|}|| j,}|r@|-| jj. d | t/0| q@W 5 Q R X W 5 Q R X W 5 Q R X |1  t&2|| q|S )!Nr  z/tasksTr  r   r(   r   Z
dump_tasks)r  r*  tokenpassword
verify_sslrG   )r  r  r  r  r=   r  targetr   r4   u$   Форкаем _dump_task_part proc=rE  u%   Таймаут дампа задач u    минут)timeoutu$   Возможно завис дампzERR-0055r   r_   r  u"   Ошибка дампа задачuK   Закончили параллельное скачивание задачu   Ошибок: r   r   r   r:  zusers.json.newr;  r  r0  )3r2  r3  r4  r   r  rs   Queuer{   rw   rr   Threadr  r   r=   r  r*  r  r  r  rF   rG   r   r  r)   rR   rJ  r   is_aliver1   TimeoutErroremptyrJ   r   r  r+   rZ   rY   r[   rc   r  r\   r=  r]   r6  rE   rz  r   r5  r>  unlinkrf   )r   r  rM  r8  r  r  r  stepr  r	  Z	max_limitr   r  r   Zissue_users_pathZall_users_pathZall_users_path_newf1f2Zf3liner-  r   r   r   r   _dump_tasks  s    

 	


  
"



BzJiraAPIImport._dump_tasksc              	   C   sZ   t |d  d}| r$t| t|d"}| j|d }t|| W 5 Q R X d S )Nr  r  rX   r   )	r   r[   rd   r  r\   r=   Z!get_project_issue_security_schemer]   r_   )r   r  r  ra   perm_schr   r   r   #_dump_project_issue_security_schemeA	  s    
z1JiraAPIImport._dump_project_issue_security_schemec           &      C   s  dd l }| jd d d }|d s*tddd |d D | _| j d	}|jd
d t| j}t	d| }| jD ]b}
z| j
 rW  d S | j jd7  _| jjd|d  d |t|d }|d}| s| jj|d }	t||d  d|	d< tj|	d d
d | jjd t|	d  d}
|
 rVt|
 t|
d}| j|	d }zx|d D ]j}|d d dkr|| jjjr|d dr| |d d | j  n| |d d | j  q|W n(   | jjd| dd d!d"  Y nX t|| W 5 Q R X | |	 | jjjr|	d# sj| j |	d gd d$ |	d%< n| jjd& t|	d  d'}| rt| t|dD}| jj!|	d d(D ]*}| j jd7  _|"t#|d)  qW 5 Q R X n~| j$| jj% d*|	d   |	d%< d|	d% krD|	d% d |	d% d+|	d%< n.| j$| jj% d,|	d% d   |	d% d-< |	d.}|r| j&d/|  | j$|d0 }|'  | |	d.< | |	d. | j( | j  | jjd1 t|	d  d2}| rt| t|dD}| jj)|	d d(D ]*}| j jd7  _|"t#|d)  q&W 5 Q R X | jjd3 t|	d  d4}| rt| t|d}| jjj*|	d d5+ D ]}| j
 r W 5 Q R  W  d S | j jd7  _| j$| }| jjjrv|d6g D ]d}|d d7kr| jjj,|d8 d|d8 d9d:|d;< |d; r| |d; | j( | j  q|"t#|d)  qW 5 Q R X | jjd< t|	d  d=}| rt-.| |  t|	d  d>}| rt-.| |  z| jj/|	d d5D ]}| j
 r6 W W  d S | j jd7  _| jjd?|d   | jj0|d |d-< | j$|d- d@ d0  |d- d@< | jjjrdAd | j1|d D |d- dB< |	d |dC< |t|d }|jd
d |d}t|dD}t|| W 5 Q R X zL|d dEkrh| jjdF | j2|d D ]}| j
 rn W  W W  d S | j jd7  _|t|d }|jd
d |d}| r| jjdG|d  dH qLg |dI< | jjdG|d   | j3|d D ]6} | j
 r   W  W W  d S |dI 4| d  qt|dD}t|| | j5dJ W 5 Q R X qLW n |j6j7k
r }! z\|!j8j9dKkrdLt|!ksdMt|!kr| j&t|! n| jjdN| dOdPd!d"  W 5 d }!~!X Y n(   | jjdN| dOdPd!d"  Y nX qW n4   |  j:d7  _:| jjdQ|	 dOdPd!d" Y nX | j&dR |	d  dS}"t|"db}| j;|	d D ]J}#| j
 	r W 5 Q R  W  d S | j jd7  _|"t#|#d)  	qW 5 Q R X | j&dT |	d  dU}$t|$d}| j<|	d D ]r}%| j
 
r4 W 5 Q R  W  d S |%d.
r\| |%d. | j( | j  | j jd7  _|"t#|%d)  
qW 5 Q R X dVtj=dW< | j j>|7  _>| jj?d
dX | jj@A  dYtj=dW< t-B|	d | t||	d< |	d  dZ}t|dD}t|	| W 5 Q R X n t|d[}tC|}	W 5 Q R X | jD|	d }| j&d\|  |  j:| jE|	|d]7  _:W qv   |  j:d7  _:|d^r| jjd_|d  d`dad d!d" n| jjdb| dad d!d" Y qvX qv| j&dc d S )dNr   r   r   	isCheckedu5   Не выбрали ни одного проекта!c                 S   s$   g | ]}|d  r|d r|d  qS )r2   r  r   )r   rR  r   r   r   r   N	  s       z0JiraAPIImport._dump_projects.<locals>.<listcomp>r  r   Tr  P   r(   u   Дампим "r   r  r   r  r   r  r  u   Дампим права/permissions.jsonr  permissionsholderr  r   	parameteru0   Не удалось сдампить права zERR-0056r  r_   r  r  ZworkflowSchemer  u/   Дампим типы задач проектаr  r  r<  z$rest/projectconfig/1/workflowscheme/)r   rJ  zrest/api/2/workflowscheme/rJ  r  u1   Ищем руководителя проекта r   u*   Дампим статусы проектаr  u$   Дампим роли проектаr  )r   r  r  Z	actorUserr?   )r1  rY  r-  u&   Дампим доски проектаz/boards/z	/sprints/u   Доска r   c                 S   s   g | ]}|qS r   r   r   r   r   r   r   	  s     Zquick_filtersr  rX   )ZscrumZsimpleu&   Дампим спринты доскиu   Спринт u    уже скачанr*  r   i  z"The board does not support sprintsuD   Данная доска не поддерживает спринтыu4   Не удалось сдампить спринты zERR-0057r   u   Не удалось сдампить доски, возможно проект не поддерживает доски или у вас нет прав project_info=u(   Дампим версии проектаr  u!   Дампим компонентыr  r   NO_CACHEr  1r  r;  u*   Дампим задачи проекта: r  r  u   Проект "u   " является приватным и не может быть импортирован, отключите приватность в Jira или предоставьте пользователю праваzERR-0058u2   Не удалось получить проект u0   Закончили дампить проекты)Frequestsr   r.   rP   r)   rY   rZ   r  r   r{   r+   r  rR   rJ  r&   r[   r=   rF   r  rd   makedirsr   r  r\   Zget_project_permission_schemerG   rJ   r@  r1   r]   r_   r  Zget_project_schemeZget_issue_for_projectr=  r>  jira_requestr  r*   raise_for_statusrE   get_statusesZget_project_rolesrj   r   rc   rmtreeZget_all_agile_boardsZget_agile_board_configurationZget_board_quick_filtersZget_sprintsZget_sprint_issuesr   r
  
exceptionsZ	HTTPErrorZresponser  r0   Zget_project_versions_paginatedZget_project_componentsenvironprogressr   r,   r-   rf   r^   Zget_project_issues_countr  )&r   r  rootZprojects_dirrM  r  r   r  Z	data_filer  permission_filera   r  	perm_dictZ
types_filer  r  r5   Zstatuses_filer?  Z	role_fileZrole_urir  r  Z
boards_dirr  r$  r  Zboard_info_filer   Zsprint_pathZsprint_file_pathr   r.  Zversion_list_filenamere  Zcomponents_list_filenamerf  r   r   r   _dump_projectsI	  s   





"  



$


"



 "



$


*      ""

    zJiraAPIImport._dump_projectsc                 C   s  | j  }t|\}}}|| d }| j d| d | j jd | j jd |   |  | _	| j j
jddr| j jd | | jjd	 n| j jd
tjd |   | j jd | | jjd | j jd | | jjd | | jjd | jjjrH| j jd | | jjd | j jd | | jjd | j d | | jjd | | jjd dtjd< d| j _| j   t   dtjd< | j jd | !  dS )u_   
        Загружаем все данные из апи, кроме аттачей
        d   u   Свободно места: ra  u$   Скачаем данные из APIu9   Дампим глобальные настройки Jirarx  Tu'   Дампим пользователейr   uA   Не дампим пользователей из-за опцийry  u   Дампим статусыr~  u    Дампим типы задачrw  issue_security_schemesu*   Дампим бизнес процессыr{  u7   Дампим схемы бизнес процессовr  u   Дампим экраныscreensZscreen_schemer   r     r  u   Дампим проектыN)"r)   rY   rc   
disk_usager*   rR   rJ  r  r  rL   r   r   rJ   r  r=   r   rQ   rl  r  r  Zget_issue_typesZget_issue_security_schemesrF   rG   Zget_workflowsZget_workflow_schemeZget_all_screensZget_screen_schemerd   r  r  r   r   r  )r   Zdownload_pathr^  usedfreeZfree_percentr   r   r   download_data#
  sB    




zJiraAPIImport.download_datac                 C   s`   dt jd< tjj| jjdddgd}|jrRt|j	|j d |_
|jdd	 t  d
t jd< d S )Nr   r  r{  r  r  )r   rg   r  Tr  r  )rd   r  rH   Z	CmfImportrJ   r)   r   r  r{   r{  r  r   r   )r   r)   r   r   r   r  K
  s    
zJiraAPIImport._calc_progressc                 C   st   dd l }|jdddd| jj d| jjj d| d| d	tj d
gddt	ddt	ddd}| j
d|j  |S )Nr   r  r  r  z&cmf_import = models.CmfImport.get(id="z#");cmf_import.process_cross_links("r  r  r  r  Tr  r  r  r  r  )r  r  r)   r   r=   rF   r  rv   r  r\   r*   r  )r   
model_namer  r  r   r   r   r   _execute_cross_linksV
  s    
.  z"JiraAPIImport._execute_cross_linksc                 C   sh  ddl }dddgdddgg}dD ]2}| jjd	| d
| j  d}tt| }|j|d}|sdq g }t| jD ]0}| 	||}	|t
j7 }||	 ||krr qqr| j  ||k r$|d t|D ]V}	|	 }
|
dk	r|  j|
7  _||	 | 	||}|t
j7 }|| | j  qqt|D ]&}	|	  |	jr,|  j|	j7  _q,q | jjd dS )uU   
        Заменим ссылки на задачи и документы
        r   Nr)   r  r  r   T)r  r   r  r   u   Обрабатываем u+    в несколько процессов: r   r(   u2   Закончили обработку ссылок)r  r)   rR   rJ  ry   varsrH   r  r  r  rv   r  r   r  r  r   r  r0   r  r  r  )r   r  r   r  r  rm   Zobj_cntr	  r  r   r  r
  r   r   r   _process_cross_links`
  sB    








z"JiraAPIImport._process_cross_linksc              	   C   s  ddl m} t|d  d}| }dd |d D }t|d}t|}W 5 Q R X | jjjj d	|d
  }t	j
j|d}	|	st	j
|d| jd}	|d |	_|	jdd |d D ]}
zd	| jjjj d	|
d
  d	}||
d rt	jj||
d  dd}n| jjd|
  W qddd| dg}ddddg}t	jj||d}|st	jj||	|d}|s| jjd|
 d|	d |  jd7  _W q|jr|j | |_n||_|
d  d! d"kr| jjjj d	|
d  d" d
  }t	jj|d}|j| |jdd n6|
d  d! d#kr8d|_|jdd n|
d  d! d$kr`d|_|jdd n|
d  d! d%krd|_|jdd n|
d  d! d&krd|_|jdd n|
d  d! d'krL| jjjr|
d  d(r| |
d  d( }n| |
d  d) }|r$|j | |jdd n&| jjd*|
 d+|d |  jd7  _n|
d  d! d,kr| jjjrd	| jjjj d	|
d  d(  d	}n&d	| jjjj d	|
d  d, d  d	}t	j!jddd| dgd-}|r|j | |jdd n&| jjd.|
 d/|d |  jd7  _n.| jjd0|
d  d!  d1|d |  jd7  _W q   | jjd2|
 d3d4d5 |  jd7  _Y qX q|	S )6Nr   )get_datar  r  c                 S   s   i | ]}|d  |d qS )Z	jira_coderB   r   r   r   r   r   rT  
  s      z6JiraAPIImport._process_permissions.<locals>.<dictcomp>Zproject_perm_permissionr;  r   r   r  Tr   r  r)   r   r   r  Z
permission)rB   Zinclude_deletedu4   Не нашли соответствия права r   r`  ra  r   access_membersaccess_project_roler_  )permr   rg   u*   Не найдено правило для zERR-0059r  r(   r  r  ZprojectRoleZapplicationRoleZprojectLeadr\  rY  r   r   r  u9   Не нашли пользователя для прав zERR-0060rv  r   u-   Не нашли группу для прав zERR-0061u'   Неизвестный тип прав zERR-0062u6   Не удалось загрузить правило zERR-0063CmfProjectPermPermissionrb  )"Zcmf.system_datar  r   r\   r]   r^   r)   r   r   rH   ZCmfProjectPermSchemerJ   r   r   r  rR   rj  ZCmfProjectPermSchemeRuler1   r0   r   r  r  r   Zaccess_local_userZaccess_ownerZaccess_responsibleZaccess_authorr=   rF   rG   r   r  rn  )r   r  r  r  Zsystem_dataZmap_permra   Zperm_scheme_dictr   Zperm_schemer  r  r   rg   Zscheme_ruleZrole_ext_idr  r   rv  r   r   r   r  
  s    
 " $&   z"JiraAPIImport._process_permissionsc                 C   sd  t ddN d}| }|dkr&qL| j r4qL| jjd|d   | jj|d dtj	d}z|
  t|d	 }t|d
"}|jddD ]}|| qW 5 Q R X | jjd|d	   tjj|d d}	d|	_|	  | jd W nJ tk
r> }
 z*|d7 }| jjd|d  d|  W 5 d }
~
X Y nX W 5 Q R X q|| W 5 Q R X d S )NFr  r   r  u    Пытаемся скачать r"  T)streamr  r  zwb+i    )Z
chunk_sizeu   Сохранили в r   r  r   r(   u+   Неудалось скачать файл r%  )r   rJ   r)   r+   rR   rJ  r=   r  rv   ZIMPORT_DOWNLOAD_TIMEOUTr  r   r\   Ziter_contentr=  rH   r  r  r   r
  r.   r  r  )r   download_queueerror_queuer  r  r5   Z	save_pathra   chunkZdownload_job_objr.  r   r   r   _download_file_worker
  s0    
<z#JiraAPIImport._download_file_workerc           	      C   s  | j jd | j }| j }d}| j dg dd| j jjjgdddgg}tj	j
|dsp| j jd	 |S g }t| jD ]J}| jj| jd
| ||dd}|| |  | j jd|  q~tj	j|ddgdD ],}| j  r q||j|j|jd q|D ]}|d q| s@|D ]}|  q0| j  rP|S | j jd | s| j  rx|S || 7 }q^|S )Nu=   Скачиваем все найденные вложенияr   zplugin.plugin.source_hashr   r   r  Fr   u   Вложений нетr  )r  r  r  u    Запустили задачу r"  r  r_  )r   r"  r  r  u%   Закончили скачивать)r)   rR   rJ  rs   r  r   r   r   rH   r  r  r  rw   rr   r  r  r   r  Zslistr+   r  r   r"  r  r  r   rJ   )	r   r  r  r5   r   Zprocsr  r   r  r   r   r   download_files  sD    





zJiraAPIImport.download_filesc                 C   s
  |  dD ]}| j r d S | jjjj d|d  }tjj|d}|s\tj|| jdd}|jrx|d |_	|d|_
||_|jdd	 |d
 D ]p}| jjjj d|d  }tjj|d}|stj|| jdd}||_|jr|d |_	|d|_
|jdd	 qq
d S )Nr  r   r   r  Trn  r   r   r   Zlevels)r   r)   r+   r   r   rH   r  rJ   r  r   r|   ri  r   rc  r   )r   r  r   Z
scheme_objrS   Zlevel_ext_idZ	level_objr   r   r   _process_security_levels(  s,    


z&JiraAPIImport._process_security_levels)rk   c                 C   s  |d d  dd}|d| jjjj  7 }|d d|g g g g dd	d	d
}|d d d dkrvd|d< d|d< nR|d d d dkrd|d< d|d< n*|d d d dkrd|d< d|d< n|d d d dkrd|d< d|d< n|d d d dkr d|d< d|d< d|d< n|d d d dkrdd|d< d|d< dd  |d d! D |d"< nd|d d d d#krd|d< d|d< n:|d d d d$krd%|d< d&|d< d|d'< d(|d< d)d  |d d! D |d"< n|d d d d*krd+|d< d+|d< d|d'< dg|d,< n|d d d d-krJd|d< d|d< d.|d< n~|d d d d/krd+|d< d+|d< d|d'< d.g|d,< nD|d d d d0krd%|d< d&|d< d|d'< d(|d< i |d"< nd }|S )1Nr   r   customfieldcfr  r   T)r  r  r  Zlogic_prefixF)r   r  
class_nameZvisible_filterrequiredZrequiredChangedZschemar  z:com.atlassian.jira.plugin.system.customfieldtypes:textareaZCmfStr
field_typeZCmfTextwidgetz:com.atlassian.jira.plugin.system.customfieldtypes:datetimeZCmfDateTimez<com.atlassian.jira.plugin.system.customfieldtypes:datepickerZCmfDatez7com.atlassian.jira.plugin.system.customfieldtypes:floatZ
CmfNumericZ	CmfNumberz<com.atlassian.jira.plugin.system.customfieldtypes:userpickerZCmfRelationr   rm   z8com.atlassian.jira.plugin.system.customfieldtypes:selectZ	CmfChoicec                 S   s   i | ]}|d  |d qS r   r   r   r   optr   r   r   rT  Y  s      z,JiraAPIImport._map_field.<locals>.<dictcomp>r  choicesz;com.atlassian.jira.plugin.system.customfieldtypes:textfieldz=com.atlassian.jira.plugin.system.customfieldtypes:multiselectCmfM2MZCmfCascadeChoiceleftZCUSTOM_CHOICE_MODELc                 S   s   i | ]}|d  |d qS r  r   r	  r   r   r   rT  b  s      zAcom.atlassian.jira.plugin.system.customfieldtypes:multiuserpickerZCmfGenericM2MrH   z=com.atlassian.jira.plugin.system.customfieldtypes:grouppickerrn  zBcom.atlassian.jira.plugin.system.customfieldtypes:multigrouppickerzAcom.atlassian.jira.plugin.system.customfieldtypes:cascadingselect)r  r)   r   r   r)  )r   rk   r  r5   r   r   r   
_map_field@  st    
 

zJiraAPIImport._map_fieldc              	      s  d | _ | jD ]Z}| jtjj d D ]B}d|krF| jdtj	   d S |d d |kr"| j| |d< q"q| jd | jj
j
j}tjj|dgd}|stj|| jdd	d
}|jdd tjj|dgd}|stjd| j|dd}d|_|jdd |jrJtjj|dgd}|s$tjd| j|d}|jrJ||_||_d|_|jdd | jjjddsbd S |jj}dd tj D }g }	g }
| jtjj d D ]}|dr|d d s| jd|d   q| |}|d d dd}|d| jj
j
j  7 }|s>| jjd|d  ddd |  jd7  _q|d d krV|
| |d! r| jd"|d  d#|d!   q||kr|| d$ |d$ kr| jjd|d  d%|d$  d&|| d$  d'dd | jd(| d)|d  d* || |d!< q| jd+| d)|d  d, ||d- |< |d. d/ d | |	| q||_|  |j   |	rtj!  t"#d tj$d0di d1d tj D }|	D ]@}|d d dd}|d| jj
j
j  7 }|| |d!< qd<t%d2 fd3d4|
D ]D}tjj&|d! d5  }t't|j(  |d d6 D ]}| q<q
| jjj}|d7 D ].}|d8 tjjkrb| jtjj d |d< qb|| j_d9t)j*d:< | j  | jj   d;t)j*d:< d S )=Nrg   r   uj   Текущая настройка не поддерживает импорт кастомных полейr   u0   Обработка кастомных полейr   r  TzJira import custom fields)r   r)   r  r   r   z"Jira import custom fields (UiForm))r  r)   r   r   r   )r  r)   r   Zimport_custom_fieldsFc                 S   s   i | ]}|d  |qS rn   r   r   ra   r   r   r   rT    s      z8JiraAPIImport._process_custom_fields.<locals>.<dictcomp>r  u!   Поле не кастомное r   r  r  r  u+   Неудалось смапить поле zERR-0064	CmfUiFormrb  r(   r  r  r   u	   Поле u    уже смаплено  в r  u@   ,                                               widget поля u5    не совпадает с существующим zERR-0065u   Поле с именем (u4   ) есть в таблице, мапим в негоu(   Создаем поле с именем u   ), и мапим в него	ui_fieldsui_group_fieldsrA  r  c                 S   s   i | ]}|d  |qS r  r   r  r   r   r   rT    s      )option_dictc                    sj    j | d d}|s" | d d}|  dd|_|r<|j|_|jrJ|  |  dg D ]}|| qVd S )Nr   r8   ZdisabledFr  )rJ   Z
cmf_hiddenr   Zchoice_parent_idrq  r   )r  Z
parent_optr  ZchildZchoice_modelcreate_optionr   r   r    s    z;JiraAPIImport._process_custom_fields.<locals>.create_optionrn   r  r   r   r   r  r  )N)+r<   rb   r   rH   r   r   r)   r*   rQ   rl  r   r   r  rJ   r   r  r  r  ZCmfUiFormSchemeRuler  r  r   r   ui_form_jsonro   r  r  r)  r1   r0   r   r,   r-   Zcustom_field_syncZgeventr  Zcustom_field_sync_update_modelsr   rg   r  rm   rd   r  )r   Zext_field_namerk   r   r  Zui_view_formr  r  shop_fieldsZ
new_fieldsZ
m2m_fieldsZui_fieldr   Zfield_classr  r   sr   r  r   _process_custom_fields{  s    

    
 

 

 





z$JiraAPIImport._process_custom_fieldsu#   Импортируем экраныc           
   
   C   s  dd t j D }| dD ]}| jjjj d|d  }t jj|dgd}|sft j|d| jd	}|j	r|d
 |_
|dd|_d|_|jdd |jj}|d D ]}|d D ]}|d dsq|d dd}|d| jjjj  7 }||krq| jt jj d D ]}	|	ds"q|	d d |d kr| jd| d|  | |	|d |< ||d d d kr|d d d |  qqqq||_|jdd |j  qd S )Nc                 S   s   i | ]}|d  |qS r  r   r  r   r   r   rT    s      z2JiraAPIImport._process_screens.<locals>.<dictcomp>r  r   r   r   r  Tr  r   r   r   r   r   Ztabsrg   Zcustomfield_r  r  r  r   u   Добавляем поле u    в экран r  r  rA  )rH   r   ro   r   r)   r   r   r  rJ   r  r   r|   r  r   r  r   rK  r  r)  r   r   r*   r  r   r,   r-   )
r   r  Zscreenr   Zui_formr  ZtabZ
jira_fieldr   rk   r   r   r   _process_screens  s@    
zJiraAPIImport._process_screensc                 C   s|  t dD ]}|   | js q qt dD ]}|  }|s( q>q(|  j|7  _|   |   |   |   |   |   |   |   | 	  | 
  | jjjr|   |   |   |   |   n|   |   |   |   | j rd S d| j_| j  t  |  D ]>}|d dd | jD kr@q| jjd|d  d q| jd	| jj  | j S )
N   r  r   c                 S   s   g | ]}|d  qS r  r   r   r   r   r   r   9  s     z0JiraAPIImport.process_import.<locals>.<listcomp>u'   Импортирован проект 'r   r  u-   Импортировано объектов: ) r  r  r0   r   r  r}  r  rz  r  r  r  r=   rF   rG   r  r  r  r  r  rj  rs  r)   r+   r  r   r   r   rP   rR   rJ  r*   r{  )r   r  r5   r   r   r   r   process_import  sP    



zJiraAPIImport.process_import)T)r   r   )T)TT)N)r   r  )or"   r#   r$   r%   r{   r'   r   r&   r   r   rD   propertyrb   ri   rl   staticmethodr   r   r   rp   rT   r   r   r   r   r   r   r   r   r   r:   r   r  r/  r(  r   rZ  rw  r}  r  rH   r  r  r  r  r  r  r  r  r  r  r  r  r  r6  r   r   r@  rK  rN  rS  rW  r  rg  rj  r  r  rs  rz  r  r  r  r  r   r   r  r  r  r  r#  r1  rr  rp  r  r   r  rL  rH  rQ  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  __classcell__r   r   rU   r   r;   <   s   
	 

	#5  


H!9
d

E'.
u$
>
,
1
@'
 


T6
%

H
7
$	
?uD [(
.Y$;u
"r;   )+Zcmf.appr   Zcmf.includeZdataclassesr5  rS  pathlibr   rc   Ztempfiler   rL  typingr   r   r   r	   r
   r   r   Zbs4r   r   Zcmf.data_providers.baser   r   Z
cmf.modelsr   Z%common.models.cmf_plugin_import_mixinr   Zmodules.jira.apir   Zmodules.jira.base_importr   rH   r   r   r   r   Z	dataclassr   r:   r;   r   r   r   r   <module>   s*   $ 