U
    ce`                     @   sp   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T dddZG dd dZdS )    )DictListOptionalIteratorN)wrapssleep)HTTPBasicAuth)*皙?         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_time ./modules/jira/api.py	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   r"   r   r!   r   backoff   s    -r#   c                   @   s  e Zd ZU dZdZdZe dZe dZe dZe dZ	e dZ
e dZe d	Ze d	Ze d
Ze dZe dZe dZe dZe dZe dZdZeed< eed< diddZdddejdddZdjeee edddZdke e dd d!Z!dld"d#Z"e#e$d$d% Z%e#e$d&d' Z&dme e dd(d)Z'dne e dd*d+Z(d,d- Z)d.d/ Z*d0d1 Z+dod2d3Z,e-d4d5d6Z.e/d7d8d9Z0d:d; Z1ee-d<d=d>Z2d?d@ Z3dAdB Z4dCdD Z5dpdEdFZ6edGdHdIZ7dqe e ddJdKZ8e9eef ddLdMZ:drdNdOZ;e/ddPdQZ<e e ddRdSZ=e9ee9f e e dTdUdVZ>ee?e d<dWdXZ@dYdZ ZAd[d\ ZBd]d^ ZCd_d` ZDdadb ZEdcdd ZFdedf ZGdgdh ZHdS )sJiraApid   z/rest/api/3z
rest/api/2z/searchz/workflow/searchz/statuses/searchz/issue/{issue_key}z/issue/{issue_key}/commentz/issue/{issue_key}/watchersz/users/searchz/fieldz/projectz/project/{project_key}z$/project/{project_id}/role/{role_id}z/auditing/recordz"/rest/api/3/workflowscheme/projectcloudurlNc	           
   
   C   s   ddl m}	 |r|}n|}|	||||||dt d| _dd| i| _|dsZ|d }|drh|nd	| | _|| _	|| _
|| _|| _d
| _|| _|rd| d| j | _i | _d S )Nr   )Jirai,  )r'   usernamepasswordtokenr&   
verify_ssltimeoutZsessionZAuthorizationzBearer /Zhttpzhttps://zorder by created ASCzproject = 'z' )Z	atlassianr(   cmfutilrequests_sessionconnheadersendswith
startswithr'   loginr+   r*   r,   jql
cmf_importsaved_files)
selfr'   r5   r+   r*   r&   r,   projectr7   r(   r   r   r   __init__`   s6    	
zJiraApi.__init__F<   )attachr-   )returnc                O   s   | j r6| jr6t j|t| j | j| j|d|}n t j|| j| j|d|}|sd|jddkrd| krt	| d |S )N)Zauthverifyr-   )r2   r?   r-   zapplication/jsonzContent-type errorMessages)
r5   r*   r/   r0   getr	   r,   r2   json	Exception)r9   r=   r-   r   r   resr   r   r   jira_request~   s    * "zJiraApi.jira_request)uriparamsr>   c           	      C   s  |r| d| dn| d}| | jd}tdd|}| jr| jjr| jjD ]\}|jj|rPt	|j
jd6}t| }t|tr|nd|iW  5 Q R    S Q R X qP|| jkrt	| j| d2}t| }t|tr|nd|iW  5 Q R  S Q R X t| j|  | j| j| |dd}| jrz|jd	krzd
|j d|j d|j d| j|  }| jj| t|| }| jrtj| j| j|d}||j  |  |j
| j|< t|tr|S d|iS )u    Запрос по API _z.jsonr@   z[/ '"{}]rdata
   )rH   r-      u   Код ошибки - z, z - u   , адрес запроса: )r7   parentname) replaceAPI_VERSIONresubr7   attachmentsrO   valuer3   openZfull_path_filerC   loadsread
isinstancedictr8   gdebugr'   rF   Zstatus_codereasontextloggerr   CmfErrorZmodelsZCmfAttachmentZupload_fileencodeZsave)	r9   rG   rH   rO   
attachmentfresultresponseZ
error_textr   r   r   call   s4    .((zJiraApi.callr   c                 c   sp   d}d}|p| j }| j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(    Получение всех задач r   ZrenderedFields)r6   startlimitexpandN)MAX_ISSUES_RESULT_PER_REQUESTr1   Zjql_get_list_of_ticketsr6   len)r9   rh   start_attotalmax_resultsissuesr   r   r   
get_issues   s    

