B
    f                @   sD  d dl mZ d dlT 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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$ 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)JiraBaseImport)JQLNormalizerc               @   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 )N)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   y@| j d  | j  r"dS  | f||}| j j  |S  tk
r   | j j  |  jd7  _| j d  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   )r5   r6   )r   )r5   r   	decorator+   s    z"catch_exception.<locals>.decoratorr   )r   r7   r   )r   r   catch_exception*   s    r8   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dddZee ddd Zee dd!d"Zee ed#d$d%Zdd(d)Zed*d+d, Zed-d.d/ Z ed0eed1d2d3Z!d4d5 Z"ed6dee#d7d8d9Z$dd:d;Z%ed<d=d> Z&ed?d@dA Z'edBdCdD Z(e)j*ddEdFZ+dGdH Z,dIdJ Z-dKdL Z.edMdNdO Z/edPdQdR Z0eedSdTdUZ1dVdW Z2dXdY Z3edZd[d\ Z4edZd]d^ Z5ed_d`da Z6edbdcdd Z7dedf Z8d	dgdhZ9e:didjdkZ;e:didldmZ<ednedodpdqZ=drds Z>edtedodudvZ?edwdxdy Z@dzd{ ZAed|d
d}d~ZBeddd ZCeddd ZDededddZEeddd ZFeddd ZGeddd ZHeddd ZIeddd ZJeddd ZKdd ZLededddZMedddZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdddZYdd ZZedoddZ[edoddZ\edoddZ]edoddĄZ^edoddƄZ_ddȄ Z`ddʄ Zaed˃ee:ed̜dd΄ZbddЄ Zcdd҄ ZddeedӜddՄZedeeeed֜dd؄ZfdddڄZgdd܄ ZhedeeeedߜddZidd Zjdd Zkdd Zldd Zmdd Zndd Zodd Zpdd Zqdd ZredddZsdd Ztdd Zueddd Zvdd Zwed dd Zxdd Zy  ZzS (  JiraAPIImportu;   Класс загрузки объектов через APIr/   _JiraAPIImport__jira_fieldsN)jirareturnc                s   t  j|| || _d| _| jjjr*d| _tjjdd| _	| 
 | _i | _i | _i | _g | _g | _d| _td}| jjj|_|| jjj |   d | _d| _d S )Nr   	accountIdsoftdev)coder   zatlassian.rest_clientF)super__init__r;   user_keyconncloudmodelsCmfActivitygetdefault_activity_get_jira_global_settingsjira_global_settingsZepicsissue_relationssubtasksboardsselected_projectsr/   loggingZ	getLoggerr(   loggerZhandlersZsetLevellevel_prepare_multiprocessingr:   update_fields)r   r;   r2   r3   rP   )	__class__r   r   rA   D   s&    


zJiraAPIImport.__init__)r<   c          	   C   s   | j r| j S | j d}| rL| jsLt|}t|| _ W d Q R X n6| j	
 | _ t|d}t| j | W d Q R X d| _| j S )Nzfields.jsonzw+F)r:   r(   get_download_pathjoinpathexistsrS   openjsonloadr;   Z
get_fieldsdump)r   	file_pathfr   r   r   jira_fields[   s    
zJiraAPIImport.jira_fieldsc          	   C   sl   dd l }|| _| j d}| j dt  }t|d}t	| j| W d Q R X |
|| d S )Nr   zfields.jsonzfields.json.zw+)shutilr:   r(   rU   rV   osgetpidrX   rY   r[   move)r   fieldsr_   r\   file_path_tmpr]   r   r   r   update_jira_fieldsk   s    z JiraAPIImport.update_jira_fieldsc             C   s(   x"| j  D ]}|d |kr|S qW d S )Nr   )r^   values)r   r   fieldr   r   r   _get_field_by_namet   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)ri   rj   r4   r   r   r   _get_field_namey   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   rn   ro   rp   rq   Zavailable_memoryr   r   r   rR      s     
 z&JiraAPIImport._prepare_multiprocessingc          
   C   st   g }ddddddddd	d
	}dddd}xF| j  D ]8\}}d| ||d }|||d||d q4W |S )uO    Сопоставление настроек для модели models.CmfTaskr   textprioritystatusZ
alarm_dateZdeadlinecmf_modified_atcmf_created_atstatus_closed_at)	summarydescriptionry   rz   Zcustomfield_10015Zduedateupdatedcreatedresolutiondatez.namez.watchCountz.votes)ry   ZwatchesZvoteszfields. N)model_field	json_path	ext_field)r^   itemsrG   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   r   
cmf_authorauthorrx   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 )Nu   ИмяZEmailu   Активныйu   Созданоu
   Авторu
   Текстu   Ключ)r   r   r   r   r   bodyr   .r'   r   r   )splitlenr^   rG   )r   Zjsonpathmappingr   r   r    _get_setting_title_from_jsonpath   s    
z.JiraAPIImport._get_setting_title_from_jsonpathTc             C   s
  |sd S x2| dD ]$}t| ts&d S | |} | sd S qW |rvt| trvdddg}x|D ]}|| krZ| | S qZW dS |rt| trg }xn| D ]f}d|kr||d d  qd|kr||d d  qd|kr||d  q|r|t| qW d|S | S )	Nr   r   r   r   r   inwardIssueoutwardIssue,)r   
isinstancedictrG   listr   r%   join)r1   r   to_strrj   Z
str_fieldsZ	str_fieldresultZrelated_objr   r   r   _get_file_val   s6    





zJiraAPIImport._get_file_valc       	         st  g  t ttt f tg tt f ttd fdd}jdg j 	d}d}d}|
 rx0 D ]$}x|d D ]}P qW |rnP qnW xdD ]}P qW |sd	d
 jjddD }|r|d }|sdd
 jdD }|r|d }|std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_funcri   r<   c                s~   xx| D ]p}| }xP|D ]H} ||d |d< ||d |d< |d |d< |j|d< qW  |j|d |S W d S )Nr   Zfile_valr   titleicon)r   rc   )r   rl   r   r   r   verbose_name)r   r   ri   r1   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   ).0r1   r   r   r   
<listcomp>  s    z7JiraAPIImport.tmplt_import_settings.<locals>.<listcomp>r'   )limitr   c             S   s   g | ]}|qS r   r   )r   r1   r   r   r   r   "  s    uS   Не найдено ни одной задачи, импорт невозможенTua   Не найдено ни одного пользователя, импорт невозможенz2022-05-22T15:22:22.593+0300u   Имяu!   Электронная почта)r   r   u
   Текст)r   r   r   selectedObjects)r   value)r
   r   r   r   r	   	TypeModelr(   load_fieldsrU   rV   rW   _get_projectsget_project_tasks_simple_getr;   
get_issues	get_usersr-   rS   r   rE   CmfTaskr   	CmfPersonr   
CmfCommentr   )	r   r   Zdump_dirtaskuserprojecttasksr   Zcomment_exampler   )r   r   r   tmplt_import_settings   sJ    $
z#JiraAPIImport.tmplt_import_settingsc             C   s   |  | jjd }ddg g gdg}x| jjddD ]}x~t|tjj d D ]f\}}|d s`qN| 	||d	 }| 
|d d
 |}|d d |d d  |d d d | qNW q4W |S )Nimport_settingsu   Задачиzcalendar-today)r   r   titlesrows   )r   rc   r   r   rj   r   r   captionr   )Z_normalize_settingsr(   json_settingsr;   r   	enumeraterE   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 }xV|D ]N}|d sq
| j ||d dd}| |d d ||d}|||d d < q
W |S )uC    Преобразование настроек для модели r   r   F)r   rj   r   )r   r   rG   )r   r1   r   Znormalized_objr   r   r   r   r   _normalize_objM  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_idz==completeDatesys_typearchive)filterz::r   r   	startDateendDate)r   parenttree_parent	list_typeplan_start_dateplan_end_dateext_idr   )
filter_objT)save_import)r   rG   r   rE   	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_listY  s&    

zJiraAPIImport._process_listu8   Обработка наблюдателей задачиc             C   s   d|d  d|d d  d}x|  |D ]r}| jjjrL| j|d |d}n| j|d |d}|sptd	| ||jks*||jks*||jkrq*|j	
| q*W t  d
S )u;   Добавляем наблюдателей в задачуu$   Наблюдатели задачи r   z: "rc   r~   "r=   )r1   uI   _process_watchers: Не найден наблюдатель задачи N)_get_issue_watchersr;   rC   rD   _get_personCmfErrorresponsibler   	cmf_owner
spectatorsr   commit_with_event)r   	issue_objr   r1   watcherpersonr   r   r   _process_watchersr  s    
zJiraAPIImport._process_watchersu#   Обработка вложенийc             C   s.  ddl m} dd l}d|d  d|d d  d}t|d	  d
}d}| r,||}x| D ]}	zy|	drwlx"|d d D ]}
|
d |	krP qW tj	
|	}tjj||ddddgd}|stj| j|d|d}|jr|
r| j|
d | j |d|_|
d |_||	d}|jdd || |jdd |
rz|j|
d ksztd|j d|
d  d|j  W d 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 d | jdd# X qlW W d Q R X x| |D ]}zytj	
|d$ }tjj||d%}|szt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 d | jdd# X q8W |S )'Nr   )RDisku   Вложения задачи r   z: "rc   r~   r   
issue_pathz /attachments/all_attachments.zip/
attachmentfilenameimport_originalurlZurl_preview_imgZurl_preview)r   r   rc   T)r(   r   r   r   r   )r1   r   )r   sizeu   Текущий размер z != u    из метыu7   Обранужена проблема вложения uI   , размер файла не совпадает с метой из JIRAzERR-0034r'   u:   Не удалось обработать вложение zERR-0035	processed	file_name)r   r   r\   )(Zrdisk.rdiskr   zipfiler   rW   ZZipFileZnamelistendswithrE   CmfDocument_get_filenameCmfAttachmentrG   r(   r   r   rB   r   r|   rX   r   Zupload_stream_filest_sizeAssertionErrorr+   r,   r0   r.   inc_stat_get_issue_attachmentsZ
upload_dirr_   copyZfull_path_fileZCmfRFileZdata_driverZget_rdZ	get_rfileZ
_file_namemake_preview)r   r   
jira_issuer   r   r1   Zall_attach_zip_patherrorsZmyzipZzip_attach_nameattach_infoZattach_namer   Zattach_fattachment_infoZrdiskZrfiler   r   r   _process_attachments  s    




,



z"JiraAPIImport._process_attachmentsuB   Обработка упоминаний пользователей)rx   r<   c             C   sz  ddl m}m} |sdS t|d}xL|jddidD ]6}y|jdr\| |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 q6 tk
rl } z0|  jd7  _| jjd| d| d|d W dd}~X Y q6X q6W t|S )u]   
        Упоминания пользователей
        confluence-userlink
        r   )urlparseparse_qsNzhtml.parserclassz
user-hover)attrszdata-account-idzdata-usernamezdata-linked-resource-idzdata-linked-resource-id_origzdata-username_orighrefr   	href_origTcmf_convertedr'   u)   Ошибка обработки тега z: zERR-0036)r1   )Zurllib.parser  r  r   find_allr  rG   r   query_get_user_info_from_dumplowerrB   r  r   r   loginr-   r/   r(   r0   r%   )r   r   rx   r  r  doc_souptagr   
parsed_urlr  	user_infoer   r   r   _process_mentions  s4    


 zJiraAPIImport._process_mentionsc             C   s   t jj}|| jj d| }|d k	r2t|S xV| dD ]H}|| j	|krV|S |dd
 |krn|S |dd
 |kr>|S q>W td| d S )Nz:user:r   r   r   usernameuQ   Не нашли информацию по пользователю в дампе )APPREDIS_DBredisrG   r(   r   pickleloadsr   rB   r  r-   )r   user_idredis_dbr  r   r   r   r    s    
z&JiraAPIImport._get_user_info_from_dumpu#   Конвертация ссылок)rx   r   c                s  |s|S t |}x|dd D ]x}|jdrJ| jjd|  q"|drz|jd drz| 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"W 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   z(/attachment(?:/content)?/(\d+)(?:/)?(.*)r'   rc   r   c                s   |  d kS )Nr   )rG   )item)	attach_idr   r   r)    r*  r   r   )r   rc   r   Zsrc_origTZvideoZcontrolsz100%widthZheightr  u   Заменили на z/people/r   )r   r  r  rG   r(   rP   infor(  
startswithurllibparseunquoter   researchnextr   rE   r   r   r  sgetr   	mimetypes
guess_typer   r   r  r%   )r   rx   r   r  r  Z	text_soupr  r   r   	url_matchattachmentsattachZ
attach_obj	mime_type
account_idr   r   )r/  r   _process_links  sd    

 
 





zJiraAPIImport._process_linksc          	   C   s>  |rd| dnd}| j jd|  | jjjrV|d dkrV| 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}
|
st	j
jddd| dg|	d}
|
st	j
jdd|d g|	d}t|dkr| j jd|d  dt| d| ddd |  jd7  _g }|sJ| j jd|d  d|  d
d|d
 g}t	j
j||	d}|sJt|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r|  jd7  _| j jd!|d
  d"|d  d#t| d| ddd |r|d }
n*| j d$|d
  d"|d  d%| tj d&}|
s~|rvd'}d}|d }xht	j
jdd| g|	dr^| j d(| d)tj |d d*\}}| d+| d*| }|d7 }qW t	j
||| j d'd,}
nd |fS |r6|
jrx|D ]}t|
|||  qW |
jr||
jkr|
j | |
_n||
_t	j }t	j }|
j !| |
j !| d'|
_"x|d- d. D ]}| jjjr>d	|d/  d	}nd	|d
  d	}d	| j jjj | }t	jjddd| dgdgd}|st	jjd
