U
    Įwh                     @   s   d dl Z d dlmZmZmZmZ d dlZd dlmZ d dl	m
Z
 d dlZd dlmZ d dlmZ d dlT G dd	 d	ejZed
Zee  dddZG dd deZdS )    N)DictListOptionalIterator)wrapssleep)
HTTPStatus)Jira)*c                   @   s   e Zd Zdd ZdS )SensitiveDataFilterc                 C   sb   t |dr^d}|jdd}td||}td||}td||}td||}||_d	S d S )
Nmsgz\1***\2z\""z("username":\s*")[^"]*(")z("password":\s*")[^"]*(")z ("webSudoPassword":\s*")[^"]*(")z("atl_token":\s*")[^"]*(")T)hasattrr   replaceresub)selfrecordreplZ	clean_msg r   ./modules/jira/api.pyfilter   s    
zSensitiveDataFilter.filterN)__name__
__module____qualname__r   r   r   r   r   r      s   r   zatlassian.rest_client皙?         c                    s    fdd}|S )u-  
    Декоратор для повторного выполнения функции через некоторое время, при возникновении ошибки.
    Использует экспоненциальный рост времени повтора(factor) до граничного времени ожидания(border_sleep_time)

    :param exception: исключения, которые отлавливаются
    :param start_sleep_time: начальное время повтора
    :param factor: во сколько раз нужно увеличить время ожидания
    :param border_sleep_time: граничное время ожидания
    :param max_attempts: максимальное количество попыток выполнения
    c                    sN   t   fdd}t   fdd}t rJ|S |S )Nc               
   ?   s~   d}}|d7 }z| |E d H W S  k
rv } z6|kr@|| krN }n|d  7 }t | W 5 d }~X Y qX qd S Nr      r   r   argskwargsZattemptZtime_outerrorborder_sleep_time	exceptionfactorfuncmax_attemptsstart_sleep_timer   r   	gen_retry*   s    z3backoff.<locals>.retry_exception.<locals>.gen_retryc               
      sx   d}}|d7 }z| |W S  k
rp } z6|kr:|| krH }n|d  7 }t | W 5 d }~X Y qX qd S r    r   r"   r&   r   r   retry>   s    z/backoff.<locals>.retry_exception.<locals>.retry)r   inspectZisgeneratorfunction)r*   r-   r.   r'   r(   r)   r+   r,   )r*   r   retry_exception)   s    
z backoff.<locals>.retry_exceptionr   )r(   r,   r)   r'   r+   r1   r   r0   r   backoff   s    -r2   c                       s  e Zd ZdZ fddZ fddZ fddZ fdd	Zd
d Z fddZ	dddZ
dd Zdee dddZd fdd	Zeedd ZeedeeedddZdee ddd Zdee dd!d"Zd#d$ Zd%d& Zd'd( Zdd)d*Zed+d,d-Zed.d/d0Z fd1d2Zeed3d4d5Z  fd6d7Z!d8d9 Z" fd:d;Z#dd<d=Z$ed>d?d@Z%dee ddAdBZ&ddCdDZ'ddEdFZ(dGdH Z)dIdJ Z*dKdL Z+e,eef ddMdNZ-dOdP Z.ddQdRZ/ddSdTZ0deddUdVZ1ee ddWdXZ2dYdZ Z3 fd[d\Z4d]d^ Z5 fd_d`Z6 fdadbZ7 fdcddZ8 fdedfZ9 fdgdhZ:didj Z;dkdl Z<dmdn Z=dodp Z>dqdr Z? fdsdtZ@dudv ZAdwdx ZBdeeedydzd{ZCdeeed|d}d~ZDdd ZEdd ZFdd ZGdd ZHdd ZIdd ZJdddZKeedddZLdd ZMdd ZNdd ZOedddZPeeedddZQedddZReedddZSedddZTedddZUdeeeeedddZVdedddZWedddZXdd ZY fddZZ  Z[S )JiraApid   c                    s   | dr|nd| }|dr2|d|d< n|d|d< d|krPd|d< d|krdt |d< t j|f|| |d| _d	| _d
| _d S )Nhttpzhttps://cloudtokenpasswordtimeout,  ZsessionFzrest/auth/1/session)	
startswithgetcmfutilZrequests_sessionsuper__init__r7   _session_valid_session_url)r   urlr#   r$   	__class__r   r   r?   \   s    
zJiraApi.__init__c                    s   | j rt || dS )u   
        Переопределенный метод
        Базовая аутентификация устанавливается только для Jira Cloud
        N)r6   r>   _create_basic_session)r   usernamer8   rC   r   r   rE   p   s    zJiraApi._create_basic_sessionc                    sH   | j j  | j| jd}t jd| j|d}| j js>tdd| _	dS )u;   
        Выполняет авторизацию
        )rF   r8   ZPOST)pathdatauR   Ошибка аутентификации: файлы cookie не полученыTN)