zJiraApi.get_issuesc                 c   s   d}d}|p| j }| jj|| j||dd}|d s6d 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 )Nr   changelog,renderedFields)rg   rh   ri   ro   u    из rm   )rj   r1   get_issues_for_boardr6   r[   r\   rk   )r9   board_idrh   rl   rm   rn   ro   r   r   r   rr      s    
"zJiraApi.get_issues_for_boardc                 c   sJ   d}d}| j j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   2   )rs   rg   rh   values)r1   Zget_all_sprintrB   )r9   rs   rg   rh   rE   rowr   r   r   get_sprints   s    zJiraApi.get_sprintsc                 c   sJ   d}d}| j j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   rt   )	sprint_idrg   rh   ro   )r1   get_sprint_issuesrB   )r9   rx   rg   rh   rE   rv   r   r   r   ry      s    zJiraApi.get_sprint_issuesc                 c   s   d}|dkst dd|pd|d}|r0||d< | jjr| j| j | j |d }d|krjt|d |d	 svd
S |d	 E d
H  |d  t|d	 7  < |r8|d |kr8d
S q8n| j	 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,operationsrt   uG   Больше 50 за раз запросить не получится!r   startAt
maxResultsri   ZworkflowNamerH   rA   ru   Nr{   )
AssertionErrorr1   r&   rF   r'   WORKFLOW_SEARCH_URIrC   rD   rk   Zget_all_workflows)r9   namesrh   ri   rH   rE   r   r   r   get_workflows   s$    zJiraApi.get_workflowsc                 c   s   | j jrd|p| jdd}|r&||d< | j| j | j |d }|d sPdS |d E dH  |d  t|d 7  < |r&|d |kr&dS q&n&|r| j |E dH  | j 	 E dH  dS )	u.    Получение всех statuses
        r   Zusagesrz   	projectIdr}   ru   Nr{   )
