Source code for diffpy.pdfgui.gui.errorreportdialog

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
##############################################################################
#
# PDFgui            by DANSE Diffraction group
#                   Simon J. L. Billinge
#                   (c) 2006 trustees of the Michigan State University.
#                   All rights reserved.
#
# File coded by:    Dmitriy Bryndin
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE.txt for license information.
#
##############################################################################

# generated by wxGlade 0.9.3 on Fri Jul 19 16:01:37 2019

import re
import webbrowser

#
# "Bug report" Dialog
#
import wx
import wx.html

# Constants ------------------------------------------------------------------

ISSUESTRACKER = "https://github.com/diffpy/diffpy.pdfgui/issues"
USERSMAILINGLIST = "https://groups.google.com/d/forum/diffpy-users"
_WEBSEARCHURL = "https://www.google.com/search?q={query}"

_MSG_TRAILER = """
<p>
You can view current bug reports and feature requests at
<a href="{issues}">{issues}</a>.
</p><p>
Discuss PDFgui and learn about new developments and features at
<a href="{mlist}">{mlist}</a>.
</p>
""".format(
    issues=ISSUESTRACKER, mlist=USERSMAILINGLIST
)

_MSG_FEATURE_REQUEST = (
    """
<p>
Share you thoughts about PDFgui!
</p>
"""
    + _MSG_TRAILER
)

_MSG_ERROR_REPORT = (
    """
<p>
PDFgui has encountered a problem.  We are sorry for the inconvenience.
</p><p>
"""
    + _MSG_TRAILER
)

# ----------------------------------------------------------------------------


