B
    nôb\v.  ã               @   sÆ   d Z ddlZddlZddlZyddlZW n ek
r<   Y nX ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZmZ ddlmZ ddlmZ dd	lmZ d
d„ ZG dd„ deƒZG dd„ deƒZdS )zº
Backend to open issues automatically on Github.

Adapted from qcrash/backends/base.py and qcrash/backends/github.py of the
`QCrash Project <https://github.com/ColinDuquesnoy/QCrash>`_.
é    N)ÚQt)ÚqAppÚQMessageBox)ÚCONF)Ú_Úrunning_under_pytest)ÚPY2)Úgithub)ÚDlgGitHubLoginc               C   s
   t  t¡S )N)ÚloggingZ	getLoggerÚ__name__© r   r   ú<lib/python3.7/site-packages/spyder/widgets/github/backend.pyÚ_logger%   s    r   c               @   s,   e Zd ZdZd
dd„Zdd„ Zddd	„ZdS )ÚBaseBackenda"  
    Base class for implementing a backend.

    Subclass must define ``button_text``, ``button_tooltip``and ``button_icon``
    and implement ``send_report(title, description)``.

    The report's title and body will be formatted automatically by the
    associated :attr:`formatter`.
    NTc             C   s(   || _ || _|| _|| _|| _d| _dS )aQ  
        :param formatter: the associated formatter (see :meth:`set_formatter`)
        :param button_text: Text of the associated button in the report dialog
        :param button_icon: Icon of the associated button in the report dialog
        :param button_tooltip: Tooltip of the associated button in the report
            dialog
        :param need_review: True to show the review dialog before submitting.
            Some backends (such as the email backend) do not need a review
            dialog as the user can already review it before sending the final
            report
        N)Ú	formatterÚbutton_textÚbutton_tooltipÚbutton_iconÚneed_reviewÚparent_widget)Úselfr   r   r   r   r   r   r   r   Ú__init__3   s    zBaseBackend.__init__c             C   s
   || _ dS )zÊ
        Sets the formatter associated with the backend.

        The formatter will automatically get called to format the report title
        and body before ``send_report`` is being called.
        N)r   )r   r   r   r   r   Úset_formatterG   s    zBaseBackend.set_formatterc             C   s   t ‚dS )a<  
        Sends the actual bug report.

        :param title: title of the report, already formatted.
        :param body: body of the reporit, already formtatted.
        :param application_log: Content of the application log.
        Default is None.

        :returns: Whether the dialog should be closed.
        N)ÚNotImplementedError)r   ÚtitleÚbodyÚapplication_logr   r   r   Úsend_reportP   s    zBaseBackend.send_report)NT)N)r   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   )   s   	
	r   c                   sX   e Zd ZdZd‡ fdd„	Zddd„Zdd„ Zdd
d„Zddd„Zdd„ Z	dd„ Z
‡  ZS )ÚGithubBackendzî
    This backend sends the crash report on a github issue tracker::

        https://github.com/gh_owner/gh_repo

    Usage::

        github_backend = spyder.widgets.github.backend.GithubBackend(
            'spyder-ide', 'spyder')
    Nc                s,   t t| ƒ |ddd¡ || _|| _d| _dS )zˆ
        :param gh_owner: Name of the owner of the github repository.
        :param gh_repo: Name of the repository on github.
        zSubmit on githubz/Submit the issue on our issue tracker on githubNT)Úsuperr"   r   Úgh_ownerÚgh_repoÚ_show_msgbox)r   r$   r%   r   )Ú	__class__r   r   r   i   s    
zGithubBackend.__init__c          
   C   s²  t ƒ  d||¡ |  ¡ }|d }|d }|d }|d }|d }	|d kr\|d kr\|d kr\dS t ƒ  d¡ |r‚|  |¡}
|d	|
 7 }yF|r–tj|d
}ntj||d}| | j¡| jƒ}|j	j
||d}W nŽ tjk
rV } zlt ƒ  d|j¡ |jjdkr| jrFt | jtdƒtdƒ¡ n(| jrFt | jtdƒtdƒ|jj ¡ dS d }~X Y nXX |d }| jr€t | jtdƒtdƒ¡}|tjtjgkrªt d| j| j|f ¡ dS d S )Nz-sending bug report on github
title=%s
body=%sÚusernameÚpasswordÚrememberÚtokenÚremember_tokenFzgot user credentialsz
Application log: %s)Zaccess_token)r(   r)   )r   r   z0Failed to send bug report on Github. response=%ri‘  zInvalid credentialsz5Failed to create Github issue, invalid credentials...zFailed to create issuez'Failed to create Github issue. Error %dZnumberzIssue created on GithubzQIssue successfully created. Would you like to open the issue in your web browser?z"https://github.com/%s/%s/issues/%dT)r   ÚdebugÚget_user_credentialsÚupload_log_filer	   ÚGitHubZreposr$   r%   ZissuesÚpostÚApiErrorÚwarningZresponseÚcoder&   r   r   r   ZquestionZYesZOkÚ
webbrowserÚopen)r   r   r   r   Úcredentialsr(   r)   r*   r+   r,   ZurlÚghZrepoÚretÚeZ	issue_nbrr   r   r   r   u   sZ    



