Handle unicode, utf8, and windows-1252
This commit is contained in:
77
config.py
77
config.py
@@ -35,6 +35,7 @@ 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
|
||||
@@ -44,22 +45,19 @@ class StreamToLogger(object):
|
||||
for line in buf.rstrip().splitlines():
|
||||
self.logger.log(self.log_level, line.rstrip())
|
||||
|
||||
|
||||
def isFrozen():
|
||||
if hasattr(sys, 'frozen'):
|
||||
return True
|
||||
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())
|
||||
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)
|
||||
|
||||
@@ -119,12 +117,12 @@ def defPaths(customSavePath):
|
||||
# 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
|
||||
@@ -134,3 +132,48 @@ def defPaths(customSavePath):
|
||||
# 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
|
||||
|
||||
@@ -17,21 +17,23 @@
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -17,19 +17,21 @@
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import wx
|
||||
import os
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
import wx
|
||||
|
||||
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)
|
||||
@@ -103,7 +116,8 @@ class GraphFrame(wx.Frame):
|
||||
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)
|
||||
@@ -171,7 +185,7 @@ class GraphFrame(wx.Frame):
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -17,28 +17,31 @@
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import wx
|
||||
import csv
|
||||
import re
|
||||
import gui.mainFrame
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import sys
|
||||
import wx.lib.mixins.listctrl as listmix
|
||||
|
||||
import wx
|
||||
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,
|
||||
@@ -82,7 +85,8 @@ class ItemStatsDialog(wx.Dialog):
|
||||
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
|
||||
@@ -144,12 +148,12 @@ class ItemStatsDialog(wx.Dialog):
|
||||
|
||||
self.Destroy()
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Class ItemStatsContainer
|
||||
###########################################################################
|
||||
|
||||
class ItemStatsContainer(wx.Panel):
|
||||
|
||||
def __init__(self, parent, stuff, item, context=None):
|
||||
wx.Panel.__init__(self, parent)
|
||||
sMkt = service.Market.getInstance()
|
||||
@@ -196,35 +200,35 @@ 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):
|
||||
|
||||
def __init__(self, parent, stuff, item):
|
||||
wx.Panel.__init__(self, parent)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
@@ -236,12 +240,12 @@ class ItemTraits ( wx.Panel ):
|
||||
mainSizer.Add(self.traits, 1, wx.ALL | wx.EXPAND, 0)
|
||||
self.Layout()
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Class ItemDescription
|
||||
###########################################################################
|
||||
|
||||
class ItemDescription(wx.Panel):
|
||||
|
||||
def __init__(self, parent, stuff, item):
|
||||
wx.Panel.__init__(self, parent)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
@@ -260,13 +264,15 @@ class ItemDescription ( wx.Panel ):
|
||||
desc = re.sub("<( *)font( *)color( *)=(.*?)>(?P<inside>.*?)<( *)/( *)font( *)>", "\g<inside>", desc)
|
||||
# Strip URLs
|
||||
desc = re.sub("<( *)a(.*?)>(?P<inside>.*?)<( *)/( *)a( *)>", "\g<inside>", desc)
|
||||
desc = "<body bgcolor='" + bgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' text='" + fgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
|
||||
desc = "<body bgcolor='" + bgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' text='" + fgcolor.GetAsString(
|
||||
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
|
||||
|
||||
self.description.SetPage(desc)
|
||||
|
||||
mainSizer.Add(self.description, 1, wx.ALL | wx.EXPAND, 0)
|
||||
self.Layout()
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Class ItemParams
|
||||
###########################################################################
|
||||
@@ -297,10 +303,12 @@ class ItemParams (wx.Panel):
|
||||
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 )
|
||||
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 )
|
||||
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:
|
||||
@@ -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,8 +492,6 @@ 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)
|
||||
@@ -507,7 +512,8 @@ class ItemParams (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),
|
||||
"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),
|
||||
@@ -531,6 +537,7 @@ class ItemParams (wx.Panel):
|
||||
else:
|
||||
return "%s %s" % (formatAmount(value, 3, 0), unitName)
|
||||
|
||||
|
||||
class ItemCompare(wx.Panel):
|
||||
def __init__(self, parent, stuff, item, items, context=None):
|
||||
wx.Panel.__init__(self, parent)
|
||||
@@ -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
|
||||
@@ -699,7 +707,6 @@ class ItemCompare(wx.Panel):
|
||||
###########################################################################
|
||||
|
||||
class ItemRequirements(wx.Panel):
|
||||
|
||||
def __init__(self, parent, stuff, item):
|
||||
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
|
||||
|
||||
@@ -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()
|
||||
@@ -862,6 +869,7 @@ class ItemEffects (wx.Panel):
|
||||
self.Thaw()
|
||||
event.Skip()
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Class ItemAffectedBy
|
||||
###########################################################################
|
||||
@@ -869,6 +877,7 @@ class ItemEffects (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
|
||||
@@ -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,7 +1268,8 @@ 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])
|
||||
for attr in attrSorted:
|
||||
|
||||
@@ -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:
|
||||
@@ -254,7 +261,6 @@ class EVE(APIConnection):
|
||||
|
||||
|
||||
class AuthedConnection(EVE):
|
||||
|
||||
def __call__(self):
|
||||
if not self._data:
|
||||
self._data = APIObject(self.get(self._endpoint), self)
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -19,29 +19,37 @@
|
||||
|
||||
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
|
||||
@@ -121,7 +130,7 @@ class NetworkSettings():
|
||||
|
||||
@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,23 +245,26 @@ 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"]
|
||||
@@ -261,29 +272,30 @@ class HTMLExportSettings():
|
||||
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
|
||||
@@ -294,7 +306,8 @@ class UpdateSettings():
|
||||
# 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)
|
||||
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?
|
||||
|
||||
Reference in New Issue
Block a user