
    !f@+                         d Z 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	Z	ddl
Z
ddlZ
 G d d      Z ed	       G d
 d             Z G d de
j                  j                        Zy)z)Crash database implementation for Github.    N)Callable)	dataclass)Anyc                       e Zd ZU dZ ej                         Zeed<   d Ze	de
defd       ZdededefdZdede
defd	Zd
edede
defdZd ZdeddfdZdefdZy)Githubz:Wrapper around Github API, used to log in and post issues._Github__last_requestc                 X    || _         d | _        d | _        d | _        d | _        || _        y N)_Github__client_id_Github__authentication_data_Github__access_token_Github__cooldown_Github__expirymessage_callback)self	client_idr   s      </usr/lib/python3/dist-packages/apport/crashdb_impl/github.py__init__zGithub.__init__   s0    $%)"" 0    datareturnc                 N    d}| j                         D ]  \  }}| d| d| } |S )z4Takes a dict and returns it as a string for POSTing. &=)items)r   stringkeyvalues       r   
_stringifyzGithub._stringify%   s=     **, 	/JCxqQug.F	/r   urlc                    ddi}| j                   rd| j                    |d<   	 t        j                  |||d      }	 t        j
                         | _        |j                          t        j                  |j                        S # t        j                  $ r }| j	                  dd| d	d
z          |d}~ww xY w# t        j
                         | _        w xY w)zKPosts the given data to the given URL.
        Uses auth token if availableAcceptzapplication/vnd.github.v3+jsonztoken Authorizationg      @)headersr   timeoutzFailed connectionzFailed connection to z.
z4Please check your internet connection and try again.N)r   requestspostRequestExceptionr   timer   raise_for_statusjsonloadstext)r   r!   r   r%   resulterrs         r   _postzGithub._post-   s     =>)/0C0C/D'EGO$
	.]]3dCPF #'))+D!zz&++&& (( 	!!#'uC0HI
 I	 #'))+Ds#   B B9B44B99B< <Cc                 D    | j                  || j                  |            S )z$Authenticate against the GitHub API.)r1   r    )r   r!   r   s      r   api_authenticationzGithub.api_authenticationB   s    zz#tt455r   ownerrepoc                 ^    d| d| d}| j                  |t        j                  |            S )z'Open a new issue on the GitHub project.zhttps://api.github.com/repos//z/issues)r1   r,   dumps)r   r4   r5   r   r!   s        r   api_open_issuezGithub.api_open_issueF   s0    -eWAdV7Czz#tzz$/00r   c                 @   | j                   dd}d}| j                  ||      }d}|d   }|d   }| j                  d|j                  ||             | j                   |d	    d
d| _        |d   | _        t        |d         t        j                         z   | _        | S )z2Enters login process. At exit, login process ends.public_repo)r   scopez$https://github.com/login/device/codezPosting an issue requires a Github account. If you have one, please follow these steps to log in.

