U
    ygQ                     @   sT   d dl mZ d dlmZmZ d dlT d dlZd dlmZ e	
dZG dd dZdS )	    )HTTPBasicAuth)urlparse	parse_qsl)*N)ApiNotFoundErrorzatlassian.rest_clientc                	   @   s  e Zd ZdZdZe dZdZdZeeeee	e	dddd	Z
eddejfd
dZddddZdOddZdPddZdd Zdd Zdd Zdd Zdd Zd d! ZdQeeeeed$d%d&ZdReeed'd(d)ZdSed*d+d,Zed-d. ZdTd/d0Z dUd1d2Z!dVd3d4Z"dWd5d6Z#d7d8 Z$d9d: Z%d;d< Z&d=d> Z'dXeeeed?d@dAZ(dYeeeeeeedDdEdFZ)dZdHdIZ*dJdK Z+edLdMdNZ,dS )[ConfluenceApiuK    Подключение по API к учетной записи Confluence z/rest/api/3z/user   zrest/api/user/bulk/migrationN)urllogintokenpasswordcloud
verify_sslreturnc              	   C   s   ddl m} |r|}n|}|ds,|d }|dr:|nd| | _|||||||t d| _dd| i| _|| _	|| _
|| _|| _|| _d S )	Nr   )
Confluence/httpzhttps://)r	   usernamer   r   r   r   ZsessionZAuthorizationzBearer )Z	atlassianr   endswith
startswithr	   cmfutilrequests_sessionconnheadersr
   r   r   r   )selfr	   r
   r   r   r   r   r    r   ./modules/confluence/api.py__init__   s,    
zConfluenceApi.__init__c                 C   s^   ddd}|p|}dj | ddd | D |s6dnd t||d	}tj||d
 dS )z

        :param method:
        :param url:
        :param data:
        :param headers:
        :param level:
        :return:
        application/json)zContent-TypeAcceptz5curl --silent -X {method} -H {headers} {data} '{url}'z -H c                 S   s   g | ]\}}d  ||qS )z
'{0}: {1}')format).0keyvaluer   r   r   
<listcomp>8   s     z0ConfluenceApi.log_curl_debug.<locals>.<listcomp> z--data '{0}')methodr   datar	   )levelmsgN)r    joinitemsZjsondumpsloggerlog)r&   r	   r'   r   r(   Zdefault_headersmessager   r   r   log_curl_debug)   s    
zConfluenceApi.log_curl_debugZGET)r&   c                O   sl   | j |d ||dd | jrJ| jrJt j|| j| jf| jd|S t j|| j| jd|S d S )Nr   params)r	   r&   r'   )authverify)r   r3   )r0   getr
   r   r   r   r   r   )r   r&   argskwargsr   r   r   confluence_request>   s    $z ConfluenceApi.confluence_requestc                 c   sp   |r|d }|d |d  }nd}d}| j j|||d}|rl|dsHql|d D ]
}|V  qP|rbql||7 }q&dS )u   
        Получим все пространства из Confluence

        :return: Список всех пространств
        r      d   )
space_typestartlimitresultsN)r   get_all_spacesr4   )r   r:   slicer;   r<   resrowr   r   r   r>   E   s    zConfluenceApi.get_all_spacesr   r9   c                 c   sX   |r|| |kr|| }| j j|||||d}|E dH  ||7 }|rL||ksT|s qTq dS )u}   
        Получим все документы из пространства со списком потомков
        )r;   r<   statusexpandN)r   get_all_pages_from_space)r   r"   r;   r<   maxrB   rC   r@   r   r   r   rD   ]   s    
z&ConfluenceApi.get_all_pages_from_spacec                 C   s   t dd | |dD S )Nc                 S   s   g | ]}d qS )r8   r   r!   objr   r   r   r$   m   s     z<ConfluenceApi.get_count_pages_from_space.<locals>.<listcomp>r   )lenrD   )r   r"   r   r   r   get_count_pages_from_spacel   s    z(ConfluenceApi.get_count_pages_from_spacec              
   c   s   t ddd}|||< d}zF| jj||d}|ds:W d S |d E d H  |d  |d 7  < W q tjk
