U
    >.iW                    @   sd  d dl mZ d dlT d dlmZmZ d dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlmZ d dl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* d dl+m,Z, eee-j. ee-j/ ee-j0 f Z1ej2G dd dZ3dd Z4G dd de*Z5dS )    )cmf_context)*)cmf_hashlibcmfutilN)Path)DictOptionalListCallableUnionTypeIterator)BeautifulSoup)permutations)dedentindent)	normalize)	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 r   )r   )r   otherr    r    r!   __eq__)   s    zEpicData.__eq__N)__name__
__module____qualname____doc__str__annotations__r"   r$   r    r    r    r!   r      s   
r   c                    s    fdd}|S )Nc                    s    fdd}|S )Nc                    s   z>| j d  | j  r$W dS  | f||}t  |W S  tk
rz   t  |  jd7  _| j d  Y dS X d S )Nz================== r      u   Ошибка )
cmf_importlog	is_cancel
cmf_commit	Exceptioncmf_rollback
has_errors	log_error)objargskwargsres)funcr   r    r!   wrapper/   s    
z3catch_exception.<locals>.decorator.<locals>.wrapperr    )r8   r9   r   )r8   r!   	decorator.   s    z"catch_exception.<locals>.decoratorr    )r   r;   r    r:   r!   catch_exception-   s    r<   c                       sH  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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dJd!d"Zee dd#d$Zee dd%d&Zee ed'd(d)ZdKd,d-Ze d.d/d0 Z!e d1d2d3 Z"e d4eed5d6d7Z#d8d9 Z$e d:ee%d;d<d=Z&dLd>d?Z'e d@dAdB Z(e dCdDdE Z)e dFdGdH Z*e+j,ddIdJZ-dKdL Z.dMdMdNZ/dNdOdPZ0dQdR Z1dSdT Z2dUdV Z3e dWdXdY Z4e dZd[d\ Z5e d]d^d_ Z6e d`dOe7dadbdcZ8ddde Z9dfdg Z:e dhdidj Z;eedkdldmZ<dndo Z=dPdrdsZ>dtdu Z?dvdw Z@e dxdydz ZAd{d| ZBe d}d~d ZCe ddd ZDe ddd ZEdd ZFdQddZGeHdddZIeHdddZJe dedddZKdd ZLdd ZMe dedddZNdd ZOe ddd ZPdd ZQdd ZRdd ZSdd ZTe ddd ZUe ddd ZVdd ZWdd ZXe ddRddZYe ddd ZZe ddSe7daddZ[e dedddZ\e ddd Z]e dddĄ Z^e dŃddǄ Z_e dȃddʄ Z`e d˃dd̈́ Zae d΃ddЄ Zbdd҄ ZcdTddԄZded՜ddׄZee d؃edٜddۄZfedٜdd݄Zgdd߄ Zhdd Zidd Zjdd Zkdd Zldd Zmdd Zndd Zodd Zpdd Zqdd ZrdUddZsdd Ztdd Zudd Zvdd Zweddd ZxedddZyedddZzedddZ{edddZ|d	d
 Z}dd Z~dd Zdd Zdd Ze deeHedddZdd Zdd ZeedddZdd Zedd d!ZdVd"d#Zd$d% ZedWeeeed(d)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zed9d:d;Zd<d= Zd>d? Ze d@dAdB ZdCdD Ze dEdFdG ZdHdI Z  ZS (X  JiraAPIImportu;   Класс загрузки объектов через APIr2   _JiraAPIImport__jira_fieldsN)jirareturnc                    s   t  j|| || _d| _| jjr(d| _tjjdd| _d | _	| 
 | _i | _i | _i | _g | _g | _d| _td}| jjj|_|| jjj |   |   d | _d| _dd	d
d| _d S )Nr   	accountIdsoftdevcoder   zatlassian.rest_clientF
logic_typepriorityresponsible)	issuetyperF   assignee)super__init__r?   user_keycloudmodelsCmfActivitygetdefault_activitycloud_id_get_jira_global_settingsjira_global_settingsZepicsissue_relationssubtasksboardsselected_projectsr2   loggingZ	getLoggerr,   loggerZhandlersZsetLevellevel_prepare_multiprocessing_set_fallback_personr>   update_fields_board_card_colors_mapping)r   r?   r5   r6   rZ   	__class__r    r!   rK   G   s2    

zJiraAPIImport.__init__)r@   c              	   C   s   | j r| j S | j d}| rL| jsLt|}t|| _ W 5 Q R X n6| j	
 | _ t|d}t| j | W 5 Q R X d| _| j S )Nfields.jsonw+F)r>   r,   get_download_pathjoinpathexistsr^   openjsonloadr?   Z
get_fieldsdump)r   	file_pathfr    r    r!   jira_fieldsh   s    
zJiraAPIImport.jira_fieldsc              	   C   sl   dd l }|| _| j d}| j dt  }t|d}t	| j| W 5 Q R X |
|| d S )Nr   rb   zfields.json.rc   )shutilr>   r,   rd   re   osgetpidrg   rh   rj   move)r   fieldsrn   rk   file_path_tmprl   r    r    r!   update_jira_fieldsx   s    z JiraAPIImport.update_jira_fieldsc                 C   s>   | j jjd}t|| _| jr2tjj|d| _nt	j
| _dS )u   
        Устанавливает резервного пользователя,
        если пользователь не будет найден в методе _get_person()
        default_user_ididN)r,   json_settingsvaluerP   bool_is_default_userrN   	CmfPerson_fallback_persongZsystem_user)r   ru   r    r    r!   r]      s
    
z"JiraAPIImport._set_fallback_personc                 C   s(   | j  D ]}|d |kr
|  S q
d S )Nr   )rm   values)r   r   fieldr    r    r!   _get_field_by_name   s    z JiraAPIImport._get_field_by_namec                    s"   t t fdd| j d }|S )Nc                    s   |  di  d kS )NschemacustomrP   rl   
field_typer    r!   <lambda>       z2JiraAPIImport._get_field_by_type.<locals>.<lambda>)nextfilterrm   r   )r   r   r   r    r   r!   _get_field_by_type   s    
z JiraAPIImport._get_field_by_type)model
field_namer@   c                 C   s&   |sd S | j |gd}|r"|d S d S )N)Zfields_namer   )import_shop_fields)r   r   r7   r    r    r!   _get_field_name   s    zJiraAPIImport._get_field_namec                 C   s<   dd l }dd l}|| _ || _tj| _tj| _| j | _	d S )Nr   )
	threadingqueueconfigZIMPORT_THREADSthreading_max_forksZIMPORT_DOWNLOAD_THREADSdownload_threading_max_forksr,   get_max_processesmax_processes)r   r   r   r    r    r!   r\      s    z&JiraAPIImport._prepare_multiprocessingc                 C   sv   g }ddddddddd	d
ddd}dddd}| j  D ]8\}}d| ||d }|||d||d q8|S )uO    Сопоставление настроек для модели models.CmfTaskr   text	cmf_ownerrG   rF   statusZ
alarm_dateZdeadlinecmf_modified_atcmf_created_atstatus_closed_at
resolution)summarydescriptionreporterrI   rF   r   Zcustomfield_10015Zduedateupdatedcreatedresolutiondater   z.namez.watchCountz.votes)rF   ZwatchesZvoteszfields. N)model_field	json_path	ext_field)rm   itemsrP   append)r   Zissue_settingsZdefault_local_attrs_mappingZadditional_json_pathZcustom_field_keyZcustom_fieldr   r    r    r!   _get_issue_import_settings   s4    

z(JiraAPIImport._get_issue_import_settingsc                  C   s    dddddddddg} | S )Nr   displayNamer   r   emailemailAddressdoes_not_workactiver    )Zuser_settingsr    r    r!   _get_user_import_settings   s
    z'JiraAPIImport._get_user_import_settingsc                  C   s    dddddddddg} | S )Nr   r   r   
cmf_authorauthorr   renderedBodyr    )Zcomment_settingsr    r    r!   _get_comment_import_settings   s
    z*JiraAPIImport._get_comment_import_settingsc                 C   sX   dddddddd}||kr$|| S | d	}t|d
kr>dS | j|d
 i ddS )N   ИмяZEmailu   Активныйu   Создано
   Автор
   Текстu   Ключ)r   r   r   r   r   bodyr   .r+   r   r   )splitlenrm   rP   )r   Zjsonpathmappingr    r    r!    _get_setting_title_from_jsonpath   s    	
z.JiraAPIImport._get_setting_title_from_jsonpathTc                 C   s  |sd S | dD ](}t| ts& d S | |} | s d S q|rvt| trvdddg}|D ]}|| krX| |   S qXdS |rt| trg }| D ]f}d|kr||d d  qd|kr||d d  qd|kr||d  q|r|t| qd|S | S )	Nr   r   r   r   r   inwardIssueoutwardIssue,)r   
isinstancedictrP   listr   r)   join)r4   r   to_strr   Z
str_fieldsZ	str_fieldresultZrelated_objr    r    r!   _get_file_val   s6    



zJiraAPIImport._get_file_valc           	         sv  g  t ttt f tg tt f ttd fdd}jdg j 	d}d}d}|
 r D ]$}|d D ]} qq~|rl qqldD ]} qq|sd	d
 jjddD }|r|d }|sdd
 jjjjd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_funcr   r@   c                    sz   | D ]p}| }|D ]H} ||d |d< ||d |d< |d |d< |j|d< q |j|d |  S d S )Nr   Zfile_valr   titleicon)r   rr   )r   r   r   r   r   verbose_name)r   r   r   r4   Zobj_settingssettingr   r   r    r!   _get_settings  s    z:JiraAPIImport.tmplt_import_settings.<locals>._get_settingszplugin.plugin.*projectsNrw   usersc                 S   s   g | ]}|qS r    r    .0r4   r    r    r!   
<listcomp>4  s     z7JiraAPIImport.tmplt_import_settings.<locals>.<listcomp>r+   limitr   c                 S   s   g | ]}|qS r    r    r   r    r    r!   r   8  s     )usernameZ	limit_enduS   Не найдено ни одной задачи, импорт невозможенTua   Не найдено ни одного пользователя, импорт невозможенz2022-05-22T15:22:22.593+0300r   u!   Электронная почта)r   r   r   )r   r   r   selectedObjects)r   ry   )r   r	   r   r   r
   	TypeModelr,   load_fieldsrd   re   rf   _get_projectsget_project_tasks_simple_getr?   
get_issues	get_usersr   r0   r^   r   rN   CmfTaskr   r|   r   
CmfCommentr   )	r   r   Zdump_dirtaskuserprojecttasksr   Zcomment_exampler    r   r!   tmplt_import_settings  sT      z#JiraAPIImport.tmplt_import_settingsc                 C   s   |  | jjd }ddg g gdg}| jjddD ]}t|tjj d D ]f\}}|d s\qJ| 	||d	 }| 
|d d
 |}|d d |d d  |d d d | qJq2|S )Nimport_settingsu   Задачиzcalendar-today)r   r   titlesrows   r   rr   r   r   r   r   r   captionr   )Z_normalize_settingsr,   rx   r?   r   	enumeraterN   r   r   r   _normalize_jira_valuer   )r   settingsr   issuenumr   ry   r    r    r!   previewT  s    zJiraAPIImport.preview)r   r@   c                 C   s\   i }|D ]N}|d sq| j ||d dd}| |d d ||d}|||d d < q|S )uC    Преобразование настроек для модели r   r   F)r   r   r   )r   r   rP   )r   r4   r   Znormalized_objr   ry   r    r    r!   _normalize_objc  s    zJiraAPIImport._normalize_objsprintkanbanc           
      C   s   dd|j gg}|dr*|dddg n|dd|g tjj|d}| jjjj d|d  }tj	| jtj
|d	 ||||d
|d|ddd|gd\}}	|	r|d	 |_|jdd |S )NZtree_parent_id==ZcompleteDatesys_typearchiver   ::rw   r   	startDateendDate)r   parenttree_parent	list_typeplan_start_dateplan_end_dateext_idr  Z
filter_objTZsave_import)rw   rP   r   rN   	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_listo  s*    


zJiraAPIImport._process_listu8   Обработка наблюдателей задачиc                 C   s   d|d  d|d d  d}g }|  |D ]n}| jjrL| j|d |d}n| j|d |d}|sptd	| ||jks,||jks,||jkrq,|| q,||_	d
S )u;   Добавляем наблюдателей в задачуu$   Наблюдатели задачи r   : "rr   r   "rA   r4   uI   _process_watchers: Не найден наблюдатель задачи N)
_get_issue_watchersr?   rM   _get_personZCmfErrorrG   r   r   r   
spectators)r   	issue_objr   r4   r  watcherpersonr    r    r!   _process_watchers  s    zJiraAPIImport._process_watchersu#   Обработка вложенийc                    s   d}d|d  d|d d  ddd	 |d d
 D   fdd} |D ](}|||d |d 7 }jd
d qT|S )Nr   u   Вложения задачи r   : 'rr   r   'c                 S   s   i | ]}t |d  |qS rv   r)   )r   Zatt_datar    r    r!   
<dictcomp>  s   
 z6JiraAPIImport._process_attachments.<locals>.<dictcomp>
attachmentc           	         s  d}d zz  | }|r$|d nd}|r4|d n| }tjj |ddddgd	}|svtj|jd
d}|jd
d |jr|r| drj|d j d|_|j|_	|d |_
||_t|dJ}|j| d
dd d
|_|jd
d |r|d }|j|kstW 5 Q R X t  W n tk
rn   t  jjd| d| d|j d| d	dd d}Y n@ tk
r   t  jjd| d| ddd d}Y nX W 5 |  S X  )Nr   rw   r   filenameimport_originalurlZurl_preview_imgZurl_previewr   r   rr   T)r   r   r,   r  r  r   r  r   rbF)Zsmart_backupZ
mark_dirtysizeu   Размер файла '' (u@   ) не соответствует размеру из меты: z	 bytes / z bytesERR-0034r+   u;   Не удалось обработать вложение ')zERR-0035)rP   rN   CmfAttachmentr,   r  r  r  rL   r   r   r   import_raw_jsonrg   Zupload_filereadst_sizeAssertionErrorr/   r3   r0   r1   )		file_namerk   errorZattachment_metaZattachment_idZattachment_namer  rl   Zattachment_sizeattachmentsZ	issue_msgr  r   r    r!   _process_attachment  sz    





z?JiraAPIImport._process_attachments.<locals>._process_attachmentr,  rk   	processed)_get_issue_attachmentsr,   inc_stat)r   r  
jira_issueerrorsr0  Zattachment_datar    r.  r!   _process_attachments  s    
Ez"JiraAPIImport._process_attachmentsuB   Обработка упоминаний пользователей)	text_soupr@   c                 C   s`  ddl m}m} |jdkr d}nd}|jddidD ]$}z|jd	rZ| |jd	 }np|jd
rx| |jd
 }nR||jd }||j}	|	dr| 	|	d d 
 }
| |
| j }ntdt|jt|jt|jt|jt|jdd}||j W q4 tk
rX } z0|  jd7  _| jjd| d| d|d W 5 d}~X Y q4X q4dS )u]   
        Упоминания пользователей
        confluence-userlink
        r   )urlparseparse_qsr   a  
                <a
                    class="external"
                    href="{person_href}"
                    rel="noopener"
                    target="_blank"
                    data-macros="mentions"
                    data-mention-type="person"
                    data-object-id="{person_id}"
                    data-title="{person_login}"
                    cmf_converted="true"
                >
                    @{person_name}
                </a>
            u	  
                <span class="macros-panel mentions-macros" contenteditable="false" data-id>
                    <span class="extension-container" data-layout="default" data-id>
                        <span class="extension-title" data-id>
                            @Упоминания <span class="excerpt-title" data-id>| {person_login}</span>
                        </span>
                        <span class="macros-actions" data-id>
                            <span class="macros-delete" data-id>
                                <svg viewbox="0 0 18 18" class="ng-star-inserted" style="width: 14px; height: 14px; color: #222222;">
                                    <path fill="#222" d="M16.5 3H12.75V1.5C12.75 1.10218 12.592 0.720644 12.3107 0.43934C12.0294 0.158035 11.6478 0 11.25 0L6.75 0C6.35218 0 5.97064 0.158035 5.68934 0.43934C5.40804 0.720644 5.25 1.10218 5.25 1.5V3H1.5V4.5H3V15.75C3 16.3467 3.23705 16.919 3.65901 17.341C4.08097 17.7629 4.65326 18 5.25 18H12.75C13.3467 18 13.919 17.7629 14.341 17.341C14.7629 16.919 15 16.3467 15 15.75V4.5H16.5V3ZM6.75 1.5H11.25V3H6.75V1.5ZM13.5 15.75C13.5 15.9489 13.421 16.1397 13.2803 16.2803C13.1397 16.421 12.9489 16.5 12.75 16.5H5.25C5.05109 16.5 4.86032 16.421 4.71967 16.2803C4.57902 16.1397 4.5 15.9489 4.5 15.75V4.5H13.5V15.75Z" stroke="none" stroke-width="1" class="ng-star-inserted"></path>
                                    <path fill="#222" d="M8.25 7.5H6.75V13.5H8.25V7.5Z" stroke="none" stroke-width="1" class="ng-star-inserted"></path>
                                    <path fill="#222" d="M11.25 7.5H9.75V13.5H11.25V7.5Z" stroke="none" stroke-width="1" class="ng-star-inserted"></path>
                                </svg>
                            </span>
                        </span>
                    </span>
                    <span class="ak-renderer-wrapper" data-id>
                        <a class="external" data-macros="mentions" data-mention-type="person" data-object-id="{person_id}" data-title="{person_login}" rel="noopener" data-id cmf_converted="true">
                            <span class="lds-ring" data-id>
                                <span data-id></span>
                                <span data-id></span>
                                <span data-id></span>
                                <span data-id></span>
                            </span>
                        </a>
                    </span>
                </span>
            class
user-hoverattrsdata-account-iddata-usernamehrefr   u[   Не найдены атрибуты для определения пользователя)Z	person_idZperson_loginZperson_hrefZperson_namehtml.parserr+   uR   Ошибка конвертации упоминания пользователя : zERR-0036r  N)urllib.parser8  r9  
class_namefind_allr=  rP   r  query_get_user_info_from_dumplowerrL   r0   r   formatr)   rw   loginr@  r   Zreplace_withZ
currentTagr2   r,   r3   )r   r7  r4   r8  r9  ZTMPLtagr  
parsed_urlrF  	user_infonew_tager    r    r!   _process_mentions  sB    


	zJiraAPIImport._process_mentionsc                 C   s   t jj}|| jj d| }|d k	r2t|S | dD ]}|| j	|krX|  S |dd
 |
 krx|  S |dd
 |
 kr|  S |dd
 |
 kr|  S |dd
 |
 kr<|  S q<td| d S )	N:user:r   r   r   r   r   r   uQ   Не нашли информацию по пользователю в дампе )APPREDIS_DBredisrP   r,   rw   pickleloadsr   rL   rH  r0   )r   user_idredis_dbrM  r    r    r!   rG  I  s     

z&JiraAPIImport._get_user_info_from_dumpu#   Конвертация ссылок)r7  r   c                    s  |j dkr|j}|dd D ]l}|jdrF| jjd|  q|drv|jd 	drv| jjd|  q| jjd	|  |dr|jd }n
|jd
 }t
j|dd dd }tdt
j|dd }|r(|d  |d d }tt fdd|d }	|	r(|	d }tj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d S )"Nr   c                 S   s   |  dp|  dS Nr@  srchas_attrrK  r    r    r!   r   a  r   z.JiraAPIImport._process_links.<locals>.<lambda>Zcmf_convertedu   Уже обработали r@  #u   Это якорь u&   Обрабатываем ссылку rZ  /?r   (/attachment(?:/content)?/(\d+)(?:/)?(.*)r+   rr   r  c                    s   |  d kS Nrw   r   itemZ	attach_idr    r!   r   t  r   r  r   )r   rr   r   Zsrc_origTZvideoZcontrolsz100%widthZheightZ	href_origu   Заменили на z/people/r   )rD  r   rE  r=  rP   r,   rZ   infor\  
startswithurllibparseunquoter   researchr   r   rN   r'  sgetr   	mimetypes
guess_typer   r  r@  )r   r7  r   r4  rK  r   r,  	url_matchr/  attachZ
attach_obj	mime_type
account_idr  r    rf  r!   _process_links\  s^    


 
 





zJiraAPIImport._process_linksc              	      s  |rd| dnd}|s|r0| j jd|  | jjr\|d dkr\| j jd|d   | || jtj	j
 d }| jjs"|d	  td
|d }dd |D }t|dkr" fdd|D } fdd|D }	|r|d |d< n|	r|	d |d< n|d |d< ||d  |d |d< d| j jjj d|| j  d}
|d	 dd}d}|D ]}t||krZt|}qZttj	jjtj	jjtj	jj}||kr0t|dkr|d |d< d|d< d|d< nbt|dkr|d |d< |d |d< d|d< n2t|dkrb|d |d< |d |d< |d |d< n2|  jd7  _| j jd|d	  d| dddd d d!g}tj	jd"d#d$|
 d$g|d%}|r:|jjd| j jjj ddkr:|r
| j jd&| d'|j  td| j jjj d(d|jj|_|jd)d* d }n0|  jd7  _| j jd+| d,|j d-d.d/d0 |sd1d"d2d3| j jjj d4gd"d5d gg}tj	jd6d7|d g|g|d%}|stj	jdd7|d g|g|d%}t|dkr| j jd8|d  d9t| d| d:dd |  jd7  _g }|s | j jd;|d  d|  d	d7|d	 g|g}tj	j||d%}|s d1g}t |t|D ]}t|dkrvdd7|d g}nnt|dkr|!dd7|d gdd7|d gg n<t|dkrT|!dd7|d gdd7|d gdd7|d gg qT||g}tj	j||d%}t|dkrR|  jd7  _| j jd<|d	  d=|d  d>t| d| d:dd |rb|d }n*| j "d?|d	  d=|d  d@| t#j$ dA}|s0|r(d)}d}|d }tj	jd6d7|% g|d%r| j "dB| dCt#j& |d dD\}}| dE| dD| }|d7 }qtj	|
|| j d)dF}nd |fS |rtd
t'|j(}dGd |D }t|dkrp|d |d6< |j)r|D ]}t*||||  q||jr|
|jkr|j |
 |_n|