_sessioncookiesclearrF   r8   r>   requestrA   RuntimeErrorr@   )r   rH   responserC   r   r   _authenticatex   s    zJiraApi._authenticatec                    s>   z t  jd| jd}|jtjkW S  tjk
r8   Y dS X dS )u~   
        Проверяет валидность текущей сессии через тестовый запрос
        GET)rG   FN)r>   rL   rA   status_coder	   ZOKrequestsRequestException)r   rN   rC   r   r   _check_session   s    zJiraApi._check_sessionc                 C   sP   | j r| jstd| jjr<| js<|  r<d| _|   dS |   |   dS )u>   
        Создает валидную сессию
        u_   Учетные данные для аутентификации не предоставленыTN)	rF   r8   
ValueErrorrI   rJ   r@   rT   user_get_websudorO   r   r   r   r   _create_valid_session   s    zJiraApi._create_valid_sessionc              
      s   | j rt j||S zJ| js$|   t j||}|jtjkrZd| _|   t j||}|W S  tj	k
r } zBt
|dr|jjtjkrd| _|   t j|| W Y S  W 5 d}~X Y nX dS )u8  
        Переопределенный метод
        Используется только для Jira Server.
        Перед запросом проверяется валидность сессии
        и при необходимости выполняется авторизация 
        FrN   N)r6   r>   rL   r@   rX   rQ   r	   ZUNAUTHORIZEDrR   rS   r   rN   )r   r#   r$   rN   erC   r   r   rL      s"    zJiraApi.requestN    c           	   
   C   s   | j }|p| j}| jd||d | jj|d||| j| jd`}td| d|j	 d|j
  |  t|d"}|j|d	D ]}|| q~W 5 Q R X W 5 Q R X d
S )ur  
        Скачивает файл

        Args:
            download_url (_type_): url файла для скачивания
            save_path (_type_): путь для сохранения файла
            timeout (_type_, optional): Таймаут. Defaults to None.
            chunk_size (_type_, optional): _description_. Defaults to 8*1024.
        rP   )methodrB   headersT)streamr\   r9   Zverifyproxiesz
HTTP: GET z ->  zwb+)
chunk_sizeN)no_check_headersr9   Zlog_curl_debugrI   r<   Z
verify_sslr^   loggerdebugrQ   reasonZraise_for_statusopenZiter_contentwrite)	r   Zdownload_urlZ	save_pathr9   r`   r\   resfchunkr   r   r   download_file   s"    

 zJiraApi.download_filec                 C   sR   d}| j dd}d}| jjr2| jj }|d}|r>||d< | j||g | jdS )u   
        Получает веб-куки sudo
        Переопределенный метод, так как метод в родительском классе выполняется некорректно
        z%secure/admin/WebSudoAuthenticate.jspaZfalse)ZwebSudoPasswordZwebSudoIsPostNzatlassian.xsrf.token	atl_token)rG   rH   filesr\   )r8   rI   rJ   Zget_dictr<   postform_token_headers)r   rB   rH   rk   rJ   r   r   r   rV      s    
zJiraApi.user_get_websudor   )returnc                 c   sp   d}d}d}|p| j }| j|||dd}|s0dS ||7 }|E dH  |t|7 }d|  k rb|krn qdS qdS )u(    Получение всех задач order by created ASCr   ZrenderedFields)jqlstartlimitexpandN)MAX_RESULTSZjql_get_list_of_ticketslen)r   rs   rq   start_attotalmax_resultsissuesr   r   r   
get_issues   s"    

zJiraApi.get_issuesc                 #   s   d}d}d}|p| j }t j||||dd}|d s8d S ||7 }t| d|d   |d E d H  |t|d 7 }d|  k r|ksn ||d krd S qd S )Nrp   r   changelog,renderedFields)rr   rs   rt   rz   u    из rx   )ru   r>   get_issues_for_boardgrc   rv   )r   board_idrs   rq   rw   rx   ry   rz   rC   r   r   r}     s&    
"zJiraApi.get_issues_for_boardc                 c   sH   d}d}| j |||d}|dg s&qD||7 }|d D ]
}|V  q6qd S )Nr   2   )r   rr   rs   values)Zget_all_sprintr<   )r   r   rr   rs   rg   rowr   r   r   get_sprints)  s    zJiraApi.get_sprints)rr   rs   fieldsc           	      c   sz   d| d}|pd|pdd}|r0d ||d< | j||d}|d	g sLqv|d
  |d 7  < |d	 D ]
}|V  qhq0dS )u  
        Возвращает все задачи в для заданного спринта.
        Включены только задачи, на просмотр которых у пользователя есть разрешение.

        Args:
            sprint_id (_type_): ID спринта
            start (int, optional): начальный индекс задач. Defaults to None.
            limit (int, optional): максимальное количество задач на странице. Defaults to None.
            fields (list, optional): необходимые поля задач. Defaults to None.

        Yields:
            dict: данные задачи
        zrest/agile/1.0/sprint/z/issuer   r   startAt