r1   r&   rj   rF   r'   STATUS_SEARCH_URIrC   rk   Zget_status_for_projectZget_all_statuses)r9   rh   
project_idrH   rE   r   r   r   get_statuses   s     
zJiraApi.get_statusesc                 C   sB   d|i}| j | j | j |d }d|kr:t|d |d S )Nr   r}   rA   ru   )rF   r'   WORKFLOW_PROJECT_URIrC   rD   )r9   project_idsrH   rE   r   r   r   get_project_scheme  s
    zJiraApi.get_project_schemec                 C   s    | j  d| d}| | S )Nz/rest/api/3/workflowscheme/z	/workflowr'   rF   rC   r9   idrG   r   r   r   get_issue_type_workflow_scheme  s    z&JiraApi.get_issue_type_workflow_schemec                 C   s   | j  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}| j 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d S )Nr   )r{   r|   z/rest/api/3/workflowschemer}   rA   ru   r{   )rj   r'   rF   rC   rD   rk   )r9   rh   rH   rG   rE   r   r   r   get_workflow_scheme!  s    zJiraApi.get_workflow_scheme)r   c                 c   sb   dd|d}| j  d}| j||d }|d s6d S |d E d H  |d  t|d 7  < qd S )Nr   rt   )r{   r|   r   z#/rest/api/3/issuetypescheme/projectr}   ru   r{   )r'   rF   rC   rk   )r9   r   rH   rG   rE   r   r   r   get_issue_type_schemes/  s    zJiraApi.get_issue_type_schemes)r   c                 C   s&   d|i}| j  d}| j||d S )Nr   z/rest/api/3/issuetype/projectr}   r   )r9   r   rH   rG   r   r   r   get_issue_for_project9  s    zJiraApi.get_issue_for_projectc                 c   s>   | j jr*| j d}| | E d H  n| j  E d H  d S )Nz/rest/api/3/issuetype)r1   r&   r'   rF   rC   get_issue_typesr9   rG   r   r   r   r   >  s    zJiraApi.get_issue_types)	issue_keyr>   c                 c   s   t dddd}| jjr>| j| j | j j|d|d }n&| j| j | j j|d|d }|	dsrdS |d E dH  |d	  t
|d 7  < qdS )
u@    Получим все комментарии по задаче r   rt   renderedBodyrz   r   r}   ZcommentsNr{   )rZ   r1   r&   rF   r'   COMMENTS_URI_FORMATformatrC   COMMENTS_URI_FORMAT_BOXrB   rk   )r9   r   rH   rE   r   r   r   get_commentsE  s    (&
zJiraApi.get_commentsc                 c   sJ   d}d}| j j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   rt   )project_keyrg   rh   ru   )r1   get_all_agile_boardsrB   r9   r   rg   rh   rE   rv   r   r   r   r   R  s    zJiraApi.get_all_agile_boardsc                 c   sJ   d}d}| j j|||d}|dg s(qF||7 }|d D ]
}|V  q8qd S )Nr   rt   )keyrg   rh   ru   )r1   get_project_versions_paginatedrB   r   r   r   r   r   ]  s    z&JiraApi.get_project_versions_paginatedc                 C   s   | j |S )N)r1   get_project_components)r9   r   r   r   r   r   h  s    zJiraApi.get_project_componentsc                 c   sv   d}d}t  }|r||d< ||d< ||d< | | j | j | }||d krTqr||7 }|d D ]
}|V  qdqd S )Nr   i  Z
projectIdsoffsetrh   rm   Zrecords)rZ   rF   r'   	AUDIT_URIrC   )r9   r   rg   rh   rH   rE   rv   r   r   r   get_audit_recordsk  s    zJiraApi.get_audit_recordsr   c                 C   sP   | j jr| | jj|d}n"| | j | jj|d  }|sHg S |d S )u(   Наблюдатели по задачеr   watchers)	r1   r&   rf   WATCHERS_URI_FORMATr   rF   r'   WATCHERS_URI_FORMAT_BOXrC   )r9   r   r   r   r   r   get_watchers{  s    "zJiraApi.get_watchersc                 c   s  | j jr| j d}dddd}|r:|d |kr:||d< | j||d }|sTq|D ]}| j j|d d	d
}dtj }tj	j
jt| }|dst|d d|  | |d< n(d|d kr|d d|  | |d< |V  qX|d  t|7  < |r:|d |kr:qq:nd}d}	d}
| j j||	|
dd}|sBq|D ]}| j j|d d	d}dtj }|dst|d ddt|   | |d< n2d|d kr|d ddt|   | |d< |V  qF|	|
7 }	|r$|	|kr$qq$dS )u    Возвращает список всех пользователей, включая активных,
            неактивных и ранее удаленных, у которых есть учетная запись Atlassian.z/rest/api/3/users/searchr   r%   z"operations,groups,applicationRolesrz   r|   r}   	accountIdzgroups,applicationRoles)Z
account_idri   @emailAddressZdisplayNameNr{   .rt   T)r)   rg   rh   Zinclude_inactive_usersr   )r   ri   @   )r1   r&   r'   rF   rC   userZconfigZ
ORG_DOMAINZcmffieldsZCmfEmailZ
max_lengthrk   rB   r/   Ztranslit_stripZuser_find_by_user_string)r9   Z	limit_endrG   rH   ZusersZ	user_infoZpostfixZmax_lenr)   rg   rh   r   r   r   	get_users  sN    

$,$
zJiraApi.get_usersc                 C   s@   | j  }t }|D ]&}d|kr.|||d < q|||d < q|S )u]    Возвращает системные и настраиваемые поля задачи r   r   )r1   Zget_all_fieldsrZ   )r9   r   rE   Zfieldr   r   r   
get_fields  s    
zJiraApi.get_fieldsc                 c   s~   d}|r|| |kr|| }dj |d}| jj|d||dd}| jjrL|}n|d }|s\d S |E d H  ||7 }||krqzqd S )Nr%   "project = "{project}" ORDER BY keyr:   z*allrq   )r   rg   rh   ri   ro   )r   r1   r6   Zadvanced_mode)r9   r   rg   maxrh   r6   re   rE   r   r   r   get_all_project_issues  s    
zJiraApi.get_all_project_issuesc                 C   s*   dj |d}| jj|ddd}t|d S )Nr   r   r   r   )rg   rh   rm   )r   r1   r6   int)r9   r   r6   re   r   r   r   get_project_issues_count  s    z JiraApi.get_project_issues_countc                 c   s$   | j  }|std|E dH  dS )u*   Возвращает все проектыuE   Не удалось получить ни одного проектаN)r1   Zget_all_projectsrD   )r9   rE   r   r   r   get_projects  s    
zJiraApi.get_projects)settings_usersr>   c                 c   s   |  | jdg D ]}t }|d }|  | jj|d d}|di  D ]}td|}|sdqN|	 }|  | j
j|d |d}|d	g D ]R}	|	d
 d |krtd|	 d| ||	d
 d  d }