|_tj+, }tj+- }|j.!| |j.!| d)|_/|dH dI D ] }| jjr d|dJ  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	d5|d	 gd gd%}|stj+|
| j d)|d	 |dK}|j)r|d	 |_0|js|
|_n|
|jkr|j |
 |_|jd)d* |j.!| q|j1r|jd)d* ||fS )LN(r&  r   u0   Импортируем пользователя ZaccountTypeZ	atlassianu   Неизвестный тип rr   r   z[,;\s]+r   c                 S   s   g | ]}|  r|  qS r    stripr   r   r    r    r!   r     s      z1JiraAPIImport._process_person.<locals>.<listcomp>r+   c                    s"   g | ]} | d d kr|qS @r   r   rz  Z
user_loginr    r!   r     s      c                    s"   g | ]}| d d  kr|qS r{  r}  rz  r~  r    r!   r     s      r   Zemail_2r       	last_name
first_namesecond_name   u?   Часть полного имени пользователя "u   " длиннее u_    символов. Фамилия, Имя и Отчество не были заполнены.zERR-0110r|   obj_typer   rg_member_ofr  LIKE%r   rr   u    ext_id пользователя N    содержит несколько ID из одного источника: z::.+?::Tr  uP   Возможно найден некорректный пользователь ud   ,так как ext_id содержит несколько ID из одного источника: 'uq   '.Необходимо повторно импортировать локальных пользователей.zERR-0004r   
error_coder  ORzNOT LIKE%::::%r   rJ  ILIKEu+   Пользователей с почтой z > zERR-0037uH   Не удалось найти пользователя с почтой u+   Пользователей с именем  (z) > uM   Не нашли пользователя среди существующих ) FuQ   Обнаружена учетная запись с дублирующим email u   , добавляем цифруr|  +)r  rJ  r,   r  c                 S   s   g | ]}|  r|  qS r    rx  rz  r    r    r!   r   Z  s      groupsr   groupId)r  r,   r  r   r(  )2r,   rZ   rh  r?   rM   warningr   r   rN   r|   r   rm  r   r   remover  r  rL   minr  Z
max_lengthr  r  r2   r3   rP   r  ry   countsubr  r   r   r   r-   rY   INFOrH  WARNINGr)   rJ  r  setattrCmfPersonGroup
jira_group
user_groupr  Z
user_localr   
is_changed)r   r   createupdater4   Zobj_msgZ	user_dictZemailsZemails_by_loginZemails_by_namer  Z	full_nameZcurrent_length_namer   Zmax_length_namerr   r  Znot_source_hash_filterZpersonsr  Z
name_combo
is_creatednrJ  Zprefix_emaildomainr   r  r  Z
group_infogroupr    r~  r!   _process_person  s   
 


*" 
&
 


   
zJiraAPIImport._process_personu   Обработка группc              	   C   s<  |  dD ]*}z| j r$W  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 t  | j jd7  _W q
   t  |  jd7  _| jjd| ddd Y q
X q
d S )Nr  r   r   r  r  r  r   r  r  T)r   r  r,   r  r(  r  r+   u4   Не удалось загрузить группу ERR-0038r  r  )r   r,   r.   r  r  rN   r  rP   r  r   r  r  r/   imported_object_countr1   r2   r3   )r   Z
group_datar  r  r    r    r!   _process_groups  s@    
 

 zJiraAPIImport._process_groupsu-   Обработка пользователейc              	   C   s  | j jjdds(| j jdtjd d S t }| dD ]}zd| j 	 rPW  d S | 
|\}}t  | j  jd7  _|jr|js|jds|r||jj W q8   t  |  jd7  _| j jd| d	d
d Y q8X q8|r| j jjddrttjjt|gd d S )N
load_usersTuA   Не грузим пользователей из-за опцийr[   r   r+   z.evateam.ruu@   Не удалось загрузить пользователя r  r|   r  Zsend_invites)r5   )r,   rx   ry   rP   r-   rY   r  setr   r.   r  r/   r  r   r   endswithaddr1   r2   r3   Zschedule_deferred_jobrN   r|   Zregister_personsr   )r   Znew_user_emailsr   r  r  r    r    r!   _process_users  s0    
 zJiraAPIImport._process_usersu#   Обработка статусовc                 C   s   |  dD ]}| j r dS | jjr0|d }n|d d }| jjjj d|d  }|dpf|d }tj	j|d}|sdd	|gd
d	dgg}tj	j|d}|stj	|| jd}||_
t||_||_|jdd t  | j jd7  _q
dS )uc   
        Грузим статусы из Jira и сопостовляем с нашими
        statusesNstatusCategoryr   r   rw   untranslatedNamer  r   r  r   )r   r,   Tr  r+   )r   r,   r.   r?   rM   r  r  rP   rN   CmfStatusCoder  r   get_status_typestatus_typer   r  r/   r  )r   r   r  r  status_nameZcmf_status_coder  r    r    r!   _process_statuses  s.    

zJiraAPIImport._process_statusesc               	      s  i }d }d }|d }dd |  |D }tjjdd}| |}|D ]}	| jjjj d|	d  }
tjjdd|
gd	}|stj||
| jd
d}|jr|d  d|	d  |_	|	dd|_
|	|_|jd
d |	d d d }|D ]f}||}|s|d dkr|}|s |d dkr |}d| jjjj d| d| d}|||< q|	d D ]}| || qRt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| jjjj d|j  |	d D ]}  d|d  }|d   }tjj||d!}|s4tj||| jd"}|d |_	|d |_
 fd#d$|d% D }tjjdd&|gd	|_  d|d'  }tjj|d(}|d)kr|rd
|_|jd
d* ||_|jd
d qqD|d+ }| jjjj d,|d  }tjj|d(}|s$tjjd-d}tj||| jd.}|d |_	||_||_|jd
d tjj|d/D ]}|jd
d0 qT| D ]b\}}| j r qtjjdd1d2| d2gd	}|||| jd3d4}tjf |}|jd
d qp|S )5Nrw   c                 S   s   i | ]}|d  |qS rv   r    r   
issue_typer    r    r!   r    s    zEJiraAPIImport._create_schemewf_for_simple_project.<locals>.<dictcomp>default.system:defaultrC   r   r  =r   Ttemplater  r,   r  r   rB  r   r   r   r  associatedWithr   
issueTypeshierarchyLevelr`  :r  workflowr   r  r  !=forcetransitionstype)r  r  )r  r  r,   c                    s(   g | ] }| d r  d|d   qS )ZfromStatusReferencer   r   r   sworkflow_hash_idr    r!   r   ?  s   
zEJiraAPIImport._create_schemewf_for_simple_project.<locals>.<listcomp>ZlinksINZtoStatusReferencer  globalZ	only_dataworkflow_scheme
::SIMPLE::softdev:default)r  r  r,   )	scheme_wfZTEXKOM_db_deleter  r  r   )r  rE   target_workflowr,   cmf_model_name)_get_issue_types_for_projectrN   CmfWorkflowrP   !_get_simplified_project_workflowsr,   r  r  r  r   r   r(  r  _create_status	CmfStatusr   r  deleterw   rH  CmfTransstatus_fromallow_empty_transition	status_toCmfSchemeWfdefault_task_workflowdefault_subtask_workflowCmfSchemeWfRuler   r.   CmfLogicType) r   Zjira_project_info	issue_mapZdefault_workflow_for_taskZdefault_workflow_for_subtask
project_idissue_typeswf_templateworkflows_dataworkflow_dataworkflow_ext_idr  issue_type_idsissue_type_idr  issue_type_ext_idr   Zworkflow_transitiontransition_ext_idtransition_type
transitionstatus_from_ext_id_liststatus_to_ext_idr  workflow_scheme_datascheme_wf_ext_idr  Ztemplate_wfrulelogic_type_ext_idrE   	rule_dictr    r  r!   #_create_schemewf_for_simple_project  s    




 






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 }|dph|d }|stj||| 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|_||_ddddd}	|	|d|_|j
dd	 |S )Nr   rw   r  r  r  r   )r  r   r,   Tr  r  r   r   r  status_code)r  r,   r  r   F#a0a0a0z#3f82d8z#e36b51z#23a055)OPENIN_PROGRESSZ	IN_REVIEWCLOSED)r,   r  r  rw   rN   r  rP   r   r  r  r  r  r  r   r   r  r  color)
r   Zjira_status_datar  status_ext_idr  r  r  r  r   Zstatus_type_colorr    r    r!   r  u  sR    "

zJiraAPIImport._create_statusc                    s  d8 fdd	}d9 fdd	}d:dd}dd	 }d
d }d|dd|dd|dd|dd|dd}	d|j  d}
g }t|D ]\}}|d }|	|}|r>zFt|d f |}|j d| }tjj|ddgd}| stjdd|d|| jd|d	}|jr* jj	
d| d|
 d | d! np|jsV jj	
d| d|
 d"| d! nDd#|j_|  t   jj	d| d|
 d$|j d%|d&  d	 |t|j  jj	d'|d&  d(|   jj	d'|d&  d)|  W nR tk
r: } z2 jjd| d|
 d*|d&  d+| d,d-d. W 5 d}~X Y nX q~ jj	d'| d/ q~tjjd0d1|gd2d3|gd4d5dggdd6}|D ]}|jdd7 qt  dS );uv   
        Обработка условий перехода
        Конвертация в bzPython код
        Nc                    sp   d j jjj d|  d}tjjdddd| dgdd| ggd}|sVtd|  d	d
|j d|j d}|S )Nr   r  r  r  r  r   r   u   Группа '   ' не найденаu8               # Пользователь в Группе 'zU'
            try:
                return g.current_user.in_person_group(group_code='@')
            except:
                return False
            )	r,   r  r  rN   r  rP   r0   r   rD   )r  r6   group_ext_idZperson_group	eval_coder   r    r!   user_in_group_condition  s    zMJiraAPIImport._process_transition_conditions.<locals>.user_in_group_conditionc                    sR    j jjj d|  }tjj|d}|s8td|  dd|j d|j d}|S )Nr   r  u
   Роль 'r  uG               # Пользователь в проектной роли 'zb'
            try:
                return g.current_user.in_project_role(self.project, role_code='r  )	r,   r  r  rN   CmfProjectRolerP   r0   r   rD   )Zjira_projectrole_idr6   role_ext_idroler  r   r    r!   in_project_role_condition  s    zOJiraAPIImport._process_transition_conditions.<locals>.in_project_role_conditionc           	         s   ddl m} | }i }r8ttfdd|d i }n  rXtt fdd|d i }|d}|d}|std	pz  d
d| d| d}|S )u   
            Условие прав
            Args:
                permission_key (str): ключ права
                permission (str): название или ключ права
            r   get_datac                    s   |  d kS )N	jira_coder   perm)permission_keyr    r!   r     r   z\JiraAPIImport._process_transition_conditions.<locals>.permission_condition.<locals>.<lambda>project_perm_permissionc                    s&   |  dd   kp$|  d kS )N	jira_namer   r  )rP   rH  r  )
permissionr    r!   r     s    r   rD   u   Право 'u   ' не найденоu.               # Только с правами 'zR'
            try:
                return self.project.check_project_role_access('zJ', obj=self)
            except:
                return False
            )cmf.system_datar  r   r   rP   r0   )	r  r  r6   r  system_dataZpermission_datapermission_nameZpermission_coder  r    )r  r  r!   permission_condition  s:    



zJJiraAPIImport._process_transition_conditions.<locals>.permission_conditionc                  [   s   d}|S )Nut               # Только Исполнитель
            return self.responsible == g.current_user
            r    r6   r  r    r    r!   allow_only_assignee  s    zIJiraAPIImport._process_transition_conditions.<locals>.allow_only_assigneec                  [   s   d}|S )Nur               # Только Постановщик
            return self.cmf_owner == g.current_user
            r    r  r    r    r!   allow_only_reporter  s    zIJiraAPIImport._process_transition_conditions.<locals>.allow_only_reporteru(   Пользователь в Группе)r  r  u3   Пользователь в Роли Проектаu   Условие Правu2   Условие Только Исполнителяu(   Условие Только Автора)z:com.atlassian.jira.workflow.condition.UserInGroupConditionz<com.atlassian.jira.workflow.condition.InProjectRoleConditionz9com.atlassian.jira.workflow.condition.PermissionConditionz7com.atlassian.jira.workflow.condition.AllowOnlyAssigneez7com.atlassian.jira.workflow.condition.AllowOnlyReporter   переход 'r  rD  r  r   Tcmf_deletedr  include_deletedrr   r   z6 eval)	r  rE   r  eval_unsafer  r  r,   r  r     Бизнес-процесс , u7   . Пользователь удалил условие K   . Изменения из импорта не будут примененыu9   . Пользователь изменил условие Fu$   . Добавлено условие r  r  u   Условие '' Jira: ' bzPython: u5   . Не удалось создать условие ''. zERR-0127CmfTransFilterr  #   ' не поддерживаетсяr  r  rD   NOT INr,   r  r   r!  r  )N)N)NN)r   r   rP   r   r  rN   r)  r,   r  rZ   r  r  r"  r  r  r/   rh  rD   r   r)   r0   r3   debugr   r  )r   
conditionsr  r  r	  r  r  r  r  Zcondition_maptransition_nameZfilter_codesr   condition_dataZcondition_name	conditionr  filter_ext_idZtrans_filterexcZtrans_filtersr    r   r!   _process_transition_conditions  s    
/

	"
z,JiraAPIImport._process_transition_conditionsc                    s  dI fdd	}dd }dJ fdd	}d|d	d
|d	d|d	d}|dkr*d}t jj }	|j d}
t jj|
ddgd}|st jd|j dd|j d|j dddd jd|
d	}|j	r jj
d| d| d|	 d| d	 dS |js jj
d| d| d |	 d| d	 dS t }g }n,t|t jrVd!|j d}t jj }	g }t|d"d#D ] \}}|d$ }||}|rlz|d% f |\}}t|}|dkr|| || nt|t jr|j d&| }t jj|ddgd}|st jdd'd|| jd|d(}|j	rJ jj
d| d| d|	 d| d	 n|js| jj
d| d| d |	 d| d	 nPd)|j_||_|  t   jj
d| d| d*|	 d|j d+|d,  d |t|j  jj
d-|d,  d.|   jj
d-|d,  d/|  W nN tk
rh } z. jd| d| d0|d,  d1| d2 W 5 d}~X Y nX n jj
d3| d4 qb|dkrz|s|js|j dd5 t   jj
d| d| d6|	 d7|j d8	 dS t|j!dd9}d:|j d;}d<d"| d=| d>}|d? t#d?"|d@ d? t#|d@ |_d)|j_|   jj
d| d| dA|	 d7|j d	 nNt|t jrt jj$dBdC|gdDdE|gdFdGdggddH}|D ]}|j dd5 qt  dS )Ku  
        Обработка пост-функций (действий) перехода
        Конвертация в bzPython код

        Действия для начального перехода создаются при помощи
        триггера автоматизации crud (CmfAutomationCrudTrigger),
        так как на текущий момент в бизнес-процессах нет возможности
        настраивать начальный переход.
        Nc                    s  ddddddddddd	dd
ddd}| | }|sLtd|  d|d }|d } d| }d}| dkr|r~|dkr|d7 }d}nT |} j|ddd\}	}
|	std| d| |d|	j 7 }d|	j d}n| dkr|s|d7 }d}n |\}}|d| 7 }n| d	kr|r6|dkrD|d7 }d}nX jjjj	 d| }t
jj |d}|s~td| d|d|j 7 }d|j d}nd| d}d | d!|  d"| d#}||fS )$uZ   
            Пост-функция "Обновить Поле Задачи"
               ИсполнительrG   )r   r   u   Описаниеr      ПриоритетrF      Решениеr   u   Темаr   )rI   r   rF   r   r   
   Поле 'r*  r   u   # Поле Nz-1u    будет очищеноFr  r     Пользователь '   ' не найден: u    в r  u    в Обычныйr   r   r  u   Резолюция 'r  z            z
            self.z = z
            )rP   r0   rG  r  r   rD   _get_cached_priorityr,   r  r  rN   CmfResolution)r   Zfield_valuer6   Z	field_mapZ
field_datafield_titleZcode_commentry   	user_datar  _priority_nameresolution_ext_idr   r  r   r    r!   update_issue_field  s`    




zLJiraAPIImport._process_transition_post_functions.<locals>.update_issue_fieldc                  [   s   d}d}||fS )Nr5  uh               # Назначить автора
            self.responsible = self.cmf_owner
            r    )r6   r>  r  r    r    r!   assign_to_reporter  s    zLJiraAPIImport._process_transition_post_functions.<locals>.assign_to_reporterc                    sX     | } j|ddd\}}|s6td|  d| d}d|j d|j d}||fS )	NFr9  r:  r;  u   НаблюдателиuR               # Добавить в наблюдатели пользователя z1
            person = models.CmfPerson.get(code='z:')
            self.spectators.append(person)
            )rG  r  r0   r   rD   )r   r6   r?  r  r@  r>  r  r   r    r!   add_to_watchers  s    
zIJiraAPIImport._process_transition_post_functions.<locals>.add_to_watchersu&   Обновить Поле Задачи)r   r  u   Назначить автораuC   Добавить в наблюдатели пользователя)zCcom.atlassian.jira.workflow.function.issue.UpdateIssueFieldFunctionzCcom.atlassian.jira.workflow.function.issue.AssignToReporterFunctionzGcom.aeroflot.jira.agreement.workflow.function.AddToWatchersPostFunctioninitialu!   начальный переходz	::initialTr  r   uA   Начальный переход бизнес-процесса 'r  uX   Действия начального перехода в бизнес-процессе rB  r   r  Z
after_save)	r   r   r  Zcrud_actionZ	eval_typer"  r,   r  r  r#  r$  u(   . Пользователь удалил r  r%  u*   . Пользователь изменил r  r+   )startrD  r  r   eval)r  rE   r"  r  r  r,   r  r  Fu   . Добавлено r  r   u   Действие 'r&  r'  u7   . Не удалось создать действие 'r(  zERR-0126u   Пост-функция 'r*  r  u   . Удален  'uY   ', так как начальный переход не содержит действийz\'zif self.workflow.code == 'z':u3   cmf_alert(f'В задаче "{self.code}" поля uC    заполнены автоматически триггером "z"')
z    u   . Добавлен r  r  rD   r+  r,   r  r,  )NN)N)%rN   ZCmfAutomationCrudTriggerr   rH  r  rP   r   rD   r,   r  rZ   r  r  r  r   r  ZCmfTransActionr   r   r  r   r"  r  r  r  r/   rh  r)   r0   r3   r-  is_newr  replacer   r   r   )r   post_functionsr  r  rC  rD  rE  Zpost_function_mapr/  Zaction_verbose_nameZtrigger_ext_idZtriggerZfield_titlesZaction_eval_codesZaction_codesr   Zpost_function_dataZpost_function_nameactionr  r>  Zaction_ext_idZtrans_actionr3  Ztrigger_nameZtrigger_condition_codeZtrigger_alert_codeZtrans_actionsr    r   r!   "_process_transition_post_functions  s*   
<




	(

z0JiraAPIImport._process_transition_post_functionsc                    sL  | j jjj d|j }| d|d  }tjj||ddgd}|sXtj||| j dd}|js| j j	d|j
 d	|j
 d
 n|d |_
|d |_fdd|d D |_|d  |_|dr<|d  tt fdd| dd}z| ||_d|_W n8   | j jd  d|j
 d|j
 ddd|d Y nX |jdd |S )uS   
        Обработка перехода бизнес-процесса
        r   rw   r  r  )r  r  rr   Tr  r  r,   r     Переход '$   ' в бизнес-процессе ';   ' был изменен и не будет обновленr   r   c                    s   g | ]} | qS r    r    )r   r  )stepsr    r!   r     s   z5JiraAPIImport._process_transition.<locals>.<listcomp>fromtofieldscreenc                    s   t | dt  kS rc  r)   rP   screen	screen_idr    r!   r     r   z3JiraAPIImport._process_transition.<locals>.<lambda>screensN7   Не удалось установить экран ID     для перехода '!   ' бизнес-процесса 'r  ERR-0122	CmfUiFormr  r4   r  )r,   r  r  rw   rN   r  rP   r  rZ   r  r   r   r  r  r   r   r   _process_screencmf_ui_formtrans_form_showr3   r  )r   transition_datarT  r  r  r  r  screen_datar    )r\  rT  r!   _process_transition  s^    




z!JiraAPIImport._process_transitionc           6         s	  dd   fdd} fdd}i }d }d }d }i }t |d d}	tjjd	d
}
|d d }|D ]}t|d }| jjjj	 d| }tjjdd|gdgd}|stj||
| jd}|d |_
|dd|_|jdd |dr|}|}|}n6|d }|D ](}d| jjjj	 d| d}|||< q|d }| j|d dD ]L}|d |kr\qF|d D ]*}|d d |d< | ||||d < qdqFt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ztjd%|j
 d&dd'}|	|}| s:td(|j
 d)t|d*}| }W 5 Q R X t|d+}|sptd,t }i }|d-D ]2}|jdd.id/jdd0}|| ||d < |d1D ]} | d }!d2}"| j
d3krd4}"|jd5|!d6} | s| jjd7|j
 d8|! d9|d: q| jdd;id/}#| |!|!| d |#rD|#jdd0ndg | d<d= d> |"d?}$|$d@ !|d  | jddAid/}%|%r|%jdd0|$dB< || |$dC< || |$dD< qq|stdEt"| dFt"| dG|dHD ]} | d<d= d> }&||&}'|'rd|'_#|'jddI | d }!| jdd;id/}#|!| d |#rR|#jdd0ndg |&dJd?}$| jddAid/}%|%r|%jdd0|$dB< || |$dC< || |$dD< |$||!< q|dKD ]x} | d<d= d> }&| d }!| jdd;id/}#|!| d |#r|#jdd0ndg |&dLd?}$|| |$dC< || |$dD< |$||!< q| j$dMt"| dNt%j& |' D ]P}(|(dO dLkrjdL})n"| (|(||})| j)|(dC |)|dP | j*|(dD |)|dP qRW qd tk