maxResults,r   paramsrz   r   r   N)joinr<   )	r   Z	sprint_idrr   rs   r   rB   r   rg   r   r   r   r   get_sprint_issues5  s    zJiraApi.get_sprint_issuesc                 c   s   d}|dkst dd|pd|d}|r0||d< | jr| d}| j||d}d	|krbt|d	 |d
 sndS |d
 E dH  |d  t|d
 7  < |r@|d |kr@dS q@n|  E dH  dS )u    Получение всех workflow
        https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-search-get
        ztransitions,transitions.rules,transitions.properties,statuses,statuses.properties,default,schemes,projects,hasDraftWorkflow,operationsr   uG   Больше 50 за раз запросить не получится!r   r   r   rt   ZworkflowNamezworkflow/searchr   errorMessagesr   Nr   )AssertionErrorr6   resource_urlr<   	Exceptionrv   Zget_all_workflows)r   namesrs   rt   r   rB   rg   r   r   r   get_workflows[  s&    
zJiraApi.get_workflowsc                 c   s   | j r| d}d|p| jdd}|r.||d< | j||d}|d sHdS |d E dH  |d	  t|d 7  < |r.|d	 |kr.dS q.n$|r| |E dH  n|  E dH  dS )
u.    Получение всех statuses
        zstatuses/searchr   Zusagesr   	projectIdr   r   Nr   )r6   r   ru   r<   rv   Zget_status_for_projectZget_all_statuses)r   rs   
project_idrB   r   rg   r   r   r   get_statusesu  s"    

zJiraApi.get_statusesc                 C   s6   d}d|i}| j ||d}d|kr.t|d |d S )Nz!rest/api/3/workflowscheme/projectr   r   r   r   r<   r   )r   r   rB   r   rg   r   r   r   get_project_scheme  s    zJiraApi.get_project_schemec                 C   s   d| d}|  |S )Nzrest/api/3/workflowscheme/z	/workflowr<   r   idurir   r   r   get_issue_type_workflow_scheme  s    z&JiraApi.get_issue_type_workflow_schemec                 C   s   d| }|  |S )Nzrest/api/3/issuetype/r   r   r   r   r   get_issue_type  s    
zJiraApi.get_issue_typec                 c   s   d|p
| j d}d}| j||d}d|kr6t|d |d sBd S |d E d H  |d  t|d 7  < |r|d |krd S qd S )Nr   r   zrest/api/3/workflowschemer   r   r   r   )ru   r<   r   rv   )r   rs   r   r   rg   r   r   r   get_all_workflow_schemes  s    z JiraApi.get_all_workflow_schemes)project_idsc                 c   sV   dd|d}d}| j ||d}|d s*d S |d E d H  |d  t|d 7  < qd S )Nr   r   )r   r   r   z"rest/api/3/issuetypescheme/projectr   r   r   )r<   rv   )r   r   r   r   rg   r   r   r   get_issue_type_schemes  s    zJiraApi.get_issue_type_schemes)r   c                 C   s   d|i}d}| j ||dS )Nr   zrest/api/3/issuetype/projectr   r   )r   r   r   r   r   r   r   get_issue_for_project  s    zJiraApi.get_issue_for_projectc                 #   s   | j rd}| |E d H  n~t  }| d}| dd t  }|rX| d| n
| d |D ]2 tt fdd|d }|r|d  d<  V  qfd S )Nzrest/api/3/issuetypejira.user.localeen_UKc                    s   | d  d kS Nr   r   )ZituZ
issue_typer   r   <lambda>      z)JiraApi.get_issue_types.<locals>.<lambda>nameuntranslatedName)	r6   r<   r>   get_issue_typesget_mypreferencesset_mypreferencesdelete_mypreferencesnextr   )r   r   issue_typescurrent_user_localeZissue_types_untranslatedZissue_type_untranslatedrC   r   r   r     s*    




zJiraApi.get_issue_types)	issue_keyro   c                 c   s   |  d}| d| d}tdddd}| jr>| j||d}n| j||d}|d	sZd
S |d	 E d
H  |d  t|d	 7  < q(d
S )u@    Получим все комментарии по задаче Zissue/z/commentr   r   zrenderedBody,propertiesr   r   ZcommentsNr   )r   dictr6   r<   rv   )r   r   Zbase_urlrB   r   rg   r   r   r   get_comments  s    

zJiraApi.get_commentsc                 #   sJ   d}d}t  j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   r   )project_keyrr   rs   r   )r>   get_all_agile_boardsr<   r   r   rr   rs   rg   r   rC   r   r   r     s    zJiraApi.get_all_agile_boardsc                 C   s   d}| j |d|id}|S )Nz3rest/greenhopper/1.0/rapidviewconfig/editmodel.jsonZrapidViewIdr   r   )r   r   r   rN   r   r   r   get_advanced_board_settings  s    z#JiraApi.get_advanced_board_settingsc                 #   sJ   d}d}t  j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   r   )keyrr   rs   r   )r>   get_project_versions_paginatedr<   r   rC   r   r   r     s    z&JiraApi.get_project_versions_paginatedc                 c   sp   |  d}d}d}t }|r$||d< ||d< ||d< | ||}||d krNql||7 }|d D ]
}|V  q^q$d S )	Nzauditing/recordr   i  Z
projectIdsoffsetrs   rx   Zrecords)r   r   r<   )r   r   rB   rr   rs   r   rg   r   r   r   r   get_audit_records  s    
zJiraApi.get_audit_records)r   c                 C   s   |  |}|d S )u(   Наблюдатели по задачеwatchers)Zissue_get_watchers)r   r   r   r   r   r   get_watchers   s    
zJiraApi.get_watchersc                 c   s4  | j rd}dddd}|r.|d |kr.||d< | j||d}|sBq|D ]}|| |d  |V  qF|d	  t|7  < |r.|d	 |kr.qq.nd
}dddd}|r|d |kr||d< |pd|d< d|d< | j||d}|sq0|D ]}|| |d  |V  q|d	  t|7  < |r|d	 |kr̐q0qdS )u   Возвращает список всех пользователей, включая активных,
            неактивных и ранее удаленных, у которых есть учетная запись Atlassian.
            в старых версиях невозможно получить больше 1000 учеток
            https://jira.atlassian.com/browse/JRASERVER-65089
            исправлено в 8.7.0, 8.6.1 и выше
            zrest/api/3/users/searchr   r4   z"operations,groups,applicationRolesr   r   r   Z	accountIdr   zrest/api/2/user/search.rF   TZincludeInactiver   N)r6   r<   updateget_user_inforv   )r   rF   Z	limit_endr   r   Zusers	user_infor   r   r   	get_users%  s:    zJiraApi.get_usersc              
   C   sT   z| j ||dW S  tjk