d|d
 gdgd}|st	j|| j d'|d
 |d0}|jr|d
 |_#|js||_n||jkr|j | |_|j$d'd1 |
j !| qW |
j%r6|
j$d'd1 |
|fS )2N()r   u0   Импортируем пользователя ZaccountTypeZ	atlassianu   Неизвестный тип rc   z::r    r'   r   Z
first_name	last_namer   rg_member_ofr  ILIKEr   )r   rc   r   LIKE%u+   Пользователей с почтой z > zERR-0037r   )obj_typeuH   Не удалось найти пользователя с почтой z==ORu+   Пользователей с именем z (z) > uM   Не нашли пользователя среди существующих z) FTuQ   Обнаружена учетная запись с дублирующим email u   , добавляем цифру@+)r   r  r(   r   groupsr   groupId)r   r(   r   r   import_raw_json)r   )&r(   rP   r1  r;   rC   rD   warningr   r   rE   r   r   r   r   rB   r   r   rG   r   r0   r/   r)   rO   INFOr  WARNINGr   setattrr   CmfPersonGroup
jira_group
user_grouprF  r   Z
user_localr   r   
is_changed)r   r   createupdater1   Zobj_msgZ	user_dictr   r   rc   r   Zpersonsr   
is_creatednr  Zprefix_emaildomainr   rV  rW  Z
group_infogroupr   r   r   _process_person8  s      "
&




 
zJiraAPIImport._process_personu   Обработка группc          	   C   s<  x4|  dD ]$}y| j r$d S d| jjjj d|d  d}tjjddd| dgdgd}|stjjdd	|d gdgd}|stj|d || jd
|d}|jr|d |_	|j
s||_
n||j
kr|j
 | |_
|jd
d |j  | j jd7  _W q   |  jd7  _| jjd| ddd Y qX qW d S )NrN  z::r   r   rH  rI  r   )r   rc   rG  T)r   r   r(   r   rP  )r   r'   u4   Не удалось загрузить группу zERR-0038rU  )rJ  )r   r(   r*   r   r   rE   rU  rG   r   r   r   r   r+   r,   imported_object_countr/   r0   )r   Z
group_datar   r^  r   r   r   _process_groups  s8    
 


zJiraAPIImport._process_groupsu-   Обработка пользователейc          	   C   s   | j jjdds(| j jdtjd d S t }x| dD ]}yZ| j 	 rNd S | 
|\}}| j  jd7  _|jr|js|jds|r||jj W q:   |  jd7  _| j jd| d	d
d Y q:X q:W |r| j jjddrttjjt|gd d S )N
load_usersTuA   Не грузим пользователей из-за опций)rQ   r   r'   z.evateam.ruu@   Не удалось загрузить пользователя zERR-0038r   )rJ  Zsend_invites)r2   )r(   r   r   rG   r)   rO   rS  setr   r*   r_  r`  r   r   r   addr/   r0   Zschedule_deferred_jobrE   r   Zregister_personsr   )r   Znew_user_emailsr   r   r[  r   r   r   _process_users  s&    
zJiraAPIImport._process_usersu#   Обработка статусовc             C   s   x|  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W dS )uc   
        Грузим статусы из Jira и сопостовляем с нашими
        statusesNstatusCategoryr   z::r   )r   z==r   )r   )r   r(   T)r   r'   )r   r(   r*   r;   rC   rD   r   r   rE   CmfStatusCoderG   r   r   get_status_typestatus_typer   r   r+   r,   r`  )r   rz   rj  r   Zcmf_status_coder   r   r   r   _process_statuses  s(    





zJiraAPIImport._process_statusesc             C   sP  i }i }d}d}x|  |d D ]r}g }xF| j|d dD ]2}|d r:|d |d d d kr:||d  q:W |  |t|g }	|	| q W tjjdd}
xt	|
 d	d
D ]\}\}}| jjjj d|d  dd| }tjjdd|gd}|s<tj||
| jd}d|d  d| d|_|jdd x4| j|d dD ] }|d |krN| || qNW xft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 qW xd|D ]\}|s|d dkr|}|s|d dkr|}d| jjjj d|d  d}|||< qW qW | jjjj d|d  }d |d  }tjj|d!}|stjjd"d}tj||| jd}||_||_||_|jdd x tjj|d#D ]}|  qW xj|
 D ]^\}}| j r P tjjdd$d%| d%gd}||d&|| jd'}tjf |}|jdd qW |S )(u)  
        У простого проекта воркфлоу привязан к issue type 1 к 1
        Поэтому надо получит все типы привязанные к проекту, на каждый тип создать WF и замапить через схему
        Nr   )
project_idZusagesr   
issueTypeszdefault.system:default)r?   r'   )startz
::SIMPLE::z::-r   =)r   )r   templater(   u9   Simple бизнес-процесс для проекта r   z (rC  T)r   workflowz==rj  )r   rc   z!=)forcehierarchyLevelr,  u(   Simple-схема для проекта )r   zsoftdev:default)	scheme_wfrH  rI  r   )
logic_typetarget_workflowcmf_model_nameru  r(   )_get_issue_types_for_project_get_statuses_for_projectr   sort
setdefaulttuplerE   CmfWorkflowrG   r   r   r(   r   r   r   r   r   _create_status	CmfStatusr   rj  deleteCmfSchemeWfdefault_task_workflowdefault_subtask_workflowCmfSchemeWfRuler*   CmfLogicType)r   Zjira_project_infoZissue_type_group_by_statuses	issue_mapZdefault_task_wfZdefault_subtask_wf
issue_typeZissue_type_status_idsjira_statusZissue_type_listwf_templateindexZ
status_idsissue_typesworkflow_ext_idrr  rz   issue_type_ext_idscheme_ext_idZscheme_nameschemerq  rulelogic_type_ext_idrv  	rule_dictr   r   r   #_create_schemewf_for_simple_project  sv     "&
z1JiraAPIImport._create_schemewf_for_simple_projectc             C   sH  | 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d	d
d ggd}|stjjdd
|d gdd
|gd	d
d ggd}|stj|| j |d}||_|d |_|d |_d|_||_||_	|j
|j d |S )Nz::r   )r   rg  r   )r   r   r(   T)r   r   z==)r   rr  status_code)rr  r(   r  r   F)	only_data)r(   r   r   r   rE   rh  rG   r   ri  rj  r   r  r   r   rx   allow_empty_transitionr  is_new)r   Zjira_status_datarr  status_ext_idr   r  rj  rz   r   r   r   r  U  s:    "

zJiraAPIImport._create_statusc       /      C   s  ddl m} dd l}i }d }d }i }tjjdd}|d d }	xt|	D ]j}
||
d }| jjjj	 d|d	  d
| }tjjdd|gd}|stj||| jd}|
d |_
|
dd|_|jdd |s|
dr|}|
d }x| j|d	 dD ]}|d	 |krqd|d krq|s.|dr.|}d
| jjjj	 d
|d	  d
}|||< x6|d D ]*}|d d |d< | ||||d	 < q^W qW xft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! qW | jjd" d#}| jj}| jj}d$}|tj|j
j }y6|j||j||d%d&d'i||d(d)}| j  d*}t!|d+}|"|j W d Q R X t#|jd,}|st$d-t% }t }x|&d.D ]}|j'dd/id0j() }|| ||d	 < xV|&d1D ]H} |*| d	 | d | j'dd2id0j() |d	 | &d3d d4 d5 qW qW |spt$d6t+| d7t+| d8x<|&d9D ].} || &d3d d4  }!d|!_,|!jdd: q|W | j-d;t+| d<t.j/ x|D ]}"| jjjj	 d
|j0 }#|# d
|"d	  }$tj1j|$|d=}%|%s&tj1|$|| jd>}%|"d |%_
|"d |%_||"d?  g|%_2||"d@  |%_3|%jdd qW W qF t$k
r }& z$| jj4dA|j
 dB|& dC|dD W d d }&~&X Y qFX qFW | jjjj	 d
|d d	  }'tj5j|'dE}(|d dF })|(s&tj5jdGd}*tj5|)d |'|)dd|)| j|*dH}(||(_6||(_7|(jdd x tj8j|(dID ]}+|+  qNW x\|9 D ]P\},}tj:jddJdK|, dKgd}-|-|dL|(| jdM}.tj8f |.}+|+jdd qjW |(S )NNr   )cmf_hashlibzdefault.system:default)r?   jira_workflow_schemeZmappingsr   z
::SIMPLE::r   z::r   rp  )r   )r   rq  r(   r   r   T)r   defaultrm  )rl  	issuetyper   subtaskrf  rg  r   rr  z==rj  )r   rc   z!=)rs  r   z&/secure/admin/WebSudoAuthenticate.jspazL/secure/admin/workflows/ViewWorkflowXml.jspa?workflowMode=live&workflowName=FzX-Atlassian-Tokenzno-check)ZwebSudoPasswordZwebSudoDestination)authZverifyZheadersdatazworkflows.xmlzw+lxmlur   Не удалось получить список переходов между статусами в виде XMLzsteps > stepzjira.status.id)r  zactions > actionzjira.descriptionzresults > unconditional-resultstep)r   r   r   fromtou   Из XML получено u    статусов и u'    переходов между нимиzglobal-actions > action)r  u   Настраиваем u1    переходов между статусами)r   rr  )r   rr  r(   r  r  u   Не удалось импортировать переходы между статусами для бизнес-процесса «u   »: zERR-0067)r1   )r   r1  zsoftdev:default)r   r   rx   rP  r(   rq  )ru  rH  rI  r   )rv  rw  rx  ru  r(   );Zcmf.utilr  requestsrE   r~  rG   Zshort_str_encr(   r   r   r   rx   r   rz  r  r  r   rj  r  r;   r   rstripr  passwordr3  r4  Zquoter   Zpostr  ZHTTPBasicAuthrU   rV   rX   writer   r-   r   selectfindr8  stripr   r   r  r)   rO   rR  r   CmfTransstatus_from	status_tor0   r  r  r  r  r   r  )/r   project_infor  r  r  Zdefault_wf_for_taskZdefault_wf_for_subtaskZall_statusesr  Zworkflows_dataZworkflow_dataZworkflow_name_hashr  rr  r  r  r  r  rz   r   r  r  Zrequest_urlZdestinationresponseZworkflows_pathr]   ZxmlZ
jira_stepsZjira_transitionsr  Zjira_status_idactionsjira_transitionZworkflow_hash_idtransition_ext_id
transitionr  r   Z	wf_schemeZwf_scheme_inforq  r  r  rv  r  r   r   r   _process_wf_scheme  s     
$


 

z JiraAPIImport._process_wf_schemec          	   C   sZ   d}t dd8 x0| j rP | }|dkr0P || |7 }qW W d Q R X || d S )Nr   F)init_views_and_dsDONE)r   r(   r*   rG   _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   s2  ddl m} t }xR| j|d | |d dD ]2}| j rBd S |d dr0||d d }q0W x|D ]}|	dd	d	d
}||ddd}y\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 ql tk
r( }	 ztd| d|	  W d d }	~	X Y qlX qlW d S )Nr   )translitr   )r   rc   labelsrD  _r+  r   ruT)Zlanguage_codereversedrK  aliasrG  r   z"%r   )r   )r   )r   u*   Не удалось создать тег z: )Ztransliterater  rc  r   _count_project_tasksr(   r*   rG   unionreplacerE   ZCmfTagr   r-   rO   rQ  )
r   r  r  tagsr   Ztag_nameZ
name_aliasr   Ztag_objr  r   r   r   _process_tags  s*    "

zJiraAPIImport._process_tagsu)   Обработка приоритетовc       
      C   s   | j jjj d|d  }tjjdd| dgd}d}dd	d
dddd}xV| dD ]H}|d |d krlqVx.|d D ]"}|d |krqv|d ||d < qvW P qVW xH|D ]@}tjjd|d}	|	stjddd|| j d}	||	_	|	j
dd qW d S )Nz::r   r   rG  rI  )r   )ZLowestZLowZMediumZHighZHighestu   Отложеноu   Минимальныйu   Самый низкийu   Низшийu   Низкийu   Среднийu   Обычныйu   Высокийu   Высшийu   Наивысшийu   Критичныйu   Критическийu   Минимальныйu   Низкийu   Обычныйu   Высокийu   Критичныйu   Блокирующий)r,  r   r'         priority_schemesr   ZprojectKeys
prioritiesr   ry   )r   r   u   Приоритет)r   r   Zorig_captionr   r(   T)r   )r(   r   r   rE   CmfCustFieldConfr   r   CmfCustFieldConfFieldrG   choicesr   )
r   r  cust_field_conf_ext_idZcust_field_confsZpriority_namesr  Zpriority_schemery   cust_field_confcust_field_conf_fieldr   r   r   _process_priorities6  s8    

z!JiraAPIImport._process_priorities)project_structr  c             C   s  t jjdd|d gddgd}|r|jj|d ksF|jr|d |jkr|d  d|d  d|d< | jjd|j	 d	|d   n|js|d |_|
  d
|d< | ||d< t jjddd|d  dg| d}|st j| j|d |d d
d}|jr@x,|D ]$}|dkrqt||||  qW |dr@d|_|j}|
  |rzx$t jj|dD ]}|jd