r }* z$| jjdQ|j
 dR|* dS|d: W 5 d }*~*X Y qdX qd|d d }+| jjjj	 d|d d  },tj+jdd|+gdTd"d gddU| jjjj	 dVggd#}-|-s`tj+j|,dW}-|d dX }.|-stj+jdYd
}/tj+|/| jddZ}-|-j,r`|+|-_
|.dd|-_||-_-||-_.||-_/g }0|d d }|D ]j}d| jjjj	 d|d  d}tj0jddUd[| d[gd#}1|0!|1 |d\ r,|1|-_1|d] r|1|-_2q|0|-_3|,|-_4|.|-_5|-jdd n| jj67d^|-j
 d_ g }2|8 D ]0\}3}tj0jddUd[|3 d[gd#}1tj9jd`d|1gdad|-ggd#}4|4r|4j,s| jj67db|-j
 dc|4j: dd|1j
 de |2!|4j: q|4stj9jd`d|1gdad|-gdfddgdTd"d ggddg}4|4r| jj67db|-j
 dc|4j: dd|1j
 dh |2!|4j: qtj9di|1|-| jdj}4||4_;|4jdd |2!|4j: qtj9jdkdl|2gdad|-gdTd"d ggddg}5|5D ]}4|4jddm qt<  |-S )nNc                 S   s2   t dd| } t dd| } t dd| } |  S )ul   
            Преобразует строку в snake_case из любого формата
            z[\.\-\s]r@  z([a-z0-9])([A-Z])z\1_\2z([A-Z])([A-Z][a-z]))rm  r  rH  )arg_namer    r    r!   to_snake_case  s    z7JiraAPIImport._process_wf_scheme.<locals>.to_snake_casec                    sN   g }|  dD ]:}i }|dD ]} |d }| ||< q || q|S )Nz$restrict-to > conditions > conditionargr   selectrE  get_textr   )rN  r.  r1  r0  rl  rj  rk  r    r!   _get_action_conditions  s    z@JiraAPIImport._process_wf_scheme.<locals>._get_action_conditionsc                    sN   g }|  dD ]:}i }|dD ]} |d }| ||< q || q|S )Nz:results > unconditional-result > post-functions > functionrl  r   rm  )rN  rM  functionZfunction_datarl  rj  rp  r    r!   _get_action_post_functions  s    zDJiraAPIImport._process_wf_scheme.<locals>._get_action_post_functionsproject_dir	workflowsr  rC   jira_workflow_schememappingsr   r  r  r  r  r  r  r,   r   r   Tr  defaultr  r   rw   r  r  r  r   r  r   r  r  r   r  	workflow_.xmlZreplace_spacesu,   XML файл бизнес-процесса 'u   ' не найденrxmlur   Не удалось получить список переходов между статусами в виде XMLzsteps > stepzjira.status.idr<  rx  z)actions > action, actions > common-actionZordinaryzcommon-actioncommonrN  rv   u7   В XML разметке бизнес-процесса 'u%   ' не найден common-action ID zERR-0121r  zjira.descriptionzresults > unconditional-resultr   step)rw   r   r   rU  rV  r  rU  zjira.fieldscreen.idrW  r.  rM  u   Из XML получено u    статусов и u'    переходов между нимиzglobal-actions > actionr  r  zinitial-actions > actionrF  u   Настраиваем u1    переходов между статусамиr  )r  r  u   Не удалось импортировать переходы между статусами для бизнес-процесса «u   »: ERR-0067r,   r  r  r  rh  r  )r  r,   r  r  ZdefaultIssueTypeZsubTask*   Схема бизнес-процесса '[   ' была изменена после импорта и не будет обновленаrE   r  -   В схеме бизнес-процесса '   ' правило )    для логического типа 'j   ' было изменено или добавлено вручную и не будет обновленоr  r,  V   ' было удалено вручную и не будет восстановленоr   r  rE   r  r,   rD   r+  r  )=r   re   rN   r  rP   r   short_str_encr,   r  r  r   r   r  _get_statuses_for_projectr  r  r   r  r  r   safe_filenamerf   FileNotFoundErrorrg   r)  r   r0   r   rn  findro  r3   
setdefaultr   r   r  r-   rY   r  r   ri  r4  rO  r  r  r  r  Zdefault_epic_workflowr  Zdefault_task_logic_typeZdefault_subtask_logic_typestrict_task_logic_typer  r(  rZ   r  r   r  rD   r  r/   )6r   project_inforq  rs  r  Zdefault_wf_for_taskZdefault_wf_for_subtaskZdefault_wf_for_epicZall_statusesworkflows_dirr  r  r  workflow_name_hashr  r  r  r  r  r  r  jira_statusr   workflow_filenameworkflow_filerl   workflow_xmlr  Z
jira_stepsZjira_transitionsr  Zjira_status_idrN  Z	action_idZaction_typeZaction_descriptionrg  Zaction_screen_idZaction_stepr  jira_transitionr  rO  Zwf_scheme_namewf_scheme_ext_id	wf_schemeZwf_scheme_infor  r  rE   current_rulesr  r  rules_for_deletionr    rp  r!   _process_wf_scheme  s   	



 




 



	z JiraAPIImport._process_wf_schemec              	   C   sX   d}t dd6 | j rq@| }|dkr.q@|| ||7 }qW 5 Q R X || d S )Nr   FZinit_views_and_dsDONE)r   r,   r.   rP   _process_issueput)r   Zissue_queueZissue_queue_errorsr   r5  r   r    r    r!   _process_issue_thread"  s    
z#JiraAPIImport._process_issue_threadu   Обработка теговc                 C   sH  ddl m} t }| |d \}}| j|d |dD ]4}| j rJ d S |d dr6||d d }q6|D ]}|	dd	d	d
}||ddd}zbdddd| dgdd|gddd| dgg}	t
jj|	d}
|
st
j|d}
|
jdd t  W qp tk
r@ } z(t  | jjd| d| ddd W 5 d }~X Y qpX qpd S )Nr   translitrw   r   rr   labelsr  r@  r^  r   ruTZlanguage_codereversedr  aliasr  r  "%r   r   r:   r  u*   Не удалось создать тег rB  zERR-0134CmfTagr  )transliterater  r  _count_project_tasksr   r,   r.   rP   unionrL  rN   r  r  r/   r0   r1   r3   )r   r  r  tagstotal_tasksr@  r   Ztag_nameZ
name_aliasr  Ztag_objrO  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}i }d }| dD ]J}|d |d	 kr\qF|d
}|d D ]}|d }|d }	|||	< qn qqF|D ]z}
tjjd|
ddgd}|stjddd|
| j dd}|j	s| j j
d| d q||_d|pdi|_|jr|jdd qd S )Nr   rw   r  r  r  r   priority_schemesr   ZprojectKeysZdefaultOptionId
prioritiesr   rF   choicesry  r!  r6  T)r   r   Zorig_captionr   r,   r  u"   Конфигурация поля ue    была изменена. Изменения из импорта не будут примененыry   Z_NONE_r  )r,   r  r  rN   CmfCustFieldConfr   r   rP   CmfCustFieldConfFieldr  rZ   r  r  ry  r  r  )r   r  cust_field_conf_ext_idcust_field_confsr  Z
default_idZpriority_schemerF   rA  Zpriority_idcust_field_confcust_field_conf_fieldr    r    r!   _process_prioritiesN  sN    


z!JiraAPIImport._process_prioritiesu5   Обработка решений(резолюций)c              
   C   s   |  dD ]}| j r d S |d }|dp6|d }| jjjj d| }tjj|d}|sttj|| j|dd}|jr||_	|d	 |_
||_|jdd
 n"| jjd| d| d| d | j jd7  _q
d S )Nresolutionsrw   r  r   r   r  T)r  r,   r(  r  r   r  u   Резолюция 
 (Jira ID r  ug   ') была изменена. Изменения из импорта не будут примененыr+   )r   r,   r.   rP   r  r  rN   r=  r  r   r   r(  r  rZ   r  r  )r   r   Zresolution_idZresolution_namerB  Zresolution_objr    r    r!   _process_resolutions  s.    

z"JiraAPIImport._process_resolutionsu   Импорт фильтров
is_processc                    s  |s j jd d S  fdd}t }d} dD ]V} j  rN d S |d }|d } j jjj d| }t	j
j|dd	d
gd}	|	st	j
 j |dd}	|	jrfz\||	_|d|	_|di  jr j|d  j |	d|	_d}
d}t }t }|d D ]p}|||	}|s q|dkr6d}
d}q jjrL|| n*|d rb|| n|d r|| q|dg D ] }|||	}|r|| qt||	_t||	_tdd ||B D }|rd}
d}|
|	_||	_||	_|	jdd t  W n\ tk
rb } z<t     j!d7  _! j j"d| d| d | d!d"d# W 5 d }~X Y nX n" j jd$|	 d%| d&| d' |d7 }q8t | }|| } j j#d(|d)d*| d+|d,d-t$|d.  d/	 d S )0Nu.   Импорт фильтров отключенc              
      s*  d}z| d }|dkr~| d d }d j jjj d| d}tjjdddd	| d	gdd|ggd
}|sztd| dnR|dkr| d d }| d d }| d d } j jjj d| }	tjjddd|	 dgd
}|s j j	d| d| d n|dkr| di  j
r| d  j
 }
| d d}| d d}z |
}W n2 tk
r } zt| dW 5 d}~X Y nX  j|ddd\}}|std|p| d|
 dn|dkrd}W nR tk
r$ } z2  jd7  _ j jd |j d!| d"|d# W 5 d}~X Y nX |S )$u  
            Получает объект (группу, проект, пользователь), которому
            необходимо предоставить доступ к фильтру

            Args:
                share_permission (dict): данные объекта прав
                task_filter (obj): объект фильтра

            Returns:
                _type_: _description_
            Nr  r  r   r   r  r  r  r  r   u"   Не найдена группа 'r  r   rw   r   r  r  r  u~   Не удалось добавить разрешение на доступ к фильтру. Не найден проект r  u=   '. Возможно он еще не импортированr   r   H   . Возможно пользователь был удален в Jira.Fr9  u,   Не найден пользователь 'r$  r&  loggedinr+   u_   Не удалось добавить разрешение на доступ к фильтру 'r(  zERR-0129r  r4   )r,   r  r  rN   r  rP   r0   
CmfProjectrZ   r  rL   rG  r  r2   r3   r   )share_permissiontask_filtershareeZshare_permission_type
group_namer  r  r   project_nameproject_ext_idrL   Z	user_nameZuser_display_namerM  r3  r@  r   r    r!   _get_sharee  sx    


z3JiraAPIImport._process_filters.<locals>._get_shareer   filtersrw   r   r   r  r(  r  rr   Tr,   r  r  r   ownerr  privateZsharePermissionsr  readonlyr  editviewZeditPermissionsc                 s   s   | ]}t |tjV  qd S r   )r   rN   r  r   r    r    r!   	<genexpr>=	  s   z1JiraAPIImport._process_filters.<locals>.<genexpr>fullr  r+   u0   Ошибка обработки фильтра 'z' (ID: z). zERR-0130CmfBqlFilterr     Фильтр r  r  uc   ') был изменен. Изменения из импорта не будут примененыu4   Импорт фильтров выполнен за .3fu
    сек.: r  .2fu   /с | ~<   u   /мин))%r,   rZ   r  time	monotonicr   r.   r  r  rN   r  rP   r  r   r   rL   r  r   r  r?   rM   r  r   r  	executorsanyperm_policy
view_scoper(  r  r/   r0   r1   r2   r3   rh  int)r   r  r  t1Zfilter_countZfilter_dataZ	filter_idZfilter_namer2  r  r  r  r  r  r  r  Zedit_permissionZhas_projectr3  t2Z
proc_speedr    r   r!   _process_filters  s    Q










(zJiraAPIImport._process_filtersc                 C   s  |d }|d }| j jd| d| ddd | j jjj d| }tjj|d	d
gd}|stjjdd|gd	ddggd	d
gd}|stj||| j dd}| j jd| ddd |j r|jr||_|d|_	|j
dd n| j jd| dtjdd n|js||_|j
dd |S )u   
        Обрабатывает проектную роль

        Args:
            role_data (dict): сырые данные проектной роли

        Returns:
            CmfProjectRole: проектная роль
        r   rw   u0   Обработка проектной роли 'r$  r&  T	anonymousr   r  r,   r  r  r  Nr  r   r  r,   r  u7   Создана новая проектная роль 'r  r   r  u   Проектная роль u_    была изменена. Новые данные из импорта не примененыr[   r  )r,   r-   r  r  rN   r
  rP   r  r   r   r  rY   r  r  )r   	role_dataZ	role_nameZrole_idr  project_roler    r    r!   _process_project_rolea	  sV    


z#JiraAPIImport._process_project_rolec                 C   s  t jj||dgd}|r\|s\|jr6|jdd t  n"| jjd| d| dtj	dd d	S |sdd	S | jd
| d|  g }|D ]}|d }|d }| jd| d| d|  |dkrZ| j
jr|d d n|d }	z| j|	dd}
||
 W n\ tk
rV } z<| jjd| d|	 d| d| d|d |  jd7  _W 5 d	}~X Y nX q|dkrl| j
jr|d d }|d d }n|d  }}d| jjjj d| d}t jjd d!d"| d"gd gd#}|st jjdd$|gd gd#}|r6|js||_n||jkr|j | |_|jdd% || n4| jjd&| d| d| d'd|d |  jd7  _q| jjd(| d)| d*|d |  jd7  _q|sd	S |st j||| jdd+}||_|jdd% t  | jjd,| d| d-t|j dd. d	S )/u   
        Добавляет участников в к роли в проекте

        Args:
            actors (list): список участников
            project_role (CmfProjectRole): проектная роль
            project_obj (CmfProject): проект
        members)r  r   rr   Tr  u+   Состав участников роли u    в проекте u[    был изменен. Новые данные из импорта не примененыr  Nu6   Добавление участников к роли u    проекта r   r  u)   Добавление участника 'z	' (type: u   ) к роли atlassian-user-role-actorrM  rA   r   raise_on_erroru?   Не удалось добавить пользователя 'r$  . zERR-0039r  r+   zatlassian-group-role-actorZ
actorGroupr  r   r  r  r  r  r  r  u3   Не удалось добавить группу 'u"   . Группа не найденаu<   Неподдерживаемый тип участника '': zERR-0040)r  r   r,   r  u   К роли u*    добавлено участников: r  )rN   ZCmfProjectRoleAssignrP   r  r  r/   r,   r-   rY   r  r?   rM   r  r   r0   r3   r2   r  r  r  r  r  r  r   )r   actorsr  project_objZrole_assignr  actorZactor_display_nameZ
actor_typerW  r   r3  Zgroup_idr  r  r  r    r    r!   _process_project_role_assign	  s    	

"

z*JiraAPIImport._process_project_role_assignu0   Обработка проектных ролейc                 C   s<   |  |}|D ](}| |}|dg }| ||| qd S )Nr  )_get_project_rolesr  rP   r  )r   r  r  rolesr  r  r  r    r    r!   _process_project_roles
  s
    

z$JiraAPIImport._process_project_roles)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|d< d|d< d|d< | ||d< t jjddd|d  dg| d}|st j| j|d |d d
d}|j}|jrf|D ]$}|dkr6q$t||||  q$|dr\d|_|
  n| jjd| d |rt jj|dD ]}|jd
d q| |d | |   | j|d | ||_| ||_| ||_| | |   | jj rX|d }|r$| !||_"n2| jj#j#j$ d|d d  }t j%j|dgd |_"n| &||_"|jrd|_'d|_(d|_)d|_*d|_+|j
d
d! |   | ,|| | -|| t j.j|d"d
d#}	|	st j.d$|d"d
d%}	|	j
d
d! t/  | 0| | j1 rd S t/  | 2|| |   | 3|| t j.j4d&d'|gd(d'd
ggd)}
|
rnd
|_5|j
d
d* t/  | j j6d+7  _6|   |S ),Nr   r   rE   r  r  r  r&  u   Проект с именем u8    уже существует! Переименуем в TZtask_allow_multiple_sprintsFZsl_only_owner_approveZsl_deny_no_approveZsl_task_only_owner_closeui_form_schemer  r  )r,   r  r   r  	isPrivater  u"   Настройки проекта u    были изменены пользователем. Изменения из импорта не будут примененыr   r  rw   r  
simplifiedr   rv  default_release_workflowr  r  epic)r   r   include_systemZEpics)r   r   r   systemr   r  has_children_archivedr   r  r+   )7rN   r  rP   rE   rw   r  r,   rZ   r  r   r  _process_screen_schemekeysrK  r  r  r  r   r   r  r  _calc_progressr  _process_permissionsZproject_perm_scheme_process_security_levelssecurity_level_scheme_process_field_conf_schemecust_field_conf_schemer  _cache_prioritiesr?   rM   r  r  r  r  r  r  Z
show_listsZ	show_blogZ
show_pfeedZ	show_diskZ	show_chat_process_versions_process_componentsr  r/   _process_tasksr.   _process_boards_process_sprintsr  r  r  )r   r  r  r  rK  r   r   Zproject_simplifiedr  epics_folderZfolder_has_children_archivedr    r    r!   _process_project
  s    "
 






zJiraAPIImport._process_projectc                 C   s   dd l }|jdddd| jjj d| jj d| d| d	| d
gddtddtddd}| jd|j d| d| d | j  |S )Nr   z/usr/bin/python3z	manage.pyshellz&plugin = models.CmfPluginJira.get(id='z(');retcode = plugin.process_issue_fork('z', 'z', r$  z);Tz"/var/log/eva-import-subprocess.loga+z&/var/log/eva-import-subprocess.err.log)Z	close_fdsZstart_new_sessionstdoutstderr[PID u(   ] Запуск процесса (offset=z, limit=r&  )	
subprocessPopenr,   r  rw   rg   r-   pidZ
log_detail)r   r  offsetr   r  procr    r    r!   _execute_task
  s      ,"
zJiraAPIImport._execute_task     c                 C   s   ||krd|fgS t || }tdt || }t|t||}t||}|| }	|| }
g }d}t|D ]8}|	}||
k r|d7 }t||}|||f ||7 }qn|S )u  
        Рассчитывает распределение задач между процессами

        Args:
            total_tasks (int): количество задач
            max_processes (int): максимальное количество одновременных процессов
            threads_per_process (int, optional): количество потоков в процессе. Defaults to 25.
            max_tasks_per_process (int, optional): максимальное количество задач
                                                   обрабатываемых в процессе. Defaults to 1000.

        Returns:
            list[tuple]: список кортежей (offset, limit)
        r   r+   )mathZceilmaxZfloorr  ranger   )r   r  r   Zthreads_per_processZmax_tasks_per_processZmin_processes_by_limitZprocesses_by_threadsZmin_processes_to_useZprocesses_to_useZ
base_tasks	remainderZdistributionr  ir   r    r    r!   _calc_task_distribution
  s$    



z%JiraAPIImport._calc_task_distributionc                 C   s   d}d}| j  dt|d}| rt| D ]h}| sBq4|j	drPq4|d rdD ]}||}|j
dd qb|d	7 }|d
 r4|d	7 }q4||fS )u  
        Получает количество успешно и неуспешно обработанных задач.
        Неуспешно - были ошибки при обрабоке саймой задачи или
        связанных объектов(комментарии, чек-листы, журнал работ и т.д.).

        Для успешно обработанных задач удаляет файл-флаги.
        r   r   r   .dirty.meta.success).processingr+  T)
missing_okr+   r,  )r,   rd   re   r)   rf   r   iterdiris_dirr   r  unlink)r   r  Zsuccess_countZfailed_count	tasks_dirtask_dirZfile_flag_name	flag_filer    r    r!   _get_processed_count
  s*    
  

z"JiraAPIImport._get_processed_countc              
   C   s  |d }d|d  d| d|d  d}t j}|r@| jjd | |\}}|rZ|rz|sz| jj| d	| d
dd d S |r|n|}| j }| jj| d| d| d| d | 	||| j
t j}	i }
t }|	s|
rt|
|k rv|	rv|	d}|\}}z| |||}||
|< W nH tk
rh } z(| jjd|j d| d| dd W 5 d }~X Y nX td qg }|
 D ]r\}}| }|d k	r|| |dkr| jd|j d| d n$| jjd|j d| d| dd q|D ]}|
|= q|
s|	rtd qt }|| }t|d\}}t|d\}}| |\}}| jj| dt|ddt|dd|d  | jjd!| d"| d|  | jjd#|| d$d% | jjd&|  d S )'Nrw   u   Проект 'r   r$  r$  r   r&  u   Будет выполнена обработка только новых или обновленных задач. Для обработки всех задач измените значение параметра 'IMPORT_ONLY_NEW_OR_UPDATED'uU   . Нет новых/обновленных задач для обработки из u    задачTr  u   . Обработка u    из u(    задач с ограничением u,    одновременных процессаr   r  r  uG   ] Процесс завершился с ошибкой. Ошибка: r%  )r  g      ?u4   ] Процесс завершился успешноuR   ] Процесс завершился с ошибкой. Код возврата: r     r  u8   . Обработка задач завершена за Z02dr  z06.3fuE   Обработано задач (успешно/неуспешно): r_  u%   Скорость обработки: r  u    задач/секu)   Всего задач в проекте: )r   ZIMPORT_ONLY_NEW_OR_UPDATEDr,   rZ   r  r  r-   r   rh  r'  r   ZIMPORT_OBJ_CNTr  perf_counterr   popr  r0   r3   r  sleepr   Zpollr   divmodr4  r  )r   r  r  Zproject_msgZonly_new_or_updatedr  Zunprocessed_tasks
task_countr   Zpending_task_chunksZactive_processesrG  
task_chunkr  r   Zprocessr3  Zprocesses_to_removeZreturn_codeenddiffZhoursr%  minutesZsecondsZsuccess_tasksZfailed_tasksr    r    r!   r    s     








&zJiraAPIImport._process_tasksu#   Обработка проектовc              
   C   s  t jjddjj}|  D ]h}z|d dd | jD kr@W q| j rRW  d S |di }|rt| 	|| 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jj d|d  d|d< |d |jj|d ||d ||d |d}| || W q tk
r   t  |  jd7  _| jjd| ddd Y qX qd S )NrB   rC   rw   c                 S   s   g | ]}|d  qS rv   r    r   r    r    r!   r     s     z3JiraAPIImport._process_projects.<locals>.<listcomp>leadzdefault_import_jira@evateam.comZdefault_import_jira)r   r   ZprojectTypeKeyZbusinesszproject.base:defaultZsoftwarezproject.agile:defaultZservice_deskzproject.servicedesk:defaultu$   ERROR! Проекты с типом u3    временно не поддерживаютсяr   r  r   r   r   )r   rE   r   activitytask_code_prefixr   r  r(  r+   u<   Не удалось импортировать проект zERR-0041r  r  )rN   rO   rP   rw   ry   r   rX   r,   r.   r  rL   r  r0   r  r  r  r1   r2   r3   )r   r@  r  project_leadr   rE   r  r    r    r!   _process_projects  sP    
" zJiraAPIImport._process_projectsc                 C   sr  |d }|d }|d }d}d}d}	d}
|dkrd| j jjj d| d}tjjddd	| d	gd
}|std| d| d|}n>|dkr|dkrdS | j|dd}n|dkr|}	| d| }
| j jjj d| }tjj|dddddgd}|stj||| j dd}|j	rF|d |_
||_||_|	|_|
|_|jdd n"| j jd| d| dtjdd t  dS )uG  
        Присваивает цвет карточке

        Args:
            card_color_data (dict): сырые данные настройки цвета карточки
            card_color_scheme (str): стратегия присвоения цвета
            board_obj (CmfKanbanBoard): доска
        ry   displayValuerw   NrE   r   r  r  r  r   u'   Не найден тип задачи 'r$  r&  rG   Z
unassignedTr  rF   rB  r  r   r  r   r  r,   r  r  u&   Цвет карточки задач 'u\   ) был изменен. Новые данные из импорта не примененыr  )r,   r  r  rN   r  rP   r0   r  CmfKanbanBoardCardColorRuler  r  rE   rG   rF   r   r  r-   rY   r  r/   )r   card_color_datacard_color_scheme	board_objry   display_valueZcard_color_idZlogic_type_ruleZresponsible_ruleZpriority_ruleZ	name_ruler  rE   Zcard_color_rule_ext_idZcard_color_ruler    r    r!   _process_board_card_color_rule  sh    	

z,JiraAPIImport._process_board_card_color_ruleu;   Обработка цветов карточек доскиc                 C   s   | dpi }| D ]\}}| j |}|s0q|d }|D ]f}|d }	z| ||| W q< tk
r }
 z(t  | jjd|	 d|
 ddd W 5 d }
~
X Y q<X q<qd S )	NZ
strategiesZ
cardColorsrD  uI   Не удалось присвоить цвет карточки для 'r(  zERR-0137rF  r  )rP   r   r_   rK  r0   r1   r,   r3   )r   card_color_configrI  Zcard_colors_strategiesZstrategy_typeZcard_colors_datarH  Zcard_colorsrG  rJ  r3  r    r    r!    _process_board_card_color_scheme  s*    z.JiraAPIImport._process_board_card_color_schemeu   Обработка досокc           2      C   s^  ddd}dddddd	d
}ddddd}t jjd|dgd}|sXt jd||d| jd}|jsld|_|  |d }| |D ]}z| j rW  dS |d }	|d }
| jj	d|	 d|
  |d d }|d }d}|d d }|r|d }|d }| jj
j
j d| }t jj|ddd d!gd"}|sDt j| j|dd#}|jr~||_d$|_d%|_|j| ||_|jdd& n"| jjd'| d(| d| d) g }|d* }|d+ 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rD||_d-|_||_|jdd& n"| jjd.| d(| d| d/ || qg }|d0 d1 ddd, D ]}|d }|d }| jj
j
j d| d| }t jj|dd d!gd"}|st j| j|dd#}|jr|d |_d-|_||_|jdd& n"| jjd2| d(| d| d) || q| jj
j
j d|	 |d3< t jjd3d4|d3 gd5d4|ggd5d6d7d8d9d:d;d!gd<}|st j|d3 | jdd=}|jrN|d |_||_||_||d> |_||_||_||_||d? d	|_||d@ d|_| j|dA dB|_d|_ |d |_|jdd& t!  n"| jjdC| d(|	 d|
 d/ | "|| t#t$dDdE |dF dG d} t#t$dHdE |dF dG ddd, d}!|!rdI|!dJ< | rdK| dJ< d}"t j%j&|dLd!dMgdN}#|#D ]X}$|$jj'pi }%|%dM}&|$jr.|&r|&|$j(kr| jjdO| dP dQ}" qRqg }'dR}&|dF dG D ]P}(z|(d })|(d }*| jj
j
j d|) }+t j%jd3d4|+gd5d4|ggd!dSgddT}$|$st j%||+| jddU}$|$jdd& |'|$j) |$j*r| jjdV|$ d(|) d|* dW W qf|$jj'p*i }%|$jr|*|$_|(dX |$_+|(dY |$_,g },|(dZ D ]l}-| jj
j
j d|-d  }.t j-j|.d[}/|/s| jj.d\|$ d(|) d|* d]|- d^|d_ qZ|,|/ qZ|,|$_/|(d` rda|$_0n |(dZ sdb|$_0n|(dJdc|$_0|%1|( n"| jjdV|$ d(|) d|* d/ |"rD|&|$_(|$j(|%dM< |%|$_|$jdd& t!  |&dR7 }&W nN t2k
r }0 z.t3  | jj.dd|) d|* d|0 de|d_ W 5 d}0~0X Y nX qft j%j&dfdg|'gd5d4|gdLdhdggddi}1|1D ]}(|(j4ddj q|1r| jjdk|1  t!  | j j5dl7  _5W q~   t3  | jj.dm| dn|d_ Y q~X q~dS )ou  
        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

        Только для Jira Server.
        Если с доской связано несколько проектов,
        то в каждом проекте создаются одинаковые доски с единым основным фильтром 
        zboard.scrum:defaultzboard.kanban:default)scrumr   z	1 queriesz2 userstoryz
