U
    $-d:                     @   sB   d dl Z d dlZd dlZd dlmZ d dlmZ G dd dZdS )    N)quote)requestc                   @   s   e Zd ZdZd$ddZeedddZd	d
 Zdd Z	dd Z
dd Zd%eeejejedddZedd Zd&ddZd'ddZedd Zdd Zd(d d!Zd)d"d#ZdS )*Driveru   
    Важно не спамить API запросами, т.к. есть ограничения.
    Кешируем всё что можно.
    N   c           	      C   s:   ddl m} |||||||d| _i | _|r6| j  d S )Nr   )Gitlab)urlZprivate_token
ssl_verifytimeouthttp_usernamehttp_password)Zgitlabr   api_reposZenable_debug)	selfr   tokenr   r	   r
   r   debugr    r   ./modules/git/gitlab.py__init__   s        zDriver.__init__sc                 C   s"   | o t j | ddt jjS )NZz+00:00)datetimeZfromisoformatreplaceZ
astimezonetimezoneZutcr   r   r   r   _parse_datetime   s    zDriver._parse_datetimec                 C   s  t tj t tj ttj}tjd }tjd }|d }t d| d| d|d   d|d t|d	 |d
 |d dg g g d}|ddko|d}|r|d t|d	 |d |d |d d |d |d d |d |d |d dkrdn|d |d dk|d dk|d| |d |d! d"}|d |d# d	 kr|d# d$ |d%< |d# d& |d'< |d# d(}|rd)|kr||d*< |d+ 	| |d,|d-|d.  }	}
}|	r|
r|r|	
d/r|	d/dd0}	|d1 	|	||d2k|d
  d3t|	dd4 d5 |d6g }|D ]N}|d6 	|d	 |d	 |d! |d7 | |d8 |d9 d$ |d9 d( d: q.|S );aO  
        https://docs.gitlab.com/ee/user/project/integrations/webhooks.html

        default gitlab.com webhook timeout - 10 sek
        gitlab use retries
        return 4xx - lead to automatically disable hook
        return 5xx - lead to temporarily disable hook
        gitlab store response headers and body for debug
        If a webhook fails repeatedly, it may be disabled automatically.

        Webhooks that return response codes in the 5xx range are understood to be failing intermittently and are
        temporarily disabled. These webhooks are initially disabled for 1 minute, which is extended on each retry
        up to a maximum of 24 hours.

        Webhooks that return response codes in the 4xx range are understood to be misconfigured and are permanently
        disabled until you manually re-enable them yourself.
        zX-Gitlab-EventzX-Gitlab-InstanceZprojectz'Gitlab.process_webhook_request: gitlab=z, event=z, repo_name=path_with_namespace idweb_urldefault_branchnameext_idr   r   )Zresponserepobranchescommitsmerge_requestsZ
event_typeZmerge_requestZobject_attributestitleiidsource_branchsourcetarget_branchtargetZ	author_iddescriptionstateopenedopendetailed_merge_status	mergeablemergedmerge_commit_sha	merged_atr   )r!   r"   numberhead_branch_name	head_repobase_branch_name	base_repoauthor_ext_idtextstatusr2   r3   	merge_shar5   r   userr!   author_nameusernameauthor_loginemail@author_emailr&   refbeforeafterzrefs/heads/   r$   Z(0000000000000000000000000000000000000000z/-/tree/)Zsafe)r!   shaZdeletedr   r%   messageZ	timestampauthor)r!   rJ   r   r<   dater@   rE   )printr   Zheadersdatajsonloadsstrgetr   append
startswithr   r   )r   Z	hook_dataeventZgitlab_server_urlZ	repo_dataresultZpr_datamrrC   rF   rG   rH   r%   Zcommit_datar   r   r   process_webhook_request    s    



 
 
	




	"     

zDriver.process_webhook_requestc                 C   s0   t |}|| jkr&| jj|| j|< | j| S )N)intr   r   projectsrS   )r   r"   r   r   r   get_repo   s    
zDriver.get_repoc                 C   sL   g }| j jjdddD ]0}|| j|j< ||jt|j|j|j	d q|S )NT)Z
membershipiteratorr    )
r   r[   listr   r   rT   r   rR   r   r   )r   rW   r#   r   r   r   available_repos   s      
zDriver.available_reposc                 C   s$   |  |}dd |jjdddD S )Nc                 S   s"   g | ]}|j |jd  |jdqS )r   )r!   rJ   r   )r!   commitr   ).0branchr   r   r   
<listcomp>   s
    z'Driver.get_branches.<locals>.<listcomp>T)get_allr]   )r\   r$   r^   )r   r"   r#   r   r   r   get_branches   s    