rN } z|jjdkr:W Y d S |W 5 d }~X Y nX d S )Nr   rt     userrR   	HTTPErrorrN   rQ   )r   r   rt   excr   r   r   get_user_info_by_keyO  s    
zJiraApi.get_user_info_by_keyc              
   C   sT   z| j ||dW S  tjk
rN } z|jjdkr:W Y d S |W 5 d }~X Y nX d S )NrF   rt   r   r   )r   rF   rt   r   r   r   r   get_user_info_by_usernameW  s    
z!JiraApi.get_user_info_by_usernamec                 C   s   d}| j r | j|| dd}n4| j||d}|s@| j||d}|sTtd| ddtj }tjj	j
t| }|d	st|d
 d |  | |d	< n(d|d	 kr|d	 d |  | |d	< |S )Nzgroups,applicationRolesz,operations)Z
account_idrt   r   r   u   Пользователь u    не найден@ZemailAddressZdisplayName)r6   r   r   r   r   ZconfigZ
ORG_DOMAINZcmfr   ZCmfEmailZ
max_lengthrv   r<   r=   Ztranslit_strip)r   r   rt   r   ZpostfixZmax_lenr   r   r   r   _  s    
$zJiraApi.get_user_infoc                 C   sb   d| d}ddd}g }| j ||d}||d  t||d krHq^|d	  |d
 7  < q|S )Nrest/api/2/field//contextr   r   r   r   r   rx   r   r   r<   extendrv   )r   r   rB   r   rg   rN   r   r   r   _get_field_contextq  s    
zJiraApi._get_field_contextc                 C   sh   d| d| d}ddd}g }| j ||d}||d  t||d	 krNqd|d
  |d 7  < q |S )Nr   	/context//optionr   r   r   r   r   rx   r   r   r   )r   ZfieldId	contextIdrB   r   rg   rN   r   r   r   _get_field_options}  s    