3 assigneez4 epicz	5 projectz7 none)r   ZparentChildrI   r  r   nonez1 -1wz2 -2wz3 -4wz6 none)z-1wz-2wz-4wZNONEu
   Доскиtree_node_is_branchr!  N)r   r   r   r   r,   Trw   r   u!   Обработка доски ID rB  rh  r   ZcardColorConfigr   r   r  r  r(  r  r  r  r  r  u   Основной фильтр z (ID u;   ) был изменен и не будет обновленZswimlanesConfigZ	swimlanesr`  Zembeddedu   Дорожка uA   ) была изменена и не будет обновленаquickFilterConfigquickFiltersu   Быстрый фильтр r  r  r   r   kanban_bql_filterswimlane_bql_filtersquick_bql_filters
limit_daysZkanban_board_columnsr  r  r,   r  r  ZswimlaneStrategyZoldDoneIssuesCutoffZcardColorStrategyrO     Доска c                 S   s   | d o| d  S NmappedStatusesisKanPlanColumnr    columnr    r    r!   r     r   z/JiraAPIImport._process_boards.<locals>.<lambda>ZrapidListConfigZmappedColumnsc                 S   s   | d o| d  S rY  r    r\  r    r    r!   r      r   z#00875ar  z#42526er,   ordernor   rr   u.   Порядок колонок на доске up    был изменен и не будет обновлен. Упорядочите колонки вручнуюFr!  r  )r   rr   r!  rE  u   Колонка uG   ) была удалена и не будет восстановленаr  r#  rZ  r  u   Для колонки u!   ) не найден статус zERR-0124r  r[  r  z#6b778cz#0052ccu5   Не удалось создать колонку ID zERR-0042rD   r+  r  r,  r  uC   Удалены колонки, отсутствующие в Jira: r+   u:   Не удалось импортировать доску zERR-0043)6rN   r  rP   r,   rP  r  _get_project_boardsr.   rZ   rh  r  r  r  r  r   r  r  r  r   r(  r  ZCmfKanbanBoardr   r   rE   rS  rU  rT  Zswimlane_typerV  r_   rH  Z"kanban_board_quick_filters_visibler/   rM  r   r   ZCmfKanbanBoardColumnr   ry   r^  rD   r  Zmin_sizeZmax_sizer  r3   mapped_status_codesr  r  r0   r1   r  r  )2r   r  r  Z
board_typeZswimlane_type_mappingZlimit_days_mappingZboard_folderr  boardboard_idZ
board_nameZboard_configrL  rS  Zboard_filterZboard_filter_idZboard_filter_nameZkanban_filter_ext_idrT  Zswimlanes_configZswimlaneZswimlane_idZswimlane_nameZswimlane_ext_idZswimlane_filterrU  ZquickfilterZquickfilter_idZquickfilter_nameZquick_filter_ext_idZquick_filterrI  Zfirst_column_with_statusesZlast_column_with_statusesZupdate_column_orderZboard_columnsZboard_columnZcolumn_dataZcolumn_ordernoZcurrent_columnsr]  Z	column_idZcolumn_nameZcolumn_ext_idra  r   r  Zstatus_globalr3  Zcolumns_for_deletionr    r    r!   r    sj   

	











 zJiraAPIImport._process_boardsu#   Обработка спринтовc                 C   s  t jjdd|gdddggddgd}t jjdd	}t }| |d
 D ]}| j r\ d S |d }| jjjj	 d|d
  }t j
jdd|gdd|ggdddddddddddgdd}	|	st j
||| jdd}	|	j}
|	jr||	_||	_|d |	_| jjs"|ddr"|	 jd|j d7  _|d |	_|d!|	_||	_|	jrT|	jdd" |d#krn|	jd$|	_n2|d%kr|	jd&|	_n|d'kr|	jd(|	_|d'krdnd|	_|	jr|	jdd" t  d)}| jjd*|	j d+t|d,   |d,   D ]N\}}|d- }|d. }| jjjj	 d| }t j!j|d/dd0d1d2d3d4dgdd5}|r|	j"#| |j$d(krP|d'kr|j%D ]}||	kr|js qqd|_nd|_|jdd6 n|d
 |d
 kr| jj&d7|d  d8| d9| d:|d  d9|d-  d;t'j(d< |d=7 }n8|  j)d=7  _)| jj*d7|d  d8| d9| d>d?|	d@ q|r~| jj*d7|d  dA| dBdC|	d@ |	jdd" |d%kr|
st j+j,|	dDs|	jd$|	_|	jdd" | jjdE|	j dF |	-  d|	_|	jdd" t  |.t/|	j0 | j j1d=7  _1| j2ddG qFt3t j
j4dd|gdddggdHgdd|_5|j5rfd|_6n t3t j
j4dd|gdHgdd|_6|jdd" t j
j7t8|dI d S )JNr   r   r   r   rP  r  r  zlist.agile_sprint:defaultrC   rw   stater   r  r  r   r   rE   r  r  r  r  r  r   cmf_archivedT)r   rr   include_archived)rE   r  r,   r  multiprojectFr  r&  r   r   r  Zfuturer   r   r  closedr  r   u0   Добавляем задачи в спринт rB  issuesr   r   zlists.cmf_archivedcache_status_typeagile_story_pointszop_gantt_task.sched_durationzop_gantt_task.sched_workzop_gantt_task.actual_work)r  rr   rf  r  u   В спринт 'u5   ' не удалось добавить задачу 'r$  u   ) проекта 'u\   ). Возможно проект или задача еще не импортированы.r  r+   u$   ). Задача не найдена.zERR-0044r  uX   ' не удалось добавить задачи из других проектов: u]   . Возможно проекты или задачи еще не импортированы.zERR-0133)	task_listu   Запуск спринта "r  r1  --)Zlist_ids)9rN   r  rP   r  r  _get_all_sprintsr,   r.   r  r  r
  rK  r  rE   r   r   r?   rM   rA  r  r  r(  r  r  r  Zget_default_statusr   re  r/   rZ   rh  r   r   r   r  r   rj  listsr-   rY   r  r2   r3   ZCmfListHistoryOTRr  Zdo_startr  r)   rw   r  r3  rz   ro  r  rP  Zrecalculate_count_cacher   )r   r  r  Zsprint_folderZsprint_logic_typeZ
sprint_idsr   Zsprint_stater  Z
sprint_objZsprint_is_newZexternal_tasks_countissue_id
issue_data	issue_keyZissue_projectZissue_ext_idr   rl  r    r    r!   r    s$   





$



.


zJiraAPIImport._process_sprintsc                 C   s$   |sd}|sd}| d| d| S )Nu   Не указаноrB  u    ➔ r    )r   r   	old_valueZ	new_valuer    r    r!   _simple_html_diffP  s
    zJiraAPIImport._simple_html_diffFc           	   
   C   s   |dkrdS z6|  |}| j|dd|d\}}|s@td| W nn tk
r } zP|r\ nD| j}| jrrd| nd}| jj| d| d	d
d |  jd7  _W 5 d}~X Y nX |S )u  
        Возвращает пользователя по какому-либо идентификатору (id, имя, логин, email и др.).

        Args:
            user_id (str): Идентификатор пользователя для поиска.
            obj (optional): Объект в контексте которого был поиск пользователя. Defaults to None.
            raise_on_error (bool, optional): Вызвать исключение при ошибке поиска
                или вернуть резервного пользователя ('Система' или пользователь по умолчанию).
                Defaults to False.

        Raises:
            Exception: Исключение при ошибке поиска пользователя.

        Returns:
            CmfPerson: Объект пользователя.
        unknownNFr  ue   Пользователь с указанными данными не найден в системе: u   по умолчанию u   'Система'u;   . Будет установлен пользователь zERR-0045r|   r  r+   )rG  r  r0   r}   r{   r,   r3   r2   )	r   rW  r4   r  r   r  r@  r3  Z
person_msgr    r    r!   r  W  s&    
 zJiraAPIImport._get_person)	dump_pathc              
   C   s   | d}| r`t|d>}|D ]2}t|}|d |d kr"|  W  5 Q R  S q"W 5 Q R X t|d}|t|d  W 5 Q R X |S )Ngroups.jsonr~  r   r  rJ  )re   rf   rg   rh   rV  writedumps)r   r  rv  Zgroups_pathrl   rowr4   r    r    r!   _dump_groups  s    

 zJiraAPIImport._dump_groupsc                 C   s   z|  |W S  tk
r   z|d}| rt|dB}|D ]6}t|}||| j kr@|  W  5 Q R  W  Y S q@W 5 Q R X | j	|}|rt|d}|
t|d  W 5 Q R X |W  Y S W n$   | jjd| tjd Y nX Y nX d S )N
users.jsonr~  r  rJ  uM   Неудалось сдампить пользователя по ключу r  )rG  r0   re   rf   rg   rh   rV  rL   r?   Zget_user_inforx  ry  r,   r-   rY   r  )r   rW  rv  Z
users_pathrl   rz  r4   rM  r    r    r!   _get_user_info  s$    

&zJiraAPIImport._get_user_infou,   Обработка журнала работ)r   c                 C   sp  | j jd d|d  d|d d  d}| |D ]2}t }d|d	< | j |d
< |di | jr| j|d | j |d|d< |d |d< |di | jr| 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 }|s6t
jf |}|jjtj|jjd! |_|jd"d# q6d S )$Nu*   Загружаем журнал работu%   Журнал работ задачи r   r  rr   r   r  rh  r   r,   r   r  r   r   updateAuthorcmf_modified_byr   started
start_dateZtimeSpentSecondsr  
time_spentcommentr   r   r   rw   r  r(  r   Zremaining_estimater  )r>  Tr  )r,   rZ   rh  _get_issue_worklogsr   rP   rL   r  r  r  rN   ZCmfTimeTrackerHistoryr  ry   datetimeZ	timedeltar  end_dater  )r   r   r   r4   worklogZtimetracker_historyhistoryr    r    r!   _process_issue_worklog  s2    


z$JiraAPIImport._process_issue_worklogc                 C   s   | dD ]}|d}||j |  || |dg }dd |D }|sd|dg |d< q
|d dd	d	 }|d
| g |d< q
dS )uF   
        Конвертирует "Фрагмент кода"
        ZprerD   r:  c                 S   s   g | ]}| d r|qS )zcode-)ri  )r   class_r    r    r!   r     s     
 z/JiraAPIImport._convert_code.<locals>.<listcomp>zlanguage-noner   -r+   z	language-N)rE  rN  extendcontentsclearr   rP   r   )r   r7  rK  Zcode_tagZ	class_tagZ
code_classrD   r    r    r!   _convert_code  s    

zJiraAPIImport._convert_codec                 C   sR   |s|S t |d}| || | ||| | | ddd |jjD }|S )Nlxmlr   c                 S   s   g | ]}t |qS r    r  )r   cr    r    r!   r     s     z/JiraAPIImport._convert_text.<locals>.<listcomp>)r   rP  rv  r  r   r   children)r   r   r4   datar7  r    r    r!   _convert_text  s    

zJiraAPIImport._convert_textu8   Обработка комментариев задачиc                 C   s@  d|d  d|d d  d}d}d}|  |D ]}|d7 }| jjjj d	|d
  }tjj|d}|r|js| jjd| d|d q0|stj||| jdd}n|	dg |di | j
r| j|d | j
 |d|_|j|_|di | j
r| j|d | j
 |d|_|d |_|d |_||_| |d |||_||_|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  _q0|dr ttdd  |d i }
|
di d!d"|_|jr|jdd# | jd$d% q0| jd&| d'|  d S )(Nu$   Комментарий задачи r   r  rr   r   r  r   r+   r   rw   r  uN   Комментарий уже есть, и правился в системе zERR-0046r  TrE  z**r   r~  r   r   r   Z
visibilityr  r  ry   r:   uL   Ошибка обработки приватного комментария zERR-0047
propertiesc                 S   s   |  ddkS )Nr   zsd.public.commentr   )pr    r    r!   r   
  r   z7JiraAPIImport._process_issue_comments.<locals>.<lambda>ZinternalFr  r  r1  u   Обработано u:    комментариев, из них приватных ) _get_issue_commentsr,   r  r  rN   r   rP   r  r3   r   rL   r  r   r   r  r   r   r   r  r   r(  r
  r  r   r  r2   r   r   r  r  r3  r-   )r   r   r   r4   cntZprivate_cntr  r  Zcmf_commentr  Zsd_public_commentr    r    r!   _process_issue_comments  sf    
 

 z%JiraAPIImport._process_issue_commentsc                 C   sf  t jjdd|gddd ggddgd}|rh|jr4|jrh|jr>dnd	}| jjd
| d| d| d d S |st j|| jdd}|jdd t j	j
dd|gddddgdddgggdd}|r| jjd
| d| d d S t j	j|dD ]}|jdd q|d }ddddd}d}	d}
tdtj}||D ]}| \}}}}}| }|rdd d! |d"D  }|dd#}n|}|t||||d$}|	d%7 }	|d&kr|
d%7 }
t j	||||||d| jd|d'}|jdd q0td(tj}||}|rD| \}}| |_|r>d#d)d! |d"D  }||_|	|_|
|_||_|jdd d S )*Nr   r  r,   r  Tr  )r   r!  rr   u   Удаленu   Изменен   Задача u   . Чек-лист r  uf    пользователем. Изменения из импорта не будут применены)r   r,   r  r  r  r  Fr,  u   . Пункты изменены пользователем. Изменения из импорта не будут примененыr  r  ry   r   r  r  ZCANCEL)r  ~r  xr   z{(?P<status>[x~+-])(?P<mandatory>!)?\s*(?:\[(?P<custom_status>[^\]]+)\]\s*)?(?P<name>[^\n]*)(?P<description>(?:\n>[^\n]*)+)?rJ  c                 s   s   | ]}|r|  V  qd S r   rx  r   liner    r    r!   r  \  s   z3JiraAPIImport._process_checklist.<locals>.<genexpr>z
>r  )r   	mandatorycustom_statusr   r   r+   r  )Z
cache_taskr   r   r   r   r,   r  r(  z6#\s*(?P<header>[^\n]*)(?P<description>(?:\n>[^\n]*)+)?c                 s   s   | ]}|r|  V  qd S r   rx  r  r    r    r!   r    s   )rN   ZCmfChecklistrP   r  r  r,   rZ   r  r  ZCmfChecklistItemro  r   r  rm  compileMfinditerr  ry  r   r   rL  rz   rn  r   r   Zchecklist_items_countZchecklist_items_done_countr(  )r   Zchecklist_datar  Z	checklistZ
action_msgZmodified_itemre  Z	items_strZstatus_mappingZitems_countZitems_done_countZitems_patternmatchr   r  r  r   r   r   Z	item_dataZheader_patternheaderr    r    r!   _process_checklist  s    	






z JiraAPIImport._process_checklistu0   Обработка плагинов задачиc                 C   s4   |  |D ]$}|d dkr
|d r
| || q
d S )Nr   z&com.railsware.SmartChecklist.checklistry   )_get_issue_propertiesr  )r   r   r  Zissue_propertyr    r    r!   _process_properties  s    z!JiraAPIImport._process_propertiesc                 C   s   g }|d  dg |d  dg  }|D ]`}| jjjj d|d  }tjj |d}|s~| jjd| dd	d
 |  jd7  _|| q(||_	d S )Nrr   ZfixVersionsversions
::version:rw   r  u!   Не найдена версия zERR-0050r
  r  r+   )
rP   r,   r  r  rN   r
  r3   r2   r   fix_versions)r   r   r  r  r  versionr  Zversion_objr    r    r!   _process_issue_versions  s     z%JiraAPIImport._process_issue_versionsc                 C   s   g }|d  dg }|D ]`}| jjjj d|d  }tjj |d}|sn| jjd| ddd	 |  jd
7  _|| q||_	d S )Nrr   
componentsr   rw   r  u%   Не найден компонент zERR-0051CmfComponentr  r+   )
rP   r,   r  r  rN   r  r3   r2   r   r  )r   r   r  Zissue_componentsr  	componentr  Zcomp_objr    r    r!   _process_issue_components  s    z'JiraAPIImport._process_issue_componentsc                 C   s   ddl m} g }|d dg }|D ]}|dddd}||d	d
d}zbdddd| dgdd|gddd| dgg}tjj|d}	|	stj|d}	|	  ||	 W q$ tk
r }
 z"| j	j
d| d|
 d|d W 5 d }
~
X Y q$X q$||_d S )Nr   r  rr   r  r  r@  r^  r   r  Tr  r  r  r  r  r  r   r   r:   u+   Не удалось создать тег 'r(  zERR-0125r  )r  r  rP   rL  rN   r  r  r   r0   r,   r3   r  )r   r   r  r  r  r  Zlabelr  filter_rK  r3  r    r    r!   _process_issue_tags  s0    z!JiraAPIImport._process_issue_tagsc              
   C   sv  ddl m} dddg}d||r&|jjp(d |t|jt|jd}d }	d }
