
    "ehdR                         d dl mZmZ d dlT d dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZ e                    d          Z G d	 d
e          ZdS )    )urlparse	parse_qsl)*N)HTTPAdapter)Retry)
Confluence)ApiNotFoundErrorzatlassian.rest_clientc                       e Zd ZdZddej        de                                ddf fd	Zd Z	d Z
d Zd	 Z fd
Zd3dZd4 fd	Zd5dZd Zd Zd Z fdZ fdZ	 	 d6dededededef
dZd7dededefd Zd8defd!Zd7d"Zd7d#Zd7d$Zd4d%Z  fd&Z!d' Z" fd(Z#d) Z$d7ded*ededefd+Z%	 	 	 	 d9ded.ededed/ededefd0Z&d1 Z'defd2Z( xZ)S ):ConfluenceApiuK    Подключение по API к учетной записи Confluence NTFc	                    |                     d          r|nd| }|                    d          s|dz  }|r|}nd } t                      j        |f|||||||d|	 |                                  t
          j        j        | _        dt          |          j	         | _
        d | _        |                                  d S )Nhttphttps:///)usernamepasswordtimeout
verify_sslsessioncloudtokenzCONFLUENCE:COOKIE:)
startswithendswithsuper__init___set_session_retriesAPPREDIS_DBredisr   netloc	redis_keycookies_dict_init_cookies)selfurlr   r   r   r   r   r   r   kwargs	__class__s             ./modules/confluence/api.pyr   zConfluenceApi.__init__   s     ^^F++Acc1AC1A1A||C   	3JC 	HHE
	
!
	
 
	
 
	
 
	
 
	
 	!!###\'
Dhsmm.BDD     c                     t          t          j        t          j        d          }| j                            dt          |                     | j                            dt          |                     dS )u   
        Конфигурирует стратегию повторных попыток
        и ассоциирует ее с сессией
           )totalstatus_forcelistbackoff_factorzhttp://)max_retriesr   N)r   configIMPORT_REQUEST_RETRY_TOTAL!IMPORT_REQUEST_RETRY_STATUS_CODES_sessionmountr   )r#   retriess     r'   r   z"ConfluenceApi._set_session_retries9   su    
 3#E
 
 

 	I{w'G'G'GHHHJ(H(H(HIIIIIr(   c                 &   | j                             | j                  }|ro	 t          j        |          }| j        j                            |           | j        j                                        | _	        dS # t          j
        $ r Y dS w xY wdS )u  
        Добавляет cookie в сессию при инициализации,
        что бы не выполнять повторную авторизацию, если cookie еще действуют.
        При недействительных cookie, выполнится авторизация,
        а cookie обновятся в сессии и кеше
        N)r   getr    pickleloadsr2   cookiesupdateget_dictr!   PickleError)r#   cookies_pickler9   s      r'   r"   zConfluenceApi._init_cookiesF   s     77 	 ,~66%,,W555$(M$9$B$B$D$D!!!%   	 	s   AA; ;BBc                     t          j        | j        j                  }| j                            | j        |d           dS )u   
        Сохраняет cookie в кеш (Redis) для последующего использования
        без выполнения повторной авторизации
        i`T  )exN)r7   dumpsr2   r9   r   setr    )r#   r=   s     r'   _save_cookieszConfluenceApi._save_cookiesV   s:    
  dm&;<<
t~~+FFFFFr(   c                     | j         j                                        }| j        |k    r|| _        |                                  dS dS )u   
        Проверяет изменение cookie и обновляет их в кеше при необходимости
        N)r2   r9   r;   r!   rB   )r#   current_cookies_dicts     r'   _check_cookieszConfluenceApi._check_cookies^   sR      $}4==?? 444 4D      54r(   c                 b     t                      j        |i |}|                                  |S N)r   requestrE   )r#   argsr%   responser&   s       r'   rH   zConfluenceApi.requestg   s4    "577?D3F33r(      c           	         | j         }|p| j        }|                     d||           | j                            |d||| j        | j                  5 }t                              d| d|j	         d|j
                    |                                 t          |d          5 }|                    |	          D ]}|                    |           	 d
d
d
           n# 1 swxY w Y   d
d
d
           d
S # 1 swxY w Y   d
S )us  
        Скачивает файл

        Args:
            download_url (_type_): url файла для скачивания
            save_path (_type_): путь для сохранения файла
            timeout (_type_, optional): Таймаут. Defaults to None.
            chunk_size (_type_, optional): _description_. Defaults to 64*1024.
        GET)methodr$   headersT)streamrO   r   verifyproxiesz
HTTP: GET z ->  zwb+)
chunk_sizeN)no_check_headersr   log_curl_debugr2   r6   r   rR   loggerdebugstatus_codereasonraise_for_statusopeniter_contentwrite)	r#   download_url	save_pathr   rT   rO   resfchunks	            r'   download_filezConfluenceApi.download_filel   s    ')T\5lGLLL]?L  
 
 	# LLVlVVVV#*VVWWW  """i'' #1 ---DD # #EGGENNNN## # # # # # # # # # # # # # #	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s7   AC9%/C!C9!C%	%C9(C%	)C99C= C=c              #      K   |r|d         }|d         |d         z
  }nd}d}	 t                                          |||          }|r|                    d          sdS |d         D ]}|V  |rdS ||z  }V)u   
        Получим все пространства из Confluence

        :return: Список всех пространств
        r   r*   d   T)
space_typestartlimitresultsN)r   get_all_spacesr6   )r#   rg   slicerh   ri   ra   rowr&   s          r'   rk   zConfluenceApi.get_all_spaces   s        	!HE!HuQx'EEEE
	''((JeSX(YYC cggi00 9~  				 UNE
	r(   r   rf   archivedpagec              #   `   K   	 |                      |||||          }|sdS |E d{V  ||z  },)ud   
        Получает архивные документы из пространства
        T)content_typeN)get_all_pages_from_space)r#   spacerh   ri   statusrq   ra   s          r'    get_all_pages_from_space_archivez.ConfluenceApi.get_all_pages_from_space_archive   sV      	//ueVZf/ggC NNNNNNNUNE	r(   c              #   \  K   t          dd          }|||<   d}	 	 |                     ||          }|                    d          sd S |d         E d {V  |dxx         |d	         z  cc<   n=# t          j        $ r+}t                              d
