Finish implementing wx 2.8 selector. Add a bunch of error catching. General cleanup.

(cherry picked from commit b0ec69e)
This commit is contained in:
Ebag333
2017-03-27 20:39:47 -07:00
parent 78a8c105f4
commit 03f12bfca1
2 changed files with 113 additions and 67 deletions

View File

@@ -20,9 +20,13 @@
import platform
import sys
# noinspection PyPackageRequirements
import wx
import config
try:
import config
except:
config = None
try:
import sqlalchemy
@@ -31,16 +35,21 @@ try:
except:
sqlalchemy_version = "Unknown"
try:
from logbook import __version__ as logbook_version
except:
logbook_version = "Unknown"
class ErrorFrame(wx.Frame):
def __init__(self, exception, tb):
def __init__(self, exception=None, tb=None, error_title='Error!'):
v = sys.version_info
wx.Frame.__init__(self, None, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 600),
style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER | wx.STAY_ON_TOP)
desc = "pyfa has experienced an unexpected error. Below is the Traceback that contains crucial \n" \
"information about how this error was triggered. Please contact the developers with the \n" \
desc = "pyfa has experienced an unexpected issue. Below is a message that contains crucial\n" \
"information about how this was triggered. Please contact the developers with the\n" \
"information provided through the EVE Online forums or file a GitHub issue."
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -51,7 +60,7 @@ class ErrorFrame(wx.Frame):
mainSizer = wx.BoxSizer(wx.VERTICAL)
headSizer = wx.BoxSizer(wx.HORIZONTAL)
headingText = wx.StaticText(self, wx.ID_ANY, "Error!", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
headingText = wx.StaticText(self, wx.ID_ANY, error_title, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
headingText.SetFont(wx.Font(14, 74, 90, 92, False))
headSizer.Add(headingText, 1, wx.ALL, 5)
@@ -79,24 +88,46 @@ class ErrorFrame(wx.Frame):
errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
mainSizer.Add(errorTextCtrl, 0, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, 5)
errorTextCtrl.AppendText("OS version: \t" + str(platform.platform()))
try:
errorTextCtrl.AppendText("OS version: \t" + str(platform.platform()))
except:
errorTextCtrl.AppendText("OS version: Unknown")
errorTextCtrl.AppendText("\n")
errorTextCtrl.AppendText("Python: \t" + '{}.{}.{}'.format(v.major, v.minor, v.micro))
try:
errorTextCtrl.AppendText("Python: \t" + '{}.{}.{}'.format(v.major, v.minor, v.micro))
except:
errorTextCtrl.AppendText("Python: Unknown")
errorTextCtrl.AppendText("\n")
errorTextCtrl.AppendText("wxPython: \t" + str(wx.__version__))
try:
errorTextCtrl.AppendText("wxPython: \t" + wx.VERSION_STRING)
except:
errorTextCtrl.AppendText("wxPython: Unknown")
errorTextCtrl.AppendText("\n")
errorTextCtrl.AppendText("SQLAlchemy: \t" + str(sqlalchemy_version))
errorTextCtrl.AppendText("\n")
errorTextCtrl.AppendText("pyfa version: {0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion))
errorTextCtrl.AppendText("Logbook: \t" + str(logbook_version))
errorTextCtrl.AppendText("\n")
try:
errorTextCtrl.AppendText("pyfa version: {0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion))
except:
errorTextCtrl.AppendText("pyfa version: Unknown")
errorTextCtrl.AppendText('\n')
errorTextCtrl.AppendText("pyfa root: " + str(config.pyfaPath or "Unknown"))
errorTextCtrl.AppendText('\n')
errorTextCtrl.AppendText("save path: " + str(config.savePath or "Unknown"))
errorTextCtrl.AppendText('\n')
errorTextCtrl.AppendText("fs encoding: " + str(sys.getfilesystemencoding() or "Unknown"))
errorTextCtrl.AppendText('\n\n')
errorTextCtrl.AppendText("EXCEPTION: " + str(exception or "Unknown"))
errorTextCtrl.AppendText('\n\n')
if tb:
for line in tb:
errorTextCtrl.AppendText(line)

131
pyfa.py
View File

@@ -18,6 +18,7 @@
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# ==============================================================================
import inspect
import os
import platform
import re
@@ -30,19 +31,10 @@ from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger,
import config
class PreCheckException(Exception):
pass
try:
import wxversion
import wx
from gui.errorDialog import ErrorFrame
except ImportError:
wxversion = None
wx = None
ErrorFrame = None
try:
import sqlalchemy
@@ -68,7 +60,7 @@ class PassThroughOptionParser(OptionParser):
largs.append(e.opt_str)
class LoggerWriter:
class LoggerWriter(object):
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
@@ -88,7 +80,27 @@ class LoggerWriter:
self.level(sys.stderr)
class PreCheckException(Exception):
def __init__(self, msg):
try:
ln = sys.exc_info()[-1].tb_lineno
except AttributeError:
ln = inspect.currentframe().f_back.f_lineno
self.message = "{0.__name__} (line {1}): {2}".format(type(self), ln, msg)
self.args = self.message,
def handleGUIException(exc_type, exc_value, exc_traceback):
try:
# Try and import wx in case it's missing.
# noinspection PyPackageRequirements
import wx
from gui.errorDialog import ErrorFrame
except:
# noinspection PyShadowingNames
wx = None
# noinspection PyShadowingNames
ErrorFrame = None
tb = traceback.format_tb(exc_traceback)
@@ -100,25 +112,31 @@ def handleGUIException(exc_type, exc_value, exc_traceback):
# Print the base level traceback
traceback.print_tb(exc_traceback)
pyfa = wx.App(False)
if exc_type == PreCheckException:
msgbox = wx.MessageBox(exc_value.message, 'Error', wx.ICON_ERROR | wx.STAY_ON_TOP)
msgbox.ShowModal()
else:
ErrorFrame(exc_value, tb)
pyfa.MainLoop()
if wx and ErrorFrame:
pyfa_gui = wx.App(False)
if exc_type == PreCheckException:
ErrorFrame(exc_value, None, "Missing Prerequisite")
else:
ErrorFrame(exc_value, tb)
pyfa_gui.MainLoop()
pyfalog.info("Exiting.")
except:
# Most likely logging isn't available. Try and output to the console
print("Exception in main thread: " + str(exc_value.message))
traceback.print_tb(exc_traceback)
pyfa = wx.App(False)
if exc_type == PreCheckException:
msgbox = wx.MessageBox(exc_value.message, 'Error', wx.ICON_ERROR | wx.STAY_ON_TOP)
msgbox.ShowModal()
else:
ErrorFrame(exc_value, tb)
pyfa.MainLoop()
if wx and ErrorFrame:
pyfa_gui = wx.App(False)
if exc_type == PreCheckException:
ErrorFrame(exc_value, None, "Missing Prerequisite")
else:
ErrorFrame(exc_value, tb)
pyfa_gui.MainLoop()
print("Exiting.")
finally:
# TODO: Add cleanup when exiting here.
@@ -190,7 +208,7 @@ if __name__ == "__main__":
else:
savePath_filename = "Pyfa.log"
savePath_Destination = os.path.join(config.savePath, savePath_filename)
config.logPath = os.path.join(config.savePath, savePath_filename)
try:
if options.debug:
@@ -205,7 +223,7 @@ if __name__ == "__main__":
level=options.logginglevel
),
TimedRotatingFileHandler(
savePath_Destination,
config.logPath,
level=0,
backup_count=3,
bubble=True,
@@ -220,7 +238,7 @@ if __name__ == "__main__":
NullHandler(),
FingersCrossedHandler(
TimedRotatingFileHandler(
savePath_Destination,
config.logPath,
level=0,
backup_count=3,
bubble=False,
@@ -248,26 +266,28 @@ if __name__ == "__main__":
with logging_setup.threadbound():
pyfalog.info("Starting Pyfa")
pyfalog.info("Logbook version: {0}", logbook_version)
pyfalog.info("Running in logging mode: {0}", logging_mode)
pyfalog.info("Writing log file to: {0}", savePath_Destination)
pyfalog.info("Writing log file to: {0}", config.logPath)
# Output all stdout (print) messages as warnings
try:
sys.stdout = LoggerWriter(pyfalog.warning)
except ValueError, Exception:
except:
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
# Output all stderr (stacktrace) messages as critical
try:
sys.stderr = LoggerWriter(pyfalog.critical)
except ValueError, Exception:
except:
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
pyfalog.info("OS version: {0}", platform.platform())
pyfalog.info("Python version: {0}", sys.version)
if sys.version_info < (2, 7) or sys.version_info > (3, 0):
exit_message = "Pyfa requires python 2.x branch ( >= 2.7 ).\nExiting."
exit_message = "Pyfa requires python 2.x branch ( >= 2.7 )."
raise PreCheckException(exit_message)
if hasattr(sys, 'frozen'):
@@ -275,34 +295,29 @@ if __name__ == "__main__":
else:
pyfalog.info("Running in a thawed state.")
# FIX THIS
try:
if options.force28 is True:
wxversion.select('2.8')
else:
wxversion.select(['3.0', '2.8'])
if hasattr(sys, 'frozen'):
pyfalog.info("Running in frozen state. Skipping wx validation.")
pyfalog.debug("wxPython version: {0}.", wxversion.getInstalled())
elif options.force28 is True:
# Remove existing wxPython
wxversion.select('2.8')
if hasattr(sys, 'frozen') and wx is not None:
pyfalog.info("Running in frozen state with wx installed. Skipping wx validation.")
pyfalog.debug("wxPython version: {0}.", wxversion.getInstalled())
elif wx is None or wxversion is None:
exit_message = "\nCannot find wxPython\nYou can download wxPython (2.8+) from http://www.wxpython.org/"
raise PreCheckException(exit_message)
if not hasattr(sys, 'frozen') and wxversion:
try:
if options.force28 is True:
pyfalog.info("Selecting wx version: 2.8. (Forced)")
wxversion.select('2.8')
else:
pyfalog.info("Selecting wx versions: 3.0, 2.8")
wxversion.select(['3.0', '2.8'])
except:
pyfalog.warning("Unable to select wx version. Attempting to import wx without specifying the version.")
else:
if options.force28 is True and wxversion.checkInstalled('2.8'):
pyfalog.info("wxPython is installed. Version: {0} (forced).", wxversion.getInstalled())
elif options.force28 is not True and (wxversion.checkInstalled('2.8') or wxversion.checkInstalled('3.0')):
pyfalog.info("wxPython is installed. Version: {0}.", wxversion.getInstalled())
else:
pyfalog.warning("\nInstalled wxPython version doesn't meet requirements.\nYou can download wxPython 2.8 or 3.0 from http://www.wxpython.org/")
pyfalog.critical("Attempting to run with unsupported version of wx. Version: {0}", wxversion.getInstalled())
if not wxversion:
pyfalog.warning("wxVersion not found. Attempting to import wx without specifying the version.")
try:
# noinspection PyPackageRequirements
import wx
from gui.errorDialog import ErrorFrame
except:
exit_message = "Cannot import wxPython. You can download wxPython (2.8+) from http://www.wxpython.org/"
raise PreCheckException(exit_message)
pyfalog.info("wxPython version: {0}.", str(wx.VERSION_STRING))
if sqlalchemy is None:
exit_message = "\nCannot find sqlalchemy.\nYou can download sqlalchemy (0.6+) from http://www.sqlalchemy.org/"