|d }|d	 }|d
kr|rr| j||d}	|r| j||d}
n|dkr|rtjj	| j
jjj d| |d}	|rtjj	| j
jjj d| |d}
n|dkr|}	|}
n|dkrl| j
jjj d|jj }|r>tjj	dd| d| g|dg d}	|rptjj	dd| d| g|dg d}
nd S tjj	|}t||jr|	r|	jjpd |d< |
r|
jjpd |d< |	r|	jjpd |d< |
r|
jjpd |d< |	r|	jjpd |d< |
r|
jjpd |d< n|	|d< |
|d< tjj|d |d |d |d |d |d |d dgd }|sr|S d S )!Nr   rr   rm  rD   r   r   )r  r   cmf_author_idr   obj_idZobj_coderU  rV  )r   rG   r  r   r   r  rF   r   r  r  r  r  
from_valueto_valueZfrom_value_codeZto_value_codeZfrom_value_nameZto_value_namer   r  r  r   r  )r   r  r  r   r  Zfrom_value_idZto_value_idrr   )Zcmfrr   rw   ry   r)   rD   r  rN   r=  rP   r,   r  r  r  r  r   
issubclassZCmfRelationBaser   CmfOrmColumnHistoryro  )r   r   Zhistory_itemr   Z
created_atr  rr   Zfields_Zhistory_datar  r  Zitem_from_idZ
item_to_idr  Z	field_clscolumn_historyr    r    r!   _get_history_field  s    
	
z JiraAPIImport._get_history_fieldu.   Обработка истории задачиc              	   C   s  dddddd}d|d  d	|d
 d  d}g }|d d D ]}| j jjj d|d  }d }|dr| j|d | j |d}n| j jd|  |d |d|d}	|d D ]}
||
d |
d }| j|}|r0|d r0|d d }|d d r0| 	|d d |
||d |}|r0|
| | ||
d |
d }d|	krZ||	d< q|	d  d | |	d< qtjj|d!d"d#d$dgd%}|stj| j d&|d'}|	D ]}t|||	|  q|jr>|jd&d( q>|rtjj|d) d S )*Nr   r5  r6  r7  u   Статус)r   rI   rF   r   r   u   История задачи r   r  rr   r   r  	changelog	historiesz	::historyrw   r   r  u   Аудит без автора r   r+   )r   r   	log_levelr   r   r   r   r   r  r   Z
fromStringZtoStringr   z<br>r   r   r  r   r  T)r,   r  r  r  )r   )r,   r  r  rP   r  rL   rZ   r  Zjira_map_fieldsr  r   rt  rN   r   r  r  r  r  Zbulk_insert)r   r   r  Zfield_title_mapr4   Zhistory_fieldsr  r  r   r  re  r   r   Zhistory_fieldr=  Zhistory_commentr   r    r    r!   _process_history%  sf    





zJiraAPIImport._process_historyu]   Обработка связей с документами Wiki и веб-страницамиc                 C   s  g }| dg D ]}| jjjj d|d  }|d }|d }|stjj |d}|shtj||| jdd}|jr|d	 |_|d
 |_||_	|j
dd q|d dkr| ddkrtd|d
 }	|	r|	d}
tjj ddd|
 gd}|sq|| d|d< q||_d S )Nremotelinksr   rw   objectZapplicationr  TrE  r   r   r  r  zcom.atlassian.confluenceZrelationshipz	Wiki Pagez$/pages/viewpage.action\?pageId=(\d+)r+   r  r  r  r   r1  )rP   r,   r  r  rN   ZCmfLinkr  r   r   r(  r  rm  rn  r  CmfDocumentr   local_links)r   r   r  r  Z
remotelinkZremotelink_ext_idZremotelink_objZremotelink_applinkr  Zpage_iddocr    r    r!   _process_remotelinksd  s@    





z"JiraAPIImport._process_remotelinksc           
   	   C   s8  i }|d }| dr@|d  dp&d}|d |d< |d |d< | d}|rn| |d	 rn| |d	 |d
< | d}|r| |d	 r| |d	 |d< |sd S zJtjj |dd |D d}|D ]}	t||	||	  q|jr|jdd W nD tk
r2   | jj	d| d| dddd |  j
d7  _
Y nX d S )Nrr   ZtimetrackingZoriginalEstimateSecondsr   r  Z
sched_workZtimetracker_sched_workz1com.atlassian.jpo:jpo-custom-field-baseline-startrw   Zsched_start_datez/com.atlassian.jpo:jpo-custom-field-baseline-endZsched_finish_datec                 S   s   g | ]}|qS r    r    r   rl   r    r    r!   r     s     z0JiraAPIImport._process_gantt.<locals>.<listcomp>)r   rr   Tr  u8   Не удалось импортировать Гант u    для задачи 'r  zERR-0112CmfGanttTaskr  r+   )rP   r   rN   r  r  r  r  r0   r,   r3   r2   )
r   r   r  ZganttZissue_fieldsZestimate_secZbaseline_start_fieldZbaseline_end_fieldZ
gantt_taskr   r    r    r!   _process_gantt  s>    
zJiraAPIImport._process_ganttc                 C   s   | j jjj d|d  }tjj|dgd}|sFtj|d|| j dd}| j| jjd|d	  }d
| d| d|_	|j
r|jdd d S )Nz
::comment:rw   r   r  r  T)r   r  r  r,   r  z/browse/r   u<   Задача импортирована из Jira: <a href="z" target="_blank">z</a>r  )r,   r  r  rN   r   rP   r?   Z
url_joinerr   r   r  r  )r   r  r   Zcomment_ext_idr  r@  r    r    r!   _add_comment_link_to_issue  s$    z(JiraAPIImport._add_comment_link_to_issueu   Обработка задачиc                     s  d}|d }d| d|d d  d}|  || jtjj d }||d< | j|d	< d
|d< | jjjj 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 rZ| j|d 	d 	| j|d|d!< |d! sZ|  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 nd&|d$< |d d' d  |d d( 	d)}
|
rD|d d( d  d*  }n }d| jjjj d| d}tjj	dd+d,| d,gd-|d.< |jj	d/}| jjrN|
r |jj	d}| |}tt fd0d1|d&}| jjjj d|d  }tjj	dd2|gd-}nL|d3 }|d4 }|	 |}| jjjj d| }tjj	dd+| d5gd-}nltt fd6d1|d7 d&}|rz|d8 }n|d9 d3 }t|}| jjjj d:| }tjj	dd2|gd-}||d;< | jjjj d|j d|d d< d  }tjj	dd2|gd=gd>|d<< |d< j |d?< |d 	d@r| jjjj d|d d@ d  }tj!j	|d|d@< |d@ s| jjdA|d 	d@ dBdd |  jd7  _|"dCd&}|r|dD dE }| jj#$dF| dG|  t%j&| jtj|ddH|d gdI\}}|| '||7 }|j(r*|)dCdJdKdLdMdNdOdPdQdRg
 | *||||_+|p>g }|D ]}|j,-| qD| .|| | /|| | 0|| | 1|| |j2dSkrtj3j	|dTd
dUgdV}||_4|j5sd
|_5|j6d
dW |d dX |_7| 8|| ||_|j9r|j6d
dW t:  | ;|| | <|| | =|| n| jj#>d| dY | ?|| |d dZ d[ rj| @|| | jA	d\r| B|| t:  | jCd]d^ tD|d_ Ed`}tF|da}|Gdb W 5 Q R X |S )cu   
        Общая логика обработки которая потом разделяется на задачи и эпики
        r   r   r  r  rr   r   r  r   r@  TZapprovedr   rw   r  rD   securityr  Zperm_security_levelu:   Не найден уровень безопасности zERR-0048r   r  r+   zStory Pointsrk  r   r  r   uB   Не найден автор(постановщик) задачи zERR-0049)r  exc_infocreatorr   u>   Не найден создатель(автор) задачи rI   rG   u6   Не найден исполнитель задачи NrH   r   r  r  r  r  r   rE   rv  c                    s    | d d d kS )Nr  r   r  r    ZwfZissuetype_idr    r!   r     r   z.JiraAPIImport._process_issue.<locals>.<lambda>r  defaultWorkflowissueTypeMappingsr  c                    s    | d kS )Nr  r    r  r  r    r!   r   -  r   rw  r   rh  r  r  r   r  r  rj  r   u'   Не найдена резолюция zERR-0116r   renderedFieldsr   u4   Создание/обновление задачи 'r  r   r  r  r  r  r  logic_prefixr   r   r  r(  z	task.epicr  rP  r   r   r  rr   r  r   u[    была изменена пользователем и не будет обновленаr  totaltimeTrackingEnabledr   r1  
issue_pathr+  wr   )Hr   r   rN   r   r   rQ   r,   r  r  rP   CmfSecurityLevelr3   r2   r   r  rL   r-   rY   ZERRORr  r(  ry   r?   rM   r  r   r   r  r   r  rw   r  r  r=  r7  rZ   rh  r   r	  r6  r  r   r  r   ro  r   r  r  r  r  r  r  r   rP  r  r   r  r  r/   r  r  r  r  r  r  rT   r  r3  r   re   rg   rx  ) r   r   r   sprintsr5  rr  r4   Znormalized_issuer  Zstory_p_fieldZsimplified_projectZissuetype_ext_idr  r  r  r  r  r  r  Zdefault_workflowZissue_type_mappingsworkflow_namer  r  rB  Z
issue_textr  r@  r   r  r3  rl   r    r  r!   r    sZ   
$ 
$
 .$
 .$
 0






*
"
 


zJiraAPIImport._process_issueu&   Обработка всех задачc                 C   s2   | j  }|D ]}| j r" d S | | qd S r   )r?   r   r,   r.   r  )r   ri  r   r    r    r!   _process_issues  s
    

zJiraAPIImport._process_issuesu3   Обработка связей всех задачc           &      C   s  |s| j jd dS ttdd | j d}t }| 	 D ]}| 
|d \}}| j|d |dD ]}| j  r  dS |d d}|r|d |d nd}	| j jjj d	|d  }
|r| j jjj d	|d  }| j|g }||
 || j|< n(|	r0| j|	g }||
 || j|	< |d d
g }|D ]}| j jjj d	|d  }d|kr|
|d d|d< | j jjj d	|d d  |d d< || j|< nLd|krD|
|d d|d< | j jjj d	|d d  |d d< || j|< qDqjq@t | }| j jd|dd | j dt| j  t }tjjdd}tjjdd}| jD ]}| j  r dS tjjddd|gdd|ggddgd}|s| j jd| d qj| j| D ]}tjj|ddgd}|s| j jd| d qҐz |j|jkrtjjd d!d"gdd#d!|gd$d!|ggd#d!|gd$d!|ggggd%}|D ]4}||_|jd&d' | j jd(| d)| d* q`||_|jd&d' nb| j jd+| d,| d- |j d.| }tjj|d/}|stj||||| j d0}|jd&d' W nR t k
r` } z2| j j!d1| d2| d3d4d5d6 |  j"d77  _"W 5 d}~X Y nX qҐqjt#  t | }| j jd8|dd d"d9dd:d;}| j jd<t| j$   t }| j% D ]\}}| j  r dS z>| j jjj d	|d= d  }
||d= d> }|r8tjj|d} ntjj|
d/} | shtjjd>d|d= d> gd%} | stj|
| j |d= d> d?} |d= d@ | _&|d= dA | _'| jd&d' tjj|d d dgd}!|!s| j jdB|d d  dC|d d  dD W qtjj|d d dgd}"|"sT| j jdE|d d  dC|d d  dD W q| j jjj d	|d  }#tjj|#d gd}|stj| |#| j dF}|jj(d"kr|!j|"ks|"j|!krtjjdd|_|!j|"kr|"}|!}n|"j|!kr|!}|"}| j jd(| d)| d* |!|_)|"|_*|jd&d' W np   |  j"d77  _"| j j!dG|d=  dH|d d  dC|d d  dI|d d  dC|d d  dJdKd5d6 Y nX qt#  t | }$| j jdL|$dd t | }%| j jdM|%dd dS )NuD   
        Постобработка связей задач
        uF   Отключена обработка связей всех задачNc                 S   s   |  di  ddkS )Nr   r   z'com.pyxis.greenhopper.jira:gh-epic-linkr   r   r    r    r!   r     r   z2JiraAPIImport._process_relations.<locals>.<lambda>rw   r   rr   r   r   Z
issuelinksr   r   )r  r   r   r  uD   Анализ связей всех задач выполнен за r      сек.u   Подзадачи: zsystem.additional_parentrC   zsystem.linkr  r   rD   r   r  uP   Не удалось связать задачи, возможно задача 'u#   ' не попала в импортparent_taskr  zrelation_type.coder  zsystem.finish:finishin_linkout_linkr   Tr  u,   Тип связи родительской 'u$   ' и дочерней задачи 'ud   ' изменен с 'Блокируется/Блокирует (ОО)' на 'Относится к'.u   У задачи 'u3   ' эпик(родительская задача) 'uo   ' из другого проекта. Создана связь 'Дополнительный родитель'z:additional_parent:r  )r  r  relation_typer  r,   u<   Не удалось создать связь задачи 'u&   ' с дочерней задачей 'r  zERR-0114r   r  r+   uG   Создание связей подзадач выполнено за zsystem.duplicatezsystem.clone)ZBlocksZ	DuplicateZRelatesZClonersu   Связи: r  r   )r  r,   r   ZinwardZoutwardu=   Не удалось найти входящую задачу r  u   ). Возможно задача не попала в импорт или находится в проекте, который еще не импортирован.u?   Не удалось найти исходящую задачу )r  r  r,   u.   Не удалось создать связь z. in_link: z), out_link: r&  zERR-0052uA   Создание связей задач выполнено за uL   Обработка связей всех задач выполнена за )+r,   rZ   r  r   r   rm   r   r  r  r   r  r   r.   rP   r  r  rV   r   rU   rh  r-   r   rN   ZCmfRelationTyper   r   ZCmfRelationOptionr   r  r  r  r  r0   r3   r2   r/   r  r   Zin_type_nameZout_type_namerD   r  r  )&r   r  Zepic_link_fieldZtotal_t1r   r  r@  r   Zissue_parentZissue_epic_keyr  Zparent_ext_idZ	sub_tasksZissue_linksZ
issue_linkZlink_ext_idZanalysis_t2Zsubtasks_t1Zadditional_parent_relationZlink_relationr  Zchild_ext_idZ
child_taskZ	relationsZrelation_optionZrelation_ext_idr3  Zsubtasks_t2Z	map_namesZrelations_t1Zissue_relationZrelation_coder  r  r  Z
rel_ext_idZrelations_t2Ztotal_t2r    r    r!   _process_relations  s   




&
&

(


 
 
Fz JiraAPIImport._process_relationsu)   Обработка компонентовr  c              
   C   s  t jj|ddddgd}|s*td| | |d D ]}z| j rTW  dS | jjjj d	|d  }t j	j|d
ddddddgd}|st j	|| jdd}||_
|d |_||_|drd|_nd|_|dr| j|d | j d|d  d|_nd|_|d dkr |j|_nD|d dkr8|j|_n,|d dkrP|j|_n|d dkrdd|_|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 t  | j jd!7  _W q8   t  |  jd!7  _| jjd"| d#d$d% Y q8X q8t t j	j!dd&|gdd&dggdd'|_"|j"rZd|_#nt t j	j!dd&|gd(|_#|jr|jdd dS ))uG  https://docs.atlassian.com/software/jira/docs/api/REST/1000.824.0/#api/2/project-getProjectComponents
        Пока грузим как списки, после доработки будут отдельные обекты

        Args:
            project_info (dict): проект из джиры как есть
        r  TrP  r  r  uV   Данный тип проекта не поддерживает компоненты rw   Nr   descr_documentdefault_ownerdefault_responsibler  r   r   re  r  rW  r   archivedFr?  u   Компонент r  ZassigneeTypeZPROJECT_DEFAULTZPROJECT_LEADZCOMPONENT_LEADZ
UNASSIGNEDr  r   r   r+   u3   Ошибка загрузки компонента ERR-0053r  r  r  r   rf  r   )$rN   r  rP   r+  _get_project_componentsr,   r.   r  r  r  r   r   r   re  r  rL   r  rG   r  r   r  r  r  r  Zcreate_descr_documentZ
text_draftry   r/   r  r1   r2   r3   rz   r  r  rP  )r   r  r  Zcomponent_folderr  r  Zcomponents_listr    r    r!   r    s    	







 	z!JiraAPIImport._process_componentsu   Обработка версийc                 C   sB  t jjd|ddgd}| j|d dD ]}zp| j rBW  d S | jjjj d|d  }t jj|dd	d
ddddddddgd}|st j|| jdd}|j	rpt j
jdd|_||_||_|d	 |_|dd|_|d|_|d|_|jj|_||_|jr|jdd |d r"d|_nd|_|jrZ|d sD|d rP|d  n
|d! |jr|jdd n| jjd"| d# t  | j jd$7  _W q&   t  |  jd$7  _| jj d%| d&d'd( Y q&X q&t!t jj"dd)|gdd)dggdd*|_#|j#rd|_$nt!t jj"dd)|gd+|_$|jr>|jdd d S ),NreleaserP  r  )r   r   rr   rw   rz  r  r  r   r   rE   r   r  r  r  r   r   re  r  TrW  zlist.release:defaultrC   r   r   r   ZreleaseDater  r  FZreleasedr  r   u   Релиз |    был изменен пользователем. Изменения из импорта не будут примененыr+   u+   Ошибка загрузки версии r  r
  r  r  r  r   )%rN   r  rP   _get_project_versionsr,   r.   r  r  r
  r  r  rE   r   r   r   r   r  r  r  r   r  r(  r  r  re  Zset_default_statusrZ   r  r/   r  r1   r2   r3   rz   r  r  rP  )r   r  r  Zrelease_folderr  r  Zversion_listr    r    r!   r  2  s    	





 	zJiraAPIImport._process_versionsu*   Обработка JQL в фильтрахc                 C   s  t  }t| jjjj}t }tjj	dddgdddggddd	d
gd}|D ]}d|j
 d|j d}|jsnqJ|jjd}|s|jjd}|s|jjd}tj| jjjjj}|jjdpi }	|	dpd}
|r|j|
krqJ|sqJz| jd | jd|  |||\}}||_tj|dd|_|jdd t  | jd|  | jd|  | jd|  |jD ]}| jj| qW qJ tk
r } z.t   | jj!d| d| d| d d!d" W 5 d}~X Y qJX qJt | }| jj"d#|d$d% dS )&uP   
        Пост обработка JQL в фильтрах задач
        r,   r  Nr  r   Tr(  ubqlbqlr   r  r  " (r&  jqlrF  ZjqlQueryapplinkZrpcUrlr   2--------------------------------------------------u   ФИЛЬТР: FZensure_asciir  zJQL:	zUBQL:	zBQL:	r  u0   : ошибка преобразования JQL r  zERR-0066r  r  uC   Обработка JQL в фильтрах выполнена за r  r  )#r   r)   r,   r  r  r  process_timerN   r  r   r   rD   r(  ry   rP   rj  rk  r8  Zext_urlnetlocr-   Zget_modifiedr  rh   ry  r  r  r/   r5  rZ   r  r0   r1   r3   rh  )r   r  r  r  Ztask_filtersr  Z
filter_msgrF  rL  r  Zrpc_urlr  r  Z	error_msgr3  r  r    r    r!   _process_jql_in_filters  s^    


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   s  dddddddddddddddd}|  dD ]}| jjd|  | j rX d	S |d
 }| jjjj d| }ddd| dg}|dr|d d d
  d| }| jjjj d| }d|ddd| dgg}tj	j|ddgd}d| jjjj d}|rdt
t||jjdkrd| jjd| d|j  t|dt|j|_|jdd d	}|d|d  }	|d  }
|s| jjd |	 d! tj	jdd"|	gddgd}|r|jsd| d|_nd| dt|jkr|dr,d| jjjj d|d
  d}|jj|d|_d| |j }t
t||dkr| jjd#|	 d$| jjjj d!d%|d&d' |  jd7  _n||_|
|	kr|
|jkr|j|
 |jdd t  q.| jjd(|	 d) ||	 }|s||
 d}| jjr4|d* d+kr d}n|d* dkrBd}n|d, rBd}tj	jd-d.|gd/gd}tj	|	|d0 d1|t|jd| d| jd2}|	|
kr|
g|_|  t  | j jd7  _q.d	S )3u$   Маппим issueType в logic_typeztask.sub:defaultztask.userstory:defaulttask.agile:defaultztask.bug:defaultztask.epic:default)zsub-tasksubtasku   подзадачаz
user storyZ	userstoryZstoryu   историяr   u   задачаZbugu   багu   ошибкаZdefectu   эпикr  r  u-   Обрабатываем тип задачи Nrw   r   r  r  r  r  Zscoper   r  r  r  r  rw  z::\d+)::r+   u   ext_id типа задачи r  r   Tr  r  r   u2   Поиск типа задачи по имени 'r  r  uW   Ошибка объединения одноименных типов с именем 'u*   ': одинаковый источник 'zERR-0118r  )r4   r  u   Тип задачи 'u2   ' не найден. Создание новогоr  r`  r  rD   r   ui_colorr   r   )r   r   r  r  r  r  r,   )r   r,   rZ   rh  r.   r  r  rP   rN   r  r   rm  findallr  ry   r  r  r)   r  ry  rL  r3   r2   r  r   r/   rH  r?   rM   r  r  )r   Z	name2coder  r  r  r  Zissue_type_scope_idrE   Zext_id_patternZissue_type_nameZissue_type_aliasZlogic_type_ext_id_oldZlogic_type_ext_id_mergedZtemplate_coder  r    r    r!   _process_issue_type  s    






	
z!JiraAPIImport._process_issue_typeu2   Обработка бизнес-процессовc                    sn  i } dD ]}|||d < q dD ]<}j r@ dS jj|d d   jjjj d|d d  d|d d  }tjj	|dstjj	d	d
}tj||jd|d _
|d d _jdd |d D ]}||d   qtjjddgdddggdgdD ]@}tjj	dd|jgddgdddggdsPq|jdd q|d D ]}j r  dS jjjj dj d|d  }tjj	|d}	|	stj|jdd}	|	jsjjd|	j dj d qh|d |	_|d |	_
fdd|d D }
tjjdd |
gd|	_t|	jt|
ksXtd!jjjj dj d|d"  }tjj	|d}|d#  }|d$kr|rd|_|jdd% ||	_|	d&rB|d& d  tt fd'd( d)d}z||	_d|	_ W n8   jj!d*  d+|	j d,j d-d.d/d0 Y nX |	jdd qht"  j j#d17  _#q*dS )2u   Импортируем workflowr  rw   ru  Nr   r   ZentityIdr  r  rC   rx  r   Tr  r  r   r  r  r  r  r   r  r  )r  r  rP  rQ  rR  rS  c                    s*   g | ]"} j jjj d j d | qS )r   )r,   r  r  rw   )r   st)r   r  r    r!   r     s     z3JiraAPIImport._process_workflow.<locals>.<listcomp>rU  r  uN   DEV: Fatal Вероятно, сломали создание статусов!rV  r  r  r  rZ  c                    s   t | dt  kS rc  rX  rY  r[  r    r!   r     r   z1JiraAPIImport._process_workflow.<locals>.<lambda>r]  r^  r_  r`  r  ra  rb  rc  r+   )$r   r,   r.   rZ   rh  r  r  rN   r  rP   r   r   r  r  r  r   r  r  rw   r  r  r  r  r   r+  rH  r  r  r   r   rd  re  rf  r3   r/   r  )r   Zjira_statusesr  Zjira_workflowZworkflow_idZtemplate_workflowr   r  r  r  r  r  r  r  rh  r    )r\  r   r  r!   _process_workflowj  s    
,

 
"