d qdW x| |d D ]}| 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}
|
sNt j||	| jd}
g |
_|
j
d
d x|dg D ]}|d dkr"| jjjr| |d  d! }nRy| |d }W n>   | jjd"|	 d#|d  d|d$  dd%|d& d }Y nX |r
|
j | n| jjd'|  qp|d d(kr0| jjjrRd|d) d*  d}nd|d  d}d| jjjj | }t j!jddd| dgdgd}|st j!jdd+|d gdgd}|r|js||_n||jkr|j | |_|j
d
d |
j | n(| jjd,| d-d.|d& |  j"d/7  _"nt#d0qpW |
j
d
d qW | $  | %| | &| | $  | j'|d1 | (||_)| *||_+| ,||_-| .| |j
d
d | /| | j0 rd S t1  | 2| | $  | 3| | j j4d/7  _4| $  |S )2Nr   z==rv  r   )r   rc   z (rC  u   Проект с именем u8    уже существует! Переименуем в TZtask_allow_multiple_sprintsui_form_schemerH  rI  )r(   r   r   r   	isPrivateprivate)r   )TEXKOM_db_deleter   z::)r   )r   )r   r(   r   r   )r   )r   project_role)r   r  r(   actorstypezatlassian-user-role-actorr  r=   uX   Не удалось найти и добавить пользователя в роль u    проекта: r   zERR-0039)r1   uR   Не удалось привязать пользователя к проекту zatlassian-group-role-actorZ
actorGrouprO  rG  u<   Не найдена группа пользователей u#    для проектной ролиzERR-0040r'   u&   Неизвестный тип роли)r  )5rE   
CmfProjectrG   rv  r   r   r(   rP   rQ  r   r   _process_screen_schemekeysr   rT  Zperm_policyr  r   r   r  _get_project_rolesr   r   CmfProjectRolerx   ZCmfProjectRoleAssignmembersr;   rC   rD   r   r0   r   rU  r/   r-   _calc_progress_process_versions_process_componentsr  _process_permissionsZproject_perm_scheme_process_security_levelssecurity_level_scheme_process_field_conf_schemecust_field_conf_schemer  _process_tasksr*   r   _process_boards_process_sprintsr`  )r   r  r  project_objr   r  r   	role_infor   roleZrole_assignactorr   Z	sub_groupr   r   r   _process_projectn  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   z/usr/bin/python3z	manage.pyshellz&plugin = models.CmfPluginJira.get(id="z(");retcode = plugin.process_issue_fork("z", "r   z", z, z);Tz"/var/log/eva-import-subprocess.logza+z&/var/log/eva-import-subprocess.err.log)	close_fdsstart_new_sessionstdoutstderru   Запустили )
subprocessPopenr(   r   r   rr   IMPORT_OBJ_CNTrX   r)   pid
log_detail)r   r  doner  procr   r   r   _execute_task  s    
4
zJiraAPIImport._execute_taskc       	      C   s  | j jd| j  d}| |d }g }x<t| jD ].}| ||}|tj7 }|	| ||kr8P q8W xp||k rt
d xXt|D ]L}| }|d k	r|  j|7  _|| | ||}|tj7 }|	| qW qlW x.t|D ]"}|  |jr|  j|j7  _qW | j jd d S )NuD   Грузим задачи в несколько процессов: r   r   r'   u0   Закончили обработку задач)r(   rP   r1  ru   r  ranger  rr   r  r   timesleepr   pollr/   removecommunicate
returncode)	r   r  r  Ztask_cntprocessr  r  r  new_procr   r   r   r    s2    





zJiraAPIImport._process_tasksu#   Обработка проектовc          
   C   s  t jjddjj}x|  D ]}yp|d dd | jD krBwd }| j rZt	  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 }|rX| |}	|	|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W d S )"Nr>   )r?   r   c             S   s   g | ]}|d  qS )r   r   )r   r1   r   r   r   r   +  s    z3JiraAPIImport._process_projects.<locals>.<listcomp>leadzdefault_import_jira@evateam.comdefault_import_jira)r   r   projectTypeKeybusinesszproject.base:defaultsoftwarezproject.agile:defaultservice_deskzproject.servicedesk:defaultu$   ERROR! Проекты с типом u3    временно не поддерживаютсяz::r   r   r   r   )r   rv  rx   activitytask_code_prefixr   r   rP  
simplifiedru  r  )r   r'   u<   Не удалось импортировать проект zERR-0041r  )rJ  )rE   rF   rG   r   r   r   rN   r(   r*   r   r   rB   r  r-   r   r   r  r  r  Zrollback_purge_eventr/   r0   )r   r  r  r  project_leadr   rv  r  Zproject_simplifiedr  r   r   r   r   _process_projects&  sV    


zJiraAPIImport._process_projectsc          
   C   s  d }t jjddjj}xz|  D ]l}y"| j r:d S |d dd | jD krTw"| 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"W d S )Nr>   )r?   r   c             S   s   g | ]}|d  qS )r   r   )r   r1   r   r   r   r   m  s    z7JiraAPIImport._process_projects_box.<locals>.<listcomp>z::r   r  zdefault_import_jira@evateam.comr  )r   r   r	  r
  zproject.base:defaultr  zproject.agile:defaultr  zproject.servicedesk:defaultu$   ERROR! Поректы с типом u3    временно не поддерживаютсяr   r   r   )r   rv  rx   r  r  r   r   rP  ru  r'   u<   Не удалось импортировать проект zERR-0041r  )rJ  )rE   rF   rG   r   r   r   r(   r*   rN   r   r   r   rB   r  r-   r  r  r   r/   r0   )r   r  r  r  r  r   rv  r  r   r   r   _process_projects_boxe  sJ    
z#JiraAPIImport._process_projects_boxu   Обработка досокc             C   s  t jjddd|d  dgd}t jjd|dgd}|sNt jd||d| jd	}|jsbd
|_|  xp| |d D ]\}y$| j rdS | jj	j	j
 d|d  |d< t jj|d ddddddddgd}|st j|d | jd}|d |_|d |_||_||_|jd
d |j  |jr|d d }|r| jj	j	j
 d|d  }t jj|dddgd}|s~t j| j|d
d}|jr|d |_||_|jd
d ||_|jd
d dddd d!d"d#}	|d d$ }
|	|
d% d"|_d|_|jjd
d x|
d& ddd' D ]~}| jj	j	j
 d|d  }t jj|dddgd}|sXt j| j|d
d}|jrp|d |_||_|jd
d |j| qW |jd
d d|_|jjd
d x|d d ddd' D ]~}| jj	j	j
 d|d  }t jj|dddgd}|st j| j|d
d}|jr*|d |_||_|jd
d |j| qW |jd
d d(d)d*d+d,}||d d d+|_x|jD ]}|  qW |j  x|d d- d. D ]}yt j|d || jd
d/}|jd
d x\|d0 D ]P}| jj	j	j
 d|d  }t jj|d1}|s$td2| d3|j| qW |jd
d |j  W n8 tk
r   |j   | jj!d4| d5|d6 Y nX qW | j j"d77  _"W qt   | jj   | jj!d8| d9|d6 Y qtX qtW 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   rH  rI  )r   u
   Доскиtree_node_is_branch)r   r   rc   N)r   r   r   r   r(   Tr   z::kanban_board_columnsrP  r   r   
limit_dayskanban_filterswimlane_filtersquick_filters)r   rc   )r   r(   r   r1  )r   r   r   )r(   r   r   z	1 queriesz2 userstoryz
3 assigneez4 epicz	5 projectz7 none)customZparentChildassigneeZepicr   ZnoneswimlanesConfigZswimlaneStrategyZ	swimlanesr,  z1 -1wz2 -2wz3 -4wz6 none)z-1wz-2wz-4wZNONEZcolumnConfigcolumns)r   r   r(   r   rf  )r   u   Не найден статус u    для колонкиuD   Не удалось создать колонку для доски zERR-0042)r1   r'   u:   Не удалось импортировать доску zERR-0043)#rE   r  rG   r   r(   r  r   _get_project_boardsr*   r   r   ZCmfKanbanBoardr   rP  r   r   r+   r,   r   CmfTaskFilterr  Zswimlane_typer  r   r  r  r  r  ZCmfKanbanBoardColumnrh  r  Zmapped_status_codesr.   r0   r`  )r   r  r   Zboard_folderboardZ	board_objZboard_filterZkanban_filter_ext_idr  Zswimlane_type_mappingZswimlanes_configZswimlaneZswimlane_ext_idZswimlane_filterZquickfilterZquick_filter_ext_idquick_filterZlimit_days_mappingcolZ	board_colrz   r  Zstatus_globalr   r   r   r    s     










zJiraAPIImport._process_boardsu#   Обработка спринтовc             C   sB  t jjddd|d  dg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}x| |d D ]}| j rd S | jjjj	 d|d  }t j
j|d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rl||_|js\d|_|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%   x:|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}|s`t j|| jd-}d.|_d/|j d0|j d1|_ ||_!|jr|j|j" d2 |j#d krt|j$d3kr|j%&| n|j%&| n0|  j'd37  _'| jj(d4|	 d5|d  d6|d7 qW |jdd t  | j j)d37  _)| j*dd8 qW d S )9Nr   rH  rI  )r   r   z==r   r   r   r  )r   rc   zlist.agile_sprint:default)r?   r   z::r   rv  r   r  rr  r   r   rz   )r   rc   T)r   r   r(   rv  r   r   )r   stateclosedCLOSEDr   ZIN_PROGRESSu0   Добавляем задачи в спринт z: issueslistscache_status_typer   z::comment-sprint:	log_levelrx   r   )r   r(   r  uB   Задача была в архивном спринте <a href="z" target="_blank">z</a>)r  r'   u-   Неизвестная задача issue_id=u    в спринте zERR-0044)r1   r   )+rE   r  rG   r   r  _get_all_sprintsr(   r*   r   r   r   r   rv  r   r   r   rX  r   r   r  rr  Zget_default_statusrz   r   rP   r1  r   r   r   r   r(  r  rx   r   r  r'  r&  r  r   r/   r0   r`  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  (  sr     "

$zJiraAPIImport._process_sprintsc             C   s$   |sd}|sd}| d| d| S )Nu   Не указаноz: u    ➔ r   )r   r   	old_valueZ	new_valuer   r   r   _simple_html_diffj  s
    zJiraAPIImport._simple_html_diffc             C   s   |dkrd S y|  |}W n&   | jjd| dddd tjS | j|d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CmfUser)rJ  F)r1   Zdefault_user_id)r   uA   ", ставим пользователя по умолчанию )rQ   uc   ", указываем системного , в дампе, указываем системногоr'   )r  r(   r0   gZsystem_userr_  r   r   rG   rE   r   r)   rO   rS  r/   )r   r%  r1   r   r   r  r   r   r   r   q  s$    
 
zJiraAPIImport._get_person)	dump_pathc          	   C   s   | d}| rTt|d2}x*|D ]"}t|}|d |d kr$|S q$W W d Q R X t|d}|t|d  W d Q R X |S )Nzgroups.jsonrr   za+
)rV   rW   rX   rY   r$  r  dumps)r   r^  r1  Zgroups_pathr]   rowr1   r   r   r   _dump_groups  s    


zJiraAPIImport._dump_groupsc             C   s   y
|  |S  tk
r   y|d}| rnt|d0}x(|D ] }t|}||| j kr@|S q@W W d Q R X | j	|}|rt|d}|
t|d  W d Q R X |S W n$   | jjd| tjd Y nX Y nX d S )Nz
users.jsonr2  za+r3  uM   Неудалось сдампить пользователя по ключу )rQ   )r  r-   rV   rW   rX   rY   r$  rB   r;   Zget_user_infor  r4  r(   r)   rO   rS  )r   r%  r1  Z
users_pathr]   r5  r1   r  r   r   r   _get_user_info  s$    



zJiraAPIImport._get_user_infou,   Обработка журнала работ)r   c             C   sN  | j jd d|d  d|d d  d}x| |D ]
}t }d|d	< | j |d
< | j|d | j |d|d< |d |d< | j|d | j |d|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tj|jjd! |_|jd"d# q:W d S )$Nu*   Загружаем журнал работu%   Журнал работ задачи r   z: "rc   r~   r   r#  rz   r(   r   )r1   r   r   updateAuthorcmf_modified_byr   Zstarted
start_dateZtimeSpentSeconds<   
time_spentr,  r   rx   z::r   r   rP  r   Zremaining_estimate)r   )ZminutesT)r   )r(   rP   r1  _get_issue_worklogsr   r   rB   rG   r   r   rE   ZCmfTimeTrackerHistoryr:  r   datetimeZ	timedeltar<  end_dater   )r   r   r   r1   worklogZtimetracker_historyhistoryr   r   r   _process_issue_worklog  s,    

z$JiraAPIImport._process_issue_worklogc       	      C   s   |s|S t |d}x|dD ]}|d}||j |  || |dg }dd |D }|sx|dg |d< q|d d	d
d
 }|d| g |d< qW t	|S )uF   
        Конвертирует "Фрагмент кода"
        zhtml.parserZprer?   r  c             S   s   g | ]}| d r|qS )zcode-)r2  )r   class_r   r   r   r     s    z/JiraAPIImport._convert_code.<locals>.<listcomp>zlanguage-noner   ro  r'   z	language-)
r   r  new_tagextendcontentsclearr   rG   r   r%   )	r   r1   rx   soupr  Zcode_tagZ	class_tagZ
code_classr?   r   r   r   _convert_code  s    


zJiraAPIImport._convert_codeu8   Обработка комментариев задачиc       
      C   s  d|d  d|d d  d}d}d}x|  |D ]}|d7 }| jjjj d	|d
  }tjj|d}|r|js| jjd| d|d q4|stj||| jdd}| j	|d | j
 |d|_|j|_| j	|d | j
 |d|_|d |_|d |_||_| ||d |_| |jj|||_| ||jj|_||_|dr|d7 }|d d dkrtjj|d d d}	|j|	 d|_n,| jjd|d  d|d |  jd7  _q4|jdd | jdd q4W | jd | d!|  d S )"Nu$   Комментарий задачи r   z: "rc   r~   r   r   r'   z::r   )r   uN   Комментарий уже есть, и правился в системе zERR-0046)r1   T)r   r   r(   r   r   r8  r   r   r   Z
