Added a bug reporting feature in the help menu

This commit is contained in:
Manuel Cortez 2018-12-22 08:08:30 -06:00
parent 2a729ffcc2
commit 17c6b7d282
7 changed files with 185 additions and 2 deletions

View File

@ -21,6 +21,7 @@
* Updated Russian translation: thanks to Дарья Ратникова. * Updated Russian translation: thanks to Дарья Ратникова.
* Fixed some conditions, especially when rendering items in feeds, that were making the client to crash. * Fixed some conditions, especially when rendering items in feeds, that were making the client to crash.
* new versions will include documentation and changelog. * new versions will include documentation and changelog.
* A new option for reporting issues directly from the help menu has been added. Issues will be publicly available in the [Project Issues page](https://code.manuelcortez.net/manuelcortez/socializer/issues)
## Changes in version 0.16 (13.12.2018) ## Changes in version 0.16 (13.12.2018)

View File

@ -10,3 +10,7 @@ update_url = "https://code.manuelcortez.net/manuelcortez/socializer/raw/master/u
# The short name will be used for detecting translation files. See languageHandler for more details. # The short name will be used for detecting translation files. See languageHandler for more details.
short_name = "socializer" short_name = "socializer"
translators = [u"Darya Ratnikova (Russian)", u"Manuel Cortez (Spanish)"] translators = [u"Darya Ratnikova (Russian)", u"Manuel Cortez (Spanish)"]
bts_name = "socializer"
bts_access_token = "U29jaWFsaXplcg"
bts_url = "https://issues.manuelcortez.net"
bts_project_id = 4

View File

@ -25,6 +25,7 @@ from wxUI import (mainWindow, commonMessages)
from wxUI.dialogs import search as searchDialogs from wxUI.dialogs import search as searchDialogs
from wxUI.dialogs import timeline, creation from wxUI.dialogs import timeline, creation
from update import updater from update import updater
from issueReporter import issueReporter
log = logging.getLogger("controller.main") log = logging.getLogger("controller.main")
@ -169,6 +170,7 @@ class Controller(object):
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.view_my_profile, menuitem=self.window.view_profile) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.view_my_profile, menuitem=self.window.view_profile)
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.view_my_profile_in_browser, menuitem=self.window.open_in_browser) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.view_my_profile_in_browser, menuitem=self.window.open_in_browser)
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.set_status, menuitem=self.window.set_status) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.set_status, menuitem=self.window.set_status)
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_report_error, menuitem=self.window.report)
def disconnect_events(self): def disconnect_events(self):
log.debug("Disconnecting some events...") log.debug("Disconnecting some events...")
@ -659,3 +661,6 @@ class Controller(object):
info = self.session.vk.client.account.saveProfileInfo(status=result) info = self.session.vk.client.account.saveProfileInfo(status=result)
commonMessages.updated_status() commonMessages.updated_status()
dlg.Destroy() dlg.Destroy()
def on_report_error(self, *args, **kwargs):
r = issueReporter.reportBug()

View File

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
############################################################
# Copyright (c) 2018 Manuel Cortez <manuel@manuelcortez.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
############################################################
import wx
import platform
import requests
import widgetUtils
import application
import paths
from requests.auth import HTTPBasicAuth
from mysc.thread_utils import call_threaded
from . import wx_ui
class reportBug(object):
def __init__(self):
self.dialog = wx_ui.reportBugDialog()
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
self.dialog.get_response()
def do_report(self, *args, **kwargs):
r = requests.post(*args, **kwargs)
if r.status_code > 300:
wx.CallAfter(self.dialog.error)
wx.CallAfter(self.dialog.progress.Destroy)
wx.CallAfter(self.dialog.success, r.json()["data"]["issue"]["id"])
def send(self, *args, **kwargs):
if self.dialog.get("summary") == "" or self.dialog.get("description") == "" or self.dialog.get("first_name") == "" or self.dialog.get("last_name") == "":
self.dialog.no_filled()
return
if self.dialog.get("agree") == False:
self.dialog.no_checkbox()
return
title = self.dialog.get("summary")
body = self.dialog.get("description")
issue_type = "issue" # for now just have issue
app_type = paths.mode
app_version = application.version
reporter_name = u"{first_name} {last_name}".format(first_name=self.dialog.get("first_name"), last_name=self.dialog.get("last_name"))
reporter_contact_type = "email" # For now just email is supported in the issue reporter
reporter_contact_handle = self.dialog.get("email")
operating_system = platform.platform()
json = dict(title=title, issue_type=issue_type, body=body, operating_system=operating_system, app_type=app_type, app_version=app_version, reporter_name=reporter_name, reporter_contact_handle=reporter_contact_handle, reporter_contact_type=reporter_contact_type)
auth=HTTPBasicAuth(application.bts_name, application.bts_access_token)
url = "{bts_url}/issue/{project_id}/new".format(bts_url=application.bts_url, project_id=application.bts_project_id)
call_threaded(self.do_report, url, json=json, auth=auth)
self.dialog.show_progress()
self.dialog.EndModal(wx.ID_OK)