"

zJiraAPIImport._process_workflowu    Обработка схем БПc                 C   s  |  dD ]}| j r  d S | jjjj d|d  }tjjdd| dgd}|sjtd|d  | jjjj d|d	  }tj	j|d
}|stj	jdd}tj	||| jdd}|j
r|d |_|dd|_||_||_||_|jdd n| jjd|j d g }|d  D ]v\}}	| jjjj d| }
tjjddd|
 dgd}tjjdd|gdd|ggd}|r|j
s| jjd|j d|j d|j d ||j q|sFtjjdd|gdd|gdddgdd d ggdd!}|r2| jjd|j d|j d|j d" ||j qtjd#||| jd$}| jjjj d|	 }tjjdd| dgd}||_|jdd ||j qtjjd%d&|gdd|gdd d ggdd!}|D ]}|jdd' qt  | j jd(7  _q
d S ))Nr  r   r  r  r  r  r   u+   Не импортировался workflow rw   r  r  rC   Tr  r   r   r   r  r  r  r  r  rE   r  r  r  r  r  r  r  r,   r  r,  r  r   r  rD   r+  r  r+   )r   r,   r.   r  r  rN   r  rP   r+  r  r  r   r   r  r  r(  r  rZ   r  r   r  r  rD   r   r  r   r  r/   r  )r   r  Zdefault_task_workflow_ext_idr  r  r  r  r  logic_type_idr  r  rE   r  r  r  r  r    r    r!   _process_workflow_scheme  s    

	z&JiraAPIImport._process_workflow_schemec                 C   sH   t jj}| dD ]0}|| j}|| jj d| t	
| qd S )Nr   rQ  )rR  rS  rT  r   rP   rL   r  r,   rw   rU  ry  )r   rX  rM  r   r    r    r!   _cache_all_users*  s    zJiraAPIImport._cache_all_usersc                 C   s   t  | _dddgdddgg}|rFtjjdd|ggd	}|d
d|g tjj|dgd}|D ].}|jj	 D ]\}}| j
t||f qlq\t| j| _dS )u  
        Кеширует приоритеты системы

        Args:
            field_config_scheme (CmfCustFieldConfScheme, optional):
                Схема кнфигурации полей установленная проекту.
                Если не указана, то кешируются все импортированные приоритеты системы.
                Defaults to None.
        r   r  rF   r,   r  NZcache_schemesr  r   r   r  r  )r  priorities_cacherN   r  r   r   r  r  ry   r   r  r)   )r   Zfield_config_schemer  r  Zfield_configsZfield_configkvr    r    r!   r  0  s"    

zJiraAPIImport._cache_prioritiesry   c                    s`   t  fdd| jD d}|dk	r&|S t  fdd| jD d}|dk	rL|S td  ddS )u  
        Получает приоритет из кеша

        Args:
            value (str): Имя или id приоритета.

        Returns:
            tuple (str, str): Кортеж, содержащий id и имя приоритета
        c                 3   s   | ]}|d   kr|V  qdS )r+   Nr    r   rF   r  r    r!   r  \  s      z5JiraAPIImport._get_cached_priority.<locals>.<genexpr>Nc                 3   s   | ]}|d   kr|V  qdS )r   Nr    r  r  r    r!   r  d  s      u   Приоритет 'uP   ' не найден. Возможно он еще не импортирован.)r   r  r0   )r   ry   Zpriority_tupler    r  r!   r<  P  s    z"JiraAPIImport._get_cached_priorityu   Простой дампr:   c           	   	   C   s   t  }| j | d}| j | d}| rFt| t|d6}| D ](}| j j	d7  _	|
t|d  qXW 5 Q R X t|| | jjdd t  | }| jjd|j d	|d
d d S )N.jsonz.json.dirtyr  r+   rJ  Tr  u
   Дамп 'u   ' выполнен за r  r  )r  r  r,   rd   re   rf   ro   r  rg   json_object_countrx  rh   ry  rn   rq   r  rZ   rh  r%   )	r   Zapi_funcr   r  rk   rs   rl   rz  r  r    r    r!   _simple_dumpl  s    

 zJiraAPIImport._simple_dumpc              	   c   sN   | j  | d}| rJt|d}|D ]}t|V  q.W 5 Q R X d S )Nr  r+)r,   rd   re   rf   rg   rh   rV  )r   r   rk   rl   rz  r    r    r!   r   ~  s    zJiraAPIImport._simple_getc              
   c   s   | j  d}| rt|D ]d}|dr2q"|drX| j jd| d|  q"t	| d| dd}t
|V  W 5 Q R X q"d S )Nr   r)  r*  u(   Пропускается каталог r_  
/info.jsonr  )r,   rd   re   rf   ro   listdirr  rZ   r-  rg   rh   ri   )r   rt  r  rl   r    r    r!   r     s    

zJiraAPIImport._get_projectsc                 C   s&   |   D ]}||d kr|  S qd S rc  )Zget_projects)r   r  r  r    r    r!   get_project  s    zJiraAPIImport.get_projectc              
   C   s@   | j  d|d}t|d}t|W  5 Q R  S Q R X d S )Nr   workflows.jsonr  )r,   rd   re   rg   rh   ri   )r   r  workflows_filerl   r    r    r!   r    s    
  z/JiraAPIImport._get_simplified_project_workflowsc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /issue_types.jsonr  r,   rd   re   rg   rh   rV  r   r  rt  rl   rz  r    r    r!   r    s    z*JiraAPIImport._get_issue_types_for_projectc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /statuses.jsonr  r  r  r    r    r!   r    s    z'JiraAPIImport._get_statuses_for_projectc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /roles.jsonr  r  r  r    r    r!   r    s    z JiraAPIImport._get_project_rolesc              
   c   sV   | j  d|d}t|D ]2}t| d| dd}t|V  W 5 Q R X qd S )Nr   rW   r_  r  r  r,   rd   re   ro   r  rg   rh   ri   )r   r  	board_dirrc  rl   r    r    r!   r`    s    z!JiraAPIImport._get_project_boardsc              
   c   sV   | j  d|d}t|D ]2}t| d| dd}t|V  W 5 Q R X qd S )Nr   r  r_  r  r  r  )r   r  sprints_dirZ	sprint_idrl   r    r    r!   rn    s    zJiraAPIImport._get_all_sprintsc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /versions.jsonr  r  r  r    r    r!   r    s    z#JiraAPIImport._get_project_versionsc              	   c   sH   | j  d|}t| dd}|D ]}t|V  q(W 5 Q R X d S )Nr   /components.jsonr  r  r  r    r    r!   r    s    z%JiraAPIImport._get_project_componentsc                 C   st   d}d}| j  d|d}| rlt| D ]:}| s>q0|jdrLq0|d rb|d7 }|d7 }q0||fS )Nr   r   r   r(  r,  r+   )	r,   rd   re   rf   r   r.  r/  r   r  )r   r  r  Zunprocessedr1  r2  r    r    r!   r    s    
z"JiraAPIImport._count_project_tasksr   c           
   
   c   s   | j  d|d}| s:| j jd| d|  d S d}t| D ]}| sXqJ|j	}|
drjqJ|r~|d s~qJ||k r|d7 }qJ||| kr qt|d	d
}	t|	V  W 5 Q R X |d7 }qJd S )Nr   r   u   Каталог u    отсутствует. Возможно он был удален или еще не создан. Необходимо повторно запустить импорт проекта r   r(  r,  r+   	info.jsonr  )r,   rd   re   rf   rZ   r  r   r.  r/  r   r  rg   rh   ri   )
r   r  rG  r   Zonly_processingr1  r  r2  task_idrl   r    r    r!   r     s.    
zJiraAPIImport.get_project_tasksc                 C   s$  |d d }i }|d D ]f}|d dkr*q|d   D ]F\}}||d|i}|di }||d s6t|d	 ||d < q6q| D ]}i }	|d   D ] \}}
|	|
t }|| qi |d< |	  D ]8\}}t|d
kr||d d< q|D ]}||d |< qqqdd | D |d< |S )u   
        Создает структуру схемы экранов проекта из данных плагина "Smart Jira Configuration"
        schemesZissueTypeScreenSchemeglobalActionsrw   )BROWSEPROJECTSCREATEISSUES
EDITISSUESr]  issueTypeIdactionsrZ  r+   ry  c                 S   s   g | ]}|qS r    r    )r   r  r    r    r!   r     s     z<JiraAPIImport._get_project_screen_scheme.<locals>.<listcomp>r  )r   r  rP   r  r   r  r  r   )r   smart_configscreen_schemer  rN  r  ry   r  r#  Zissue_type_screensr\  rZ  Zissue_type_screenr    r    r!   _get_project_screen_scheme  s0    z(JiraAPIImport._get_project_screen_schemec                 C   s   t |d d}| r$t| |  |d d }|D ]}|d }zn| jjd| d | j	
tj|}tjd| d	d
d}||}t|d}	|	| W 5 Q R X W q< tk
r }
 z$| jjd| d|
 dddd W 5 d }
~
X Y q<X q<d S )Nrt  ru  rv  rw  r   u(   Дамп бизнес-процесса 'u   ' как XMLr{  r|  Tr}  zwb+uB   Не удалось получить бизнес-процесс 'u   ' как XML: r  r  rj   r  
error_type)r   re   rf   rn   rmtreemkdirr,   rZ   rh  r?   Zget_workflow_as_xmlrj  rk  quoter   r  rg   rx  r0   r3   )r   r  r  r  r  r  r  r  r  rl   r3  r    r    r!   _get_project_workflows_as_xml  s0    


z+JiraAPIImport._get_project_workflows_as_xmlc                 C   s  dd | j j|dD }g }|r.| j |}n&| j jdd}|dt|d d d	d |D }i }|D ]}t|d
 }	t|d }
| j |
D ]t}||d |d i d}|	dkr|D ]*}||krq||d |d d|d |< qq|	|d |d d|d |	< qqj|S )Nc                 S   s   g | ]}t |d  qS rv   r  r  r    r    r!   r   6  s   z>JiraAPIImport._get_field_config_issue_type.<locals>.<listcomp>rz  T)Z
is_defaultry  rw   )r"  fieldConfigurationIdc                 S   s$   g | ]}|d  dkrt |d  qS )r"  ry  r  )r   field_configurationr    r    r!   r   I  s   r"  r-  )rw   contextisHidden
isRequired)ZissuetypeIdr0  r1  r/  )r?   get_issue_for_projectZ"get_field_configuration_issue_typeZget_field_configr   r)   Zget_field_config_fieldsr  )r   field_configuration_scheme_idr  Zissue_types_projectZfield_configuration_mappingZfield_config_defaultZissue_types_schemefields_usedr.  r  Zfield_configuration_idr   
field_usedr  r    r    r!   _get_field_config_issue_type4  sN    
z*JiraAPIImport._get_field_config_issue_typec                 C   s  | j |}| ||}| D ]X}|d }|ds:q | j ||}|sNq | j ||}z| j ||}W nz tk
r }	 z\i }|  j	d7  _	d| d| d|	 }
t
|	dr|
d|	jj 7 }
| jj|
d	d
dd W 5 d}	~	X Y nX | j ||}|dr:|d  D ]&\}}|| |dk	r||d< qq |D ]:}|d |}|sZq>|| |dk	r>||d< q>q |S )u   
        Возвращает список используемых полей в проекте
        в виде сруктуры как через плагин "Smart Jira Configuration" в box версии
        rw   customfield_r+   u9   Не удалось получить опции поля u    в контексте rB  responsez HTTP: Response text -> zERR-0109r  rj   r'  NisAnyIssueTyper/  options)r?   Z&get_project_field_configuration_schemer6  r   ri  Z!get_field_context_project_mappingZget_field_contextZget_field_context_optionr0   r2   hasattrr8  r   r,   r3   Z#get_field_context_issuetype_mappingrP   r   r  )r   r  r3  r4  r5  Zfield_used_idZ
context_idr/  Zcontext_optionr3  Z
error_textZcontext_issuetypesr  Zcontext_issue_typer    r    r!   _get_project_fields_usedp  sL    





z&JiraAPIImport._get_project_fields_usedc                 c   sB   |d  d}t |D ]$}|dkr&q|| d| dV  qd S )Nr  z/attachmentsall_attachments.zipr_  )r,  rk   )ro   r  )r   r   Zattachments_pathr,  r    r    r!   r2    s
    z$JiraAPIImport._get_issue_attachmentsc              	   c   s>   |d  d}t |d}|D ]}t|V  qW 5 Q R X d S )Nr  z/comments.jsonr  )rg   rh   rV  )r   r   comments_file_pathrl   rz  r    r    r!   r    s    z!JiraAPIImport._get_issue_commentsc              	   C   s6   |d  d}t |d}t|}W 5 Q R X |p4g S )Nr  z/worklog.jsonr  rg   rh   ri   )r   r   r>  rl   r7   r    r    r!   r    s    z!JiraAPIImport._get_issue_worklogsc              
   C   s:   |d  d}t |d}t|W  5 Q R  S Q R X d S )Nr  z/properties.jsonr  r?  )r   r   Zproperties_file_pathrl   r    r    r!   r    s    z#JiraAPIImport._get_issue_propertiesc              
   C   s:   |d  d}t |d}t|W  5 Q R  S Q R X d S )Nr  z/watchers.jsonr  r?  )r   r   Zwatchers_file_pathrl   r    r    r!   r    s    z!JiraAPIImport._get_issue_watchersc              
   C   sD   | j  d}| r@t|d}t|W  5 Q R  S Q R X i S )Nglobal_settings.jsonr  )r,   rd   re   rf   rg   rh   ri   )r   global_settings_file_pathrl   r    r    r!   rS     s
    z'JiraAPIImport._get_jira_global_settingsc              	   C   sJ   | j  }| j d}t|d}t|| W 5 Q R X |d | _d S )Nzcloud_id.jsonrc   ZcloudId)	r?   Zget_cloud_idr,   rd   re   rg   rh   rj   rR   )r   r  	data_filerl   r    r    r!   _get_cloud_id  s
    
zJiraAPIImport._get_cloud_idc                 C   s   | j jd | j D ]}|d s&qzd| j|d |d< |d D ]B}z0| j|d |d }||d< |d | W qD   Y qDX qDW q   Y qX q| 	| j d S )Nu0   Получение контекста полейr   rw   r/  r:  )
r,   rZ   rh  rm   r   r?   Z_get_field_context_get_field_optionsr  rt   )r   r   r/  r:  r    r    r!   _get_fields_context  s     z!JiraAPIImport._get_fields_contextc                 C   s  t jj}|d }| |\}}| j||dD ]}| j rB dS t|d d}| j	 d}| j	 d}	|
 r6t||	 t|d}
t|dr}t|	d\}|
D ]P}||kr|| t|}|| j}|r|| jj d	| t| qW 5 Q R X W 5 Q R X W 5 Q R X |  t|	| t|d d
}| j	 d
}| j	 d}|
 r,t|d  t|| t|dR}
t|d<}t|d&}|
D ]}||kr|| qW 5 Q R X W 5 Q R X W 5 Q R X |  t|| q,dS )u]   
        Собирает пользователей и группы из задач
        rw   r   Nr  r|  zusers.json.newr~  r  rQ  rw  zgroups.json.newa)rR  rS  rT  r  r   r,   r.   r   re   rd   rf   rn   copyrg   rx  rh   rV  rP   rL   r  rw   rU  ry  r0  rq   close)r   r  rX  r  r  r@  r   Zissue_users_pathZall_users_pathZall_users_path_newf1f2Zf3r  rM  r   Zissue_groups_pathZall_groups_pathZall_groups_path_newr    r    r!   _collect_users_and_groups  sP    



$
,z'JiraAPIImport._collect_users_and_groupsc              	   C   s@   | j  }| j d}t|d}t|| W 5 Q R X d S )Nr@  rc   )r?   Zget_configurations_of_jirar,   rd   re   rg   rh   rj   )r   Zglobal_settings_datarA  rl   r    r    r!   _dump_jira_global_settings  s    
z(JiraAPIImport._dump_jira_global_settingsu/   Обработка ссылок в тексте)r   attachments_dirr   c                    s  d}|s|S t |ddd D ](}d}|dr8d}|j| }z|drh| jjd|  W q |d	stj	
| jj|}|| jjs| jjd
|  W q t|dd \}}	|s| jjd|  W q tdtj	|}
|
r`|
d  |
d dd} |d kr`|d d }tt fdd|d }|r`| jjd|  W q tj	|dd dd }tj|}||}tjj||d | jjjjd}|stj| j||d | jjjjd}||_||_d|_|   t!  W q  t"k
rH } z,t#  | jjd| d|  |d7 }W 5 d }~X Y q X q t |d}|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"  qf|S )%Nr   r  c                 S   s   |  dp|  dS rY  r[  r]  r    r    r!   r   $  r   z+JiraAPIImport._dump_links.<locals>.<lambda>rZ  r@  zmailto:u   Это почта: httpuH   Это внешняя ссылка, оставляем как есть: ra  u   Это не файл: rb  r+   r  r@  rr   r  c                    s   |  d kS rc  r   rd  rf  r    r!   r   =  r   uE   Этот файл уже обработан во вложениях: r_  r`  rw   )r@  
obj_ext_idr  )r,   r@  rO  r  Fu0   Не удалось скачать ссылку rB  rA  r:  r;  r<  r>  r  r?  r   ))r   rE  r\  r=  ri  r,   rZ   r  rj  rk  urljoinr?   r   rp  rq  r   rm  rn  rl  r   r   rN   r  Z_get_filenamere   CmfImportDownloadrP   r  r  pathr   
downloadedr  r/   r0   r1   r}  r8  r9  rF  rH  )r   r   rM  r   r2   rK  r   r   rt  encodingrr  Zattach_filenamer/  rs  r   r,  rk   download_jobrO  Zdoc_souprL  rF  r    rf  r!   _dump_links  s~    



 




 zJiraAPIImport._dump_linksc                 C   s   | j D ]}| j | d sq||s&q|| di }| D ]z}|dsNq>|d |d |d |d d}|drd	d
 |d  D |d< | j | dg }||kr||  qq>q| | j  dS )u   
        В box версии, контексты полей получаем из плагина "Smart Jira Configuration"
        r   r/  rw   r   isGlobalContextr9  )rw   r   rW  r9  r:  c                 S   s   g | ]}|qS r    r    )r   optionr    r    r!   r   v  s     z5JiraAPIImport._get_field_contexts.<locals>.<listcomp>N)rm   rP   r   r  r   rt   )r   r4  r   Zcontextsr/  Zcontext_dataZfield_contextr    r    r!   _get_field_contextsb  s*    