visibilityr  r  r   )r   uL   Ошибка обработки приватного комментария zERR-0047)r   r,  r   u   Обработано u:    комментариев, из них приватных )_get_issue_commentsr(   r   r   rE   r   rG   r   r0   r   rB   r   r   r9  r{   r|   r   r  rx   rA  r   rI  rP  r  r   r   r  r/   r   r  r)   )
r   r   r   r1   cntZprivate_cntr,  r   Zcmf_commentr  r   r   r   _process_issue_comments  sH    




z%JiraAPIImport._process_issue_commentsu0   Обработка плагинов задачиc       	      C   s   |j jp
d}x| |D ]}|d dkr|d rt|d}|jdddid	}x`|d d
D ]N}|sfq\|dr||d}n|jdddid	}||dd   || q\W || t||j _qW |j	r|j
dd d S )Nr   r   z&com.railsware.SmartChecklist.checklistr   zhtml.parserZulr  ztox-checklist)r  r3  ro  liztox-checklist--checkedr'   T)r   )rx   r   _get_issue_propertiesr   rD  r   r2  r   r%   rX  r   )	r   r   r   rx   Zissue_propertyrH  Z	checklistvalrM  r   r   r   _process_properties  s"    


z!JiraAPIImport._process_propertiesc          	   C   s  d|d  d|d d  d}dd | j tjj d D }xR|d	 d
 D ]@}| jjjj d|d  }d }|dr| j|d | j	 |d}n| jj
d|  |d |d|d}xv|d D ]j}	|	d }
||	d }|r|d rd}
| |
|	d |	d }d|kr||d< q|d  d| |d< qW tjj|ddddddgd }|sdtj| jd!|d"}x|D ]}t||||  qjW |  qJW d S )#Nu   История задачи r   z: "rc   r~   r   c             S   s   i | ]}||d  qS )r   r   )r   rg   r   r   r   
<dictcomp>  s    z2JiraAPIImport._process_history.<locals>.<dictcomp>	changelog	historiesz	::historyr   r   )r1   u   Аудит без автора r   r'   )r|   r   r(  r   r   rg   r   r   Z
fromStringZtoStringrx   z<br>r(   r|   r   r(  r   )r   rc   T)r(   r   r   )r   rE   r   r   r(   r   r   rG   r   rB   rP   rQ  r.  r   rT  r   )r   r   r   r1   Zjira_map_fieldsrA  r   r   r,  r.  r   rg   ZdiffZhistory_commentr   r   r   r   _process_history  s0    



zJiraAPIImport._process_historyu   Обработка задачиc             C   s$  d}| j jjj d|d d d  }tjjddd| dgd	}|s`td
|d d d  d|d  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r| j jjj d|d dd  }tjj|d|d< |d s| j jd|d d ddd |  jd 7  _| d!}	|	r|d |	d |d"< |d d#r^| j|d d#| j|d$|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| j|d d)| j|d$|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| j|d d,| j|d$|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/< |d0 r|d1 d2 |d0< ||d/< |pg }d| j jjj d|d d3 d  d}
tjjddd|
 dgd	|d4< | j jd5|  tj| j tj	|dd6|d gd7\}}|| ||7 }| ||jj|_|  |jj|||_| !||jj|_|d d8 d9 r| "|| | j#d:r| $|| x|D ]}|j%&| qW x|d d;g |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(&| qW x||d dAg D ]h}| j jjj d|d  }tj)j|d}|s| j jdB| dCdDd |  jd 7  _n|j*&| qW |d dE |_+||_,|j-r|j.ddF t/  | 0|| |d dGg }|rpyt1| j || W n   | j j2dH Y nX | 3|| | 4|| | j jjj dI|d  }tj5j|d}|stj5|| j dJ}||_6| j7j8 dK|d  }dL| dM| dN|_dO|_9|j.ddF |j:;  | j <dPdQ |S )Ru   
        Общая логика обработки которая потом разделяется на задачи и эпики
        r   z::rc   r   r   r   rH  rI  )r   u$   Не проекта с ключем r   u   Задача z: "r~   r   z%::rz   rj  )r   rc   r'  r  TZapprovedr?   security)r   Zperm_security_levelu:   Не найден уровень безопасности zERR-0048r   )rJ  r'   zStory PointsZagile_story_pointsreporter)r1   r   u*   Не найден автор задачи zERR-0049)rm   exc_infocreatorr   u?   Не найден ответственный по задаче r  r   u6   Не найден исполнитель задачи r   rx   renderedFieldsr   r  rv  u2   Пытаемся создать задачу из z==)r   r,  totaltimeTrackingEnabledZfixVersionsZversionsz
::version:u!   Не найдена версия zERR-0050r   
componentsu%   Не найден компонент zERR-0051CmfComponentr   )r   r  u/   Не удалось привязать тегиz
::comment:)r   r(   zbrowse/u<   Задача импортирована из Jira: <a href="z" target="_blank">z</a>r  r   r   )=r(   r   r   rE   r  rG   r   r   r   r   r   r  rj  rH   CmfSecurityLevelr0   r/   rh   r   rB   r)   rO   ZERRORr  rP   r1  r   r   r  r  rx   r   rA  rI  rL  rJ   rB  r&  r   r   Zfix_versionsr]  r\  r}   rP  rX  r   r   r   Zprocess_tagsZexcepionrP  rT  r   r   r;   r   r(  r+   r,   r  )r   r   sprintsr	  Zproject_ext_idr   r1   Znormalized_issuer   Zstory_p_fieldr  r   r  r   versionZversion_obj	componentZcomp_objr  r+  r,  r  r   r   r   r  :  s    ",
$


$

.$

.$

.

& 
&


zJiraAPIImport._process_issueu&   Обработка всех задачc             C   s4   | j  }x$|D ]}| j r"d S | | qW d S )N)r;   r   r(   r*   r  )r   r%  r   r   r   r   _process_issues  s
    


zJiraAPIImport._process_issuesu3   Обработка связей всех задачc             C   s  x|   D ]t}xl| j|d | |d dD ]J}| j rFdS |d d}| jjjj d|d  }|r| jjjj d|d  }| j|g }|	| || j|< |d dg }x|D ]}| jjjj d|d  }	d|kr0||d	 d
|d< | jjjj d|d d  |d d< || j
|	< qd|kr||d	 d
|d< | jjjj d|d d  |d d< || j
|	< qW q2W qW | jdt| j  x| jD ]|}| j rdS tjj|d}
xV| j| D ]H}tjj|dgd}|s| jjd|  q|
|_|jdd qW qW | jj  ddddd}| jjdt| j
   xT| j
 D ]D\}}| j rdS y| jjjj d|d d  }||d d }|rtjj|d}ntjj|d}|s tjjdd|d d gd}|sHtj|| j|d d d}|d d  |_|d d! |_|jdd tjj|d d d}|s| jjd"|d d	  d#|d d  d$ wltjj|d d d}|s| jjd%|d d	  d#|d d  d$ wl| jjjj d|d  }tjj|d}|stj|| jd&}||_||_||_|jdd W np   |  jd'7  _| jj d(|d  d)|d d	  d#|d d  d*|d d	  d#|d d  d+d,d-d. Y nX qlW | jj  dS )/uD   
        Постобработка связей задач
        r   )r   Nrc   r   z::Z
issuelinksr   r   )r   r   r   r   u   Подзадачи: )r   parent_task)r   rc   uq   Не удалось связать задачи, возможно задача не попала в импорт T)r   zsystem.finish:finishzsystem.duplicatezsystem.linkzsystem.clone)ZBlocksZ	DuplicateZRelatesZClonersu   Связи: r  r   )r?   z==)r   )r   r(   r   ZinwardZoutwardu=   Не удалось найти входящую задачу z (u   ). Возможно задача не попала в импорт или находится в проекте, который еще не импортирован.u?   Не удалось найти исходящую задачу )r   r(   r'   u.   Не удалось создать связь z. in_link: z), out_link: rC  zERR-0052r   )rJ  )!r   r   r  r(   r*   rG   r   r   rL   r   rK   r)   r   rE   r   rP   rQ  rc  r   r+   r,   r1  r  r   ZCmfRelationTypeZin_type_nameZout_type_nameZCmfRelationOptionin_linkout_linkrelation_typer/   r0   )r   r   r   Zissue_parentr   Zparent_ext_idZ	sub_tasksZissue_linksZ
issue_linkZlink_ext_idrc  Zchild_ext_idZ
child_taskZ	map_namesZrelation_ext_idZissue_relationZrelation_coderf  rd  re  Z
rel_ext_idZrelation_optionr   r   r   _process_relations  s    &




&&
$$Fz JiraAPIImport._process_relationsu)   Обработка компонентов)r  c          	   C   s  t jjddd|d  dgddgd}t jj|ddd	gd
}|sNtd| x| |d D ]}yz|js~d|_|  | j	 rd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| j|d | j d|d  d|_|d dkr6|j|_n.|d dkrN|j|_n|d dkrd|j|_|jr|jr|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 q`   |  jd"7  _| jjd#| d$d%d& Y q`X q`W dS )'uG  https://docs.atlassian.com/software/jira/docs/api/REST/1000.824.0/#api/2/project-getProjectComponents
        Пока грузим как списки, после доработки будут отдельные обекты

        Args:
            project_info (dict): проект из джиры как есть
        r   rH  rI  r   r   )r   rc   r\  Tr  )r   r   Zinclude_systemrc   uV   Данный тип проекта не поддерживает компоненты r   Nz::descr_documentdefault_ownerdefault_responsibler   r   r   )r   rc   )r   r(   r   r   r  u   Компонент )r1   ZassigneeTypeZPROJECT_DEFAULTZPROJECT_LEADZCOMPONENT_LEAD)r   r   r   r'   u3   Ошибка загрузки компонента zERR-0053r]  )rJ  )rE   r  rG   r   r  _get_project_componentsr  r   r(   r*   r   r   r]  r   r   r   r   rB   ri  r   rj  r   r   rX  rh  Zcreate_descr_documentZ
text_draftr   r`  r/   r0   )r   r  r  r   ra  r   Zcomponents_listr   r   r   r  ?  sX    




z!JiraAPIImport._process_componentsu   Обработка версийc          	   C   s  t jjddd|d  dgdgd}t jjd|d}t jjd|d}xf| j|d	 d
D ]P}y| j rpd 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rH|d s2|d r>|d n
|d |jrd|jrd|jdd | j jd7  _W qX   |  jd7  _| jjd| ddd Y qXX qXW d S )Nr   rH  rI  z"scheme_wf.default_release_workflow)r   rc   release)r   r   r   r   )rl  z
::version:)r   T)r   r(   r   zlist.release:default)r?   r   r   r   )r   ZarchivedZreleasedr$  ZOPENr'   u+   Ошибка загрузки версии zERR-0053r   )rJ  )rE   r  rG   r   _get_project_versionsr(   r*   r   r   r   r  rv  r   r   rx   ru  Zdefault_release_workflowrr  r   rX  r   r   Zset_default_statusr`  r/   r0   )r   r  r  Zrelease_folderr*  r`  r   Zversion_listr   r   r   r  z  sB    





zJiraAPIImport._process_versionsu*   Обработка JQL в фильтрахc       	   	   C   s  t | }t }tjjdddgdddgd}x|D ]}d|j d	|j d
}|jsTq2|jj	
d}|st|jj	
d}|szq2y@||}||_|jdd | jjd| d| d|  W q2   | jjd| d| ddd Y q2X q2W t | }| jjd|dd dS )uP   
        Пост обработка JQL в фильтрах задач
        r(   z!=NrP  ubql2r   )r   rc   r   z" (rC  jqlr  T)r   u   Фильтр z: JQL u%    переобразован в UBQL2 u0   : ошибка преобразования JQL zERR-0066r  )rJ  uC   Обработка JQL в фильтрах выполнена за z.3fu    сек.)r   r  process_timerE   r  r   r   r?   rP  r   rG   Zget_modifiedrn  r   r(   rP   r1  r0   )	r   ro  t1Ztask_filtersZtask_filterZ
filter_msgr  rn  t2r   r   r   _process_jql_in_filters  s6    

z%JiraAPIImport._process_jql_in_filtersu   Обработка аудитаc             C   s   dS )u)   
        Грузим аудит
        Nr   )r   r   r   r   _process_audit  s    zJiraAPIImport._process_auditu2   Обработка логических типовc             C   sv  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}x|  dD ]}| jjd|  | j rdS | jjjj d|d  }tjj	ddd| dgd}|rqt|	|d }|r@tjj	dd|d gdgd}|j
r$d| |j
 |_
nd| d|_
|jdd qt| 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 qt| 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  _qtW dS )(u$   Маппим issueType в logic_typeu   Подзадачаztask.sub:default)r   r?   Z	UserStoryztask.userstory:defaultz
Task Agileztask.agile:defaultBugztask.bug:defaultEpicztask.epic:default)zSub-taskZSubtasku   ПодзадачаZStoryu   ИсторияZTasku   Задачаru  u   Багu   Ошибкаu   Эпикrv  r  u-   Обрабатываем тип задачи Nz::r   r   rH  z%::z::%)r   r   r?   z==)r   rc   T)r  u   Ищем по имени "r   rG  u*   Не нашли, создаем новыйrt  r,  r'   r  r   r   )r   r   rx   rx  rq  )r   r(   rP   r1  r*   r   r   rE   r  rG   r   r   r  r;   rC   rD   r   r   r   r   r`  )r   Z	name2coder  r  rv  Zlogic_type_dictZtemplate_coderq  r   r   r   _process_issue_type  sr    