zDriver.get_branches)rJ   pathsinceuntilrL   c           
      #   s   |}t    fdddD }| |jjf |dddD ]T}	|	j|	j|	j|	j| |	j|	j	|	j
t|	j|	jd|	jd|	jdd	V  q:d S )
Nc                    s   i | ]} | r| | qS r   r   )ra   pZlocals_r   r   
<dictcomp>   s    z'Driver.iter_commits.<locals>.<dictcomp>)ref_namerf   rg   rh   rL   T)Z
with_statsr]   	additions	deletionstotal)r!   rJ   r   r<   rM   r@   rE   parentsrm   rn   ro   )localsr\   r%   r^   r   r   rK   r   Zauthored_dater@   rE   Z
parent_idsZstatsrS   )
r   r"   rJ   rf   rg   rh   rL   rl   Zget_commits_kwargsr`   r   rj   r   iter_commits   s$    
"   
 
 

zDriver.iter_commitsc                 C   s   t |dr|jn|jp|j}t |dr2|jdk}n
|jdk}|jt|j|j	|j
|j|j|j|j|jd|jd|jd|j|jdkrd	n|j||jd
k|j| |j|o|d|o|d|o|d|jdS )N
merge_userr1   r2   Zcan_be_mergedr!   rA   r   r/   r0   r3   )r!   r"   r6   r7   r8   Zhead_shar9   r:   r@   rB   r;   r<   r=   r2   r3   r>   r5   Zmerged_by_nameZmerged_by_loginZmerged_by_ext_idr   )hasattrrs   Z	merged_byZ	closed_byr1   Zmerge_statusr'   rR   r   r(   r)   Zsource_project_idrJ   r+   Ztarget_project_idrL   rS   r-   r.   r4   r   r5   r   )clsrX   rs   r2   r   r   r   _mr2dict   s4    





zDriver._mr2dictc                 C   sH   ddl m} | |}z|j|}W n |k
r<   Y d S X | |S )Nr   )UnknownObjectException)Zgithubrw   r\   mergerequestsrS   rv   )r   r"   r6   rw   r#   rX   r   r   r   get_merge_request   s    
zDriver.get_merge_requestTc                    s4     |}|rdnd} fdd|jj|ddD S )Nr/   allc                    s   g | ]}  |qS r   )rv   )ra   rX   r   r   r   rc     s     z-Driver.get_merge_requests.<locals>.<listcomp>T)r.   rd   )r\   rx   r^   )r   r"   Z	only_openr#   r.   r   r{   r   get_merge_requests   s    
zDriver.get_merge_requestsc                 C   s   dt j|  S )Nz&git_webhook_name=)urllibparser   )webhook_namer   r   r   _webhook_name_url_tag  s    zDriver._webhook_name_url_tagc                 C   s>   |  |}| |}|jjddD ]}||jkr"|  S q"d S )NT)rd   )r   r\   hooksr^   r   )r   r"   r   tagr#   hookr   r   r   _get_webhook_by_name	  s
    


zDriver._get_webhook_by_nameFc                 K   s   |  |}| ||}	|| |7 }t|| d}
dD ]}d|
|< q6|	rd}|	  D ]P\}}||
kr||
| krt|	||
|  d}qX|drX|rXt|	|d d}qX|std|	  d|
  |		  ntd|
  |j
|
}	t|	jS )	N)r   Zenable_ssl_verification)Zmerge_requests_eventsZpush_eventsTFZ_eventsz-gitlab driver: webhook config differ gitlab: z	 != eva: zgitlab: create webhook )r\   r   r   dictasdictitemssetattrendswithrN   Zsaver   ZcreaterR   r   )r   r"   Zwebhook_urlr   Zinsecure_sslZsecretwebhook_ext_id_kwargsr#   r   Zwebhook_configrV   Zequalkeyvaluer   r   r   setup_webhook  s,    


zDriver.setup_webhookc                 K   s0   |  ||}|r,td|  d |  d S )Nzgitlab: delete webhook())r   rN   r   delete)r   r"   r   r   r   r   r   r   r   cleanup_webhook5  s    zDriver.cleanup_webhook)NNNr   NNN)NNNNN)N)T)FNN)NN)__name__
__module____qualname____doc__r   staticmethodrR   r   rY   r\   r_   re   r   rr   classmethodrv   ry   r|   r   r   r   r   r   r   r   r   r   	   sN               
l	           
;



     
#r   )r   rP   r}   Zurllib.parser   Zflaskr   r   r   r   r   r   <module>   s
   