109
src/issueReporter/wx_ui.py Normal file
View File

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
############################################################
# Copyright (c) 2018 Manuel cortez <manuel@manuelcortez.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
############################################################
import wx
import widgetUtils
import application
class reportBugDialog(widgetUtils.BaseDialog):
def __init__(self):
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
self.SetTitle(_(u"Report an error"))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
summaryLabel = wx.StaticText(panel, -1, _(u"Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize)
self.summary = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.summary)
dc.SetFont(self.summary.GetFont())
self.summary.SetSize(dc.GetTextExtent("a"*80))
summaryB = wx.BoxSizer(wx.HORIZONTAL)
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
summaryB.Add(self.summary, 0, wx.ALL, 5)
sizer.Add(summaryB, 0, wx.ALL, 5)
first_nameLabel = wx.StaticText(panel, -1, _(u"First Name"), size=wx.DefaultSize)
self.first_name = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.first_name)
dc.SetFont(self.first_name.GetFont())
self.first_name.SetSize(dc.GetTextExtent("a"*40))
first_nameB = wx.BoxSizer(wx.HORIZONTAL)
first_nameB.Add(first_nameLabel, 0, wx.ALL, 5)
first_nameB.Add(self.first_name, 0, wx.ALL, 5)
sizer.Add(first_nameB, 0, wx.ALL, 5)
last_nameLabel = wx.StaticText(panel, -1, _(u"Last Name"), size=wx.DefaultSize)
self.last_name = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.last_name)
dc.SetFont(self.last_name.GetFont())
self.last_name.SetSize(dc.GetTextExtent("a"*40))
last_nameB = wx.BoxSizer(wx.HORIZONTAL)
last_nameB.Add(last_nameLabel, 0, wx.ALL, 5)
last_nameB.Add(self.last_name, 0, wx.ALL, 5)
sizer.Add(last_nameB, 0, wx.ALL, 5)
emailLabel = wx.StaticText(panel, -1, _(u"Email address (Will not be public)"), size=wx.DefaultSize)
self.email = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.email)
dc.SetFont(self.email.GetFont())
self.email.SetSize(dc.GetTextExtent("a"*30))
emailB = wx.BoxSizer(wx.HORIZONTAL)
emailB.Add(emailLabel, 0, wx.ALL, 5)
emailB.Add(self.email, 0, wx.ALL, 5)
sizer.Add(emailB, 0, wx.ALL, 5)
descriptionLabel = wx.StaticText(panel, -1, _(u"Here, you can describe the bug in detail"), size=wx.DefaultSize)
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
dc = wx.WindowDC(self.description)
dc.SetFont(self.description.GetFont())
(x, y) = dc.GetMultiLineTextExtent("0"*2000)
self.description.SetSize((x, y))
descBox = wx.BoxSizer(wx.HORIZONTAL)
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
descBox.Add(self.description, 0, wx.ALL, 5)
sizer.Add(descBox, 0, wx.ALL, 5)
self.agree = wx.CheckBox(panel, -1, _(u"I know that the {0} bug system will get my email address to contact me and fix the bug quickly").format(application.name,))
self.agree.SetValue(False)
sizer.Add(self.agree, 0, wx.ALL, 5)
self.ok = wx.Button(panel, wx.ID_OK, _(u"Send report"))
self.ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel"))
btnBox = wx.BoxSizer(wx.HORIZONTAL)
btnBox.Add(self.ok, 0, wx.ALL, 5)
btnBox.Add(cancel, 0, wx.ALL, 5)
sizer.Add(btnBox, 0, wx.ALL, 5)
panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def no_filled(self):
wx.MessageDialog(self, _(u"You must fill out the following fields: first name, last name, email address and issue information."), _(u"Error"), wx.OK|wx.ICON_ERROR).ShowModal()
def no_checkbox(self):
wx.MessageDialog(self, _(u"You need to mark the checkbox to provide us your email address to contact you if it is necessary."), _(u"Error"), wx.ICON_ERROR).ShowModal()
def success(self, id):
wx.MessageDialog(self, _(u"Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You have received an email with more information regarding your report. You've reported the bug number %i") % (id), _(u"reported"), wx.OK).ShowModal()
self.Destroy()
def error(self):
wx.MessageDialog(self, _(u"Something unexpected occurred while trying to report the bug. Please, try again later"), _(u"Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal()
self.Destroy()
def show_progress(self):
self.progress = wx.ProgressDialog(title=_(u"Sending report..."), message=_(u"Please wait while your report is being send."), maximum=100, parent=self)
self.progress.ShowModal()

View File

@ -51,6 +51,7 @@ class mainWindow(wx.Frame):
self.documentation = help_.Append(wx.NewId(), _(u"Manual")) self.documentation = help_.Append(wx.NewId(), _(u"Manual"))
self.check_for_updates = help_.Append(wx.NewId(), _(u"Check for updates")) self.check_for_updates = help_.Append(wx.NewId(), _(u"Check for updates"))
self.changelog = help_.Append(wx.NewId(), _(u"Chan&gelog")) self.changelog = help_.Append(wx.NewId(), _(u"Chan&gelog"))
self.report = help_.Append(wx.NewId(), _(u"Report an error"))
mb.Append(player, _(u"Audio player")) mb.Append(player, _(u"Audio player"))
mb.Append(help_, _(u"Help")) mb.Append(help_, _(u"Help"))
self.SetMenuBar(mb) self.SetMenuBar(mb)