z!JiraAPIImport._get_field_contextsc                 C   sJ  | j |d }| jD ] }| j| d s,q|d |s<q|d | d}|r|D ]}|ds|| jd| tj qV| j jr| j| dg D ]*}|d |d kr|dr|d |d< qqV|| j| d krV| j| d 	| qV| j| d	 d 
d
dd }|dkr>|d | }|r8| || j |d  q|dkr~|d | pXg }	|	D ]}| || j |d  q^q|dkr|d | }
|
r8| |d | |d  q|dkr|d | pg }|D ]}
| |
|d  qq|dkr|d | }| j| dg }|r|| tt|| j| d< q| | j dS )u   На коробке только через мету задачи можно получить варианты выбора полей

        Args:
            issue (dict): задача
        r   r   rr   ZallowedValuesrw   u   Выбор без id: r:  r  r   r  r+   r`  
userpickerr  multiuserpickergrouppickermultigrouppickerr  N)r?   Zget_issue_metarm   rP   r,   r-   rY   r  rM   r   r   r}  rL   r{  r  r   r  rt   )r   r   metar   r:  rX  Zcur_optcustom_field_typesr   r   r  r  r   r    r    r!   rD  ~  sV    






z JiraAPIImport._get_field_options)r   r  c              	   C   sR   | j | j|d |}t|d d}t|d}tj||dd W 5 Q R X d S )Nrw   rt  r  rc   Fr  )r?   Z get_simplified_project_workflowsrR   r   re   rg   rh   rj   )r   r   r  ru  r  rl   r    r    r!   "_dump_simplified_project_workflows  s    z0JiraAPIImport._dump_simplified_project_workflowsc           &      C   s(  t dd d}| }|d kr0|| qzdddd |D  d}| jj|t|d	d
}|d }	|	D ]>}
z.z| j	 rW W  W W 5 Q R  dS | jj
d|
d  d |t|
d }|t|
d d }| rt|| |jdd ||
d< | |
 |d}| jjjj d|
d  }|
d d D ]}|d }|d }|d }|t|}|dt|}| d| }tjj|| jjjjdddgd}|stj|| jjjj| jdd}||_||_||_|js| s
d|_||_|  |d rH| |d  | j | qHt  | j d!r|d"}| rbt!"| t#|d#}| j$|
d }|D ]^}|d i | jr| |d  | j | |d$i | jr| |d$ | j | qt%&|| W 5 Q R X | jj'r6|
d% d& d'kr6d(d | j(|
d D |
d% d)< |
d% d) D ](}|d rB| |d  | j | qB|
d d*r| |
d d*| j| |
d d+r| |
d d+i | j| |
d d,i r| |
d d,i | j| || )|
d- d. ||
7 }|d/}| r4t!"| | jj
d0 t#|d1}| j*|
d D ]}|d i | jr| |d  | j | |d$i | jr| |d$ | j | |+t%,|d2  | j j-d7  _-| j.d3 || )|d4 ||
7 }q^W 5 Q R X | j/|
d |
d5< | j0|
d }|d6}t#|d#}t%&|| W 5 Q R X | j1|
d } | D ]}!| |!| j | qr|d7}"t#|"d#}t%&| | W 5 Q R X t|| |jdd |d8}#t|2dd9|
d< t#|#d#.}t%&|
| | j j-d7  _-| j.d: W 5 Q R X |d;}$t#|$d<}|+d9 W 5 Q R X W nL t3k
r }% z,|d7 }| jj4d=|
 d>|% d?d@dAdB W 5 d }%~%X Y nX W 5 t  X qrW nV t3k
r }% z6| jj4dC|d  dD| d>|% d?d@dAdB |d7 }W 5 d }%~%X Y nX || qW 5 Q R X d S )ENFr  r   zid in (r$  c                 S   s   g | ]}|qS r    r    )r   r  r    r    r!   r     s     z1JiraAPIImport._dump_task_part.<locals>.<listcomp>r&  zchangelog,renderedFields)r   expandri  r+   u   Задача 'r   r  rw   r)  Texist_okr  r/  r   rr   r  r  Zcontentr   r@  rR  )rO  r  rr   )rO  r  r,   r  r   r  zworklog.jsonrc   r~  r  r  (   c                 S   s   g | ]}|qS r    r    )r   r  r    r    r!   r     s    r  r   r  rI   r  r   zcomments.jsonu#   Дампим комментарииr  rJ  r  r   r  zproperties.jsonzwatchers.jsonr  r   r   r,  r  u0   Не удалось скачать задачу r  zERR-0111r   rj   r'  uB   Не удалось получить задачи проекта 'r  )5r   rP   r  r   r?   r  r   r/   r,   r.   rZ   rh  re   r)   rf   rn   rq   r*  rD  r  r  rN   rQ  r   r@  rR  r  rS  r(  r  r}  rL   rT   ro   r  rg   Zissue_get_worklogrh   rj   rM   Zget_changelogrV  Zget_commentsrx  ry  r	  r3  Zget_issue_remotelinksZget_issue_propertiesZget_watchersrL  r0   r3   )&r   r1  r  task_chunk_queuetasks_that_are_doner5  r;  r  r8  ri  r   r2  Ztask_dir_tmprM  Ztask_ext_idZattZatt_idr,  Zdownload_urlZatt_pathZatt_path_tmpZ
att_ext_idrU  Zworklog_file_namerl   Zworklogsr  r  Zcomments_file_namer  r  Zproperties_fileZwatchersr  Zwatchers_fileZ	info_pathr3  r3  r    r    r!   _dump_task_part  s   









  


$



zJiraAPIImport._dump_task_partc              	      s  t |d  d}|jdd  j }d}t j}d|krF| fddtdt jD } j }|D ]}|| qv|d  g }	t jD ]R}
 j	j
 jd	|
d
  ||||dd}|	| |   jjd|  qd}| }t| j d
  j }|| } jjd|d  d|d d  d|d  d |	D ]8}|j|d | rT jjddddd tdqT jjd | s|| 7 }q jjd|  |S )Nrt  /tasksTrb  r   2   c                    s   g | ]} j ||  qS r    )task_id_list)r   r&  r   Ztask_chunk_sizer    r!   r   y  s   z-JiraAPIImport._dump_tasks.<locals>.<listcomp>Z_dump_task_part_r+   )r1  r  re  rf  targetr   r6   u   Запущен r  u&   Тайм-аут дампа задач r5  u   ч u   м u   сtimeoutu$   Возможно завис дампzERR-0055r   rj   r'  u"   Ошибка дампа задачuK   Закончили параллельное скачивание задачu   Ошибок: )r   r*  r   Queuer   rj  r$  r  r   r   Threadrg  r   rG  r,   rZ   rh  r   is_aliver3   TimeoutErroremptyrP   )r   r  r1  rf  r5  r  Ztask_chunksre  r;  threadsr&  threadZtime_per_taskZtime_per_chunkZchunks_per_threadZtotal_time_per_threadr    rk  r!   _dump_tasksl  sf    





&

zJiraAPIImport._dump_tasksc              	   C   sH  | j jd|d  d|d  d | j|d }|r|dsi }| jjr`| j|d }n<|dg D ].}|d d	krl|d
 D ]}|d ||d < qql|dg D ]R}g |d< ||d g D ]4}|d | |d dkr| 	|d | j 
  qqt|d  d}	|	 r"t|	 t|	d}
t||
 W 5 Q R X d S )NuH   Дамп схемы безопасности задач проекта "r   r  r   r&  rw   r  r  BROWSE_PROJECTSr  r  levelsr  r   ry   rt  /issue_security_scheme.jsonrc   )r,   rZ   rh  r?   Z!get_project_issue_security_schemerP   rM   Z get_issue_security_level_membersr   r}  rd   r   rf   ro   r  rg   rh   rj   )r   r  r$  Zsecurity_schemeZsecurity_level_membersrN  security_levelr[   member	dump_filerl   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}i }z"d}| jj	|d d
|d}W n: tk
r } z| j jt|d	d
dd W 5 d }~X Y nX t|| |W  5 Q R  S Q R X d S )Nug   Дампим конфигурацию проекта через плагин "Smart Jira Configuration"rt  z/smart_config.jsonr  )	ZprojectInformationZprojectSchemesZprojectIssuetypesZprojectVersionsZprojectComponentsZprojectMembersZprojectCustomfieldsZprojectGlobalActionsZprojectWorkflowActionsr   r   )r:  ERR-0056r  rj   r'  )r,   rZ   rh  r   rf   ro   r  rg   r?   Zget_project_smart_configr   r0   r3   r)   rh   rj   )r   r  Zsmart_config_filerl   r$  r:  r3  r    r    r!   _dump_smart_config  s$    
 z JiraAPIImport._dump_smart_configEtc/UTC%Y-%m-%d %H:%M)dttzrI  r@   c                 C   sN   | pt j t jj|} t|}tjt j | ||}||}|S r   )	r  nowtimezoneutcstrftimepytzZlocalizestrptimeZ
astimezone)r  r  rI  Zdt_tzZdt_strr    r    r!   _datetime_in_user_tz  s
    

z"JiraAPIImport._datetime_in_user_tzc           E      C   s0  dd l }| jd d d }|d s*tddd |d D | _| j d	}|jd
d t| j}t	d| }| jD ]}|d }|d }|d }	z(| j
 rW  d S | j jd7  _| jjd|	 d ||}
|| d}|
d}| jjr| jj| jjd}n| jj| jjd}|r6|d d nd}| jj|d}d }| rt|d}t|}|d}W 5 Q R X |r| ||}|
 rt|
| ntj|d
d t }| j|}t ||d< d }| jjs| !|}| jjd t"|d  d}| r$t#| t|d}| j$|d }zv|d  D ]h}|d! d" d#krJ| jjr|d! dr| %|d! d | j  n| %|d! d$ | j  qJW n(   | jj&d%| d&d'd(d)  Y nX t'|| W 5 Q R X | j(||d* | jjr|d+ s\| j)|d d d, |d-< | j*|d |d.< | +|d |d/< n| jjd0 t"|d  d1}| rt#| g }t|dR}| jj,|d dD ]8}|-|d  | j jd7  _|.t/|d2  qW 5 Q R X | j0|d |d3< | 1|| n| j0|d |d-< d|d- krV|d- d |d- d4|d-< n| j2|d- d |d- d5< |d6i |d- d6< | 3| |d7r| 4||d.< |d8i |d/< | 5|d/  |d9}|r| j6d:|  | jj|d; d
d<|d9< | %|d9 | j7 | j  | jjd= t"|d  d>}| rRt#| t|dD}| jj8|d dD ]*}| j jd7  _|.t/|d2  qpW 5 Q R X | jjd? t"|d  d@} |  rt#|  t| d}| jj9|d dA: D ]}!| j
 r$ W 5 Q R  W  d S | j jd7  _| jj|!d
d<}"g }#|"dBg D ]}$|$d" dCkrTzN| jjr| jj;|$dD d|$dD dEdF|$dG< n| jj;|$d d|$dG< W nn |j<j=k
r" }% zJ|%j>j?dHkr|#-|$ | jj@dI|"d  dJ|% dK W Y qTn W 5 d }%~%X Y nX |$dGrT| %|$dG | j7 | j  qT|"dBrv|#D ]}&|"dB #|& q`|.t/|"d2  qW 5 Q R X | jjdL t"|d  dM}'|' rtA|' |'  t"|d  dN}(|( rtA|( |(  z| jjB|d dAD ]})| j
 r6 W W  d S | j jd7  _| jjdO|)d   | jC|)d |)d5< | jD|)d5 dP d |)d5 dP< | jE|)d }*| jjrdQdRdSd | jF|)d D ii}+|*G|+ |*|)d5 dT< | jj	s| jH|)d },tIt|,dk|)d5 dU< |d |)dV< |'t |)d }-|-jd
d |-d}.t|.dW}t'|)| W 5 Q R X z|)d" dXkr,| jjdY | jJ|)d D ]}/| j
 	r W  W W  d S |/dZ |)d k	rԐ	q| j jd7  _|(t |/d }0|0jd
d |0d}1|1 
r4| jjd[|/d  d\ 	q| jj
sN|)d5 dU |/dU< i |/d]< | jjd[|/d   | jjK|/d d^gd_D ]t}2| j
 
r  W  W W  d S |2d }3|3|2d |2d` d^ d |2d` d^ d |2d` d^ d dadb}4|4|/d] |3< 
qt|1dW}t'|/| | jLdc W 5 Q R X 	qW n |j<j=k
r }5 z\|5j>j?ddkrdet |5kspdft |5kr| j6t |5 n| jj&dg|) dhdid(d)  W 5 d }5~5X Y n(   | jj&dg|) dhdid(d)  Y nX qW n4   |  jMd7  _M| jj&dj| dhdid(d) Y nX | j6dk t"|d  dl}6|6 rDt#|6 t|6db}| jN|d D ]J}7| j
 r W 5 Q R  W  d S | j jd7  _|.t/|7d2  q`W 5 Q R X | j6dm t"|d  dn}8|8 rt#|8 t|8d}| jO|d D ]r}9| j
 r( W 5 Q R  W  d S |9d9rP| %|9d9 | j7 | j  | j jd7  _|.t/|9d2  qW 5 Q R X dotjPdp< | j jQ|7  _Q| jjRd
dq tS  drtjPdp< t|d |
 t |
|d< |d  ds}t|dW}t'|| W 5 Q R X t | }:| jjdt|	 du|:dvdw t"|d  dx};|r| T|d \}<}=|; s| jj@dy|	 dz|d  d{|; d|| d}	 d }n,|<s| jj@d~|	 dz|; d| d} d }|d d s|d d }>| jj&d|> d|> d|	 d| d	dd'd(d) ntUjUVtUjWjXYd}?| |?|}@d}At }| jjZ|d ||@d}B|Brfd|	 d|B }C|st|@r|Cd7 }C|r|Cd| 7 }C|@r|Cd|@ 7 }C|Cd| d7 }C| j6|C d|d  d}D|r|Dd| d7 }D|@r|Dd|@ d7 }D|Dd7 }Ddd | jj[|Ddd_D | _\|A| j]|d7 }At | }:| jjd|	 du|:dvdw | ^| n| jjd|	 d |As|?|d< t|dW}t'|| W 5 Q R X n|  jM|A7  _MW qv   |  jMd7  _M|dr| jj&d|	 ddd'd(d) n| jj&d| dd'd(d) Y qvX qv| j6d d S )Nr   r   ry   	isCheckedu5   Не выбрали ни одного проекта!c                 S   s$   g | ]}|d  r|d r|d  qS )r4   r  r    )r   valr    r    r!   r     s       z0JiraAPIImport._dump_projects.<locals>.<listcomp>r  r   Trb  P   rw   r   r   r+   u   Дампим "r  r)  r  )rF  )r   ZtimeZoner  rz  r~  Z	dump_datert  u   Дампим права/permissions.jsonr  permissionsholderr  r   	parameteru0   Не удалось сдампить права r  r  rj   r'  )r$  r  ZworkflowSchemerv  jira_screen_schemer4  u/   Дампим типы задач проектаr  rJ  r  )rw   rh  rh  ru  r  Z
fieldsUsedr?  u1   Ищем руководителя проекта r   )absoluteu*   Дампим статусы проектаr  u$   Дампим роли проектаr  )r   r  r  Z	actorUserrA   )r   ru  rM  i  u&   Пользователь к роли "u   " не найден. u+   . Возможно он был удаленu&   Дампим доски проектаz/boards/z	/sprints/rX  r   rQ  rR  c                 S   s   g | ]}|qS r    r    )r   Zqfr    r    r!   r     s    r   rg  r  rc   )rN  Zsimpleu&   Дампим спринты доскиZoriginBoardIdu   Спринт u    уже скачанri  r   r  rr   )rw   r   r   )rw   r   r   r   i  z"The board does not support sprintsuD   Данная доска не поддерживает спринтыu4   Не удалось сдампить спринты zERR-0057r
  u   Не удалось сдампить доски, возможно проект не поддерживает доски или у вас нет прав project_info=u(   Дампим версии проектаr  u!   Дампим компонентыr  r   NO_CACHEr  1r  u&   Дамп данных проекта "u   " выполнен за r  r  rh  u$   В каталоге проекта "r  u5   ), отсутствует каталог задач (u@   ). Дата последнего успешного дампа (u   ) будет сброшена.u/   В каталоге задач проекта "ud   ) отсутствуют задачи. Дата последнего успешного дампа (rx  ZhavePermissionu   Не удалось выполнить дамп задач проекта. Пользователь не имеет разрешения 'uA   '. Предоставьте пользователю право 'u0   ' в схеме прав для проекта 'r$  r&  zERR-0128r  )r  r  u$   Дамп задач проекта 'r  u    (в периодu    с u    по u4    включительно, часовой пояс: zproject = 'r  z AND updated >= 'z AND updated <= 'z ORDER BY updatedc                 S   s   g | ]}t |d  qS rv   r  )r   r   r    r    r!   r     s   r  u$   Дамп задач проекта "u   В проекте 'u5   ' нет новых/обновленных задачr  u   Проект "u   " является приватным и не может быть импортирован, отключите приватность в Jira или предоставьте пользователю праваzERR-0058u2   Не удалось получить проект u0   Закончили дампить проекты)_requestsr   r0   rX   r,   rd   re   r*  r   r  r.   r	  rZ   rh  r?   rM   Zuser_find_by_user_stringr   Zget_permissionsrf   rg   rh   ri   rP   r  rn   rq   ro   makedirsr  r  r  r)   r  r   r  Zget_project_permission_schemer}  r3   rj   r~  Zget_project_schemeZget_project_screen_schemer<  r2  r   rx  ry  Zget_project_workflow_schemer`  Zget_workflow_schemer,  r&  rY  r-   rL   get_statusesZget_project_rolesr   r   
exceptionsZ	HTTPErrorr8  r  r  r)  Zget_all_agile_boardsZget_agile_board_configurationZ
get_filterZget_advanced_board_settingsZget_board_quick_filtersr  Zget_agile_board_projectrz   Zget_sprintsZget_sprint_issuesr3  r2   Zget_project_versions_paginatedZget_project_componentsenvironprogressr  r/   r  r  r  r  r  r  Zget_project_issues_count_duringZjql_get_list_of_ticketsrj  rw  rK  )Er   r  rootZprojects_dirr  r  r   r  r   r  rt  Zproject_tmp_dirrB  rM  Zuser_tzZuser_permissionsZlast_dump_daterl   Zcurrent_dumpZlast_dump_date_utcr  r  r$  permission_fileZperm_sch	perm_dictZ
types_filer  r  rB  Zstatuses_filerz  Z	role_fileZrole_uriZ	role_infoZunfound_actorsr  r3  Zunfound_actorZ
boards_dirr  rb  Zadvanced_settingsZquick_filtersZboard_projectsr  Zboard_info_filer   Zsprint_pathZsprint_file_pathr   rp  rq  rO  Zversion_list_filenamer  Zcomponents_list_filenamer  r  r1  r  r@  r  Znew_dump_date_utcZnew_dump_dateZtask_errorsr:  Zinfo_msgr  r    r    r!   _dump_projects  s   












"  



"




"



"



 
 






	*      

"

"


 


    zJiraAPIImport._dump_projectsc                 C   s4  | j  }t|\}}}|| d }| j d| d | j jd | jjr`| 	  | 
  | 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r^| 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 | j d | | jjd | 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   Свободно места: r  u$   Скачаем данные из APIu9   Дампим глобальные настройки Jirar  Tu'   Дампим пользователейr   uA   Не дампим пользователей из-за опцийr  u   Дампим статусыr  u    Дампим типы задачr  Zissue_security_schemesu*   Дампим бизнес процессыru  u7   Дампим схемы бизнес процессовr  u   Дампим экраныr]  r%  u!   Дампим приоритетыr  r  u+   Дамп решений(резолюций)r  u   Дамп фильтровr  r   r     r  u   Дампим проектыN)'r,   rd   rn   
disk_usager-   rZ   rh  r?   rM   rC  rE  rL  rS   rT   rx   ry   rP   r
  r   rY   r  r  r  Zget_issue_typesZget_issue_security_schemesZget_workflowsZget_all_workflow_schemesZget_all_screensZget_screen_schemeZget_all_prioritiesZget_priority_schemesZget_all_resolutionsZget_all_filtersro   r  r  r  r/   r  )r   Zdownload_pathr  usedfreeZfree_percentr    r    r!   download_data  sV    





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  rw   rr   r  Tr  r  )ro   r  rN   Z	CmfImportrP   r,   rw   r	  r  r  r  r  r/   )r   r,   r    r    r!   r    s    
zJiraAPIImport._calc_progressc                  C   s  ddl m} t|d  d}| }dd |d D }t|d}t|}W 5 Q R X | jjjj d	|d
  }t	j
j|d}	|	st	j
|d| jd}	|	jr|d |	_|	jdd n| jjd|	 d ddg}
ddddddddddddd d!d"d#g}|
| }d$g|
 }t	jj|	|d%D ]n}|jsF| jjd&|	 d'|jj d( q|
D ]}t||g  qJ|D ]}t||d) qb|jdd q|d* D ]$}zd	| jjjj d	|d
  d	}||d+ rt	jj||d+  dd,}n| jjd-|  W qd.d/d0| d0g}t	jj||d1}|st	jj||	|d2}|sf| jjd3| d4|	d5 |  jd67  _W q|jr|j | |_n||_|jsW q|d7 d8 d9kr| jjjj d	|d7 d9 d
  }t	jj|d}|j| n|d7 d8 d:krd|_nn|d7 d8 d;krd|_nR|d7 d8 d<kr:d|_n6|d7 d8 d=kr\d|_d|_ n|d7 d8 d>krxd|_!n|d7 d8 d?kr| j"j#r|d7 d@r| $|d7 d@ }n| $|d7 dA }|r|j%| n,| jjdB| dC|d5 |  jd67  _W qnb|d7 d8 dDkr<| j"j#rNd	| jjjj d	|d7 d@  d	}n&d	| jjjj d	|d7 dD d  d	}t	j&jd.d/d0| d0gd.gd1}|s|d7 dD d }t	j&jddE|gd.gd1}|r|js||_n||jkr|j | |_|jdd |j%| n,| jjdF| dG|d5 |  jd67  _W qn4| jjdH|d7 d8  dI|d5 |  jd67  _W q|jdd W n2   | jjdJ| dKdLdM |  jd67  _Y nX qdNdOdPdQdRdSgdTgdUdVgdW}|' D ]\}}zt	jjdXdY|gdZdY|	gg|d1}|D ]\}t	jjdXdY|gdZdY|	gg|d1}|js:q
|D ]}t||t(|| q>|jdd q
W n@   | jjd[|	 d\| d]| d^d_d`dM |  jd67  _Y nX qt)  |	S )aNr   r  rt  r  c                 S   s$   i | ]}| d r|d  |d qS )r  rD   r   r   r    r    r!   r    s   
 z6JiraAPIImport._process_permissions.<locals>.<dictcomp>r  r~  r   rw   r  Tr  r  r,   r   r  u#   Схема прав доступа u@    была изменена и не будет обновленаaccess_project_roleaccess_membersaccess_local_useraccess_ownerZaccess_owner_assistantaccess_authorZaccess_spectatorsZaccess_executorsaccess_responsibleZaccess_list_owneraccess_project_ownerZaccess_project_owner_assistantZaccess_project_spectatorsZaccess_project_executorsaccess_sdesk_clientZaccess_anonymousZaccess_guestZaccess_sharelink_anonymousr   r_  u&   В схеме прав доступа u+    было изменено правило 'u,   ', оно не будет обновленоFr  r  )rD   r!  u4   Не нашли соответствия права r  r  r  r  )project_permissionr   rr   u*   Не найдено правило для zERR-0059r  r+   r  r  projectRole)applicationRoleZanyoneprojectLeadrI   r   sd.customer.portal.onlyr   ry   r  u9   Не нашли пользователя для прав zERR-0060r  r  u-   Не нашли группу для прав zERR-0061u'   Неизвестный тип прав zERR-0062u6   Не удалось загрузить правило zERR-0063CmfProjectPermPermissionr  zPPP-RELEASE-EDITzPPP-OBJ-CREATEzPPP-OBJ-EDITzPPP-OBJ-DELETEzPPP-OBJ-TREEMOVEzPPP-OBJ-ORDERzPPP-TSK-ASSIGN-EXECUTORSzPPP-TSK-DEADLINEzPPP-TSK-ORDER)zPPP-PR-ADMINzPPP-TSK-ASSIGNzPPP-TSK-SCHEDULEzproject_permission.coder  r   u   В схеме uR    не удалось скопировать разрешения из права 'u   ' в 'r  zERR-0113CmfProjectPermSchemeRule)*r  r  r   rg   rh   ri   r,   r  r  rN   ZCmfProjectPermSchemerP   r  r   r  rZ   r  r  r   r  r  r  r3   r2   r  r
  r  r   r  r  r  r  r  r  r?   rM   r  r  r  r   getattrr/   ) r   r  r  r  r  Zmap_permrl   Zperm_scheme_dictr  Zperm_schemeZrule_list_access_fieldsZrule_bool_access_fieldsZrule_access_fieldsZrule_fieldsZscheme_ruleZ
list_fieldZ
bool_fieldr  r  r  r  r  r  r  r  Zcopy_access_rulesZfrom_rule_codeZto_rulesZ	from_ruleZto_rule_codeZto_ruleZrule_access_fieldr    r    r!   r    sr   



 "





 

