From 0d4f24ade9aec5e3d263bf4f78817b612467658b Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Sat, 26 Nov 2016 22:57:53 -0800 Subject: [PATCH] Handle unicode, utf8, and windows-1252 --- config.py | 109 +++++++++++----- gui/bitmapLoader.py | 22 ++-- gui/graphFrame.py | 67 ++++++---- gui/itemStats.py | 284 +++++++++++++++++++++-------------------- service/pycrest/eve.py | 31 +++-- service/settings.py | 63 +++++---- 6 files changed, 333 insertions(+), 243 deletions(-) diff --git a/config.py b/config.py index 9e3dc3d36..a251be1cb 100644 --- a/config.py +++ b/config.py @@ -31,18 +31,20 @@ gameDB = None class StreamToLogger(object): - """ - Fake file-like stream object that redirects writes to a logger instance. - From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/ - """ - def __init__(self, logger, log_level=logging.INFO): - self.logger = logger - self.log_level = log_level - self.linebuf = '' + """ + Fake file-like stream object that redirects writes to a logger instance. + From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/ + """ + + def __init__(self, logger, log_level=logging.INFO): + self.logger = logger + self.log_level = log_level + self.linebuf = '' + + def write(self, buf): + for line in buf.rstrip().splitlines(): + self.logger.log(self.log_level, line.rstrip()) - def write(self, buf): - for line in buf.rstrip().splitlines(): - self.logger.log(self.log_level, line.rstrip()) def isFrozen(): if hasattr(sys, 'frozen'): @@ -50,16 +52,12 @@ def isFrozen(): else: return False -def getPyfaRoot(): - base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0] - root = os.path.dirname(os.path.realpath(os.path.abspath(base))) - root = unicode(root, sys.getfilesystemencoding()) - return root def __createDirs(path): if not os.path.exists(path): os.makedirs(path) + def defPaths(customSavePath): global debug global pyfaPath @@ -77,32 +75,32 @@ def defPaths(customSavePath): # Python 2.X uses ANSI by default, so we need to convert the character encoding pyfaPath = getattr(configforced, "pyfaPath", pyfaPath) if pyfaPath is None: - pyfaPath = getPyfaRoot() + pyfaPath = getPyfaPath() # Where we store the saved fits etc, default is the current users home directory if saveInRoot is True: savePath = getattr(configforced, "savePath", None) if savePath is None: - savePath = os.path.join(pyfaPath, "saveddata") + savePath = getPyfaPath("saveddata") else: savePath = getattr(configforced, "savePath", None) if savePath is None: - if customSavePath is None: # customSavePath is not overriden - savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")), - sys.getfilesystemencoding()) + if customSavePath is None: # customSavePath is not overriden + savePath = getSavePath() else: savePath = customSavePath __createDirs(savePath) if isFrozen(): - os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem") - os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem") + certName = "cacert.pem" + os.environ["REQUESTS_CA_BUNDLE"] = getPyfaPath(certName) + os.environ["SSL_CERT_FILE"] = getPyfaPath(certName) - format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s' - logging.basicConfig(format=format, level=logLevel) - handler = logging.handlers.RotatingFileHandler(os.path.join(savePath, "log.txt"), maxBytes=1000000, backupCount=3) - formatter = logging.Formatter(format) + loggingFormat = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s' + logging.basicConfig(format=loggingFormat, level=logLevel) + handler = logging.handlers.RotatingFileHandler(getSavePath("log.txt"), maxBytes=1000000, backupCount=3) + formatter = logging.Formatter(loggingFormat) handler.setFormatter(formatter) logging.getLogger('').addHandler(handler) @@ -114,23 +112,68 @@ def defPaths(customSavePath): sys.stdout = sl # This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this. - #stderr_logger = logging.getLogger('STDERR') - #sl = StreamToLogger(stderr_logger, logging.ERROR) - #sys.stderr = sl + # stderr_logger = logging.getLogger('STDERR') + # sl = StreamToLogger(stderr_logger, logging.ERROR) + # sys.stderr = sl # The database where we store all the fits etc - saveDB = os.path.join(savePath, "saveddata.db") + saveDB = getSavePath("saveddata.db") # The database where the static EVE data from the datadump is kept. # This is not the standard sqlite datadump but a modified version created by eos # maintenance script - gameDB = os.path.join(pyfaPath, "eve.db") + gameDB = getPyfaPath("eve.db") ## DON'T MODIFY ANYTHING BELOW ## import eos.config - #Caching modifiers, disable all gamedata caching, its unneeded. + # Caching modifiers, disable all gamedata caching, its unneeded. eos.config.gamedataCache = False # saveddata db location modifier, shouldn't ever need to touch this eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False" eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False" + + +def getPyfaPath(Append=None): + base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0] + root = os.path.dirname(os.path.realpath(os.path.abspath(base))) + if type(root) == str: # leave unicode ones alone + try: + root = root.decode('utf8') + except UnicodeDecodeError: + root = root.decode('windows-1252') + + if not Append: + return root + + if type(root) == str: # leave unicode ones alone + try: + path = os.path.abspath(os.path.join(root, Append)).decode('utf8') + except UnicodeDecodeError: + path = os.path.abspath(os.path.join(root, Append)).decode('windows-1252') + else: + path = os.path.abspath(os.path.join(root, Append)) + + return path + + +def getSavePath(Append=None): + root = os.path.expanduser(os.path.join("~", ".pyfa")) + if type(root) == str: # leave unicode ones alone + try: + root = root.decode('utf8') + except UnicodeDecodeError: + root = root.decode('windows-1252') + + if not Append: + return root + + if type(root) == str: # leave unicode ones alone + try: + path = os.path.abspath(os.path.join(root, Append)).decode('utf8') + except UnicodeDecodeError: + path = os.path.abspath(os.path.join(root, Append)).decode('windows-1252') + else: + path = os.path.abspath(os.path.join(root, Append)) + + return path diff --git a/gui/bitmapLoader.py b/gui/bitmapLoader.py index 45026bedb..2b991a818 100644 --- a/gui/bitmapLoader.py +++ b/gui/bitmapLoader.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of pyfa. @@ -15,23 +15,25 @@ # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . -#=============================================================================== +# =============================================================================== -import os.path -import config -import wx -import zipfile import cStringIO +import os.path +import zipfile + +import wx + +import config try: from collections import OrderedDict except ImportError: from utils.compat import OrderedDict -class BitmapLoader(): +class BitmapLoader(): try: - archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r') + archive = zipfile.ZipFile(config.getPyfaPath('imgs.zip'), 'r') except IOError: archive = None @@ -42,7 +44,7 @@ class BitmapLoader(): @classmethod def getStaticBitmap(cls, name, parent, location): static = wx.StaticBitmap(parent) - static.SetBitmap(cls.getBitmap(name,location)) + static.SetBitmap(cls.getBitmap(name, location)) return static @classmethod @@ -85,7 +87,7 @@ class BitmapLoader(): except KeyError: print "Missing icon file from zip: {0}".format(path) else: - path = os.path.join(config.pyfaPath, 'imgs', location, filename) + path = config.getPyfaPath('imgs\\' + location + "\\" + filename) if os.path.exists(path): return wx.Image(path) diff --git a/gui/graphFrame.py b/gui/graphFrame.py index 2cedc84d1..4efac6b14 100644 --- a/gui/graphFrame.py +++ b/gui/graphFrame.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of pyfa. @@ -15,21 +15,23 @@ # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . -#=============================================================================== +# =============================================================================== + +import os import wx -import os -from gui.bitmapLoader import BitmapLoader + import gui.display import gui.globalEvents as GE - -from gui.graph import Graph -import service import gui.mainFrame +import service +from gui.bitmapLoader import BitmapLoader +from gui.graph import Graph enabled = True mplImported = False + class GraphFrame(wx.Frame): def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT): @@ -46,9 +48,20 @@ class GraphFrame(wx.Frame): try: cache_dir = mpl._get_cachedir() except: - cache_dir = unicode(os.path.expanduser(os.path.join("~", ".matplotlib"))) + cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib")) + if type(cache_dir) == str: # leave unicode ones alone + try: + cache_dir = cache_dir.decode('utf8') + except UnicodeDecodeError: + cache_dir = cache_dir.decode('windows-1252') cache_file = os.path.join(cache_dir, 'fontList.cache') + if type(cache_file) == str: # leave unicode ones alone + try: + cache_file = cache_file.decode('utf8') + except UnicodeDecodeError: + cache_file = cache_file.decode('windows-1252') + if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file): # remove matplotlib font cache, see #234 os.remove(cache_file) @@ -58,7 +71,7 @@ class GraphFrame(wx.Frame): from matplotlib.figure import Figure enabled = True if mpl.__version__[0] != "1": - print "pyfa: Found matplotlib version ",mpl.__version__, " - activating OVER9000 workarounds" + print "pyfa: Found matplotlib version ", mpl.__version__, " - activating OVER9000 workarounds" print "pyfa: Recommended minimum matplotlib version is 1.0.0" self.legendFix = True except: @@ -91,19 +104,20 @@ class GraphFrame(wx.Frame): self.figure = Figure(figsize=(4, 3)) - rgbtuple = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ).Get() - clr = [c/255. for c in rgbtuple] - self.figure.set_facecolor( clr ) - self.figure.set_edgecolor( clr ) + rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get() + clr = [c / 255. for c in rgbtuple] + self.figure.set_facecolor(clr) + self.figure.set_edgecolor(clr) self.canvas = Canvas(self, -1, self.figure) - self.canvas.SetBackgroundColour( wx.Colour( *rgbtuple ) ) + self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple)) self.subplot = self.figure.add_subplot(111) self.subplot.grid(True) self.mainSizer.Add(self.canvas, 1, wx.EXPAND) - self.mainSizer.Add(wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0 , wx.EXPAND) + self.mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, + wx.EXPAND) self.gridPanel = wx.Panel(self) self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND) @@ -122,8 +136,8 @@ class GraphFrame(wx.Frame): self.graphSelection.SetSelection(0) self.fields = {} self.select(0) - self.sl1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - self.mainSizer.Add(self.sl1,0, wx.EXPAND) + self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) + self.mainSizer.Add(self.sl1, 0, wx.EXPAND) self.mainSizer.Add(self.fitList, 0, wx.EXPAND) self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem) @@ -160,18 +174,18 @@ class GraphFrame(wx.Frame): self.gridPanel.DestroyChildren() self.fields.clear() - #Setup textboxes + # Setup textboxes for field, defaultVal in view.getFields().iteritems(): textBox = wx.TextCtrl(self.gridPanel, wx.ID_ANY, style=0) self.fields[field] = textBox textBox.Bind(wx.EVT_TEXT, self.onFieldChanged) - sizer.Add(textBox, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) + sizer.Add(textBox, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) if defaultVal is not None: if not isinstance(defaultVal, basestring): defaultVal = ("%f" % defaultVal).rstrip("0") if defaultVal[-1:] == ".": - defaultVal = defaultVal + "0" + defaultVal += "0" textBox.ChangeValue(defaultVal) @@ -189,7 +203,8 @@ class GraphFrame(wx.Frame): else: label = field - imgLabelSizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY, label), 0, wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 3) + imgLabelSizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY, label), 0, + wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 3) sizer.Add(imgLabelSizer, 0, wx.ALIGN_CENTER_VERTICAL) self.draw() @@ -204,7 +219,7 @@ class GraphFrame(wx.Frame): try: success, status = view.getPoints(fit, values) if not success: - #TODO: Add a pwetty statys bar to report errors with + # TODO: Add a pwetty statys bar to report errors with self.SetStatusText(status) return @@ -218,15 +233,15 @@ class GraphFrame(wx.Frame): return if self.legendFix and len(legend) > 0: - leg = self.subplot.legend(tuple(legend), "upper right" , shadow = False) + leg = self.subplot.legend(tuple(legend), "upper right", shadow=False) for t in leg.get_texts(): t.set_fontsize('small') for l in leg.get_lines(): l.set_linewidth(1) - elif not self.legendFix and len(legend) >0: - leg = self.subplot.legend(tuple(legend), "upper right" , shadow = False, frameon = False) + elif not self.legendFix and len(legend) > 0: + leg = self.subplot.legend(tuple(legend), "upper right", shadow=False, frameon=False) for t in leg.get_texts(): t.set_fontsize('small') @@ -269,10 +284,10 @@ class FitList(wx.Panel): fitToolTip = wx.ToolTip("Drag a fit into this list to graph it") self.fitList.SetToolTip(fitToolTip) + class FitDisplay(gui.display.Display): DEFAULT_COLS = ["Base Icon", "Base Name"] def __init__(self, parent): gui.display.Display.__init__(self, parent) - diff --git a/gui/itemStats.py b/gui/itemStats.py index 63e4ce67d..c0c270519 100644 --- a/gui/itemStats.py +++ b/gui/itemStats.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of pyfa. @@ -15,38 +15,41 @@ # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . -#=============================================================================== +# =============================================================================== + +import csv +import re +import sys import wx -import re -import gui.mainFrame -from gui.bitmapLoader import BitmapLoader -import sys -import wx.lib.mixins.listctrl as listmix import wx.html -from eos.types import Fit, Ship, Citadel, Module, Skill, Booster, Implant, Drone, Mode, Fighter -from gui.utils.numberFormatter import formatAmount -import service +import wx.lib.mixins.listctrl as listmix + import config +import gui.mainFrame +import service +from eos.types import Fit, Ship, Citadel, Module, Skill, Booster, Implant, Drone, Mode, Fighter +from gui.bitmapLoader import BitmapLoader from gui.contextMenu import ContextMenu from gui.utils.numberFormatter import formatAmount -import csv try: from collections import OrderedDict except ImportError: from utils.compat import OrderedDict + class ItemStatsDialog(wx.Dialog): counter = 0 + def __init__( self, victim, fullContext=None, pos=wx.DefaultPosition, size=wx.DefaultSize, - maximized = False - ): + maximized=False + ): wx.Dialog.__init__( self, @@ -55,7 +58,7 @@ class ItemStatsDialog(wx.Dialog): title="Item stats", pos=pos, size=size, - style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER| wx.SYSTEM_MENU + style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU ) empty = getattr(victim, "isEmpty", False) @@ -77,26 +80,27 @@ class ItemStatsDialog(wx.Dialog): victim = None self.context = itmContext if item.icon is not None: - before,sep,after = item.icon.iconFile.rpartition("_") - iconFile = "%s%s%s" % (before,sep,"0%s" % after if len(after) < 2 else after) + before, sep, after = item.icon.iconFile.rpartition("_") + iconFile = "%s%s%s" % (before, sep, "0%s" % after if len(after) < 2 else after) itemImg = BitmapLoader.getBitmap(iconFile, "icons") if itemImg is not None: self.SetIcon(wx.IconFromBitmap(itemImg)) - self.SetTitle("%s: %s%s" % ("%s Stats" % itmContext if itmContext is not None else "Stats", item.name, " (%d)"%item.ID if config.debug else "")) + self.SetTitle("%s: %s%s" % ("%s Stats" % itmContext if itmContext is not None else "Stats", item.name, + " (%d)" % item.ID if config.debug else "")) self.SetMinSize((300, 200)) if "wxGTK" in wx.PlatformInfo: # GTK has huge tab widgets, give it a bit more room self.SetSize((580, 500)) else: self.SetSize((550, 500)) - #self.SetMaxSize((500, -1)) + # self.SetMaxSize((500, -1)) self.mainSizer = wx.BoxSizer(wx.VERTICAL) self.container = ItemStatsContainer(self, victim, item, itmContext) self.mainSizer.Add(self.container, 1, wx.EXPAND) if "wxGTK" in wx.PlatformInfo: - self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) + self.closeBtn = wx.Button(self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0) + self.mainSizer.Add(self.closeBtn, 0, wx.ALL | wx.ALIGN_RIGHT, 5) self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent) self.SetSizer(self.mainSizer) @@ -112,13 +116,13 @@ class ItemStatsDialog(wx.Dialog): counter = ItemStatsDialog.counter dlgStep = 30 - if counter * dlgStep > ppos.x+psize.width-dlgsize.x or counter * dlgStep > ppos.y+psize.height-dlgsize.y: + if counter * dlgStep > ppos.x + psize.width - dlgsize.x or counter * dlgStep > ppos.y + psize.height - dlgsize.y: ItemStatsDialog.counter = 1 dlgx = ppos.x + counter * dlgStep dlgy = ppos.y + counter * dlgStep if pos == wx.DefaultPosition: - self.SetPosition((dlgx,dlgy)) + self.SetPosition((dlgx, dlgy)) else: self.SetPosition(pos) if maximized: @@ -138,26 +142,26 @@ class ItemStatsDialog(wx.Dialog): def closeEvent(self, event): - if self.dlgOrder==ItemStatsDialog.counter: + if self.dlgOrder == ItemStatsDialog.counter: ItemStatsDialog.counter -= 1 self.parentWnd.UnregisterStatsWindow(self) self.Destroy() + ########################################################################### ## Class ItemStatsContainer ########################################################################### -class ItemStatsContainer ( wx.Panel ): - - def __init__( self, parent, stuff, item, context = None): - wx.Panel.__init__ ( self, parent ) +class ItemStatsContainer(wx.Panel): + def __init__(self, parent, stuff, item, context=None): + wx.Panel.__init__(self, parent) sMkt = service.Market.getInstance() - mainSizer = wx.BoxSizer( wx.VERTICAL ) + mainSizer = wx.BoxSizer(wx.VERTICAL) - self.nbContainer = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 ) - mainSizer.Add( self.nbContainer, 1, wx.EXPAND |wx.ALL, 2 ) + self.nbContainer = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0) + mainSizer.Add(self.nbContainer, 1, wx.EXPAND | wx.ALL, 2) if item.traits is not None: self.traits = ItemTraits(self.nbContainer, stuff, item) @@ -188,7 +192,7 @@ class ItemStatsContainer ( wx.Panel ): self.SetSizer(mainSizer) self.Layout() - def __del__( self ): + def __del__(self): pass def mouseHit(self, event): @@ -196,54 +200,54 @@ class ItemStatsContainer ( wx.Panel ): if tab != -1: self.nbContainer.SetSelection(tab) + ########################################################################### ## Class AutoListCtrl ########################################################################### class AutoListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ListRowHighlighter): - def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, ID, pos, size, style) listmix.ListCtrlAutoWidthMixin.__init__(self) listmix.ListRowHighlighter.__init__(self) + ########################################################################### ## Class AutoListCtrl ########################################################################### class AutoListCtrlNoHighlight(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ListRowHighlighter): - def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, ID, pos, size, style) listmix.ListCtrlAutoWidthMixin.__init__(self) + ########################################################################### ## Class ItemTraits ########################################################################### -class ItemTraits ( wx.Panel ): - +class ItemTraits(wx.Panel): def __init__(self, parent, stuff, item): - wx.Panel.__init__ (self, parent) + wx.Panel.__init__(self, parent) mainSizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(mainSizer) self.traits = wx.html.HtmlWindow(self) self.traits.SetPage(item.traits.traitText) - mainSizer.Add(self.traits, 1, wx.ALL|wx.EXPAND, 0) + mainSizer.Add(self.traits, 1, wx.ALL | wx.EXPAND, 0) self.Layout() + ########################################################################### ## Class ItemDescription ########################################################################### -class ItemDescription ( wx.Panel ): - +class ItemDescription(wx.Panel): def __init__(self, parent, stuff, item): - wx.Panel.__init__ (self, parent) + wx.Panel.__init__(self, parent) mainSizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(mainSizer) @@ -260,28 +264,30 @@ class ItemDescription ( wx.Panel ): desc = re.sub("<( *)font( *)color( *)=(.*?)>(?P.*?)<( *)/( *)font( *)>", "\g", desc) # Strip URLs desc = re.sub("<( *)a(.*?)>(?P.*?)<( *)/( *)a( *)>", "\g", desc) - desc = "" + desc + "" + desc = "" + desc + "" self.description.SetPage(desc) - mainSizer.Add(self.description, 1, wx.ALL|wx.EXPAND, 0) + mainSizer.Add(self.description, 1, wx.ALL | wx.EXPAND, 0) self.Layout() + ########################################################################### ## Class ItemParams ########################################################################### -class ItemParams (wx.Panel): - def __init__(self, parent, stuff, item, context = None): - wx.Panel.__init__ (self, parent) - mainSizer = wx.BoxSizer( wx.VERTICAL ) +class ItemParams(wx.Panel): + def __init__(self, parent, stuff, item, context=None): + wx.Panel.__init__(self, parent) + mainSizer = wx.BoxSizer(wx.VERTICAL) self.paramList = AutoListCtrl(self, wx.ID_ANY, - style = #wx.LC_HRULES | - #wx.LC_NO_HEADER | - wx.LC_REPORT |wx.LC_SINGLE_SEL |wx.LC_VRULES |wx.NO_BORDER) - mainSizer.Add( self.paramList, 1, wx.ALL|wx.EXPAND, 0 ) - self.SetSizer( mainSizer ) + style= # wx.LC_HRULES | + # wx.LC_NO_HEADER | + wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER) + mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0) + self.SetSizer(mainSizer) self.toggleView = 1 self.stuff = stuff @@ -290,29 +296,31 @@ class ItemParams (wx.Panel): self.attrValues = {} self._fetchValues() - self.m_staticline = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - mainSizer.Add( self.m_staticline, 0, wx.EXPAND) - bSizer = wx.BoxSizer( wx.HORIZONTAL ) + self.m_staticline = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) + mainSizer.Add(self.m_staticline, 0, wx.EXPAND) + bSizer = wx.BoxSizer(wx.HORIZONTAL) - self.totalAttrsLabel = wx.StaticText( self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT) + self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0) + bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT) - self.toggleViewBtn = wx.ToggleButton( self, wx.ID_ANY, u"Toggle view mode", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle view mode", wx.DefaultPosition, wx.DefaultSize, + 0) + bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL) - self.exportStatsBtn = wx.ToggleButton( self, wx.ID_ANY, u"Export Item Stats", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.exportStatsBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.exportStatsBtn = wx.ToggleButton(self, wx.ID_ANY, u"Export Item Stats", wx.DefaultPosition, wx.DefaultSize, + 0) + bSizer.Add(self.exportStatsBtn, 0, wx.ALIGN_CENTER_VERTICAL) if stuff is not None: - self.refreshBtn = wx.Button( self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT ) - bSizer.Add( self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL) - self.refreshBtn.Bind( wx.EVT_BUTTON, self.RefreshValues ) + self.refreshBtn = wx.Button(self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT) + bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshValues) - mainSizer.Add( bSizer, 0, wx.ALIGN_RIGHT) + mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT) self.PopulateList() - self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON,self.ToggleViewMode) + self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleViewMode) self.exportStatsBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ExportItemStats) def _fetchValues(self): @@ -348,7 +356,7 @@ class ItemParams (wx.Panel): event.Skip() def ToggleViewMode(self, event): - self.toggleView *=-1 + self.toggleView *= -1 self.UpdateList() event.Skip() @@ -412,17 +420,17 @@ class ItemParams (wx.Panel): ) def PopulateList(self): - self.paramList.InsertColumn(0,"Attribute") - self.paramList.InsertColumn(1,"Current Value") + self.paramList.InsertColumn(0, "Attribute") + self.paramList.InsertColumn(1, "Current Value") if self.stuff is not None: - self.paramList.InsertColumn(2,"Base Value") - self.paramList.SetColumnWidth(0,110) - self.paramList.SetColumnWidth(1,90) + self.paramList.InsertColumn(2, "Base Value") + self.paramList.SetColumnWidth(0, 110) + self.paramList.SetColumnWidth(1, 90) if self.stuff is not None: - self.paramList.SetColumnWidth(2,90) + self.paramList.SetColumnWidth(2, 90) self.paramList.setResizeColumn(0) self.imageList = wx.ImageList(16, 16) - self.paramList.SetImageList(self.imageList,wx.IMAGE_LIST_SMALL) + self.paramList.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL) names = list(self.attrValues.iterkeys()) names.sort() @@ -461,7 +469,6 @@ class ItemParams (wx.Panel): else: attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons")) - index = self.paramList.InsertImageStringItem(sys.maxint, attrName, attrIcon) idNameMap[idCount] = attrName self.paramList.SetItemData(index, idCount) @@ -485,11 +492,9 @@ class ItemParams (wx.Panel): if self.stuff is not None: self.paramList.SetStringItem(index, 2, valueUnitDefault) - - self.paramList.SortItems(lambda id1, id2: cmp(idNameMap[id1], idNameMap[id2])) self.paramList.RefreshRows() - self.totalAttrsLabel.SetLabel("%d attributes. " %idCount) + self.totalAttrsLabel.SetLabel("%d attributes. " % idCount) self.Layout() def TranslateValueUnit(self, value, unitName, unitDisplayName): @@ -505,15 +510,16 @@ class ItemParams (wx.Panel): attribute = service.Attribute.getInstance().getAttributeInfo(value) return "%s (%d)" % (attribute.name.capitalize(), value) - trans = {"Inverse Absolute Percent": (lambda: (1-value)*100, unitName), - "Inversed Modifier Percent": (lambda: (1-value) * 100, unitName), - "Modifier Percent": (lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName), + trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName), + "Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName), + "Modifier Percent": ( + lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName), "Volume": (lambda: value, u"m\u00B3"), "Sizeclass": (lambda: value, ""), - "Absolute Percent": (lambda: (value * 100) , unitName), + "Absolute Percent": (lambda: (value * 100), unitName), "Milliseconds": (lambda: value / 1000.0, unitName), "typeID": (itemIDCallback, ""), - "groupID": (groupIDCallback,""), + "groupID": (groupIDCallback, ""), "attributeID": (attributeIDCallback, "")} override = trans.get(unitDisplayName) @@ -527,9 +533,10 @@ class ItemParams (wx.Panel): fvalue = formatAmount(v, 3, 0, 0) else: fvalue = v - return "%s %s" % (fvalue , override[1]) + return "%s %s" % (fvalue, override[1]) else: - return "%s %s" % (formatAmount(value, 3, 0),unitName) + return "%s %s" % (formatAmount(value, 3, 0), unitName) + class ItemCompare(wx.Panel): def __init__(self, parent, stuff, item, items, context=None): @@ -546,7 +553,8 @@ class ItemCompare(wx.Panel): self.toggleView = 1 self.stuff = stuff self.item = item - self.items = sorted(items, key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else None) + self.items = sorted(items, + key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else None) self.attrs = {} # get a dict of attrName: attrInfo of all unique attributes across all items @@ -618,7 +626,7 @@ class ItemCompare(wx.Panel): def processPrices(self, prices): for i, price in enumerate(prices): - self.paramList.SetStringItem(i, len(self.attrs)+1, formatAmount(price.price, 3, 3, 9, currency=True)) + self.paramList.SetStringItem(i, len(self.attrs) + 1, formatAmount(price.price, 3, 3, 9, currency=True)) def PopulateList(self): self.paramList.InsertColumn(0, "Item") @@ -626,11 +634,11 @@ class ItemCompare(wx.Panel): for i, attr in enumerate(self.attrs.keys()): name = self.attrs[attr].displayName if self.attrs[attr].displayName else attr - self.paramList.InsertColumn(i+1, name) - self.paramList.SetColumnWidth(i+1, 120) + self.paramList.InsertColumn(i + 1, name) + self.paramList.SetColumnWidth(i + 1, 120) - self.paramList.InsertColumn(len(self.attrs)+1, "Price") - self.paramList.SetColumnWidth(len(self.attrs)+1, 60) + self.paramList.InsertColumn(len(self.attrs) + 1, "Price") + self.paramList.SetColumnWidth(len(self.attrs) + 1, 60) sMkt = service.Market.getInstance() sMkt.getPrices([x.ID for x in self.items], self.processPrices) @@ -648,7 +656,7 @@ class ItemCompare(wx.Panel): else: valueUnit = formatAmount(value, 3, 0, 0) - self.paramList.SetStringItem(i, x+1, valueUnit) + self.paramList.SetStringItem(i, x + 1, valueUnit) self.paramList.RefreshRows() self.Layout() @@ -669,7 +677,7 @@ class ItemCompare(wx.Panel): trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName), "Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName), "Modifier Percent": ( - lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName), + lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName), "Volume": (lambda: value, u"m\u00B3"), "Sizeclass": (lambda: value, ""), "Absolute Percent": (lambda: (value * 100), unitName), @@ -698,19 +706,18 @@ class ItemCompare(wx.Panel): ## Class ItemRequirements ########################################################################### -class ItemRequirements ( wx.Panel ): - +class ItemRequirements(wx.Panel): def __init__(self, parent, stuff, item): - wx.Panel.__init__ (self, parent, style = wx.TAB_TRAVERSAL) + wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) - #itemId is set by the parent. - self.romanNb = ["0","I","II","III","IV","V","VI","VII","VIII","IX","X"] - self.skillIdHistory=[] - mainSizer = wx.BoxSizer( wx.VERTICAL ) + # itemId is set by the parent. + self.romanNb = ["0", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"] + self.skillIdHistory = [] + mainSizer = wx.BoxSizer(wx.VERTICAL) - self.reqTree = wx.TreeCtrl(self, style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.NO_BORDER) + self.reqTree = wx.TreeCtrl(self, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.NO_BORDER) - mainSizer.Add(self.reqTree, 1, wx.ALL|wx.EXPAND, 0) + mainSizer.Add(self.reqTree, 1, wx.ALL | wx.EXPAND, 0) self.SetSizer(mainSizer) self.root = self.reqTree.AddRoot("WINRARZOR") @@ -720,17 +727,17 @@ class ItemRequirements ( wx.Panel ): self.reqTree.SetImageList(self.imageList) skillBookId = self.imageList.Add(BitmapLoader.getBitmap("skill_small", "gui")) - self.getFullSkillTree(item,self.root,skillBookId) + self.getFullSkillTree(item, self.root, skillBookId) self.reqTree.ExpandAll() self.Layout() - def getFullSkillTree(self,parentSkill,parent,sbIconId): + def getFullSkillTree(self, parentSkill, parent, sbIconId): for skill, level in parentSkill.requiredSkills.iteritems(): - child = self.reqTree.AppendItem(parent,"%s %s" %(skill.name,self.romanNb[int(level)]), sbIconId) + child = self.reqTree.AppendItem(parent, "%s %s" % (skill.name, self.romanNb[int(level)]), sbIconId) if skill.ID not in self.skillIdHistory: - self.getFullSkillTree(skill,child,sbIconId) + self.getFullSkillTree(skill, child, sbIconId) self.skillIdHistory.append(skill.ID) @@ -738,7 +745,7 @@ class ItemRequirements ( wx.Panel ): ## Class ItemEffects ########################################################################### -class ItemEffects (wx.Panel): +class ItemEffects(wx.Panel): def __init__(self, parent, stuff, item): wx.Panel.__init__(self, parent) self.item = item @@ -761,17 +768,17 @@ class ItemEffects (wx.Panel): def PopulateList(self): - self.effectList.InsertColumn(0,"Name") - self.effectList.InsertColumn(1,"Active") + self.effectList.InsertColumn(0, "Name") + self.effectList.InsertColumn(1, "Active") self.effectList.InsertColumn(2, "Type") if config.debug: self.effectList.InsertColumn(3, "Run Time") - self.effectList.InsertColumn(4,"ID") + self.effectList.InsertColumn(4, "ID") - #self.effectList.SetColumnWidth(0,385) + # self.effectList.SetColumnWidth(0,385) self.effectList.setResizeColumn(0) - self.effectList.SetColumnWidth(1,50) + self.effectList.SetColumnWidth(1, 50) self.effectList.SetColumnWidth(2, 80) if config.debug: self.effectList.SetColumnWidth(3, 65) @@ -840,7 +847,7 @@ class ItemEffects (wx.Panel): """ import os - file = os.path.join(config.pyfaPath, "eos", "effects", "%s.py"%event.GetText().lower()) + file = config.getPyfaPath("eos\\effects\\%s.py" % event.GetText().lower()) if not os.path.isfile(file): open(file, 'a').close() @@ -848,7 +855,7 @@ class ItemEffects (wx.Panel): if 'wxMSW' in wx.PlatformInfo: os.startfile(file) elif 'wxMac' in wx.PlatformInfo: - os.system("open "+file) + os.system("open " + file) else: import subprocess subprocess.call(["xdg-open", file]) @@ -862,13 +869,15 @@ class ItemEffects (wx.Panel): self.Thaw() event.Skip() + ########################################################################### ## Class ItemAffectedBy ########################################################################### -class ItemAffectedBy (wx.Panel): +class ItemAffectedBy(wx.Panel): ORDER = [Fit, Ship, Citadel, Mode, Module, Drone, Fighter, Implant, Booster, Skill] + def __init__(self, parent, stuff, item): wx.Panel.__init__(self, parent) self.stuff = stuff @@ -884,33 +893,33 @@ class ItemAffectedBy (wx.Panel): mainSizer = wx.BoxSizer(wx.VERTICAL) - self.affectedBy = wx.TreeCtrl(self, style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.NO_BORDER) - mainSizer.Add(self.affectedBy, 1, wx.ALL|wx.EXPAND, 0) + self.affectedBy = wx.TreeCtrl(self, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.NO_BORDER) + mainSizer.Add(self.affectedBy, 1, wx.ALL | wx.EXPAND, 0) - self.m_staticline = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + self.m_staticline = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) - mainSizer.Add( self.m_staticline, 0, wx.EXPAND) - bSizer = wx.BoxSizer( wx.HORIZONTAL ) + mainSizer.Add(self.m_staticline, 0, wx.EXPAND) + bSizer = wx.BoxSizer(wx.HORIZONTAL) - self.toggleExpandBtn = wx.ToggleButton( self, wx.ID_ANY, u"Expand All", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.toggleExpandBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.toggleExpandBtn = wx.ToggleButton(self, wx.ID_ANY, u"Expand All", wx.DefaultPosition, wx.DefaultSize, 0) + bSizer.Add(self.toggleExpandBtn, 0, wx.ALIGN_CENTER_VERTICAL) - self.toggleNameBtn = wx.ToggleButton( self, wx.ID_ANY, u"Toggle Names", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.toggleNameBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.toggleNameBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle Names", wx.DefaultPosition, wx.DefaultSize, 0) + bSizer.Add(self.toggleNameBtn, 0, wx.ALIGN_CENTER_VERTICAL) - self.toggleViewBtn = wx.ToggleButton( self, wx.ID_ANY, u"Toggle View", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer.Add( self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle View", wx.DefaultPosition, wx.DefaultSize, 0) + bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL) if stuff is not None: - self.refreshBtn = wx.Button( self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT ) - bSizer.Add( self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL) - self.refreshBtn.Bind( wx.EVT_BUTTON, self.RefreshTree ) + self.refreshBtn = wx.Button(self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT) + bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL) + self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshTree) - self.toggleNameBtn.Bind(wx.EVT_TOGGLEBUTTON,self.ToggleNameMode) - self.toggleExpandBtn.Bind(wx.EVT_TOGGLEBUTTON,self.ToggleExpand) - self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON,self.ToggleViewMode) + self.toggleNameBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleNameMode) + self.toggleExpandBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleExpand) + self.toggleViewBtn.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleViewMode) - mainSizer.Add( bSizer, 0, wx.ALIGN_RIGHT) + mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT) self.SetSizer(mainSizer) self.PopulateTree() self.Layout() @@ -950,7 +959,7 @@ class ItemAffectedBy (wx.Panel): self.Thaw() - def ToggleExpand(self,event): + def ToggleExpand(self, event): self.expand *= -1 self.ExpandCollapseTree() @@ -1059,7 +1068,8 @@ class ItemAffectedBy (wx.Panel): else: item = afflictor.item - items[attrName].append((type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False))) + items[attrName].append( + (type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False))) # Make sure projected fits are on top rootOrder = container.keys() @@ -1135,7 +1145,6 @@ class ItemAffectedBy (wx.Panel): treeItem = self.affectedBy.AppendItem(child, display, itemIcon) self.affectedBy.SetPyData(treeItem, afflictor) - def buildModuleView(self, root): # We first build a usable dictionary of items. The key is either a fit # if the afflictions stem from a projected fit, or self.stuff if they @@ -1259,9 +1268,10 @@ class ItemAffectedBy (wx.Panel): else: penalized = "" - attributes.append((attrName, (displayName if displayName != "" else attrName), attrModifier, attrAmount, penalized, attrIcon)) + attributes.append((attrName, (displayName if displayName != "" else attrName), attrModifier, + attrAmount, penalized, attrIcon)) - attrSorted = sorted(attributes, key = lambda attribName: attribName[0]) + attrSorted = sorted(attributes, key=lambda attribName: attribName[0]) for attr in attrSorted: attrName, displayName, attrModifier, attrAmount, penalized, attrIcon = attr diff --git a/service/pycrest/eve.py b/service/pycrest/eve.py index c0f33becd..8218f2bc5 100644 --- a/service/pycrest/eve.py +++ b/service/pycrest/eve.py @@ -1,14 +1,17 @@ -import os import base64 +import logging +import os +import re import time import zlib import requests +from requests.adapters import HTTPAdapter -from . import version +import config from compat import bytes_, text_ from errors import APIException -from requests.adapters import HTTPAdapter +from . import version try: from urllib.parse import urlparse, urlunparse, parse_qsl @@ -24,9 +27,7 @@ try: from urllib.parse import quote except ImportError: # pragma: no cover from urllib import quote -import logging -import re -import config + logger = logging.getLogger("pycrest.eve") cache_re = re.compile(r'max-age=([0-9]+)') @@ -51,7 +52,13 @@ class FileCache(APICache): os.mkdir(self.path, 0o700) def _getpath(self, key): - return os.path.join(self.path, str(hash(key)) + '.cache') + path = os.path.join(self.path, str(hash(key)) + '.cache') + if type(path) == str: # leave unicode ones alone + try: + path = path.decode('utf8') + except UnicodeDecodeError: + path = path.decode('windows-1252') + return path def put(self, key, value): with open(self._getpath(key), 'wb') as f: @@ -111,7 +118,7 @@ class APIConnection(object): }) session.headers.update(additional_headers) session.mount('https://public-crest.eveonline.com', - HTTPAdapter()) + HTTPAdapter()) self._session = session if cache: if isinstance(cache, APICache): @@ -249,19 +256,18 @@ class EVE(APIConnection): def temptoken_authorize(self, access_token=None, expires_in=0, refresh_token=None): self.set_auth_values({'access_token': access_token, - 'refresh_token': refresh_token, - 'expires_in': expires_in}) + 'refresh_token': refresh_token, + 'expires_in': expires_in}) class AuthedConnection(EVE): - def __call__(self): if not self._data: self._data = APIObject(self.get(self._endpoint), self) return self._data def whoami(self): - #if 'whoami' not in self._cache: + # if 'whoami' not in self._cache: # print "Setting this whoami cache" # self._cache['whoami'] = self.get("%s/verify" % self._oauth_endpoint) return self.get("%s/verify" % self._oauth_endpoint) @@ -281,6 +287,7 @@ class AuthedConnection(EVE): self.refr_authorize(self.refresh_token) return self._session.delete(resource, params=params) + class APIObject(object): def __init__(self, parent, connection): self._dict = {} diff --git a/service/settings.py b/service/settings.py index 89f871973..71dbc9977 100644 --- a/service/settings.py +++ b/service/settings.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of pyfa. @@ -15,33 +15,41 @@ # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . -#=============================================================================== +# =============================================================================== import cPickle import os.path -import config import urllib2 +import config + + class SettingsProvider(): - BASE_PATH = os.path.join(config.savePath, "settings") + BASE_PATH = config.getSavePath("settings") settings = {} _instance = None + @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = SettingsProvider() return cls._instance def __init__(self): if not os.path.exists(self.BASE_PATH): - os.mkdir(self.BASE_PATH); + os.mkdir(self.BASE_PATH) def getSettings(self, area, defaults=None): s = self.settings.get(area) if s is None: p = os.path.join(self.BASE_PATH, area) + if type(p) == str: # leave unicode ones alone + try: + p = p.decode('utf8') + except UnicodeDecodeError: + p = p.decode('windows-1252') if not os.path.exists(p): info = {} @@ -71,6 +79,7 @@ class SettingsProvider(): for settings in self.settings.itervalues(): settings.save() + class Settings(): def __init__(self, location, info): self.location = location @@ -115,13 +124,13 @@ class NetworkSettings(): _instance = None # constants for serviceNetworkDefaultSettings["mode"] parameter - PROXY_MODE_NONE = 0 # 0 - No proxy + PROXY_MODE_NONE = 0 # 0 - No proxy PROXY_MODE_AUTODETECT = 1 # 1 - Auto-detected proxy settings - PROXY_MODE_MANUAL = 2 # 2 - Manual proxy settings + PROXY_MODE_MANUAL = 2 # 2 - Manual proxy settings @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = NetworkSettings() return cls._instance @@ -184,12 +193,11 @@ class NetworkSettings(): def setAccess(self, access): self.serviceNetworkSettings["access"] = access - def autodetect(self): + @staticmethod + def autodetect(): proxy = None - proxAddr = proxPort = "" proxydict = urllib2.ProxyHandler().proxies - txt = "Auto-detected: " validPrefixes = ("http", "https") @@ -237,53 +245,57 @@ class NetworkSettings(): self.serviceNetworkSettings["password"] = password - """ Settings used by the HTML export feature. """ + + class HTMLExportSettings(): _instance = None @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = HTMLExportSettings() return cls._instance def __init__(self): - serviceHTMLExportDefaultSettings = {"enabled": False, "path": config.pyfaPath + os.sep + 'pyfaFits.html', "minimal": False } - self.serviceHTMLExportSettings = SettingsProvider.getInstance().getSettings("pyfaServiceHTMLExportSettings", serviceHTMLExportDefaultSettings) + serviceHTMLExportDefaultSettings = {"enabled": False, "path": config.pyfaPath + os.sep + 'pyfaFits.html', + "minimal": False} + self.serviceHTMLExportSettings = SettingsProvider.getInstance().getSettings("pyfaServiceHTMLExportSettings", + serviceHTMLExportDefaultSettings) def getEnabled(self): return self.serviceHTMLExportSettings["enabled"] def setEnabled(self, enabled): self.serviceHTMLExportSettings["enabled"] = enabled - - + def getMinimalEnabled(self): return self.serviceHTMLExportSettings["minimal"] def setMinimalEnabled(self, minimal): self.serviceHTMLExportSettings["minimal"] = minimal - def getPath(self): return self.serviceHTMLExportSettings["path"] def setPath(self, path): self.serviceHTMLExportSettings["path"] = path + """ Settings used by update notification """ + + class UpdateSettings(): _instance = None @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = UpdateSettings() return cls._instance @@ -293,8 +305,9 @@ class UpdateSettings(): # Updates are completely suppressed via network settings # prerelease - If True, suppress prerelease notifications # version - Set to release tag that user does not want notifications for - serviceUpdateDefaultSettings = {"prerelease": True, 'version': None } - self.serviceUpdateSettings = SettingsProvider.getInstance().getSettings("pyfaServiceUpdateSettings", serviceUpdateDefaultSettings) + serviceUpdateDefaultSettings = {"prerelease": True, 'version': None} + self.serviceUpdateSettings = SettingsProvider.getInstance().getSettings("pyfaServiceUpdateSettings", + serviceUpdateDefaultSettings) def get(self, type): return self.serviceUpdateSettings[type] @@ -302,6 +315,7 @@ class UpdateSettings(): def set(self, type, value): self.serviceUpdateSettings[type] = value + class CRESTSettings(): _instance = None @@ -313,13 +327,13 @@ class CRESTSettings(): return cls._instance def __init__(self): - # mode # 0 - Implicit authentication # 1 - User-supplied client details serviceCRESTDefaultSettings = {"mode": 0, "server": 0, "clientID": "", "clientSecret": "", "timeout": 60} - self.serviceCRESTSettings = SettingsProvider.getInstance().getSettings("pyfaServiceCRESTSettings", serviceCRESTDefaultSettings) + self.serviceCRESTSettings = SettingsProvider.getInstance().getSettings("pyfaServiceCRESTSettings", + serviceCRESTDefaultSettings) def get(self, type): return self.serviceCRESTSettings[type] @@ -327,5 +341,4 @@ class CRESTSettings(): def set(self, type, value): self.serviceCRESTSettings[type] = value - # @todo: migrate fit settings (from fit service) here?