z!JiraAPIImport._process_issue_typeu2   Обработка бизнес-процессовc                s  i }x  dD ]}|||d < qW xf  dD ]V} j rFd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 x$|d D ]} ||d   qW xft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 q*W x|d D ]} j rd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s6td jjjj dj d|d  }tjj	|d|	_|	jdd qzW  j jd 7  _q2W dS )!u   Импортируем workflowrf  r   	workflowsNr   z::ZentityId)r   ztask.agile:default)r?   )r   rq  r(   r   T)r   rr  z==r   rj  )r   rc   z!=)r   )rs  Ztransitions)r   rr  )r   rr  r(   c                s*   g | ]"} j jjj d j d | qS )z::)r(   r   r   r   )r   st)r   rr  r   r   r   L	  s    z3JiraAPIImport._process_workflow.<locals>.<listcomp>r  INuN   DEV: Fatal Вероятно, сломали создание статусов!r  r'   )r   r(   r*   rP   r1  r   r   rE   r~  rG   rx   r   r   r  r  r   rj  r  r   r  r  r   r  r  r`  )r   Zjira_statusesr  Zjira_workflowZworkflow_idZtemplate_workflowrz   r  r  r  Zstatus_from_ext_id_listZstatus_to_ext_idr   )r   rr  r   _process_workflow	  sN    
,
"

"zJiraAPIImport._process_workflowu    Обработка схем БПc          
   C   s  x|  dD ]}| j r"d S | jjjj d|d  }tjjdd| dgd}|sltd|d  |d	 |d
d| jjjj d|d  ddi||d}t	
| jtj|dd|d g\}}|sxtjj|dD ]}|  qW x|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 qW | j jd7  _qW d S )Nworkflow_schemez::ZdefaultWorkflowr   rH  z::%)r   u+   Не импортировался workflow r   r   r   r   r?   zsoftdev:default)r   rx   r   rq  r  r  z==)ru  ZissueTypeMappingsz%::r   )rv  rw  rx  ru  r(   T)r   r'   )r   r(   r*   r   r   rE   r~  rG   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  Zworkflow_namerv  rr  r  r   r   r   _process_workflow_schemeT	  sD    

(
z&JiraAPIImport._process_workflow_schemec             C   sL   t jj}x>| dD ]0}|| j}|| jj d| t	
| qW d S )Nr   z:user:)r   r!  r"  r   rG   rB   rc  r(   r   r#  r4  )r   r&  r  r   r   r   r   _cache_all_usersy	  s    zJiraAPIImport._cache_all_usersu   Простой дамп)r   c          	   C   s   | j  | d}| j  | d}| r>t| t|d:}x2| D ](}| j  jd7  _|t	
|d  qRW W d Q R X t|| | j jdd t  d S )Nz.jsonz.json.dirtyza+r'   r3  T)r  )r(   rU   rV   rW   r`   r  rX   json_object_countr  rY   r4  r_   rb   r   r   )r   Zapi_funcr   r\   rd   r]   r5  r   r   r   _simple_dump	  s    
"zJiraAPIImport._simple_dumpc          	   c   sR   | j  | d}| rNt|d }x|D ]}t|V  q0W W d Q R X d S )Nz.jsonzr+)r(   rU   rV   rW   rX   rY   r$  )r   r   r\   r]   r5  r   r   r   r   	  s    
zJiraAPIImport._simple_getc          
   c   s   | j  d}| rxrt|D ]d}|dr4q$|drZ| j jd| d|  q$t	| d| dd}t
|V  W d Q R X q$W d S )Nr   z.dirtyz.metau(   Пропускается каталог r   z
/info.jsonzr+)r(   rU   rV   rW   r`   listdirr   rP   rQ  rX   rY   rZ   )r   project_dirrl  r]   r   r   r   r   	  s    

zJiraAPIImport._get_projectsc             C   s&   x |   D ]}||d kr
|S q
W d S )Nr   )Zget_projects)r   rl  r  r   r   r   get_project	  s    zJiraAPIImport.get_projectc          	   c   sL   | j  d|}t| dd }x|D ]}t|V  q*W W d Q R X d S )Nr   z/issue_types.jsonzr+)r(   rU   rV   rX   rY   r$  )r   rl  r  r]   r5  r   r   r   ry  	  s    
z*JiraAPIImport._get_issue_types_for_projectc          	   c   sL   | j  d|}t| dd }x|D ]}t|V  q*W W d Q R X d S )Nr   z/statuses.jsonzr+)r(   rU   rV   rX   rY   r$  )r   rl  r  r]   r5  r   r   r   rz  	  s    
z'JiraAPIImport._get_statuses_for_projectc          	   c   sL   | j  d|}t| dd }x|D ]}t|V  q*W W d Q R X d S )Nr   z/roles.jsonzr+)r(   rU   rV   rX   rY   r$  )r   rl  r  r]   r5  r   r   r   r  	  s    
z JiraAPIImport._get_project_rolesc          
   c   sZ   | j  d|d}x@t|D ]2}t| d| dd}t|V  W d Q R X q W d S )Nr   rM   r   z
/info.jsonzr+)r(   rU   rV   r`   r  rX   rY   rZ   )r   rl  	board_dirZboard_idr]   r   r   r   r  	  s    z!JiraAPIImport._get_project_boardsc          
   c   sZ   | j  d|d}x@t|D ]2}t| d| dd}t|V  W d Q R X q W d S )Nr   r_  r   z
/info.jsonzr+)r(   rU   rV   r`   r  rX   rY   rZ   )r   rl  sprints_dirZ	sprint_idr]   r   r   r   r)  	  s    zJiraAPIImport._get_all_sprintsc          	   c   sL   | j  d|}t| dd }x|D ]}t|V  q*W W d Q R X d S )Nr   z/versions.jsonzr+)r(   rU   rV   rX   rY   r$  )r   rl  r  r]   r5  r   r   r   rm  	  s    
z#JiraAPIImport._get_project_versionsc          	   c   sL   | j  d|}t| dd }x|D ]}t|V  q*W W d Q R X d S )Nr   z/components.jsonzr+)r(   rU   rV   rX   rY   r$  )r   rl  r  r]   r5  r   r   r   rk  	  s    
z%JiraAPIImport._get_project_componentsc             C   s<   d}| j  d|d}| r8tdd t|D }|S )Nr   r   r   c             s   s   | ]}| d  V  qdS ))z.dirtyz.metaN)r   )r   entryr   r   r   	<genexpr>	  s    z5JiraAPIImport._count_project_tasks.<locals>.<genexpr>)r(   rU   rV   rW   sumr`   r  )r   rl  count	tasks_dirr   r   r   r  	  s
    z"JiraAPIImport._count_project_tasksr     c          
   c   s   | j  d|d}| s:| j jd| d|  d S xltt|D ]Z\}}||k r\qJ|	drhqJ||| krvP t
| d| dd}t|V  W d Q R X qJW d S )	Nr   r   u   Каталог u    отсутствует. Возможно он был удален или еще не создан. Необходимо повторно запустить импорт проекта )z.dirtyz.metar   z
/info.jsonzr+)r(   rU   rV   rW   rP   rQ  r   r`   r  r   rX   rY   rZ   )r   rl  rn  r   r  iZtask_idr]   r   r   r   r   	  s    
zJiraAPIImport.get_project_tasksc             C   s@  |d d }i }xv|d D ]j}|d dkr,qxV|d   D ]F\}}||d|i}|di }||d s:t|d	 ||d < q:W qW x| D ]}i }	x0|d   D ] \}}
|	|
t }|| qW i |d< xL|	  D ]@\}}t|d
kr||d d< qx|D ]}||d |< qW qW qW dd | D |d< |S )u   
        Создает структуру схемы экранов проекта из данных плагина "Smart Jira Configuration"
        schemesZissueTypeScreenSchemeglobalActionsr   )BROWSEPROJECTSCREATEISSUES
EDITISSUESscreensissueTypeIdactionsscreenr'   r  c             S   s   g | ]}|qS r   r   )r   vr   r   r   r   	
  s    z<JiraAPIImport._get_project_screen_scheme.<locals>.<listcomp>r  )r   r|  rG   rw   rf   rc  rd  r   )r   smart_configscreen_schemer  r  issue_type_idr   r  r  Zissue_type_screens	screen_idr  Zissue_type_screenr   r   r   _get_project_screen_scheme	  s0    
z(JiraAPIImport._get_project_screen_schemec             c   sF   |d  d}x2t |D ]$}|dkr(q|| d| dV  qW d S )Nr   z/attachmentszall_attachments.zipr   )r   r\   )r`   r  )r   r   Zattachments_pathr   r   r   r   r  
  s
    z$JiraAPIImport._get_issue_attachmentsc          	   c   sB   |d  d}t |d }x|D ]}t|V  q W W d Q R X d S )Nr   z/comments.jsonzr+)rX   rY   r$  )r   r   comments_file_pathr]   r5  r   r   r   rJ  
  s    
z!JiraAPIImport._get_issue_commentsc          	   C   s6   |d  d}t |d}t|}W d Q R X |p4g S )Nr   z/worklog.jsonzr+)rX   rY   rZ   )r   r   r  r]   r4   r   r   r   r=  
  s    z!JiraAPIImport._get_issue_worklogsc          	   C   s.   |d  d}t |d}t|S Q R X d S )Nr   z/properties.jsonzr+)rX   rY   rZ   )r   r   Zproperties_file_pathr]   r   r   r   rN   
  s    z#JiraAPIImport._get_issue_propertiesc          	   C   s.   |d  d}t |d}t|S Q R X d S )Nr   z/watchers.jsonzr+)rX   rY   rZ   )r   r   Zwatchers_file_pathr]   r   r   r   r   %
  s    z!JiraAPIImport._get_issue_watchersc          	   C   s8   | j  d}| r4t|d}t|S Q R X i S )Nzglobal_settings.jsonzr+)r(   rU   rV   rW   rX   rY   rZ   )r   global_settings_file_pathr]   r   r   r   rI   *
  s
    z'JiraAPIImport._get_jira_global_settingsc          	   C   s@   | j  }| j d}t|d}t|| W d Q R X d S )Nzglobal_settings.jsonzw+)r;   Zget_jira_global_settingsr(   rU   rV   rX   rY   r[   )r   Zglobal_settings_datar  r]   r   r   r   _dump_jira_global_settings1
  s    
z(JiraAPIImport._dump_jira_global_settingsu/   Обработка ссылок в тексте)rx   attachments_dirr   c                s  d}|s|S xDt |ddd D ]*}d}|dr<d}|j| }y|drj| jjd|  w$|d	stj	
| jj|}|| jjs| jjd
|  w$t|dd \}}	|s| jjd|  w$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$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
rN } z2| jj!$  | jjd| d|  |d7 }W d d }~X Y q$X q$W t |d}x|jddid D ]}|jd!r| %|jd! |d"  nb|jd#r| %|jd# |d"  n<tj	&|jd }tj	'|j(}| %|d$ d ) |d"  qpW |S )%Nr   r  c             S   s   |  dp|  dS )Nr  r'  )r(  )r  r   r   r   r)  =
  r*  z+JiraAPIImport._dump_links.<locals>.<lambda>r'  r  zmailto:u   Это почта: ZhttpuH   Это внешняя ссылка, оставляем как есть: r-  u   Это не файл: z(/attachment(?:/content)?/(\d+)(?:/)?(.*)r'   r  r  rc   r   c                s   |  d kS )Nr   )rG   )r.  )r/  r   r   r)  V
  r*  uE   Этот файл уже обработан во вложениях: r   r,  r   )r  
obj_ext_idr   )r(   r  r  r   Fu0   Не удалось скачать ссылку z: zhtml.parserr  z
user-hover)r  zdata-account-idr   zdata-usernamer   )*r   r  r(  r  r2  r(   rP   rQ  r3  r4  Zurljoinr;   r   r:  r;  r   r6  r7  r5  r8  r   rE   r   r   rV   CmfImportDownloadrG   r   r   pathr   
downloadedr   r+   r,   r-   r.   r7  r  r  r  r  )r   rx   r  r   r/   r  r   r   r?  encodingr<  Zattach_filenamer=  r>  r   r\   download_jobr  r  r  r  r   )r/  r   _dump_links7
  sz    



 

"zJiraAPIImport._dump_linksc             C   s   x| j D ]}| j | d sq||s(q|| di }x| D ]x}|dsRqB|d |d |d |d d}|drd	d
 |d  D |d< | j | dg }||kr|| P qBW qW | | j  dS )u   
        В box версии, контексты полей получаем из плагина "Smart Jira Configuration"
        r  contextr   r   isGlobalContextisAnyIssueType)r   r   r  r  optionsc             S   s   g | ]}|qS r   r   )r   optionr   r   r   r   
  s    z5JiraAPIImport._get_field_contexts.<locals>.<listcomp>N)r^   rG   rf   r|  r   re   )r   fields_usedrj   Zcontextsr  Zcontext_dataZfield_contextr   r   r   _get_field_contexts{
  s(    




z!JiraAPIImport._get_field_contextsc             C   sb  | j |d }x>| jD ]2}| j| d s0q|d |s@q|d | d}|rx|D ]}|ds| jd| tj q\| j jj	rxh| j| dg D ]*}|d |d kr|dr|d |d< qW q\|| j| d kr\| j| d 
| q\W | j| d	 d d
dd }|dkrL|d | }|rN| || j |d  q|dkr|d | pfg }	x|	D ]}| || j |d  qnW q|dkr|d | }
|
rN| |d | |d  q|dkr|d | pg }xj|D ]}
| |
|d  qW q|dkr|d | }| j| dg }|r|| tt|| j| d< qW | | j dS )u   На коробке только через мету задачи можно получить варианты выбора полей

        Args:
            issue (dict): задача
        r   r  rc   ZallowedValuesr   u   Выбор без id: r  childrenschema:r'   r,  