| d|            Y d }~d S d }~ww xY w)Nr      rh   ri   zrest/api/user/memberofTparamsrj   rh   ri   uL   Не удалось получить группы пользователя "". )dictr6   requests	HTTPErrorrW   warning)r#   keyvaluerz   r$   ra   http_errs          r'   user_member_ofzConfluenceApi.user_member_of   s     AR(((s&		hhs6h22wwy)) Fy>)))))))w6'?2%      Cns   C   C  yA   C   C  D  D  D		s   ,A0 $A0 0B*? B%%B*c                     	 |                      |          }nE# t          $ r8}t                              d| d|            t	                      }Y d }~nd }~ww xY w|S )NuL   Не удалось получить данные пользователя "r{   )get_mobile_parameters	ExceptionrW   r   r|   )r#   r   infoerrors       r'   get_user_detailzConfluenceApi.get_user_detail   sz    	--h77DD 	 	 	NN~jr~~w|~~66DDDDDD	 s    
A.AAc              #     K   | j         rt          dddd          }	 |                     d|          }|d	         sd S |d	         D ]}|d
         |                     d                   }                    fd|                                D                        d |                     dd                   D             d<   V  |dxx         |d         z  cc<   t          dddd          }	  | j        di |}|d	         sd S |d	         D ]}|d
         d         dk    rt          	                    d           /|d
         |                     |d
         d                   }                    fd|                                D                        d |                     dd                   D             d<   V  |dxx         |d         z  cc<   )Nr   rw   zuser=""zoperations,personalSpace)rh   ri   cqlexpandTzrest/api/search/userry   rj   user	accountIdr   c              3   :   K   | ]\  }}|vs|d k    ||fV  dS  N .0kvr   s      r'   	<genexpr>z.ConfluenceApi.get_all_users.<locals>.<genexpr>   D        =  =41a#$D==AGG "#A4;GGG =  =r(   c                     g | ]}|S r   r   r   gs     r'   