r } z td	| d
|  W Y d S d }~X Y qX qd S )Nr      r;   r<   zrest/api/user/memberofr1   r=   r;   r<   uL   Не удалось получить группы пользователя "". )dictr   r4   requestsZ	HTTPErrorr-   warning)r   r"   r#   r1   r	   r@   Zhttp_errr   r   r   user_member_ofo   s    
zConfluenceApi.user_member_ofc              
   C   sT   z| j |}W n> tk
rN } z td| d|  t }W 5 d }~X Y nX |S )NuL   Не удалось получить данные пользователя "rM   )r   Zget_mobile_parameters	Exceptionr-   rP   rN   )r   r   infoerrorr   r   r   get_user_detail   s    zConfluenceApi.get_user_detailc                 #   s~  | j jrtddddd}| j jd|d}|d s4d S |d D ]\}|d	  | j d
 d}  fdd| D  dd | d
 d
 D  d<  V  q<|d  |d 7  < qntddddd}| j jf |}|d sd S |d D ]~}|d	 d dkrt	
d q|d	  | j|d	 d d}  fdd| D  dd | d d D  d<  V  q|d  |d 7  < qd S )Nr   rJ   zuser=""zoperations,personalSpace)r;   r<   cqlrC   zrest/api/search/userrL   r=   user	accountIdr   c                 3   s*   | ]"\}}| ks|d kr||fV  qdS r%   Nr   r!   kvrW   r   r   	<genexpr>   s     z.ConfluenceApi.get_all_users.<locals>.<genexpr>c                 S   s   g | ]}|qS r   r   r!   gr   r   r   r$      s     z/ConfluenceApi.get_all_users.<locals>.<listcomp>groupsr;   r<   z	type=userz&user.operations,user.status,user.emailr   Zrecovery_adminu   В вашем Confluence включен режим восстановления! Не оставляйте Confluence в режиме восстановления и не используйте учетную запись recovery_admin!c                 3   s*   | ]"\}}| ks|d kr||fV  qdS rZ   r   r[   r^   r   r   r_      s     c                 S   s   g | ]}|qS r   r   r`   r   r   r   r$      s     )r   r   rN   r4   rU   updater+   rQ   rV   r-   rP   )r   r1   r@   rA   Z	user_infor   r^   r   get_all_users   s4    
zConfluenceApi.get_all_usersc                 c   sF   t ddd}| jjf |}|s"d S |E d H  |d  |d 7  < qd S )Nr   rJ   rK   r;   r<   )rN   r   get_all_groups)r   r1   r@   r   r   r   re      s    
zConfluenceApi.get_all_groupsc                 c   sP   t dd|dd}| jjf |}|s&d S |D ]
}|V  q*|d  |d 7  < qd S )Nr   rJ   zoperations,status)r;   r<   
group_namerC   r;   r<   )rN   r   get_group_members)r   rf   r1   r@   rA   r   r   r   rg      s    zConfluenceApi.get_group_membersrJ   T)
content_idr;   r<   rC   r   c                 c   s  d| d}i }|dk	r$t ||d< |dk	r8t ||d< |dk	rH||d< |sTd|d< | jj||d	}|d
 D ]0}	|rdd | j|	d ||dD |	d< |	V  ql|d }
|
d}|sqt|}tt|j}|d |d< |dr|d|d< |drT|d|d< qTdS )u  
        Получает все комментарии к документу

        Args:
            content_id (str): ID страницы(документа) в Confluence
            expand (str): Cвойства элемента, которые нужно расширить, например, expand='body,version,history'
            children (bool): Создать иерархическую структуру с дочерними элементами

        Yields:
            Iterator[list]: элемент
        rest/api/content/z/child/commentNr;   r<   rC   alldepthrL   r=   c                 S   s   g | ]}|qS r   r   rF   r   r   r   r$      s     z3ConfluenceApi.get_page_comments.<locals>.<listcomp>id)rC   childrenrm   _linksnextcursor)intr   r4   get_page_commentsr   rN   r   query)r   rh   r;   r<   rC   rm   r	   r1   r@   resultlinksnext_
next_parsers   r   r   r   rr      s:    


zConfluenceApi.get_page_comments)	key_spacerC   r   c                 c   s   d}d}| j j|d|||dd}|d D ]X}|drzdd	 | |d
 D |d d d< t|d d d |d d d< |V  q(|d sq||7 }qdS )ui  
        Получим все документы из корня пространства.

        :param key_space: Идентификатор пространства.
        :param expand: Дополнительные данные по документам.

        :return: Соответствие id документа и его данных.
        r   2   rootpage)rk   rC   r;   r<   Zcontent_typer=   rm   c                 S   s   g | ]}|qS r   r   rF   r   r   r   r$      s     z;ConfluenceApi.get_root_pages_from_space.<locals>.<listcomp>rl   sizeN)r   Zget_space_contentr4   get_childrenrH   )r   rx   rC   r;   r<   r@   rA   r   r   r   get_root_pages_from_space   s    	
$ z'ConfluenceApi.get_root_pages_from_spacerC   c                 c   s\   t |||d}| jj|f|}|rX|ds.qX|d D ]
}|V  q6|d  |d 7  < qd S )N)r;   r<   rC   r=   r;   r<   )rN   r   Zget_attachments_from_contentr4   )r   page_idr;   r<   rC   r1   r@   rA   r   r   r   get_all_attachment  s    z ConfluenceApi.get_all_attachmentc           	      C   sL   t ||}ddi}t| jD ]*}t j||||dd}|jdkr qHq|S )Nr   r   
   )r2   r1   r   timeout   )r   rangeRETRY_COUNTr   r   r4   Zstatus_code)	clsr
   r   r	   r1   r2   r   ir@   r   r   r   call  s    
   
zConfluenceApi.callc                 C   s.   z| j j||dW S  tk
r(   Y d S X d S )N)userkeyrC   )r   Zget_user_details_by_userkeyr   )r   r   rC   r   r   r   get_user_info_by_key  s    z"ConfluenceApi.get_user_info_by_keyc                 C   s   | j jr| j j||dS d S )Nr   )r   r   get_user_details_by_accountid)r   rX   rC   r   r   r   get_user_info%  s    zConfluenceApi.get_user_infoc                 C   sX   z<| j jr,| j|d}| j j|d |dW S | j j||dW S  tk
rR   Y d S X d S )NrY   rX   )Z	accountidrC   )r   rC   )r   r   get_account_idr   Zget_user_details_by_usernamer   )r   r   rC   rW   r   r   r   get_user_info_by_username)  s    z'ConfluenceApi.get_user_info_by_usernamec                 C   s4   |rd|i}nd|i}| j j| j|d}|d d S )Nr   r   rL   r=   r   )r   r4   USER_ACCOUNTS_ID_URI)r   r   r   r1   r@   r   r   r   r   2  s
    
zConfluenceApi.get_account_idc                 O   s`   | j j|f||}d|ddkr\dd | |D }||d d d< t||d d d	< |S )
Nzchildren.pagerC   r%   c                 S   s   g | ]}|qS r   r   rF   r   r   r   r$   D  s     z0ConfluenceApi.get_page_by_id.<locals>.<listcomp>rm   r{   r=   r|   )r   get_page_by_idr4   r}   rH   )r   rl   r5   r6   r{   rm   r   r   r   r   <  s    zConfluenceApi.get_page_by_idc                 c   s8   d}d}| j j|||d}|s q4|E d H  ||7 }qd S )Nr   ry   rK   )r   Zget_page_child_by_type)r   Z	parent_idr;   r<   r@   r   r   r   r}   I  s    
zConfluenceApi.get_childrenc                 c   s&   t | j| d d E d H  d S )N)listr    get_all_restrictions_for_contentvalues)r   r   r   r   r   r   S  s    z.ConfluenceApi.get_all_restrictions_for_contentc                 c   sV   t dd|d}| jjf |}|d E d H  |d  |d 7  < |d |d k rqRqd S )Nr   r9   )r;   r<   r   r=   r;   r<   r|   )rN   r   Zget_page_labels)r   r   r1   r@   r   r   r   get_all_page_labelsV  s    z!ConfluenceApi.get_all_page_labels)rh   version_numberrC   r   c                 C   sN   | j jrd| d| }nd| d| }i }|dk	r>||d< | j j||dS )u  
        Получает определенную версию документа

        Args:
            content_id (str): ID страницы(документа) в Confluence
            version_number (int): номер версии страницы(документа)
            expand (str): Cвойства элемента, которые нужно расширить, например, expand='body,version,history'

        Return:
            dict: данные версии документа
        ri   z	/version/rest/experimental/content/NrC   rL   )r   r   r4   )r   rh   r   rC   r	   r1   r   r   r   get_page_version`  s    zConfluenceApi.get_page_version   r   )rh   current_versionr;   r<   last_versionsrC   r   c                 c   s  |sdS | j jrd| d}nd| d}i }|dk	rBt||d< |dk	rVt||d< |dk	rf||d< d}	zn| j j||d	}
|
d
 }|d}|
d D ]>}|	d7 }	d|  kr|	k rn nd} q|d d }|V  qW n   t|ddD ]~}|	d7 }	d|  kr|	k rn n qlz| |||V  W q tk
rh } ztd| d| V  W 5 d}~X Y qX qd}Y nX |sqt|}tt	|j
}|d |d< |dr|d|d< |drj|d|d< qjdS )u  
        Получает версии страницы (историю документа)
        При большом количестве данных в версиях, limit > 5 может не работать,
        зависает, либо падает с ошибкой по таймауту.
        Получение версий списком может упасть с ошибкой 500 "Internal Server Error", если в ответе будет кривая версия.
        При получении ошибки при запросе списков, пытаемся получить версии по одной.

        Args:
            content_id (str): ID страницы(документа) в Confluence
            current_version (int): номер текущй версии страницы(документа)
            last_versions (int): колчество послених версий для получения, при "-1" - получение всех версий
            expand (str): Cвойства элемента, которые нужно расширить, например, expand='body,version,history'

        Yields:
            Iterator[list]: элемент
        Nri   z/versionr   r;   r<   rC   r   rL   rn   ro   r=   r8   Fnumberr   u   версия z. rp   )r   r   rq   r4   r   r   rR   r   rN   r   rs   )r   rh   r   r;   r<   r   rC   r	   r1   Zversion_countr@   ru   rv   versionr   excrw   rs   r   r   r   get_page_versionsw  sV    
*

zConfluenceApi.get_page_versionsry   c                 c   s   d}i }|d k	r||d< |d k	r,t ||d< |d k	r@t ||d< |d k	rP||d< | jj||d}|d D ]
}|V  qh|d }	|	d	}
|
sqt|
}tt|j}|d |d< |d
r|d
|d
< |d	rP|d	|d	< qPd S )Nzrest/api/content/searchrV   r;   r<   rC   rL   r=   rn   ro   rp   )rq   r   r4   r   rN   r   rs   )r   rV   r;   r<   rC   r	   r1   r@   Zcontentru   rv   rw   rs   r   r   r   content_cql  s0    


zConfluenceApi.content_cqlc                 C   sP   | j jr$| j j|dd}|dg S d}ddd|gd}| j j||dd	g S )
NZpermissions)	space_keyrC   z!rpc/json-rpc/confluenceservice-v2z2.0ZgetSpacePermissionSets   )Zjsonrpcr&   rl   r1   )r'   rt   )r   r   Z	get_spacer4   Zpost)r   r   Z
space_datar	   r'   r   r   r   get_space_permissions  s    z#ConfluenceApi.get_space_permissions)r   c                 C   s   d}| j |S )u   
        Получает связи с другими системами

        Return:
            applinks (dict): данные связей с другими системами
        zrest/applinks/3.0/applinks)r   r4   )r   r	   r   r   r   get_applinks  s    zConfluenceApi.get_applinks)NN)r   r9   NNN)r   rJ   NT)N)r   rJ   N)N)N)N)NN)N)r   r   r   N)r   ry   N)-__name__
__module____qualname____doc__ZAPI_VERSIONZUSER_URIr   r   strboolr   staticmethodloggingDEBUGr0   r7   r>   rD   rI   rQ   rU   rd   re   rg   rq   r   rr   rN   r~   r   classmethodr   r   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   	   sp   


	#	        1



	



    S
!r   )Zrequests.authr   urllib.parser   r   Zcmf.includerO   Zatlassian.errorsr   r   Z	getLoggerr-   r   r   r   r   r   <module>   s   