zGithubBackend.send_reportc             C   s8   t  dd¡}t  dd¡}t  ddd¡}|s.d}|||fS )z"Get the stored credentials if any.Úmainzreport_error/remember_mezreport_error/remember_tokenzreport_error/usernameÚ )r   Úget)r   Úremember_mer,   r(   r   r   r   Ú_get_credentials_from_settings°   s    z,GithubBackend._get_credentials_from_settingsFc          	   C   sv   |rd|rd|rdt  dd|¡ yt d||¡ W n6 tk
rb   | jrZt | jt	dƒt	dƒ¡ d}Y nX t  dd|¡ dS )	z!Store credentials for future use.r;   zreport_error/usernamer	   zFailed to store passwordz‹It was not possible to securely save your password. You will be prompted for your Github credentials next time you want to report an issue.Fzreport_error/remember_meN)
r   ÚsetÚkeyringÚset_passwordÚ	Exceptionr&   r   r3   r   r   )r   r(   r)   r*   r   r   r   Ú_store_credentialsº   s    

z GithubBackend._store_credentialsc          	   C   sd   |rR|rRyt  dd|¡ W n6 tk
rP   | jrHt | jtdƒtdƒ¡ d}Y nX t 	dd|¡ dS )	zStore token for future use.r	   r+   zFailed to store tokenz‚It was not possible to securely save your token. You will be prompted for your Github token next time you want to report an issue.Fr;   zreport_error/remember_tokenN)
rA   rB   rC   r&   r   r3   r   r   r   r@   )r   r+   r*   r   r   r   Ú_store_tokenÌ   s    

zGithubBackend._store_tokenc          	   C   sv  d}d}|   ¡ \}}}to$tj d¡ }|rx|rx|rxyt d|¡}W n2 tk
rv   | jrrt	 
| jtdƒtdƒ¡ Y nX |rÄ|rÄyt dd¡}W n2 tk
rÂ   | jr¾t	 
| jtdƒtdƒ¡ Y nX tƒ s`t | j|||||¡}|d	 r(|d
 r(|r(|  |d	 |d
 |d ¡ t dd|d ¡ |d rr|rr|  |d |d ¡ t dd|d ¡ nt||d||dS |S )z+Get user credentials with the login dialog.NZlinuxr	   zFailed to retrieve passwordzIIt was not possible to retrieve your password. Please introduce it again.r+   zFailed to retrieve tokenzFIt was not possible to retrieve your token. Please introduce it again.r(   r)   r*   r;   zreport_error/remember_mer,   zreport_error/remember_tokenr<   )r(   r)   r+   r*   r,   )r?   r   ÚsysÚplatformÚ
startswithrA   Zget_passwordrC   r&   r   r3   r   r   r   r
   ZloginrD   r   r@   rE   Údict)r   r)   r+   r(   r>   r,   Zvalid_py_osr7   r   r   r   r.   Þ   sT    





z"GithubBackend.get_user_credentialsc             C   sj   t  ¡ }y2t tj¡ |jjdddd|iid}t ¡  W n" t j	k
r\   t
ƒ  d¡ dS X |d S d S )	NzSpyderIDE logTzSpyderIDE.logZcontent)ZdescriptionZpublicÚfilesz%Failed to upload log report as a gistz%"Failed to upload log file as a gist"Zhtml_url)r	   r0   r   ZsetOverrideCursorr   Z
WaitCursorZgistsr1   ZrestoreOverrideCursorr2   r   r3   )r   Zlog_contentr8   r9   r   r   r   r/     s    zGithubBackend.upload_log_file)N)N)F)F)r   r   r    r!   r   r   r?   rD   rE   r.   r/   Ú__classcell__r   r   )r'   r   r"   ^   s   

;


;r"   )r!   r   rF   r5   rA   rC   Zqtpy.QtCorer   Zqtpy.QtWidgetsr   r   Zspyder.config.mainr   Zspyder.config.baser   r   Zspyder.py3compatr   Zspyder.utils.externalr	   Zspyder.widgets.github.gh_loginr
   r   Úobjectr   r"   r   r   r   r   Ú<module>   s"   5