$&    	z"JiraAPIImport._process_permissionsc                 C   s  t dd d}| }|dkr&q| j r4qtjj|ddddd	gd
}t|j}t|j}t|j	}t|j
d}	t|	dkrd|	d  dnd}
d| d}|jr|jd }|d }| d|dd}| jj|
 d| d| d zX| jj||tjd | jj|
 d| d| d d|_|  t  | jd W q tk
r } z>t  | jj|
 d| d| d| dd d!|d" |d7 }W 5 d }~X Y qX q|| W 5 Q R X d S )#NFr  r   r  r   r@  rR  rO  r(  r  r   r+   u   [Задача ID: z] r   r  r#  i   r  r  z MB)u   Скачивание r  rn  u	   Файл u    сохранен в 'Tr  u"   Ошибка скачивания r(  zERR-0027rQ  rj   )r  r  r(  Zext_href)r   rP   r,   r.   rN   rQ  r)   r   r@  rR  rO  r   r   r(  rZ   rh  r?   Zdownload_filer   ZIMPORT_DOWNLOAD_TIMEOUTrS  r  r/   r3  r0   r1   r3   r  )r   download_queueerror_queuer5  Zdownload_job_idZdownload_objr,  Zfile_urlrk   Zext_id_splitZtask_id_msg	file_sizeZfile_size_mbr3  r    r    r!   _download_file_worker  sf    




 
 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dd	d
gg}| j  	d}d}g }| j
D ]n}|d }	|	|	}
t|
dst|
d }
dd|
 dgg}tjj|| d}|rv||7 }|||  qv|s| j jd |S | j jd|  g }t| jD ]L}| jj| jd| ||dd}|| |  | j jd|  q|D ],}tjj|dgdD ]}||j qqpt  |D ]}|d q| s|D ]}|  q| j  r|S | s|| 7 }q| j jd|  |S )Nu=   Скачиваем все найденные вложенияr   zplugin.plugin.source_hashr  r  rS  Fr   r  r=  r   rw   r_  rR  r  r  r   u3   Нет вложений для скачиванияu'   Скачивание вложений: Z_download_file_worker_)r  r  rl  u    Запустили задачу rm  r  r  uC   Закончили скачивание файлов, ошибок )r,   rZ   rh  r   rp  r   r  r  rd   re   rX   r)   r  rN   rQ  r  r   r$  r   r   rq  r  rG  Zslistr  rw   r/   rt  r   r.   rP   )r   r  r  r2   Zmain_filterZprojects_pathZattachment_countr  r   r  Zproject_pathZpath_filterZdownload_countru  r&  rv  r  rU  r    r    r!   download_files  sj    






zJiraAPIImport.download_filesc                 C   s&  | j  rd S | j jd|d  d|d  d d }t|d  d}t|}t|}W 5 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 |d D ]8}|d  d|d	  d}| j jjj	 d|d	  }	t
jj|	d
}
|
s@t
j||	| j dd}
|
jr|d |
_|d|
_t
jj|
dD ]}|jdd ql|dg D ]B}zt
j|
d}|d}|d}|dkrt
jjdd|_n|dkr,| j jjj	 d| }t
jj|d
}|rt
jj|d
|_ntd| n<|dkrJt
jjdd|_n|dkrht
jjdd|_n |d krt
jjd!d|_n|d"krl|rZd| j jjj	 d| d}t
jjd#d$d%| d%gd#gd&}|s| jjr|d' n|}t
jjdd(|gd#gd&}|rJ|js||_n||jkr6|j | |_|jdd ||_ntd)| nt
jjd*d|_n|d+krz| |}W n2 tk
r } zt| d,W 5 d }~X Y nX | j|d-d-d.\}}|r||_ntd/| n~|d0kr>| j jjj	 d| }t
j j|d
}|r.t!|jg|_"ntd1| n*|d2krZt
jjd3d|_ntd4| |jdd t#  W nP tk
r } z0|  j$d57  _$| j j%d6| d7| d8|d9 W 5 d }~X Y nX q|
jdd t#  |d:rt&|d:t&|d	 kr|
|_'|jdd qt#  |S );NuV   Импортируем схему безопасности задач проекта "r   r  r   r&  rt  rz  r   rw   r  TrW  r   r  ry  r  rE  r  r  r  r  ry   r  zvar:current_userrC   r  u0   Не найдена проектная роль r  zvar:project_ownerr   z
var:authorrI   zvar:responsibler  r  r  r  r  r  r  u!   Не найдена группа ZUsersr   r  Fr9  u+   Не найден пользователь )ZgroupCustomFieldZuserCustomFieldu>   Не найдено пользовательское поле r  zsdesk-client:defaultu-   Неизвестный тип правила r+   uF   Не удалось создать правило для уровня r  zERR-0070r  ZdefaultSecurityLevelId)(r,   r.   rZ   rh  r   rg   rh   ri   r  r  rN   ZCmfSecurityLevelSchemerP   r  r   r   r(  r  r  ZCmfSecurityLevelRuler   r  r|   Zaccess_memberr
  r0   r  r?   rM   r  rG  r  CmfCustFieldr)   Zaccess_task_fieldsr/   r2   r3   r  Zdefault_task_security_level)r   r  r
  r}  rl   r  Zscheme_ext_idr[   Z	level_msgZlevel_ext_idr{  Z
level_ruler|  member_typemember_valuer  r  r  r  r  rM  r3  r  r@  cust_field_ext_id
cust_fieldr    r    r!   r	  D  s    












 


$z&JiraAPIImport._process_security_levelsr   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rd|d< nx|dkrd|d< nd|dkrd|d< nP|dkrd|d< n<|dkrd|d< dd |d D |d< n|dkrd|d< dd |d D |d< n|d kr2d!|d< |d |d< n|d"krNd#|d< i |d< n|d$krbd%|d< n|d&krvd&|d< n|d'krd(|d< np|d)krd*|d< n\|d+krd,|d< nH| jjd-|d.  d/|d  d0|d d  d1d2d3d4 |  jd7  _d }|S )5Nr   rw   customfieldcfr@  r   T)r  r  r@  r  F)r   r   rD  Zvisible_filterrequiredZrequiredChangedr   r   r  r+   r`  Ztextarear   field_custom_typeZ	textfieldr)   floatr   )rn  Zradiobuttons
choice_strc                 S   s   i | ]}|d  |d qS rw   ry   r    r   optr    r    r!   r    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    s      r  r  Zcascadingselectchoice_cascade_multiZ
datepickerdater  rZ  r   r[  r   )r]  r\  r  r8  r   r$  u6   ) имеет неподдерживаемый тип 'r  zERR-0064r  r  )rL  r,   r  r  rH  r   r3   r2   )r   r   rD  r7   r   r_  r    r    r!   
_map_field  s^    
 













&zJiraAPIImport._map_fieldc                    sz  d | _ | jD ]Z}| jtjj d D ]B}d|krF| jdtj	   d S |d d |kr"| j| |d< q"q| j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s| jjd d S | jd dd tj D }g }g }| jtjj d D ]}|dr<|d d sV| jd|d   q| |}	|d d dd}
|
d| jj
j
j  7 }
|
|d< |	s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  d$|d d  d%|j d&||
 d  d'	d(d)d* q| jd+|
 d,|d  d- ||
 |d.< n(| jd/|
 d,|d  d0 || |jr|d |_|	d d1kr|jjpi }t |j!jpt  }|d d2 D ]}|d3 s8q&i t  }|d4g D ]:}t"j#|d5 d6d7d8}|d5 |< |d9 rN|$| qNfd:d;|D }|%| |%  qq&|}||_t&||_!|j'rd|_(|| |jdd< t)  tj*j||
||d=}|stj*||
||d=jdd< qt)  |+  |rtj,t-j-. /d>d
dd? tj0d@d
i dAd tj D }|D ]}||d  |d.< qdI fdBdC	|D ]D}tjj1|d. dD  }t2t|j3  |d d4 D ]}| qq| jjj}|dE D ].}|d tjjkr| jtjj d |d< q|| j_dFt4j5dG< d| jj_'| j  t)  dHt4j5dG< d S )JNrr   r   uj   Текущая настройка не поддерживает импорт кастомных полейrw   r   r  u8   Экран проектов Jira по умолчаниюTr   r  r  r,   r   _customr  )r   r  r   Zimport_custom_fieldsFuI   Отключен импорт пользовательских полейu8   Импорт пользовательских полейc                 S   s   i | ]}|d  |qS r   r    r  r    r    r!   r  ;  s      z8JiraAPIImport._process_custom_fields.<locals>.<dictcomp>r   u!   Поле не кастомное r   r  r  r@  r   r  )r  r  r  r   widgetr  r   disabled_choices)r   r   r  dirtyr  r,   r  u,   Неудалось смапить поле 'r$  u   ): widget поля 'u7   ' не совпадает с существующим 'r  zERR-0065r  r  u   Поле с именем r  u4   ) есть в таблице, мапим в негоr   u(   Создаем поле с именем u   ), и мапим в негоr  r/  rW  r:  ry   r      seplengthdisabledc                    s   h | ]}| kr|qS r    r    )r   r   )default_choicesr    r!   	<setcomp>  s   z7JiraAPIImport._process_custom_fields.<locals>.<setcomp>r  )r  r   r   ui_form_groupz%Y%m%d%H%M%S)Zmeta_versionZ
model_namer  r  c                 S   s   i | ]}|d  |qS r  r    r  r    r    r!   r    s      c                    s   t | tr4 j| d}|s$ | d}|jr|  npt | tr j| d d}|s` | d d}| dd|_|rz|j|_|jr|  | dg D ]}|| qd S )Nr:   ry   r  Fr  )	r   r)   rP   r  r  r   Z
cmf_hiddenrw   Zchoice_parent_id)rX  Z
parent_optry   child)choice_modelcreate_optionr    r!   r    s"    



z;JiraAPIImport._process_custom_fields.<locals>.create_optionr   r   r   r  r  )N)6r>   rm   r   rN   r   r   r,   r-   rY   r  r  r  rb  rP   r  r  CmfUiFormGrouprx   ry   rZ   r  r   r  rL  rH  r   r  r  r3   r  r   r  r  r  r   translit_stripr  r  r   r  r  r/   CmfUiFormFieldinvalidate_cacheZcustom_fields_gen_metar  r  r  Zcustom_field_sync_update_modelsrr   varsr   ro   r  )r   Zext_field_namer   r  ui_view_formr  shop_fieldsZ
new_fieldsZ
m2m_fieldsZui_fieldr   r  Zcurrent_choicesZcurrent_disabled_choicesr/  default_disabled_choicesrX  
option_keyr  ui_form_fieldZfield_classr   r  r    )r  r  r  r!   _process_custom_fields  s"   





6














z$JiraAPIImport._process_custom_fieldsc                    sR  dd t j D }|d }|d }| jjjj d| }t jj|ddgd}|s| jj	d	| d
| d t jd|d| jd}|j
}|jr||_|dd|_||_|  n| jjd| d |r| jjsddddddddddddddiddddddddddddd	}t jj|d }	|	D ]J}
||
j}|rr|d!d"|
_|d#d"|
_|d |
_|
jdd$ q6nrg }t jjd%d&|gd'd&dgdd&d ggd(gd)}|D ]>}||kr|jdd* q|j|_|jdd$ || qd d d d d d+}	| jjs|	D ]}dd&|gd,d&|d-kr2d.nd/gd%d&|gg}|d0kr\|d1d&d2g t jj|dd,gd3}
|
st jj|d,gd4}|r|d5 }
d|
_|
jdd$ n"| jjd6| d7| d8| d9 |
|	|< qt  t|d: }|d: D ]J}|d;kr|	d< r|	d< }
n|d }|d }| d| }t jj|d,d=gdd>}
|
s| jj	d?| d@| d
| d t jd/||d| jdA}
|
jr| jjdB| dC|
j d
| dD| dE	 nL|
js| jjd6| dF|
j d
| dD| dE	 n||
_||
_|
jdd$ |dG D ](}|d   dHs.q dIdJ}|dK| jjjj   7 }||krbqt!t" fdLdM| j#t jj$ dG d }|sq| jjjj d|dN d  }t j%j|dOdPgd}t jjdQd&|gd%d&|ggdRgd4}|r |js | jjd6| dS|j& dT|j'j dU q|st jjdQd&|gd%d&|gd=d&dgddVd ggddW}|r~| jjd6| dS|j& dX qt j|||| jddY}|j(dZkr|	d[ p|
|_'n$|j(d\kr|	d] p|
|_'n|
|_'|j)r|j'j*}|j'j}| jj	d?| d^|j& d
| d_|d/krd`nda db| dc |jdd$ qq|+  t  |S )dNc                 S   s   i | ]}|d  |qS r  r    r  r    r    r!   r    s      z1JiraAPIImport._process_screen.<locals>.<dictcomp>rw   r   r   r   r,   r  u   Создан экран 'r$  r&  r   T)r  r  r  r,   r   r   u   Экран r  r!  )r  r^  i  i  i  r^  i  ip  )hiddenr^  iX  i@  i(#  )	_main   Участники   Даты   Планu   Разработкаu
   СвязиZ_addonr  _descrr  r  Fr  r  r   r  r  z-cmf_created_at)r   Zorder_byr  )r  r  r  r  r  r  r  r  tabr  rN  Zclick)r   r  rr   r  r   u   На экране u6    не найдена системная группа 'u   '. Возможно она была удалена пользователем. Поля на экране могут отображаться некорректно. Создайте группу с названием 'u$   ' и повторите импортZtabsr+   r  r  )r  rr   r!  u   На экран u$    добавлена вкладка ')r  r   r  r  r,   u   C экрана uD    пользователем была удалена вкладка 'rB  uL   ). Изменения из импорта не будут примененыuF    пользователем была изменена вкладка 'rr   r7  r  r  r@  c                    s   |  do| d d  kS )Nr   rw   r   r  Zjira_field_idr    r!   r     s    
z/JiraAPIImport._process_screen.<locals>.<lambda>r   r   r  r  zui_form_group.typeu    поле 'um   ' было изменено или уже добавлено пользователем во вкладку 'uL   '. Изменения из импорта не будут примененыr  r,  u   ' было удалено пользователем. Изменения из импорта не будут применены)r  r   r   r,   r  )r   r   r  r  r  )r  r  r  u    добавлено поле 'r  u   во вкладкуu   в группуrI  r  ),rN   r   r   r,   r  r  rb  rP   rZ   rh  rK  r  r   r   r(  r  r  r?   rM   r  r   r  r  r^  r  r  r   r/   r   r  ri  rL  rH  r   r   r   r   r  r   r  r  r  r  r  )r   rZ  r  r\  Zscreen_nameZscreen_ext_idui_formZui_form_is_newZdefault_groupsZui_form_groupsr  Zgroup_configZcurrent_ui_form_fieldsZui_form_fieldsr  r  r  r  Znum_tabsr  Ztab_idZtab_nameZ
tab_ext_idZ
jira_fieldr   r   r  r  Z
group_typer    r  r!   rd    s   

 %
	





		
2zJiraAPIImport._process_screenu,   Обработка схемы экрановc              
   C   s  | dr>|d }|d }| jjjj d| }tjj |dgd}|sZtj|| jdd}|jrdd	 | d
D }|jstj	j
|dD ]}|  q|d |_|jdd |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|d  D ]\}}| |}|sl| jjd| d| ddd q0z| |}W n0   | jjd| d| ddd Y q0Y nX dd d!d"d d!d"d#}| j r  d S ||d$| |d| jd%}tj	j f |d&d'gi}|stj	f |}|
r*|j|
 |jdd q0qn| 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  rw   r   r   r  TrW  c                 S   s   i | ]}|d  |qS rv   r    r  r    r    r!   r  4  s      z8JiraAPIImport._process_screen_scheme.<locals>.<dictcomp>r]  )r  r   r  r  r"  ry  r  r  r  r  r   ;   Не удалось найти логический тип r  CmfUiFormSchemer  r#  u8   Не удалось найти в дампе экран u    для zERR-0069u:   Не удалось импортировать экран zERR-0068r  r  r)  )ry  r  r  r  r   r!  r  r   )r  rm  r  Zcrud_choicer,   rr   logic_typesr   u+   : Схема экранов проекта r  r  )rP   r,   r  r  rN   r  r  r   rK  ZCmfUiFormSchemeRuler   r  r   r  r  r3   r   rd  r.   r  r   rb  r  rm  r  r/   )r   r  Zscreen_scheme_dataZscreen_scheme_idr  r  r]  r  Zissue_type_datar  rE   r  rN  r\  rZ  r  Zaction_mappingr  r  r    r    r!   r  #  s    





z$JiraAPIImport._process_screen_schemec                 C   s  i }t  }|ds|S dd tj D }|d  D ]}|d dsLq8|d dd}|d| jj	j	j
  7 }||krq8| jtjj d	 D ]}|d
sq|d |d
 d kr|d  D ]\\}}	|	dsq| }
|	|
d< ||i }|
||
d < |	d r|di }|
||
d < qqq8| D ]\}}d}| jj	j	j
 d|d  }|d  d|d  }|dkrd| 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 | D ]h\}}
|
d }	| jj	j	j
 d| }tjj|d"d#d$gd}tjj||d%}|stj||| jd&}|	d'd(|_|	d)d( |_|jd*kr|jjpi }t |jjpt  }i }t  }|	d+i  D ]N}tj|d, d-d.d/}|d, ||< |d0 rH|| ||kr|| q| | ||_t!||_||_t!||_|  |j"r|jdd! t#  qDq,|S )1u1    Импорт конфигураций полейr4  c                 S   s   i | ]}|d  |qS r  r    r  r    r    r!   r    s      z5JiraAPIImport._process_field_conf.<locals>.<dictcomp>rw   r7  r  r  r@  rr   r   r/  r9  r  Nr   r   5   : Конфигурация полей проекта r   r  r  r  r   r  r  CmfCustFieldConfSchemer  u    для типа     по умолчаниюr   r  Tr  r  r  r  r  )r  r   )r  r   r,   r1  Fr0  r  r:  ry   r  r  r  r  )$r  rP   rN   r   r   r   ri  rL  r,   r  r  rH  r   r   r   rG  r  r  r3   r  r  r  r  r  r  Zvisibler  r  ry   r  r   r  r  r   r  r/   )r   r  Zlogic_type_fieldslogic_type_field_confr  r5  r   Z
task_fieldr   r/  r   rr   rE   r  r   r  r  Zfield_idZfield_ext_idr  r  r  r  r  r  rX  r  r    r    r!   _process_field_conf  s    



	





z!JiraAPIImport._process_field_confuA   Обработка схемы конфигурации полейc                 C   s  | 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
rntjj|dD ]}|jdd qt }|D ]V\}}	|	|	 ||	|r|gng d| j d}
|s4d|
d< tjf |
}|jdd
 q|D ]}	|	  |	jdd
 qR|  || _|S )Nr   rw   r   r  r   u@   : Схема конфигурации полей проекта r   Tr  r  r  r  r  r  r  )r   r  r  r  r,   r+   r^  )r,   r  r  rN   r  rP   r  r  r  r  r  ZCmfCustFieldConfSchemeRuler   r  r  Z
calc_cacher  r  )r   r  r  r  r  r  r  Zfield_confsrE   Z
field_confr  r    r    r!   r  &   sV    

z(JiraAPIImport._process_field_conf_schemec                 C   sF  |    |  j|  7  _| j  |   |   |   |   |   |   |   | 	  |   | 
  |   |   | jjr|   |   |   |   |   | j| jjjddd | j| jjjddd |   |   | jjjddr"|  j| j 7  _n| jjd | j r@d S d| j_| j  t  | jd |   D ]}|d	 d
d | j!D krql| jj"d|d  d t#j$sqlz6d| jj%j%j& d|d	  d}| jj'|| jjd W n8 t(k
r" } z| jj)d|  W 5 d }~X Y nX ql| jd| jj*  | j S )NZprocess_task_linksTr  Zimport_filtersZprocess_linksu2   Отключена обработка ссылокr  r  rw   c                 S   s   g | ]}|d  qS rv   r    r   r    r    r!   r      s     z0JiraAPIImport.process_import.<locals>.<listcomp>u'   Импортирован проект 'r   r  r   )rZ   uC   Не удалось создать отчет по проекту. u-   Импортировано объектов: )+r  r2   r  r?   rH  r  r  r  r  r  r  r  rM   r  r  rC  r  r,   rx   ry   rP   r  r  r  Zprocess_cross_linksrZ   r  r.   r  r  r/   r-   r   rX   rh  r   ZIMPORT_COLLECT_STATSr  r  Zproject_statsr0   r-  r  )r   r   r  r3  r    r    r!   process_import[   sf    

*zJiraAPIImport.process_import)T)r   r   )TTN)NN)NN)T)r   r!  )NF)N)T)N)r   r!  F)N)Nr  r  )r%   r&   r'   r(   r  r*   r   r)   r   r   rK   propertyrm   rt   r]   r   r   staticmethodr   r   r	   r   r\   r   r   r   r   r   r   r   r   r  r<   r  r6  rP  rG  r   rv  r  r  r  r  rN   r  r  r  r4  rO  ri  r  r  r  r  r  rz   r  r  r  r  r  r  r'  r4  r  rC  rK  rM  r  r  rt  r  r   r{  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r<  r
  r   r   r  r  r  r  r  r`  rn  r  r  r  r   r&  r,  r6  r<  r2  r  r  r  r  rS   rC  rE  rK  rL  rV  rY  rD  r   r`  rg  rw  r~  r  r  r  r  r  r  r  r  r	  r  r  rd  r  r  r  r  __classcell__r    r    r`   r!   r=   B   s  
!	
	"

	#> 


WV7 u
#

 7 W  <  K

1
 A;w
  
6 g
.G

   	
 6)8}
O
>
'* l
  f
]
=

 
\
b #<7/C= %H" 	   34 U>F A H  Ex 4r=   )6Zcmf.appr   Zcmf.includeZcmf.utilr   r   Zdataclassesr"  r  r  r  rU  rm  rp  pathlibr   rn   rj  typingr   r   r	   r
   r   r   r   Zbs4r   	itertoolsr   textwrapr   r   unicodedatar   Z
cmf.modelsr   Z%common.models.cmf_plugin_import_mixinr   Zmodules.jira.apir   Zmodules.jira.base_importr   Zmodules.jira.jql.parserr   rN   r   r|   r   r   Z	dataclassr   r<   r=   r    r    r    r!   <module>   s8   $ 