<listcomp>z/ConfluenceApi.get_all_users.<locals>.<listcomp>   s    %e%e%eAa%e%e%er(   groupsrh   ri   z	type=userz&user.operations,user.status,user.emailr   recovery_adminu   В вашем Confluence включен режим восстановления! Не оставляйте Confluence в режиме восстановления и не используйте учетную запись recovery_admin!c              3   :   K   | ]\  }}|vs|d k    ||fV  dS r   r   r   s      r'   r   z.ConfluenceApi.get_all_users.<locals>.<genexpr>   r   r(   c                     g | ]}|S r   r   r   s     r'   r   z/ConfluenceApi.get_all_users.<locals>.<listcomp>   s    %c%c%cAa%c%c%cr(   r   )
r   r|   r6   r   r:   itemsr   r   rW   r   )r#   rz   ra   rm   	user_infor   s        @r'   get_all_userszConfluenceApi.get_all_users   s     :  	3C]^^^F3hh5fhEE9~ Fy>  Cv;D $ 4 4d;>O 4 P PIKK  =  =  =  =9??3D3D  =  =  = = = =%e%e1D1D[RVWbRc1d1d%e%e%eDNJJJJw6'?23 EmnnnF3dh((((9~ Fy>  C6{:.2BBB (t u u u !v;D $ 4 4c&k*>U 4 V VIKK  =  =  =  =9??3D3D  =  =  = = = =%c%c1D1DZQUV`Qa1b1b%c%c%cDNJJJJw6'?2!3r(   c              #      K   t          dd          }	  t                      j        di |}|sd S |E d {V  |dxx         |d         z  cc<   <)Nr   rw   rx   Trh   ri   r   )r|   r   get_all_groups)r#   rz   ra   r&   s      r'   r   zConfluenceApi.get_all_groups   sw      AR(((	/(%''(22622C NNNNNNN7OOOvg.OOO	/r(   c              #      K   t          dd|d          }	  t                      j        di |}|sd S |D ]}|V  |dxx         |d         z  cc<   =)	Nr   rw   zoperations,status)rh   ri   
group_namer   Trh   ri   r   )r|   r   get_group_members)r#   r   rz   ra   rm   r&   s        r'   r   zConfluenceApi.get_group_members   s      ARJGZ[[[	/+%''+55f55C   				7OOOvg.OOO	/r(   rw   
content_idrh   ri   r   returnc              #     K   d| d}i }|t          |          |d<   |t          |          |d<   |||d<   |sd|d<   	 |                     ||
          }|d         D ]3}	|r+d |                     |	d         ||          D             |	d<   |	V  4|d         }
|
                    d          }|sdS t          |          }t	          t          |j                            }|d         |d<   |                    d          r|                    d          |d<   |                    d          r|                    d          |d<   )u  
        Получает все комментарии к документу

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

        Yields:
            Iterator[list]: элемент
        rest/api/content/z/child/commentNrh   ri   r   alldepthTry   rj   c                     g | ]}|S r   r   r   objs     r'   r   z3ConfluenceApi.get_page_comments.<locals>.<listcomp>  s*     *d *d *d## *d *d *dr(   id)r   childrenr   _linksnextcursor)intr6   get_page_commentsr   r|   r   query)r#   r   rh   ri   r   r   r$   rz   ra   resultlinksnext_