||
 ||
dV  qqNqdS )u8   Возвращает участников проектаrK   rO   r   )r   Zrolesz\d+$r   )r   role_idZactorsZ	actorUserr   u+   Не найден пользователь u*    участвующий в проекте r   )project_nameproject_member_emailN)rf   PROJECTS_URIrB   setPROJECT_URI_FORMATr   ru   rR   searchgroupPROJECT_ROLES_URI_FORMATr`   add)r9   r   r:   Zadded_users_to_projectr   Zproject_infoZroler   Z	role_infoZactorr   r   r   r   get_project_members  s$    
zJiraApi.get_project_membersc                 C   s0   | j | jj|dddid}|s$g S |d d S )u2   Возвращает вложения задачиr   r   rb   r}   )rf   ISSUE_URI_FORMATr   )r9   r   rT   r   r   r   get_attachments  s    zJiraApi.get_attachmentsc                 C   s.   |j dddd }| | j d| }|jS )uJ   
        Скачиваем содержимое вложения
        r.   r   )maxsplit)splitrF   r'   Zcontent)r9   r'   rG   re   r   r   r   get_attachment_content  s
    zJiraApi.get_attachment_contentc                 c   sl   | j  d| d}tdddd}| j||d }|ds@d S |d E d H  |d	  t|d 7  < q d S )
Nzrest/agile/1.0/board/z/quickfilterr   rt   r   rz   r}   ru   r{   )r'   rZ   rF   rC   rB   rk   )r9   rs   rG   rH   rE   r   r   r   get_board_quick_filters  s    
zJiraApi.get_board_quick_filtersc                 C   s$   | j |}| j j|d dd}|S )Nr   all)ri   )r1   get_project_permission_schemeZget_permissionscheme)r9   r   Zschemer   r   r   r     s    z%JiraApi.get_project_permission_schemec                 C   sP   t j| jd|d}g }| | }|d D ]}|| |d   q.|S )Nzrest/api/2/issue
propertieskeysr9   )ospathjoinr'   rF   rC   append)r9   issue_idrG   r   rE   rv   r   r   r   get_issue_properties  s    zJiraApi.get_issue_propertiesc                 C   s   | j |}|d S )NZworklogs)r1   issue_get_worklog)r9   r   rE   r   r   r   r     s    zJiraApi.issue_get_worklogc                 C   s   t j| jd}| | S )Nzrest/api/2/configuration)r   r   r   r'   rF   rC   r   r   r   r   get_jira_global_settings  s    z JiraApi.get_jira_global_settingsc                 C   s"   z| j |W S    Y dS X d S )Nr@   )r1   !get_project_issue_security_scheme)r9   r   r   r   r   r   #  s    z)JiraApi.get_project_issue_security_schemec                 c   s&   | j  D ]}| j |d V  q
d S )Nr   )r1   get_issue_security_schemesZget_issue_security_scheme)r9   Zschr   r   r   r   )  s    z"JiraApi.get_issue_security_schemes)NN)N)r   )r   )Nr   )r   N)r   )N)N)r   N)I__name__
__module____qualname__rj   rQ   ZAPI_BOX_VERSIONZISSUES_SEARCH_URIr   r   r   r   r   r   r   Z	USERS_URIZ
FIELDS_URIZFIELDS_BOX_URIr   r   r   r   r   bool__annotations__strr;   requestsZResponserF   r   rZ   rf   r   rp   rr   r#   rD   rw   ry   r   r   r   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$   F   sx   
















	#






1
	
r$   )r   r   r   r   )typingr   r   r   r   r    	functoolsr   timer   r   Zrequests.authr	   Zcmf.includer#   r$   r   r   r   r   <module>   s   
;