zJiraApi._get_field_optionsc                 C   s   |   }t }|D ]}d|kr,|||d < n|||d < | jr|d rg |d< g |d< z`| |d |d< |d D ]@}z.| |d |d }||d< |d | W qr   Y qrX qrW q   Y qX qg |d< g |d< q|S )u]    Возвращает системные и настраиваемые поля задачи r   r   Zcustomcontextoptions)Zget_all_fieldsr   r6   r   r   r   )r   r   rg   fieldr   r   r   r   r   
get_fields  s.    
zJiraApi.get_fieldsc                 C   s
   |  |S N)Zissue_editmeta)r   r   r   r   r   get_issue_meta  s    zJiraApi.get_issue_metac                 c   sz   d}|r|| |kr|| }dj |d}| j|d||dd}| jrH|}n|d }|sXd S |E d H  ||7 }||krqvqd S )Nr4   z"project = "{project}" ORDER BY key)project*allr|   r   rr   rs   rt   rz   )formatrq   advanced_mode)r   r   rr   maxrs   rq   rN   rg   r   r   r   get_all_project_issues  s    
zJiraApi.get_all_project_issuesc           
      c   s   d}d| d}|r$|d| d7 }|r8|d| d7 }|d7 }|rX|| |krX|| }| j |d||dd	}| jrx|}	n|d
 }	|	sd S |	E d H  ||7 }||kr@qq@d S )Nr4   project = "r    AND updated >= " AND updated <= " ORDER BY updatedr   r|   r   rz   )rq   r   )
r   r   rr   r   
start_dateend_daters   rq   rN   rg   r   r   r   get_all_project_issues_during  s&    
z%JiraApi.get_all_project_issues_duringc                 C   sX   d| d}|r |d| d7 }|r4|d| d7 }|d7 }| j |ddd}t|d	 S )
Nr   r   r   r   r   r   r!   )rr   rs   rx   )rq   int)r   r   r   r   rq   rN   r   r   r   get_project_issues_count_during  s    z'JiraApi.get_project_issues_count_duringc                 c   s"   |   }|std|E dH  dS )u*   Возвращает все проектыuE   Не удалось получить ни одного проектаN)Zget_all_projectsr   )r   rg   r   r   r   get_projects  s    zJiraApi.get_projectsc                 c   sb   d| d}t dddd}| j||d}|ds6d S |d E d H  |d	  t|d 7  < qd S )
Nzrest/agile/1.0/board/z/quickfilterr   r   ZrenderedBodyr   r   r   r   )r   r<   rv   )r   r   r   r   rg   r   r   r   get_board_quick_filters  s    
zJiraApi.get_board_quick_filtersc                    s"   t  |}| j|d dd}|S )Nr   all)rt   )r>   get_project_permission_schemeZget_permissionscheme)r   r   schemerC   r   r   r     s    z%JiraApi.get_project_permission_schemec                 C   sD   d| d}g }|  |}|d D ]}|| j |d dd q"|S )Nzrest/api/2/issue/z/propertieskeysr   T)absolute)r<   append)r   issue_idr   Z
propertiesrg   r   r   r   r   get_issue_properties  s    
zJiraApi.get_issue_propertiesc                    s   t  |}|d S )NZworklogs)r>   issue_get_worklog)r   r   rg   rC   r   r   r      s    zJiraApi.issue_get_worklogc                    s$   zt  |W S    i  Y S X d S r   )r>   !get_project_issue_security_scheme)r   r   rC   r   r   r     s    z)JiraApi.get_project_issue_security_schemec                 #   s$   t   D ]}| |d V  q
d S r   )r>   get_issue_security_schemesZget_issue_security_scheme)r   ZschrC   r   r   r   
  s    z"JiraApi.get_issue_security_schemesc                    s   d}ddd}g }| j s$t  }qh| j||d}||d  t||d krRqh|d  |d	 7  < q|D ]}| |d
 |d< ql|S )Nzrest/api/2/screensr   r   r   r   r   rx   r   r   r   Ztabs)r6   r>   get_all_screensr<   r   rv   get_screen_tabs)r   r   r   rg   rN   ZscrrC   r   r   r     s    

zJiraApi.get_all_screensc                    sH   z2t  |}|D ]}| j||d d|d< q|W S    g  Y S X d S )Nr   )	screen_idtab_idr   )r>   r   get_tab_fields)r   r   rN   ZtabrC   r   r   r   $  s    zJiraApi.get_screen_tabsc                 C   s$   z|  ||W S    g  Y S X d S r   )Zget_screen_tab_fields)r   r   r   r   r   r   r   -  s    zJiraApi.get_tab_fieldsc                 C   sr   g }| j rnd| jd}d}| j||d}d|kr<t|d |dg sJqn||d  |d  |d 7  < q|S )	Nr   r   z rest/api/2/issuetypescreenschemer   r   r   r   r   )r6   ru   r<   r   r   )r   resultsr   r   rN   r   r   r   get_screen_scheme3  s    zJiraApi.get_screen_schemec                 C   sT   d}d|i}| j ||d}d|kr.t|d |d d d }| |d |d	< |S )
Nz(rest/api/3/issuetypescreenscheme/projectr   r   r   r   r   ZissueTypeScreenSchemer   r   )r<   r   get_screen_scheme_issuetypes)r   r   rB   r   rN   Zscreen_schemer   r   r   get_project_screen_schemeG  s    z!JiraApi.get_project_screen_schemec                 C   s   zd}d| j |d}g }| j||d}d|kr:t|d |dg sHql||d  |d  |d 7  < q|D ]}| |d	 |d
< qp|W S    g  Y S X d S )Nz(rest/api/3/issuetypescreenscheme/mappingr   )r   r   ZissueTypeScreenSchemeIdr   r   r   r   r   ZscreenSchemeIdactions)ru   r<   r   r   get_screen_scheme_actions)r   screen_scheme_idrB   r   r   rN   resultr   r   r   r  U  s&    z$JiraApi.get_screen_scheme_issuetypesc                 C   sV   z@d}d|i}| j ||d}d|kr0t|d |d d d W S    i  Y S X d S )Nzrest/api/3/screenschemer   r   r   r   r   Zscreensr   )r   r  rB   r   rN   r   r   r   r  s  s    z!JiraApi.get_screen_scheme_actionsc                    s"   zt   W S    g  Y S X d S r   )r>   get_all_prioritiesrW   rC   r   r   r    s    zJiraApi.get_all_prioritiesc                 C   s   d| d}ddd}g }| j ||d}d|kr<t|d | dg sJq||d D ]}||d	  qR|d
  |d 7  < q|S )Nrest/api/2/priorityscheme/z	/projectsr   r:   r   r   r   r   r   r   r   )r<   r   r   )r   	scheme_idrB   r   Zproject_keysrN   r   r   r   r   get_priority_scheme_projects  s    
z$JiraApi.get_priority_scheme_projectsc                 C   sr   d| d}ddd}g }| j ||d}d|kr<t|d | dg sJqn||d  |d	  |d
 7  < q|S )Nr	  z/prioritiesr   r:   r   r   r   r   r   r   )r<   r   r   )r   r
  rB   r   
prioritiesrN   r   r   r   get_priority_scheme_priorities  s    
z&JiraApi.get_priority_scheme_priorities)rr   rs   ro   c                 C   s   | j rd}d }d}nd}d}d}i }|d k	r8t||d< |d k	rLt||d< |rX||d< g }| j||d	}||g sxq|| D ]d}	| j r| |	d
 |	d< | |	d
 |	d< n*g |	d< |	d D ]}
|	d | |
 q||	 q|d  |d 7  < q\|S )Nzrest/api/2/priorityschemer   zrest/api/2/priorityschemeszschemes.projectKeysschemesr   r   rt   r   r   ZprojectKeysr  Z	optionIds)r6   r   r<   r  r  r   Zget_priority_by_id)r   rr   rs   rB   rt   r   r   r  rN   r   Zpriority_idr   r   r   get_priority_schemes  s8    zJiraApi.get_priority_schemes)r   r   
issuetypesc                 C   s`  d}d}z| j || jd}W nl tk
r } zNd| d}t|drp|d|jj d|jj d	|jj d
| 7 }t|W 5 d }~X Y nX | d}|dkrd| d| }t|d}	d|i}
|r||
d< |r||
d< z| j |	|
d}W np tk
rZ } zPd| d}t|drB|d|jj d|jj d	|jj d
| 7 }t|W 5 d }~X Y nX |S )Nu   Установите плагин "Smart Jira Configuration" версии 4.8.12, 4.8.9, 4.8.7, 4.7.3 или 4.5.1. по ссылке https://marketplace.atlassian.com/apps/1221996/smart-jira-configuration-formerly-smart-project-config-docs/version-historyz1rest/plugins/1.0/com.eis.jira.plugins.jiradoc-key)r\   u   Для получения полной конфигурации проекта не установлен плагин "Smart Jira Configuration". z. rN   u   Код ошибки - z, z - u   , адрес запроса: version)z4.8.12z4.8.9z4.8.7z4.7.3z4.5.1u.   Неверная версия плагина (z). z-rest/smart-configuration/1.0/getProjectConfig
projectKeyr   r  r   uN   Не удалось получить конфигурацию проекта "u6   " через плагин "Smart Jira Configuration". )	r<   ra   r   r   rN   rQ   rd   textZCmfError)r   r   r   r  Z
error_textZ
plugin_urlrN   r   Zplugin_versionrB   r   r   r   r   get_project_smart_config  sF    