next_parser   s                 r'   r   zConfluenceApi.get_page_comments   s      =*<<<!%jjF7O!%jjF7O%F8 	$#F7O	3((3v(..Ci.   d*d *d9O9OPVW[P\W]Ya :P :c :c *d *d *dF:& MEIIf%%E !%J:#34455E#GnF7Oyy"" 7#(99X#6#6x yy   3!&6!2!2v-	3r(   	key_spacec              #   v  K   d}d}	 |                      |d|||d          }|d         D ]}|                    d          rdd	 |                     |d
                   D             |d         d         d<   t          |d         d         d                   |d         d         d<   |V  |d         sdS ||z  })ui  
        Получим все документы из корня пространства.

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

        :return: Соответствие id документа и его данных.
        r   2   Trootro   )r   r   rh   ri   rq   rj   r   c                     g | ]}|S r   r   r   s     r'   r   z;ConfluenceApi.get_root_pages_from_space.<locals>.<listcomp><  s    9f9f9f##9f9f9fr(   r   sizeN)get_space_contentr6   get_childrenlen)r#   r   r   rh   ri   ra   rm   s          r'   get_root_pages_from_spacez'ConfluenceApi.get_root_pages_from_space,  s       
	((&W\di;A ) C CC9~  77:&& ^9f9fIZIZ[^_c[dIeIe9f9f9fC
OF+I669#j/&:QR[:\6]6]C
OF+F3				y> UNE
	r(   c              #      K   t          |||          }	  | j        |fi |}|r|                    d          sd S |d         D ]}|V  |dxx         |d         z  cc<   M)N)rh   ri   r   Trj   rh   ri   )r|   get_attachments_from_contentr6   )r#   page_idrh   ri   r   rz   ra   rm   s           r'   get_all_attachmentz ConfluenceApi.get_all_attachmentC  s      Ev>>>	/3$3GFFvFFC cggi00 9~  				7OOOvg.OOO	/r(   c                 T    	 |                      ||          S # t          $ r Y d S w xY w)N)userkeyr   )get_user_details_by_userkeyr	   )r#   r   r   s      r'   get_user_info_by_keyz"ConfluenceApi.get_user_info_by_keyN  sB    	33GF3SSS 	 	 	44	s    
''c                 B    | j         r|                     ||          S d S )N)r   )r   get_user_details_by_accountid)r#   r   r   s      r'   get_user_infozConfluenceApi.get_user_infoT  s2    : 	P55i5OOO	P 	Pr(   c                     	 | j         r3|                     |          }|                     |d         |          S |                     ||          S # t          $ r Y d S w xY w)Nr   r   )	accountidr   )r   r   )r   get_account_idr   get_user_details_by_usernamer	   )r#   r   r   r   s       r'   get_user_info_by_usernamez'ConfluenceApi.get_user_info_by_usernameX  s    	z f**H*==99DDU^d9eee44hv4VVV 	 	 	44	s   9A A 
A! A!c                 f    d}|rd|i}nd|i}|                      ||          }|d         d         S )Nzrest/api/user/bulk/migrationr   r   ry   rj   r   r6   )r#   r   r   r$   rz   ra   s         r'   r   zConfluenceApi.get_account_ida  sI    , 	* (+FF)Fhhs6h**9~a  r(   c                     t                      j        |g|R i |}d|                    dd          v rNd |                     |          D             }||d         d         d<   t	          |          |d         d         d<   |S )	Nzchildren.pager   r   c                     g | ]}|S r   r   r   s     r'   r   z0ConfluenceApi.get_page_by_id.<locals>.<listcomp>s  s    BBBBBBr(   r   ro   rj   r   )r   get_page_by_idr6   r   r   )r#   r   rI   r%   ro   r   r&   s         r'   r   zConfluenceApi.get_page_by_idk  s     &uww%g??????fjj26666BBt'8'8'A'ABBBH2:DV$Y//28}}DV$V,r(   c              #   d   K   d}d}	 |                      |||          }|sd S |E d {V  ||z  }*)Nr   rw   Trx   )get_page_child_by_type)r#   	parent_idrh   ri   ra   s        r'   r   zConfluenceApi.get_childrenx  s[      	--iuE-RRC NNNNNNNUNE	r(   c              #      K   t          t                                          |                                                    d d         E d {V  d S )N)listr    get_all_restrictions_for_contentvalues)r#   r   r&   s     r'   r   z.ConfluenceApi.get_all_restrictions_for_content  sW      @@IIPPRRSSTWUWTWXXXXXXXXXXr(   c              #      K   t          dd|          }	  | j        d	i |}|d         E d {V  |dxx         |d         z  cc<   |d         |d         k     rd S F)
Nr   rf   )rh   ri   r   Trj   rh   ri   r   r   )r|   get_page_labels)r#   r   rz   ra   s       r'   get_all_page_labelsz!ConfluenceApi.get_all_page_labels  s      AS':::	&$&0000C9~%%%%%%%7OOOvg.OOO6{VG_,,	r(   version_numberc                 r    | j         r	d| d| }nd| d| }i }|||d<   |                     ||          S )u  
        Получает определенную версию документа

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

        Return:
            dict: данные версии документа
        r   z	/version/rest/experimental/content/Nr   ry   )r   r6   )r#   r   r   r   r$   rz   s         r'   get_page_versionzConfluenceApi.get_page_version  sf     : 	UKjKK>KKCCTzTTNTTC%F8xxFx+++r(      r   current_versionlast_versionsc           	   #     K   |sdS | j         rd| d}nd| d}i }|t          |          |d<   |t          |          |d<   |||d<   d}		 	 |                     ||
          }