userpickerr   multiuserpickergrouppickermultigrouppickerr  N)r;   Zget_issue_metar^   rG   r(   r)   rO   rS  rC   rD   r   r   r7  rB   r6  rE  r   rc  re   )r   r   metarj   r  r  Zcur_optcustom_field_typesr   r   r^  rN  rf   r   r   r   _get_field_options
  sV    










z JiraAPIImport._get_field_options)last_dump_datenew_dump_datec	       "      C   sd  t ddN || _d}	| jjd| d|  yx| jj|d ||||dD ]}
zyz| j rpdS | jjd	|
d
  d |t|
d }|t|
d d }|	 rt
|| |jdd ||
d< | |
 |d}|
d d rp| jjdt|
d d   ytj| jjd|
d  d}| jjjrft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
r4 } z$| jj dt! d| dddd  W d d }~X Y nX x8|
d d D ](}|d!rD| "|d! | j# | qDW | j$d"r
|d#}|	 rt%| t&|d$^}| j'|
d }x:|D ]2}| "|d! | j# | | "|d% | j# | qW t()|| W d Q R X x8|
d& d' D ](}|d!r| "|d! | j# | qW |
d d(rr| "|
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/}x| j,|
d D ]~}| "|d! | j# | | "|d% | j# | |-t(.|d0  | j j/d7  _/| j0d1 |  j*| +|d2 ||
7  _*q>W W d Q R X | j1|
d }|d3}t&|d$}t()|| W d Q R X | j2|
d }x |D ]}| "|| j# | qW |d4} t&| d$}t()|| W d Q R X t
|| |jdd |d5}!t|3dd6|
d< t&|!d$.}t()|
| | j j/d7  _/| j0d7 W d Q R X W n(   |	d7 }	| jj4d8|
  Y nX W d | jj  X qTW W n.   | jj4d9|d:  d; |	d7 }	Y nX |5|	 W d Q R X d S )<NF)r  r   u   Задачи с u    до r   )rn  maxr:  r?  r'   u   Задача 'r   'z.dirtyT)exist_okr   r=  rc   r   u%   Обработка вложений: zsecure/attachmentzip/z.zipzsecure/issueAttachments/zall_attachments.zipz::)r  r  r   )r(   r  r  r   u:   Не удалось обработать вложение z: zERR-0054r   r[   )rJ  
error_typer   r[  zworklog.jsonzw+r8  rR  rS  rV  rX  r  rY  r   zcomments.jsonu#   Дампим комментарииza+r3  r,  r   zproperties.jsonzwatchers.jsonz	info.jsonr   r   u0   Не удалось скачать задачу u2   Не получить задачи проекта r   u    с сервера)6r   r;   r(   rP   r1  Zget_all_project_issues_duringr*   rV   r%   rW   r_   rb   mkdirr  r   r`   r  r   r   rC   rD   r   r   rE   r  rG   r   r  r   r+   r,   r-   r0   r  r7  rB   rJ   r  rX   Zissue_get_worklogrY   r[   r/   r  Zget_commentsr  r4  r  r  Zget_issue_propertiesZget_watchersr  	exceptionr  )"r   rn  r  r  r  r;   tasks_that_are_doner  r  r	  r   Ztask_dirZtask_dir_tmpr  r  r   Zattach_file_pathr   r  r  r
  Zworklog_file_namer]   Zworklogsr@  rA  Zcomments_file_namer,  Z
propertiesZproperties_fileZwatchersr   Zwatchers_fileZ	info_pathr   r   r   _dump_task_part
  s    


 




   


,



zJiraAPIImport._dump_task_part)r  rK  r  r  c             C   s  t jj}t|d  d}|jdd | j }d}t|| j d }	|	sNd}	d}
g }d}x||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 }
q\W |	d }| jjd|	 d x@|D ]8}|j|d | r.| jjddddd tdq.W | jjd x| s|| 7 }qzW | jjd|  x| j |d | !|d dD ]}| j" r|S t|d #d}| j$ #d}| j$ #d}|% rt&'|| t(|d}t(|d|}t(|df}x^|D ]V}||krR|)| t*+|}|| j,}|rR|-| jj. d | t/0| qRW W d Q R X W d Q R X W d Q R X |1  t&2|| t|d #d!}| j$ #d!}| j$ #d"}|% rt(|d#3  t&'|| t(|dV}t(|d@}t(|d*}x"|D ]}||kr^|)| q^W W d Q R X W d Q R X W d Q R X |1  t&2|| qW |S )$Nr  z/tasksT)r  r   r'   r   Z
dump_tasks)r   r  tokenr  
verify_sslrD   )rn  r  r  r  r;   r  r  r  )targetr   r3   u$   Форкаем _dump_task_part proc=r;  u%   Таймаут дампа задач u    минут)timeoutu$   Возможно завис дампzERR-0055r   r[   )rJ  r  u"   Ошибка дампа задачuK   Закончили параллельное скачивание задачu   Ошибок: r   )r   r   z
users.jsonzusers.json.newr2  za+z:user:zgroups.jsonzgroups.json.newa)4r   r!  r"  r   r  ro   Queuerw   rs   rn   Threadr  r   r;   r   r  r  r  r  rC   rD   r   rn  r(   rP   r1  r   Zis_aliver0   TimeoutErroremptyrG   r   r  r*   rV   rU   rW   r_   r  rX   r  rY   r$  rB   rc  r   r#  r4  unlinkrb   close)r   r  rK  r  r  r&  r  r  r	  r  r  r  Z	max_limitr  r  r   Zissue_users_pathZall_users_pathZall_users_path_newf1f2Zf3liner  r   Zissue_groups_pathZall_groups_pathZall_groups_path_newr   r   r   _dump_tasksL  s    



&




D


.zJiraAPIImport._dump_tasksc          	   C   s^  | j jd|d  d|d  d | j|d }|r|dsi }| jjjrf| j|d }nDxB|dg D ]2}|d d	krtx |d
 D ]}|d ||d < qW qtW xf|dg D ]V}g |d< xH||d g D ]4}|d 	| |d dkr| 
|d | j   qW qW t|d  d}	|	 r8t|	 t|	d}
t||
 W d Q R X d S )NuH   Дамп схемы безопасности задач проекта "r   z" (r   rC  r   r  r  ZBROWSE_PROJECTSrU  r  levelsr  r   r   r  z/issue_security_scheme.jsonzw+)r(   rP   r1  r;   Z!get_project_issue_security_schemerG   rC   rD   Z get_issue_security_level_membersr   r7  rU   r   rW   r`   r  rX   rY   r[   )r   r  r  Zsecurity_schemeZsecurity_level_membersr  security_levelrQ   member	dump_filer]   r   r   r   #_dump_project_issue_security_scheme  s,    


z1JiraAPIImport._dump_project_issue_security_schemec             C   s   | j jd t|d  d}| r2t| t|dt}i }y"d}| jj	|d d
|d}W n: tk
r } z| j jt|d	d
dd W d d }~X Y nX t|| |S Q R X d S )Nug   Дампим конфигурацию проекта через плагин "Smart Jira Configuration"r  z/smart_config.jsonza+)	ZprojectInformationZprojectSchemesZprojectIssuetypesZprojectVersionsZprojectComponentsZprojectMembersZprojectCustomfieldsZprojectGlobalActionsZprojectWorkflowActionsr   r   )r  zERR-0056r  r[   )rJ  r  )r(   rP   r1  r   rW   r`   r  rX   r;   Zget_project_smart_configr   r-   r0   r%   rY   r[   )r   r  Zsmart_config_filer]   r  r  excr   r   r   _dump_smart_config  s     

z JiraAPIImport._dump_smart_configEtc/UTC%Y-%m-%d %H:%M)dttzformatr<   c             C   sN   | pt j t jj|} t|}tjt j | ||}||}|S )N)	r>  nowtimezoneutcstrftimepytzZlocalizeZstrptimeZ
astimezone)r  r  r  Zdt_tzZdt_strr   r   r   _datetime_in_user_tz  s
    

z"JiraAPIImport._datetime_in_user_tzc       9      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| }x| jD ]}|d }|d }y| j
 rd S | j jd7  _| jjd| d ||}	|| d}
|	d}| jjjr| jjj| jjd}n| jjj| jjd}|r4|d d nd}d }| rt|d}t|}|d}W d Q R X |r| ||}tjtjjd}| ||}|	 rt|	|
 nt j!|
d
d t"# }| jj$|d }t%|
|d< d }| jjjs
| &|}| jjd t'|d  d}| r>t (| t|d}| j)|d }y|xv|d  D ]j}|d! d" d#krf| jjjr|d! dr| *|d! d | j  n| *|d! d$ | j  qfW W n(   | jj+d%| d&d'd(d)  Y nX t,|| W d Q R X | j-||d* | jjjr|d+ s| j.|d gd d, |d-< | j/|d g|d.< | j0|d |d/< n| jjd0 t'|d  d1}| rt (| t|dH}x@| jj1|d d2D ]*}| j jd7  _|2t3|d3  qW W d Q R X n| j4| jj5 d4|d   |d-< d|d- krb|d- d |d- d5|d-< n.| j4| jj5 d6|d- d   |d- d7< |d8r| 6||d.< |d9i |d/< | 7|d/  |d:}|r*| j8d;|  | j4|d< }|9  | |d:< | *|d: | j: | j  | jjd= t'|d  d>}| r^t (| t|dH}x@| jj;|d d2D ]*}| j jd7  _|2t3|d3  q~W W d Q R X | jjd? t'|d  d@} |  rt (|  t| d}x| jjj<|d dA= D ]}!| j
 r*d S | j jd7  _| j4|! }"g }#x
|"dBg D ]}$|$d" dCkr^yT| jjjr| jjj>|$dD d|$dD dEdF|$dG< n| jjj>|$d d|$dG< W nh |j?j@k
r, }% zD|%jAjBdHkr|#C|$ | jjDdI|"d  dJ|% dK w^n W d d }%~%X Y nX |$dGr^| *|$dG | j: | j  q^W |"dBrx|#D ]}&|"dB (|& qnW |2t3|"d3  qW W d Q R X | jjdL t'|d  dM}'|' rtE|' |'  t'|d  dN}(|( rtE|( |(  yRxJ| jjF|d dAD ]2})| j
 rDd S | j jd7  _| jjdO|)d   | jjG|)d |)d7< | j4|)d7 dP d<  |)d7 dP< | jH|)d }*| jjjrdQd | jI|)d D |)d7 dR< ndSd |*dT dU D |)d7 dR< |*dV |)d7 dV< |*dW |)d7 dX< |d |)dY< |'t%|)d }+|+jd
d |+d},t|,dZ}t,|)| W d Q R X y<|)d" d[k
r| jjd\ x| jJ|)d D ]}-| j
 	rd S | j jd7  _|(t%|-d }.|.jd
d |.d}/|/ 
r$| jjd]|-d  d^ 	qg |-d_< | jjd]|-d   x<| jK|-d D ](}0| j
 