&

&z JiraApi.get_project_smart_configc                 C   s   d| d}ddd}i }| j ||d}d|kr<t|d | dg sJq|d D ]&}|t|d	 g }||d
  qR|d  |d 7  < q|S )Nz rest/api/2/issuesecurityschemes/z/membersr   r   r   r   r   r   ZissueSecurityLevelIdZholderr   r   )r<   r   
setdefaultstrr   )r   Zsecurity_scheme_idrB   r   Zsecurity_level_membersrN   membermembersr   r   r    get_issue_security_level_members  s    z(JiraApi.get_issue_security_level_membersc                 C   sD   d| d}|d| j d}| j||d}|dg s8dS |d d S )uR    Возвращает контекст пользовательского поляrest/api/3/field/r   r   r   r   r   r   r   Nru   r<   )r   field_id
context_idrB   r   rN   r   r   r   get_field_context(  s    zJiraApi.get_field_contextc           
   
   C   s   d| d| d}d| j d}i }z| j||d}W n< tjk
rp } z|jjdkr^W Y 
dS  W 5 d}~X Y nX |d	g }|sq|D ]}	|	||	d
 < q|d  |d 7  < q"|S )u`    Возвращает опции контекста пользовательского поля r  r   r   r   r   r   i  Nr   r   r   r   )ru   r<   rR   r   rN   rQ   )
r   r  r  rB   r   r   rN   r   r   valuer   r   r   get_field_context_option8  s$    
z JiraApi.get_field_context_optionc                 C   s~   d| d}|d| j d}g }| j||d}|dg s:qz|d D ] }|drB|t|d  qB|d  |d	 7  < q|S )
u    Возвращает сопоставленный список типов задач и контекста пользователького поля r  z/context/issuetypemappingr   r  r   r   issueTypeIdr   r   )ru   r<   r   r  )r   r  r  rB   r   r  rN   r   r   r   r   #get_field_context_issuetype_mappingT  s    
z+JiraApi.get_field_context_issuetype_mappingc           
   
   C   s   d| d}d| j d}g }z| j||d}W nN tjk
r| } z.|jjdkrhtd| d W Y 
q|W 5 d	}~X Y nX |d
g sq||d
  |d  |d 7  < qd	}|D ]0}	|	d|kr|	d   S |	dr|	d }q|S )uz    Возвращает список контекстов пользовательского поля для проекта r  z/context/projectmappingr   r   r   r   uA   Не удалось получить контексты поля u@   . Пользовательское поле не найдено.Nr   r   r   r   r   ZisGlobalContext)	ru   r<   rR   r   rN   rQ   rb   Zwarningr   )
r   r  r   rB   r   ZcontextsrN   r   Zglobal_contextr   r   r   r   !get_field_context_project_mappingl  s.    