|
d         }|                    d          }|
d         D ]*}|	dz  }	d|cxk    r|	k     rn nd} n|d         dz
  }|V  +n|#  t          |dd          D ]a}|	dz  }	d|cxk    r|	k     rn n nI	 |                     |||          V  4# t
          $ r!}t          d| d|           V  Y d}~Zd}~ww xY wd}Y nxY w|sdS t          |          }t          t          |j	                            }|d         |d<   |                    d          r|                    d          |d<   |                    d          r|                    d          |d<   )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]: элемент
        Nr   z/versionr   rh   ri   r   r   Try   r   r   rj   r*   Fnumberr   u   версия z. r   )
r   r   r6   ranger   r   r   r|   r   r   )r#   r   r   rh   ri   r   r   r$   rz   version_countra   r   r   versionr   excr   r   s                     r'   get_page_versionszConfluenceApi.get_page_versions  s     2  	4: 	D:j:::CCCzCCCC!%jjF7O!%jjF7O%F8'	3hhs6h22H		&))"9~ " "G!Q&MM9999M99999 %&-h&7!&;O!MMMM&+OQ&C&C Q QN!Q&MM9999M99999Q"33JPVWWWWWW$ Q Q Q'(O(O(O#(O(OPPPPPPPPPPQ  !%J:#34455E#GnF7Oyy"" 7#(99X#6#6x yy   3!&6!2!2vO'	3s7   A'B8 8,D1%C?>D1?
D*	D% D1%D**D1c                     | j         r-|                     |d          }|                    dg           S d}ddd|gd}|                     ||                              d	g           S )
Npermissions)	space_keyr   z!rpc/json-rpc/confluenceservice-v2z2.0getSpacePermissionSets   )jsonrpcrN   r   rz   )datar   )r   	get_spacer6   post)r#   r   
space_datar$   r   s        r'   get_space_permissionsz#ConfluenceApi.get_space_permissions  s|    : 	5)MRRJ>>-4441. k	
 
 yy4y((,,Xr:::r(   c                 0    d}|                      |          S )u   
        Получает связи с другими системами

        Return:
            applinks (dict): данные связей с другими системами
        zrest/applinks/3.0/applinksr   )r#   r$   s     r'   get_applinkszConfluenceApi.get_applinks  s     ,xx}}r(   )NrK   )NN)r   rf   rn   ro   )r   rw   NTrG   )r   rw   N)r   r   r   N)*__name__
__module____qualname____doc__r/   !IMPORT_CONFLUENCE_REQUEST_TIMEOUTcmfutilrequests_sessionr   r   r"   rB   rE   rH   rd   rk   ru   r   r   r   r   r   strr   r   r   r|   r   r   r   r   r   r   r   r   r   r   r   r   r  r  __classcell__)r&   s   @r'   r   r      s       UU 8((**' ' ' ' ' 'RJ J J   G G G! ! !    
# # # #:     0	 	 	 	     !3 !3 !3F/ / / / // / / / / 8:7;/3 /3C /3!$/314/3"%/3@D/3 /3 /3 /3b 3  t    .	/ 	/S 	/ 	/ 	/ 	/   P P P P   ! ! ! !      Y Y Y Y Y  , ,3 , ,S ,\` , , , ,6 Q3 Q3Q3 Q3 	Q3
 Q3 Q3 Q3 
Q3 Q3 Q3 Q3f; ; ;	d 	 	 	 	 	 	 	 	r(   r   )urllib.parser   r   cmf.includer7   r}   requests.adaptersr   urllib3.util.retryr   	atlassianr   atlassian.errorsr	   logging	getLoggerrW   r   r   r(   r'   <module>r     s    , , , , , , , ,       ) ) ) ) ) ) $ $ $ $ $ $             - - - - - -			2	3	3B B B B BJ B B B B Br(   