rjd S |-d_ C|0d  
qVW t|/dZ}t,|-| | jLd` W d Q R X 	qW W n |j?j@k
r8 }1 z\|1jAjBdakrdbt%|1k
sdct%|1kr| j8t%|1 n| jj+dd|) dedfd(d)  W d d }1~1X Y n(   | jj+dd|) dedfd(d)  Y nX q.W W n4   |  jMd7  _M| jj+dg| dedfd(d) Y nX | j8dh t'|d  di}2|2 rt (|2 t|2dV}xN| jN|d D ]:}3| j
 rd S | j jd7  _|2t3|3d3  qW W d Q R X | j8dj t'|d  dk}4|4 rht (|4 t|4d~}xv| jO|d D ]b}5| j
 rd S |5d:r| *|5d: | j: | j  | j jd7  _|2t3|5d3  qW W d Q R X dlt jPdm< | j jQ|7  _Q| jjRd
dn | jjST  dot jPdm< t|d |	 t%|	|d< |d  dp}t|dZ}t,|| W d Q R X t"# | }6| jjdq| dr|6dsdt t'|d  du}7|r4|7 s| jjDdv| dw|d  dx|7 dy| dz	 d }n6| U|d s4| jjDd{| dw|7 d|| dz d }t"# }| jjV|d ||d}}d~| }8|sh|r|8d7 }8|r|8d| 7 }8|r|8d| 7 }8|8d| d7 }8| j8|8 |  jM| jW||||d7  _Mt"# | }6| jjd| dr|6dsdt | jMs,||d< t|dZ}t,|| W d Q R X W qz   |  jMd7  _M|drn| jj+d| ddd'd(d) n| jj+d| dd'd(d) Y qzX qzW | j8d d S )Nr   r   r   	isCheckedu5   Не выбрали ни одного проекта!c             S   s$   g | ]}|d  r|d r|d  qS )r1   r  r   )r   rO  r   r   r   r     s    z0JiraAPIImport._dump_projects.<locals>.<listcomp>r  r   T)r  P   r   r   r'   u   Дампим "r   z.dirtyz	info.json)r  )r  ZtimeZonezEtc/UTCr2  Z	dump_datez%Y-%m-%d %H:%Mr   r  u   Дампим праваz/permissions.jsonza+permissionsholderr  r   	parameteru0   Не удалось сдампить права zERR-0056r  r[   )rJ  r  )r  r  ZworkflowSchemer  jira_screen_schemer  u/   Дампим типы задач проектаz/issue_types.json)rl  r3  z$rest/projectconfig/1/workflowscheme/)r   r1  zrest/api/2/workflowscheme/r1  r  Z
fieldsUsedr  u1   Ищем руководителя проекта r   u*   Дампим статусы проектаz/statuses.jsonu$   Дампим роли проектаz/roles.json)r   r  zatlassian-user-role-actorZ	actorUserr=   )r  r@  r  i  u&   Пользователь к роли "u   " не найден. u+   . Возможно он был удаленu&   Дампим доски проектаz/boards/z	/sprints/u   Доска r   c             S   s   g | ]}|qS r   r   )r   r1   r   r   r   r     s    r  c             S   s   g | ]}|qS r   r   )r   r   r   r   r   r     s    ZquickFilterConfigZquickFiltersr  ZoldDoneIssuesCutoffr  rl  zw+)ZscrumZsimpleu&   Дампим спринты доскиu   Спринт u    уже скачанr%  r   i  z"The board does not support sprintsuD   Данная доска не поддерживает спринтыu4   Не удалось сдампить спринты zERR-0057r   u   Не удалось сдампить доски, возможно проект не поддерживает доски или у вас нет прав project_info=u(   Дампим версии проектаz/versions.jsonu!   Дампим компонентыz/components.jsonr   NO_CACHE)r  1z
/info.jsonu&   Дамп данных проекта "u   " выполнен за z.3fu    сек.z/tasksu$   В каталоге проекта "z" (u5   ), отсутствует каталог задач (u@   ). Дата последнего успешного дампа (u   ) будет сброшена.u/   В каталоге задач проекта "ud   ) отсутствуют задачи. Дата последнего успешного дампа ()r:  r?  u*   Дампим задачи проекта: u    (в периодu    с u    по u4    включительно, часовой пояс: rC  )r  rK  r  r  u$   Дамп задач проекта "r  u   Проект "u   " является приватным и не может быть импортирован, отключите приватность в Jira или предоставьте пользователю праваzERR-0058u2   Не удалось получить проект u0   Закончили дампить проекты)Xr  r   r-   rN   r(   rU   rV   r  r   rw   r*   r  rP   r1  r;   rC   rD   Zuser_find_by_user_stringr  rW   rX   rY   rZ   rG   r  r>  r  r  r  r  r_   rb   r`   makedirsr  rp  r  r%   r  r   r  Zget_project_permission_schemer7  r0   r[   r  Zget_project_schemeZget_project_screen_schemeZget_project_fields_usedZget_issue_for_projectr  r4  jira_requestr   r  r  r)   raise_for_statusrB   get_statusesZget_project_rolesrf   r   
exceptionsZ	HTTPErrorr  r  r   rQ  ZrmtreeZget_all_agile_boardsZget_agile_board_configurationZget_advanced_board_settingsZget_board_quick_filtersZget_sprintsZget_sprint_issuesr  r/   Zget_project_versions_paginatedZget_project_componentsenvironprogressr   r+   r,   r  Zget_project_issues_count_duringr  )9r   r  rootZprojects_dirrK  r  r   rl  Zproject_namer  Zproject_tmp_dirZ	data_filer  Zuser_tzr  r]   Zcurrent_dumpZlast_dump_date_utcZnew_dump_date_utcr  rq  r  r  permission_fileZperm_sch	perm_dictZ
types_filer  r  r4   Zstatuses_filer5  Z	role_fileZrole_urir  Zunfound_actorsr  r  Zunfound_actorZ
boards_dirr  r  Zadvanced_settingsr  Zboard_info_filer   Zsprint_pathZsprint_file_pathr   r  Zversion_list_filenamer`  Zcomponents_list_filenamera  rr  r  Zinfo_msgr   r   r   _dump_projects  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 | 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   Свободно места: rI  u$   Скачаем данные из APIu9   Дампим глобальные настройки Jirarb  Tu'   Дампим пользователейr   uA   Не дампим пользователей из-за опций)rQ   u   Дампим статусыrf  u    Дампим типы задачr  Zissue_security_schemesu*   Дампим бизнес процессыrx  u7   Дампим схемы бизнес процессовr|  u   Дампим экраныr  r  u!   Дампим приоритетыr  r  r   r     r  u   Дампим проектыN)$r(   rU   r_   Z
disk_usager)   rP   r1  r  rI   rJ   r   r   rG   r  r;   r   rO   rS  r~  r  Zget_issue_typesZget_issue_security_schemesrC   rD   Zget_workflowsZget_workflow_schemeZget_all_screensZget_screen_schemeZget_all_prioritiesZget_priority_schemesr`   r  r  r   r   r  )r   Zdownload_pathrZ  ZusedZfreeZfree_percentr   r   r   download_dataN  sH    




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   rc   r  T)r  r  )r`   r  rE   Z	CmfImportrG   r(   r   r  rw   r`  r  r   r   )r   r(   r   r   r   r  y  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   z/usr/bin/python3z	manage.pyr  z&cmf_import = models.CmfImport.get(id="z#");cmf_import.process_cross_links("z", "z", z, z);Tz"/var/log/eva-import-subprocess.logza+z&/var/log/eva-import-subprocess.err.log)r  r  r  r  u   Запустили )r  r  r(   r   r;   rC   r   rr   r  rX   r)   r  )r   
model_namer  r  r  r   r   r   _execute_cross_links  s    
0z"JiraAPIImport._execute_cross_linksc             C   st  dddgdddgg}xJdD ]@}| j jd| d	| j  d
}tt| }|j|d}|s`qg }x<t| jD ].}| ||}|t	j
7 }|| ||krpP qpW | j   x|||k r(td xbt|D ]V}| }	|	dk	r|  j|	7  _|| | ||}
|t	j
7 }||
 | j   qW qW x2t|D ]&}|  |jr4|  j|j7  _q4W qW | j jd dS )uU   
        Заменим ссылки на задачи и документы
        r(   z!=Nr   z==T)r   r   r  r   u   Обрабатываем u+    в несколько процессов: r   )r   r'   u2   Закончили обработку ссылок)r(   rP   r1  ru   varsrE   r  r  r  rr   r  r   r  r  r   r   r  r/   r  r  r  )r   r   r  r  ri   Zobj_cntr  r  r  r  r  r   r   r   _process_cross_links  s@    






z"JiraAPIImport._process_cross_linksc          	   C   s  ddl m} t|d  d}| }dd |d D }t|d}t|}W d Q R X | jjjj d	|d
  }t	j
j|d}	|	st	j
|d| jd}	|d |	_|	jdd xf|d D ]X}
yd	| jjjj d	|
d
  d	}||
d rt	jj||
d  dd}n| jjd|
  wd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|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 n|
d  d! d#kr8d|_|jdd n|
d  d! d$kr`d|_|jdd nz|
d  d! d%krd|_|jdd nR|
d  d! d&krd|_|jdd n*|
d  d! d'krd|_|jdd n|
d  d! d(krv| jjjr|
d  d)r,|  |
d  d) }n|  |
d  d* }|rL|j!| |jdd n&| jjd+|
 d,|d |  jd7  _nd|
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gd}|s,|
d  d- d }t	j"jdd.|gdgd}|r|jsB||_n||jkr^|j | |_|jdd |j!| |jdd n&| jjd/|
 d0|d |  jd7  _n.| jjd1|
d  d!  d2|d |  jd7  _W q   | jjd3|
 d4d5d6 |  jd7  _Y qX qW |	S )7Nr   )get_datar  z/permissions.jsonc             S   s   i | ]}|d  |d qS )r?   Z	jira_coder   )r   r1   r   r   r   rQ    s    z6JiraAPIImport._process_permissions.<locals>.<dictcomp>Zproject_perm_permissionr2  z::r   )r   T)r   r   r(   r   )r   r  Z
permission)r?   Zinclude_deletedu4   Не нашли соответствия права r   rH  rI  r   access_membersaccess_project_role)r   rc   )Zproject_permissionr   rc   u*   Не найдено правило для zERR-0059)r1   r'   r  r  projectRole)applicationRoleZanyoneprojectLeadr  rV  zsd.customer.portal.onlyr   r   r  u9   Не нашли пользователя для прав zERR-0060r^  rG  u-   Не нашли группу для прав zERR-0061u'   Неизвестный тип прав zERR-0062u6   Не удалось загрузить правило zERR-0063CmfProjectPermPermission)rJ  )#Zcmf.system_datar  r   rX   rY   rZ   r(   r   r   rE   ZCmfProjectPermSchemerG   r   r   r  rP   rQ  ZCmfProjectPermSchemeRuler0   r/   r   r  r  r   Zaccess_local_userZaccess_ownerZaccess_responsibleZaccess_authorZaccess_sdesk_clientr;   rC   rD   r   r  rU  )r   r  r  r  Zsystem_dataZmap_permr]   Zperm_scheme_dictr   Zperm_schemer  Zpermr   rc   Zscheme_rulerole_ext_idr  r   r^  
group_namer   r   r   r    s    

"
$& 


z"JiraAPIImport._process_permissionsc             C   sj  t ddT d}x<| }|dkr(P | j r4P | jjd|d   | jj|d dtj	d}y|
  t|d	 }t|d
&}x|jddD ]}|| qW W d Q R X | jjd|d	   tjj|d d}	d|	_|	  | jd W nJ tk
rB }
 z*|d7 }| jjd|d  d|  W d d }
~
X Y nX W d Q R X qW || W d Q R X d S )NF)r  r   r  u    Пытаемся скачать r  T)streamr  r  zwb+i    )Z
chunk_sizeu   Сохранили в r   )r   r   r'   u+   Неудалось скачать файл z: )r   rG   r(   r*   rP   r1  r;   r  rr   ZIMPORT_DOWNLOAD_TIMEOUTr  r   rX   Ziter_contentr  rE   r  r  r   r  r-   r  r  )r   download_queueerror_queuer	  r  r4   Z	save_pathr]   chunkZdownload_job_objr  r   r   r   _download_file_worker  s2    
>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 }xXt| jD ]J}| jj| jd
| ||dd}|| |  | j jd|  qW x@tj	j|ddgdD ](}| j  rP ||j|j|jd qW x|D ]}|d qW | sLx|D ]}|  q:W | j  r\|S | j jd x,| s| j  r|S || 7 }qlW |S )Nu=   Скачиваем все найденные вложенияr   zplugin.plugin.source_hashr   z==r  F)r   u   Вложений нетr
  )r  r  )r  r   r3   u    Запустили задачу r  r  )r   rc   )r   r  r  r  u%   Закончили скачивать)r(   rP   r1  ro   r  r   r   r   rE   r  r  r  rs   rn   r  r
  r   rn  Zslistr*   r  r   r  r  r  r   rG   )	r   r  r  r4   r   Zprocsr  r  r  r   r   r   download_files<  sB    