z)JiraApi.get_field_context_project_mappingc                 c   sb   d| d}d| j d}| j||d}|dg }|s8q^|D ]
}|V  q<|d  |d 7  < qd	S )
u8    Возвращает поля конфигурации zrest/api/3/fieldconfiguration/z/fieldsr   r   r   r   r   r   Nr  )r   Zfield_configuration_idrB   r   rN   r   r   r   r   r   get_field_config_fields  s    zJiraApi.get_field_config_fieldsFc                 C   sn   d}d| j |d}g }| j||d}|dg s2qV||d  |d  |d 7  < q|rf|rf|d S |S dS )	u    Возвращает список конфигураций или конфигурацию по умолчанию при is_default=Truezrest/api/3/fieldconfigurationr   )r   r   Z	isDefaultr   r   r   r   N)ru   r<   r   )r   Z
is_defaultrB   r   Zfield_configurationsrN   r   r   r   get_field_config  s    zJiraApi.get_field_config)field_configuration_scheme_idro   c                 C   s"   d}d|i}| j ||d}|d S )u  
        Возвращает список сопоставления типа задачи и конфигурации поля

        Args:
            field_configuration_scheme_id (str): ID схемы конфигурации полей

        Returns:
            list: список сопоставления типа задачи и конфигурации поля
        z+rest/api/3/fieldconfigurationscheme/mappingZfieldConfigurationSchemeIdr   r   r   )r   r'  rB   r   rN   r   r   r   "get_field_configuration_issue_type  s    
z*JiraApi.get_field_configuration_issue_typec                 C   sD   d}d|i}| j ||d}|d d }d}| dr@|d d }|S )	uR    Возвращает схему конфигурации полей прокта z+rest/api/3/fieldconfigurationscheme/projectr   r   r   r   NZfieldConfigurationSchemer   r   )r   r   rB   r   rN   r  r'  r   r   r   &get_project_field_configuration_scheme  s    
z.JiraApi.get_project_field_configuration_schemec                 C   s"   d| }| j |dddid}|S )u   
        Получает бизнес-процесс как XML

        Args:
            name (str): название бизнес-процесса

        Returns:
            str: содержимое в формате XML
        zKsecure/admin/workflows/ViewWorkflowXml.jspa?workflowMode=live&workflowName=TZAcceptzapplication/xml)not_json_responser\   r   )r   r   rB   rN   r   r   r   get_workflow_as_xml  s    

zJiraApi.get_workflow_as_xmlc                 C   s   d}|  |S )u   
        Получает cloudId для Jira
        https://developer.atlassian.com/cloud/jira/software/rest/intro/#base-url-differences

        Returns:
            dict: результат ответа
        z_edge/tenant_infor   )r   rB   r   r   r   get_cloud_id  s    zJiraApi.get_cloud_id)r   c                 C   s    d| }ddi}| j ||dS )u   
        Получает информацию о схеме бизнес-процессов проекта

        Args:
            project_key (str): Ключ проекта

        Returns:
            dict: результат ответа
        z$rest/projectconfig/1/workflowscheme/ZoriginalTr   r   )r   r   rB   r   r   r   r   get_project_workflow_scheme  s    

z#JiraApi.get_project_workflow_scheme)cloud_idr   issue_type_idsc                    s   d| d}ddi}g }|D ]}| ||d qd|i}| j|||d}	|	d }
|	d	 }|D ]8}|d D ]* tt fd
d|
d}|rj | qjq^|S )u  
        Получает информацию бизнес-процессов
        для проектов с упрощенной конфигурацией (simplified) 

        Args:
            cloud_id (str): ID облака
            project_id (int): ID проекта
            issue_type_ids (list): список ID типов задачи

        Returns:
            list: данные бизнес-процессов
        z-gateway/api/jira/project-configuration/query/z/2/workflowZuseTransitionLinksFormatT)r"  r   ZprojectAndIssueTypes)r   rH   statuses	workflowsc                    s   | d  d kS )NZstatusReferencer   )sZworkflow_statusr   r   r   /  r   z:JiraApi.get_simplified_project_workflows.<locals>.<lambda>N)r   rm   r   r   r   )r   r.  r   r/  rB   r   Zproject_and_issue_typesZissue_type_idrH   rN   r0  r1  Zworkflowstatusr   r3  r    get_simplified_project_workflows  s2    
z(JiraApi.get_simplified_project_workflows)r   c              
   C   sf   d}d|i}z| j ||dd}W n> tjk
r^ } z|jjdkrJW Y dS |W 5 d}~X Y nX |jS )u   
        Возвращает значение настройки текущего пользователя

        Args:
            key (str): ключ настройки

        Returns:
            _type_: значение
        rest/api/2/mypreferencesr   T)r   r   r   N)r<   rR   r   rN   rQ   r  )r   r   rB   r   rN   r   r   r   r   r   9  s    


zJiraApi.get_mypreferences)r   rH   c                 C   s"   d}d|i}| j ||i |d dS )u   
        Устанавливает значение настройки текущего пользователя

        Args:
            key (str): ключ настройки
            data (str): значение настройки
        r6  r   )rH   rl   r   N)Zput)r   r   rH   rB   r   r   r   r   r   S  s    zJiraApi.set_mypreferencesc                 C   s:   d}d|i}z| j ||d W n tjk