[docs] class ErrorReportDialog(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: ErrorReportDialog.__init__ kwds["style"] = ( kwds.get("style", 0) | wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.RESIZE_BORDER ) wx.Dialog.__init__(self, *args, **kwds) self.SetSize((540, 600)) self.label_header = wx.html.HtmlWindow(self, wx.ID_ANY) self.label_log = wx.StaticText(self, wx.ID_ANY, "Error Log:") self.text_ctrl_log = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.static_line_1 = wx.StaticLine(self, wx.ID_ANY) self.button_google = wx.Button(self, wx.ID_ANY, "Google This Error") self.button_copyErrorLog = wx.Button(self, wx.ID_ANY, "Copy Error Log") self.button_close = wx.Button(self, wx.ID_CANCEL, "Close") self.__set_properties() self.__do_layout() self.Bind(wx.EVT_BUTTON, self.onGoogle, self.button_google) self.Bind(wx.EVT_BUTTON, self.onCopyErrorLog, self.button_copyErrorLog) # end wxGlade self.__customProperties() return def __set_properties(self): # begin wxGlade: ErrorReportDialog.__set_properties self.SetTitle("Problem Report for PDFgui") self.SetSize((540, 600)) # end wxGlade def __do_layout(self): # begin wxGlade: ErrorReportDialog.__do_layout sizer_main = wx.BoxSizer(wx.VERTICAL) sizer_buttons = wx.BoxSizer(wx.HORIZONTAL) sizer_log = wx.BoxSizer(wx.VERTICAL) sizer_label = wx.BoxSizer(wx.HORIZONTAL) sizer_label.Add(self.label_header, 1, wx.EXPAND, 5) sizer_main.Add(sizer_label, 1, wx.ALL | wx.EXPAND, 5) sizer_log.Add(self.label_log, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 5) sizer_log.Add(self.text_ctrl_log, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 5) sizer_main.Add(sizer_log, 3, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10) sizer_main.Add(self.static_line_1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 5) sizer_buttons.Add((20, 20), 1, 0, 0) sizer_buttons.Add(self.button_google, 0, wx.ALL, 5) sizer_buttons.Add(self.button_copyErrorLog, 0, wx.ALL, 5) sizer_buttons.Add(self.button_close, 0, wx.ALL, 5) sizer_main.Add(sizer_buttons, 0, wx.EXPAND, 0) self.SetSizer(sizer_main) self.Layout() # end wxGlade def __customProperties(self): """Set custom properties.""" # Events self.errorReport = True self.label_header.Bind(wx.html.EVT_HTML_LINK_CLICKED, self.onURL) return
[docs] def ShowModal(self): # there are 2 modes: error report and feature request if self.text_ctrl_log.GetValue().strip() == "": self.SetTitle("Feature Request / Bug Report") self.label_header.SetPage(_MSG_FEATURE_REQUEST) self.label_header.SetBackgroundColour("") self.label_log.Hide() self.text_ctrl_log.Hide() self.button_google.Hide() self.button_copyErrorLog.Hide() self.SetSize((540, 200)) self.errorReport = False else: self.SetTitle("Problem Report for PDFgui") self.label_header.SetPage(_MSG_ERROR_REPORT) self.label_header.SetBackgroundColour("") self.text_ctrl_log.Show() self.errorReport = True wx.Dialog.ShowModal(self)
[docs] def onGoogle(self, event): # wxGlade: ErrorReportDialog.<event_handler> """Handle the "Google This Error" button. Search for path-independent module and function names and for error message extracted from exception traceback. """ from urllib.parse import quote_plus traceback = self.text_ctrl_log.GetValue() terms = _extractSearchTerms(traceback) str_to_search = " ".join(terms) if terms else traceback.strip() query = quote_plus(str_to_search) url = _WEBSEARCHURL.format(query=query) webbrowser.open(url) event.Skip() return
[docs] def onCopyErrorLog(self, event): # wxGlade: ErrorReportDialog.<event_handler> # copy the traceback enclosed in GitHub block quotations so it is easier to paste into GitHub issue. traceback = self.text_ctrl_log.GetValue() clipdata = wx.TextDataObject() clipdata.SetText("```\n" + traceback.strip() + "\n```\n") wx.TheClipboard.Open() wx.TheClipboard.SetData(clipdata) wx.TheClipboard.Close() event.Skip() return
[docs] def onURL(self, event): # wxGlade: ErrorReportDialog.<event_handler> # click on the URL link in dialog, it will open the URL in web browser. link = event.GetLinkInfo() webbrowser.open(link.GetHref())
# end of class ErrorReportDialog # Helper functions ----------------------------------------------------------- def _extractSearchTerms(tbtext): """Extract search words from a Python exception traceback. Parameters ---------- tbtext : str Python exception traceback converted to a string. Returns ------- searchterms : list List of search terms to be used for Google search. """ # extract module names and function names from a traceback modfncpairs = re.findall(r"File.*?([^/\\]*[.]py).*?, line \d+, in (\w+)", tbtext, re.MULTILINE) modfnc = list(sum(modfncpairs, ())) # find the last line starting with "SomeError: ...". lasterr = re.findall(r"^\w+Error:.*", tbtext, re.MULTILINE) rv = modfnc + lasterr[-1:] return rv # testing code ############################################################ _EXAMPLE_TRACEBACK = r""" Traceback (most recent call last): File "C:\DiffPy\Python25\lib\site-packages\diffpy.pdfgui-1.0_r3067_20090410-py2.5.egg\ diffpy\pdfgui\gui\errorwrapper.py", line 60, in _f return func(*args, **kwargs) File "C:\DiffPy\Python25\lib\site-packages\diffpy.pdfgui-1.0_r3067_20090410-py2.5.egg\ diffpy\pdfgui\gui\mainframe.py", line 2176, in onSave self.control.save(self.fullpath) File "C:\DiffPy\Python25\lib\site-packages\diffpy.pdfgui-1.0_r3067_20090410-py2.5.egg\ diffpy\pdfgui\control\pdfguicontrol.py", line 507, in save self.projfile = projfile.encode('ascii') UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 115: ordinal not in range(128) """.strip()
[docs] class MyApp(wx.App):
[docs] def OnInit(self): self.dialog = ErrorReportDialog(None, -1, "") self.SetTopWindow(self.dialog) self.test() self.dialog.ShowModal() self.dialog.Destroy() return True
[docs] def test(self): """Testing code goes here.""" self.dialog.text_ctrl_log.SetValue(_EXAMPLE_TRACEBACK) return
# end of class MyApp if __name__ == "__main__": app = MyApp(0) app.MainLoop() # end of testing code #####################################################