zJiraAPIImport.download_filesc             C   sD  | j  rd S | j jd|d  d|d  d d }t|d  d}t|}t|}W d Q R X |r@| j jjj	 d|d	  }t
jj|d
}|st
j|| j dd}|jr|d |_|d|_||_|jdd xZ|d D ]L}|d  d|d	  d}| j jjj	 d|d	  }	t
jj|	d
}
|
sDt
j||	| j dd}
|
jr|d |
_|d|
_x$t
jj|
dD ]}|jdd qrW xZ|dg D ]H}yt
j|
d}|d}|d}|dkrt
jjdd|_n|dkr8| j jjj	 d| }t
jj|d
}|r&t
jj|d
|_ntd| n>|dkrVt
jjdd|_n |dkrtt
jjdd|_n|d krt
jjd!d|_n|d"krz|rhd| j jjj	 d| d}t
jjd#d$d%| d%gd#gd&}|s| jjjr|d' n|}t
jjdd(|gd#gd&}|rX|js(||_n||jkrD|j | |_|jdd ||_ntd)| nt
jjd*d|_n|d+kry| |}W n2 tk
r } zt| d,W d d }~X Y nX | j |d-d-d.\}}|r||_ntd/| n~|d0krL| j jjj	 d| }t
j!j|d
}|r<t"|jg|_#ntd1| n*|d2krht
jjd3d|_ntd4| |jdd |j$%  W nP tk
r } z0|  j&d57  _&| j j'd6| d7| d8|d9 W d d }~X Y nX qW |
jdd |
j$%  |d:rt(|d:t(|d	 kr|
|_)|jdd qW |j$%  |S );NuV   Импортируем схему безопасности задач проекта "r   z" (r   rC  r  z/issue_security_scheme.jsonz::r   )r   T)r   r(   r   r   )r   r  z ()r   r   r(   r   )r   )r  r  r  r   r  zvar:current_user)r?   r   u0   Не найдена проектная роль r  zvar:project_ownerrV  z
var:authorr  zvar:responsibler^  r   rH  rI  )r   rc   r  rG  u!   Не найдена группа ZUsersr   uH   . Возможно пользователь был удален в Jira.F)rY  rZ  u+   Не найден пользователь )ZgroupCustomFieldZuserCustomFieldu>   Не найдено пользовательское поле zsd.customer.portal.onlyzsdesk-client:defaultu-   Неизвестный тип правила r'   uF   Не удалось создать правило для уровня z. zERR-0070)r1   ZdefaultSecurityLevelId)*r(   r*   rP   r1  r   rX   rY   rZ   r   r   rE   ZCmfSecurityLevelSchemerG   r   r   rx   rP  r   r^  ZCmfSecurityLevelRuler   r  r   Zaccess_memberr  r-   rU  r;   rC   rD   r   r  r_  CmfCustFieldr%   Zaccess_task_fieldsr+   r,   r/   r0   rw   Zdefault_task_security_level)r   r  r  r  r]   r  r  rQ   Z	level_msgZlevel_ext_idr  Z
level_ruler  member_typemember_valuer  r  r   r^  r  r  r  r   r  cust_field_ext_id
cust_fieldr   r   r   r  `  s    














 

 
$
z&JiraAPIImport._process_security_levels)rg   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dd }|dkr~d|d< n>|dkrd|d< n*|dkrd|d< n|dkrd|d< n|dkrd|d< dd |d d D |d< n|dkrd|d< dd |d d D |d< n|d kr8d!|d< |d d |d< n|d"krTd#|d< i |d< nh|d$krhd%|d< nT|d&kr|d&|d< n@|d'krd(|d< n,|d)krd*|d< n|d+krd,|d< nd }|S )-Nr   r   customfieldcfr  r   T)r  rr  r  Zlogic_prefixF)r   r  
class_nameZvisible_filterrequiredZrequiredChangedr  r  r  r'   r,  Ztextarearx   field_custom_typeZ	textfieldr%   floatr   )r  Zradiobuttons
choice_strc             S   s   i | ]}|d  |d qS )r   r   r   )r   optr   r   r   rQ    s    z,JiraAPIImport._map_field.<locals>.<dictcomp>r  r  )ZmultiselectZmulticheckboxeschoice_multic             S   s   i | ]}|d  |d qS )r   r   r   )r   r  r   r   r   rQ    s    r  r  Zcascadingselectchoice_cascade_multiZ
datepickerZdater>  r  r   r  r   )r  r  rN  )r  r(   r   r   r  r   )r   rg   r  r4   r  r   r   r   
_map_field  sL    















zJiraAPIImport._map_fieldc          
      sF  d | _ xd| jD ]Z}xT| jtjj d D ]>}d|krF| jdtj	 d S |d d |kr&| j| |d< q&W qW | jd | jj
j
j}tjj|dgd}|stjd|d	| jd
}d|_|  tjjdd|d}| jjjddsd S dd tj D }g }g }x| jtjj d D ]}|dr6|d d sP| jd|d   q| |}	|d d dd}
|
d| jj
j
j  7 }
|
|d< |	s| jjd|d  ddd |  jd7  _q|	d d kr|| | jj
j
j d!|d d  }tjj|d"d#d$d%gd}|s>tj|d |d |	d d	|| jd	d&}|
|kr||
 d" |jjkr| jjd|d  d'|j d(||
 d"  d)dd q| jd*|
 d+|d  d, ||
 |d-< n(| jd.|
 d+|d  d/ || |jr|d |_|	d d0kri }g }xf|d d1 D ]V}|d2 s0qx>|d3g D ].}|d4 ||d < |d5 r>||d  q>W P qW ||_||_|j rd	|_!|| |jd	d6 |j"#  tj$j||
||d7}|stj$||
||d7jd	d6 qW |j"#  |%  |rhtj&t'j'( )d8ddd9 tj*d:di d;d tj D }x|D ]}||d  |d-< qNW dC fd<d=	xP|D ]H}tjj+|d- d>  }t,t|j-  x|d d3 D ]}| qW q~W | jjj}x:|d? D ].}|d tjjkr| jtjj d |d< qW || j_d@t.j/dA< | j  | jj"#  dBt.j/dA< d S )DNrc   r   uj   Текущая настройка не поддерживает импорт кастомных полейr   u0   Обработка кастомных полейr   )r   rc   u8   Экран проектов Jira по умолчаниюT)r   r   r   r(   r   Z_customr^  )r   r  r   Zimport_custom_fieldsFc             S   s   i | ]}||d  qS )rj   r   )r   r]   r   r   r   rQ  P  s    z8JiraAPIImport._process_custom_fields.<locals>.<dictcomp>r  u!   Поле не кастомное r   r  r  r  r   u+   Неудалось смапить поле zERR-0064	CmfUiForm)rJ  r'   r  )r  r  r  z::widgetr  r   disabled_choices)r   r   r  dirtyr   r(   r   u   , widget поля u5    не совпадает с существующим zERR-0065u   Поле с именем z (u4   ) есть в таблице, мапим в негоr   u(   Создаем поле с именем u   ), и мапим в негоr  r  r  r  r   disabled)r   )r  r   r   ui_form_groupz%Y%m%d%H%M%S)Zmeta_versionr  rs  rx  c             S   s   i | ]}||d  qS )rj   r   )r   r]   r   r   r   rQ    s    c                s   t | tr4 j| d}|s$ | d}|jr|  ntt | tr j| d d}|s` | d d}| dd|_|rz|j|_|jr|  x| dg D ]}|| qW d S )N)r   r   r   Fr  )	r   r%   rG   rX  r   r   Z
cmf_hiddenr   Zchoice_parent_id)r  Z
parent_optr   Zchild)choice_modelcreate_optionr   r   r#    s"    



z;JiraAPIImport._process_custom_fields.<locals>.create_optionrj   r   r   r  r  )N)0r:   r^   r   rE   r   r   r(   r)   rO   rS  r   r   r  rG   rx  r   CmfUiFormGroupr   r   rk   r  r  r  r0   r/   r   r  r  r   r   r  r  rX  r  r+   r,   CmfUiFormFieldinvalidate_cacheZcustom_fields_gen_metar>  r  r  Zcustom_field_sync_update_modelsrc   r  ri   r`   r  )r   Zext_field_namerg   r   ui_view_formr!  shop_fieldsZ
new_fieldsZ
m2m_fieldsZui_fieldr   r  r  r  r  r  ui_form_fieldZfield_classr   r  r   )r"  r#  r   _process_custom_fields1  s    




"












z$JiraAPIImport._process_custom_fieldsc             C   s  dd t j D }| jjjj d|d  }t jj|dgd}|sx| jd|d  d	|d  d
 t j|d| jd}|j	rx|d |_
|dd|_d|_|  x|d D ]}| jjjj d|d  d|d  }t jj|d}|s.| jd|d  d	|d  d| d t jd||d| jd}|j	r|d |_
|jdd x&|d D ]}|d dspqV|d dd}	|	d| jjjj  7 }	|	|krqVx| jt jj d D ]}
|
dsАq|
d d |d kr| jjjj d|
d d  }t jj|d}t jj||	||d}|sf| jd|	 d | d!| d t j||	||djdd P qW qVW qW |  |j  |S )"Nc             S   s   i | ]}||d  qS )rj   r   )r   r]   r   r   r   rQ    s    z1JiraAPIImport._process_screen.<locals>.<dictcomp>z::r   r   )r   rc   u   Создаем экран "r   z" (rC  T)r   r   r(   r   r   r   Ztabs)r   u   Создаем вкладку "u   ) экрана "r   tab)r  r   r   r   r(   )r   rc   customfield_r  r  r  r   )r  r   r   r!  u   Добавляем поле "u   " на экран "u   " во вкладку ")rE   r   rk   r(   r   r   r  rG   r)   r   r   rx   rx  r   r$  r2  r  r  r   r   r  r%  r&  r+   r,   )r   r  r(  Zscreen_ext_idui_formr+  Z
tab_ext_idr!  Z
jira_fieldr   rg   r  r  r)  r   r   r   _process_screen  sz    

$"



zJiraAPIImport._process_screenu,   Обработка схемы экрановc          
   C   s(  | drH|d }|d }| jjjj d| }tjj |dgd}|sZtj|| jdd}|jrdd	 | d
D }|d |_|j	dd |j
sxtjj|dD ]}|  qW xh|d D ]}|d }	d }
|	dkr,| jjjj d|	 }tjj ddd| dgd}
|
s,| jjd|	 ddd qx|d  D ] \}}| |}|sx| jjd| d| ddd q<y| |}W n.   | jjd| d| ddd w<Y nX dd d!d"d d!d"d#}| j rd S ||d$| |d| jd%}tjj f |d&d'gi}|stjf |}|
r0|j|
 |j	dd q<W qW n| jjjj d|d  }tjj |dgd}|stj|d(  d)|d  || jdd*}|j	dd tjj | jjjjdgd}|jrtjj |dgd}|stj|d| jd+}|jr||_||_d$|_|j	dd t  |S ),Nr  r   z::r   )r   rc   T)r   r(   r   c             S   s   i | ]}||d  qS )r   r   )r   r  r   r   r   rQ  B  s    z8JiraAPIImport._process_screen_scheme.<locals>.<dictcomp>r  r   )r   )r  r  r  r  r   rH  z%::z::%)r   u;   Не удалось найти логический тип zERR-0067CmfUiFormScheme)rJ  r  u8   Не удалось найти в дампе экран u    для zERR-0069u:   Не удалось импортировать экран zERR-0068rY  rZ  read)r  rY  ZeditZviewr  r  r  r   )r  r  rx  Zcrud_choicer(   rc   logic_typesr   u+   : Схема экранов проекта )r   r   r(   r   )r   r   r(   )rG   r(   r   r   rE   r/  r   r   r   r   r  ZCmfUiFormSchemeRuler   r  r  r0   r   r.  r*   r1  r   r  r  r  rx  r   )r   r  Zscreen_scheme_dataZscreen_scheme_idr   r  r  r  Zissue_type_datar  rv  r  r  r  r  r-  Zaction_mappingr  r'  r   r   r   r  1  s    






z$JiraAPIImport._process_screen_schemec             C   sR  i }t  }|ds|S dd tj D }x|d  D ]}|d dsPq<|d dd}|d| jj	j	j
  7 }||krq<x| jtjj d	 D ]}|d
sq|d |d
 d krxl|d  D ]\\}}	|	dsq| }
|	|
d< ||i }|
||
d < |	d r|di }|
||
d < qW qW q<W x| D ]
\}}d}| jj	j	j
 d|d  }|d  d|d  }|dkr d| jj	j	j
 d| d}tjjddd| dgd}|s| jjd| ddd q>|d| 7 }|d|d  7 }n|d7 }tjj|dgd}|s@tj||d| jd }|jdd! |||f x| D ]\}}
|
d }	| jj	j	j
 d| }tjj|d"gd}tjj||d#}|stj||| jd$}|	d%d&|_|	d'd& |_|jd(kr:i }g }xB|	d)i  D ].}|d* ||d < |d+ r||d  qW ||_||_|  qXW q>W |S ),u1    Импорт конфигураций полейr  c             S   s   i | ]}||d  qS )rj   r   )r   r]   r   r   r   rQ    s    z5JiraAPIImport._process_field_conf.<locals>.<dictcomp>r   r,  r  r  r  rc   r   r  r  anyNz::r   u5   : Конфигурация полей проекта r   r   rH  rI  )r   u;   Не удалось найти логический тип zERR-0067CmfCustFieldConfScheme)rJ  u    для типа u    по умолчаниюr   )r   rc   T)r   r   r   r(   )r   r  )r  r   )r  r   r(   Z
isRequiredFZisHiddenr  r  r   r   )rc  rG   rE   r   rk   rf   r2  r  r(   r   r   r  r   r   r   r  r|  r  r0   r  r   rd  r  r  r  Zvisibler  r   r  r  )r   r  Zlogic_type_fieldslogic_type_field_confr(  Z
field_usedrj   Z
task_fieldZlogic_type_idr  rg   rc   rv  r  r   r  r  Zfield_idZfield_ext_idr  r  r  r  r  r   r   r   _process_field_conf  s    






z!JiraAPIImport._process_field_confuA   Обработка схемы конфигурации полейc       
      C   sR  | j jjj d|d  }tjj|dgd}|sbtj|d  d|d  || j dd	}|jdd
 tjj|dgd}|stj|d  d|d  d|d| j d}|jdd
 | |}|	d |f |j
rFx"tjj|dD ]}|jdd qW xT|D ]L\}}|||r|gng d| j d}	|s*d|	d< tjf |	}|jdd
 qW |  |S )Nz::r   r   )r   rc   r   u@   : Схема конфигурации полей проекта r   T)r   r   r(   r   )r   u5   : Конфигурация полей проекта u    по умолчанию)r   r   r   r(   )r   )r  )r   r  r1  r   r(   r'   Zorderno)r(   r   r   rE   r3  rG   r   r  r5  rd  r   ZCmfCustFieldConfSchemeRuler   r  r&  )
r   r  r   r  r  r4  r  rv  Z
field_confr  r   r   r   r    sD    


z(JiraAPIImport._process_field_conf_schemec             C   s  x t dD ]}|   | js
P q
W xt dD ]}|  }|s,P q,W |  j|7  _|   |   |   |   |   |   |   |   |   | 	  | j
jjr|   |   |   |   |   n|   |   |   |   |   | j rd S d| j_| j  t  xJ|  D ]>}|d dd | jD krPq.| jjd|d  d q.W | jd	| jj  | j S )
Nr  r  r   c             S   s   g | ]}|d  qS )r   r   )r   r1   r   r   r   r   l  s    z0JiraAPIImport.process_import.<locals>.<listcomp>u'   Импортирован проект 'r   r  u-   Импортировано объектов: ) r  r  r/   r  r  ra  re  rk  rw  r*  r;   rC   rD   r{  r}  r  r  r  rg  rs  rt  r(   r*   r  r   r   r   rN   rP   r1  r)   r`  )r   r  r4   r   r   r   r   process_importE  sR    


 zJiraAPIImport.process_import)T)r   r   )T)TTN)N)N)r   r  )NN)NN)N)Nr  r  ){r!   r"   r#   r$   rw   r&   r   r%   r   r   rA   propertyr^   re   rh   staticmethodr   r   r   rl   rR   r   r   r   r   r   r   r   r   r   r8   r   r  r  r  r   rA  r_  ra  re  rk  rE   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r.  r   r   r6  r7  rB  rI  rL  rP  rT  r  rb  rg  r  r  rs  rt  rw  r{  r}  r~  r  r   r   r  ry  rz  r  r  r)  rm  rk  r  r   r  r  rJ  r=  rN  r   rI   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r*  r.  r  r5  r  r6  __classcell__r   r   )rT   r   r9   ?   s   
	!	
#> J!9n#V, 8 #?- B) m:'*I8%#C=xU"	  f+
,e$ = 3Nym.r9   )0Zcmf.appr   Zcmf.includeZdataclassesr  r>  r  r#  r:  Zpathlibr   r_   Ztempfiler   r3  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   Zmodules.jira.jql.parserr   rE   r   r   r   r   Z	dataclassr   r8   r9   r   r   r   r   <module>   s0   $ 