r4   Y nX dS )u   
        Удаляет значение настройки текущего пользователя

        Args:
            key (str): ключ настройки
        r6  r   r   N)deleterR   r   )r   r   rB   r   r   r   r   r   e  s    zJiraApi.delete_mypreferences)workflow_scheme_idc                 C   s   d| }|  |S )u   
        Получает информацию о схеме бизнес-процессов

        Args:
            workflow_scheme_id (str): id схемы бизнес-процесса
        zrest/api/2/workflowscheme/r   )r   r8  rB   r   r   r   get_workflow_schemet  s    
zJiraApi.get_workflow_scheme)r   r   r   r   ro   c           	      C   sx   |  d}i }|r||d< |r&||d< |r2||d< |r>||d< | jrb|  }d|d  |d< | j||d}|d S )	u,  
        Возвращает список разрешений, указывающий, какие разрешения есть у пользователя.
        Подробную информацию о разрешениях пользователя можно получить
        в глобальном контексте, контексте проекта или задачи

        Args:
            project_id (str, optional): ID проекта. Defaults to None.
            project_key (str, optional): Ключ проекта. Defaults to None.
            issue_id (str, optional): ID задачи. Defaults to None.
            issue_key (str, optional): Ключ задачи. Defaults to None.

        Returns:
            dict: Информация о разрешениях
        Zmypermissionsr   r  ZissueIdZissueKeyr   permissionsr   )r   r6   Zget_all_permissionsr   r   r<   )	r   r   r   r   r   rB   r   Zall_permissionsr:  r   r   r   get_permissions~  s    
zJiraApi.get_permissionsc                 C   s   d}ddd}|r||d< ndddd	d
g}d ||d< g }| j||d}|dsVq||d  |d rnq|d  |d 7  < q<|S )u2  
        Получает список всех фильтров из Jira Cloud

        Args:
            expand (str, optional): параметры для получения расширенных данных. Defaults to None.

        Returns:
            list: список фильтров
        zrest/api/2/filter/searchr   r   r   rt   rq   ownerdescriptionZsharePermissionsZeditPermissionsr   r   r   ZisLastr   r   )r   r<   r   )r   rt   rB   r   Zexpand_listfiltersrN   r   r   r   get_all_filters_cloud  s,    


zJiraApi.get_all_filters_cloudc                 C   s   ddl m} d}dddddd}g }| j||| jdd}||d	}|jd
dd}|sVq|jdddidD ]"}|d}	| |	}
||
 qh|jdddsq|d  d7  < q$|S )u  
        Получает список всех фильтров из Jira Server / Data Center

        В Jira Server / Data Center нет метода API для получения списка фильтров.
        Но можно получить ID фильтров через парсинг HTML-разметки страницы фильтров
        из раздела Администрирование > Система > Фильтры,
        и затем по ID фильтре получить информацию о нем через API.

        При указании параметров "decorator" и "contentOnly" в запросе, можно получить
        только необходимую часть HTML с таблицей списка фильтров и указателем пагинации.
        В таблице выводится по 20 фильтров на странице.

        Returns:
            list: список фильтров
        r   )BeautifulSoupz+secure/admin/filters/ViewSharedFilters.jspaZnoneTr   )Z	decoratorZcontentOnlyZ
sortColumnZsortAscendingpagingOffset)r   r\   r*  ZlxmltableZ	mf_browse)r   trzdata-filter-id)Zattrsaz	icon-next)class_rA  r!   )Zbs4r@  r<   rn   findZfind_allZ
get_filterr   )r   r@  rB   r   r>  rN   ZsoupZtable_resultsZfilter_dataZ	filter_idZfilter_r   r   r   get_all_filters_server  s6    


zJiraApi.get_all_filters_serverc                 C   s   | j r|  S |  S dS )u8   
        Получает все фильтры
        N)r6   r?  rG  rW   r   r   r   get_all_filters  s    zJiraApi.get_all_filtersc                 #   s   t   }| d}| dd t   }|r<| d| n
| d |D ]2 tt fdd|d}|rv|d  d<  V  qJdS )uw   
        Получает все решения

        Yields:
            dict: данные решения
        r   r   c                    s   | d  d kS r   r   )ruZ
resolutionr   r   r   *  r   z-JiraApi.get_all_resolutions.<locals>.<lambda>Nr   r   )r>   get_all_resolutionsr   r   r   r   r   )r   Zresolutionsr   Zresolutions_untranslatedZresolution_untranslatedrC   rJ  r   rK    s$    




zJiraApi.get_all_resolutions)NrZ   )r   )r   )NNN)Nr   )r   N)r   )N)NN)N)N)r   N)r   NNN)NN)r   r4   )NN)F)NNNN)N)\r   r   r   ru   r?   rE   rO   rT   rX   rL   rj   rV   r   r   r{   r}   r2   r   r   r   listr   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  r  r  r  r  r  r  r  r  r  r!  r#  r$  r%  r&  r(  r)  r+  r,  r-  r5  r   r   r   r9  r;  r?  rG  rH  rK  __classcell__r   r   rC   r   r3   Y   s   

   %

)
*


      


	(7"
2    ()7	r3   )r   r   r   r   )r   typingr   r   r   r   r/   	functoolsr   timer   rR   r5   r	   Z	atlassianr
   Zcmf.includeZloggingZFilterr   Z	getLoggerrb   Z	addFilterr2   r3   r   r   r   r   <module>   s   

;