Open the following URL. When requested, write this code to enable apport to open an issue.
URL:  {url}
Code: {code}verification_uri	user_codezLogin required)r!   codedevice_codez,urn:ietf:params:oauth:grant-type:device_code)r   r@   
grant_typeinterval
expires_in)	r   r3   r   formatr   r   intr*   r   )r   r   r!   responsepromptr?   s         r   	__enter__zGithub.__enter__K   s    !--F4**35 	 )*$.#D0QR ))&}56H&
"
 #:.H\23diikAr   _Nc                 .    d | _         d| _        d| _        y )Nr   )r   r   r   )r   rI   s     r   __exit__zGithub.__exit__j   s    %)"r   c                    | j                   st        d      t        j                         }| j                  || j                  z
  z
  }||z   | j
                  kD  r| j                  dd       t        d      |dkD  rt        j                  |       d}| j                  || j                         }d|v r3|d   dk(  ry	|d   d
k(  rt        |d         | _        y	t        d|       d|v r|d   | _
        yt        d|       )znAsks Github if the user has logged in already.
        It respects the wait-time requested by Github.
        z9Authentication not started. Use a with statement to do sozFailed loginz0Github authentication expired. Please try again.zGithub authentication expiredr   z+https://github.com/login/oauth/access_tokenerrorauthorization_pendingF	slow_downrB   zUnknown error from Github: access_tokenTzUnknown response from Github: )r   RuntimeErrorr*   r   r   r   r   sleepr3   rE   r   )r   current_timewaittimer!   rF   s        r   authentication_completezGithub.authentication_completeo   s    ))K  yy{??lT5H5H&HI("T]]2!! R >??a<JJx ;**30J0JKh $;; K/"%hz&:";!<XJGHHX%"*>":D;H:FGGr   )__name__
__module____qualname____doc__r*   r   float__annotations__r   staticmethoddictstrr    r   r1   r3   r9   rH   rK   boolrU    r   r   r   r      s    D%DIIKNE'1  #  ' 'C 'C '*6c 6 6# 61C 1s 1$ 13 1
>3 4 
 H  Hr   r   T)frozenc                       e Zd ZU eed<   y)IssueHandler!   N)rV   rW   rX   r^   r[   r`   r   r   rc   rc      s    	Hr   rc   c            	          e Zd ZdZd Zdej                  defdZd Z		 	 ddej                  de
dz  d	e
dz  defd
Zdej                  dedefdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZd Z	 	 	 d dZy)!CrashDatabasezjGithub crash database.
    This is a Apport CrashDB implementation for interacting with Github issues
    c                     t         j                  j                  j                  | ||       |d   | _        |d   | _        |d   | _        t        |d         | _        d| _	        d| _
        y)z<Initialize some variables. Login is delayed until necessary.repository_ownerrepository_namegithub_app_idlabelsN)apportcrashdbre   r   rg   rh   app_idsetrj   	issue_urlgithub)r   	auth_fileoptionss      r   r   zCrashDatabase.__init__   se    $$--dIwG '(: ;&'89o.'(+,r   reportr   c                     d}|j                         D ]  \  }}|d| d| dz  } d|t        | j                        dS )z>Formats report info as markdown and creates Github issue JSON.r   z**z**
z

zIssue submitted via apport)titlebodyrj   )r   listrj   )r   rs   body_markdownr   r   s        r   _format_reportzCrashDatabase._format_report   sW     ,,. 	7JCr#d5'66M	7 2!4;;'
 	
r   c                     t        | j                  |      5 }|j                         s	 |j                         s|cd d d        S # 1 sw Y   y xY wr
   )r   rm   rU   )r   user_message_callbackrp   s      r   _github_loginzCrashDatabase._github_login   sH    DKK!67 	6446 446	 	 	s   "AAANprogress_callbackr{   c                    | j                  |      sJ | j                  |      | _        | j                  t        d      | j	                  |      }| j
                  | j                  2| j                  j                  | j                  | j
                  |      }n7d|v r(d|v r$| j                  j                  |d   |d   |      }nt        d      t        |d         S )zaUpload given problem report return a handle for it.
        In Github, we open an issue.
        zFailed to login to GithubSnapGitOwnerSnapGitNamez9Couldn't determine which repository to file the report inhtml_urlr!   )	acceptsr|   rp   rQ   ry   rh   rg   r9   rc   )r   rs   r}   r{   r   rF   s         r   uploadzCrashDatabase.upload   s     ||F###(()>?;;:;;""6*$$,1F1F1N{{11%%t';';TH v%-6*A{{11~&}(=tH K  x
344r   handlec                     |j                   S )zpReturn a URL that should be opened after report has been uploaded
        and upload() returned handle.
        r   )r   rs   r   s      r   get_comment_urlzCrashDatabase.get_comment_url   s     zzr   c                     t        d      Nz?This method is not relevant for Github database implementation.NotImplementedError)r   crash_idrs   s      r   _mark_dup_checkedzCrashDatabase._mark_dup_checked       !M
 	
r   c                     t        d      r   r   r   r   s     r   
can_updatezCrashDatabase.can_update   r   r   c                     t        d      r   r   )r   rs   r   	master_ids       r   close_duplicatezCrashDatabase.close_duplicate   r   r   c                     t        d      r   r   r   s     r   downloadzCrashDatabase.download   r   r   c                     t        d      r   r   r   s     r   duplicate_ofzCrashDatabase.duplicate_of   r   r   c                     t        d      r   r   r   s     r   get_affected_packagesz#CrashDatabase.get_affected_packages   r   r   c                     t        d      r   r   r   s     r   get_distro_releasez CrashDatabase.get_distro_release   r   r   c                     t        d      r   r   r   s    r   get_dup_uncheckedzCrashDatabase.get_dup_unchecked  r   r   c                     t        d      r   r   r   s     r   get_fixed_versionzCrashDatabase.get_fixed_version  r   r   c                     t        d      r   r   )r   rs   r   s      r   
get_id_urlzCrashDatabase.get_id_url  r   r   c                     t        d      r   r   r   s    r   get_unfixedzCrashDatabase.get_unfixed  r   r   c                     t        d      r   r   r   s    r   get_unretracedzCrashDatabase.get_unretraced  r   r   c                     t        d      r   r   r   s     r   is_reporterzCrashDatabase.is_reporter  r   r   c                     t        d      r   r   )r   r   masters      r   mark_regressionzCrashDatabase.mark_regression  r   r   c                     t        d      r   r   )r   r   invalid_msgs      r   mark_retrace_failedz!CrashDatabase.mark_retrace_failed$  r   r   c                     t        d      r   r   r   s     r   mark_retracedzCrashDatabase.mark_retraced)  r   r   c                     t        d      r   r   )r   r   rs   commentchange_descriptionattachment_comment
key_filters          r   updatezCrashDatabase.update.  s     "M
 	
r   )NNr
   )FNN) rV   rW   rX   rY   r   rk   Reportr]   ry   r|   r   rc   r   r^   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r`   r   r   re   re      s    

V]] 

t 

 .215	55 $d?5  ($	5
 
5@fmm [ S 






























 !
r   re   )rY   r,   r*   collections.abcr   dataclassesr   typingr   r'   rk   apport.crashdbr   rc   rl   re   r`   r   r   <module>r      sg    /   $ !    wH wHt $  b
FNN00 b
r   