This commit is contained in:
MaruMaruOO
2019-02-14 01:24:07 -05:00
20 changed files with 150 additions and 60 deletions

View File

@@ -0,0 +1,17 @@
"""
Migration 30
- changes to prices table
"""
import sqlalchemy
def upgrade(saveddata_engine):
try:
saveddata_engine.execute("SELECT status FROM prices LIMIT 1")
except sqlalchemy.exc.DatabaseError:
# Just drop table, table will be re-created by sqlalchemy and
# data will be re-fetched
saveddata_engine.execute("DROP TABLE prices;")

View File

@@ -17,17 +17,20 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>. # along with eos. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================== # ===============================================================================
from sqlalchemy import Table, Column, Float, Integer from sqlalchemy import Table, Column, Float, Integer
from sqlalchemy.orm import mapper from sqlalchemy.orm import mapper
from eos.db import saveddata_meta from eos.db import saveddata_meta
from eos.saveddata.price import Price from eos.saveddata.price import Price
prices_table = Table("prices", saveddata_meta, prices_table = Table("prices", saveddata_meta,
Column("typeID", Integer, primary_key=True), Column("typeID", Integer, primary_key=True),
Column("price", Float, default=0.0), Column("price", Float, default=0.0),
Column("time", Integer, nullable=False), Column("time", Integer, nullable=False),
Column("failed", Integer)) Column("status", Integer, nullable=False))
mapper(Price, prices_table, properties={ mapper(Price, prices_table, properties={
"_Price__price": prices_table.c.price, "_Price__price": prices_table.c.price,

View File

@@ -542,8 +542,17 @@ def commit():
with sd_lock: with sd_lock:
try: try:
saveddata_session.commit() saveddata_session.commit()
saveddata_session.flush() except Exception:
except Exception as ex: saveddata_session.rollback()
exc_info = sys.exc_info()
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
def flush():
with sd_lock:
try:
saveddata_session.flush()
except Exception:
saveddata_session.rollback() saveddata_session.rollback()
exc_info = sys.exc_info() exc_info = sys.exc_info()
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])

View File

@@ -239,7 +239,7 @@ class Item(EqBase):
self.__offensive = None self.__offensive = None
self.__assistive = None self.__assistive = None
self.__overrides = None self.__overrides = None
self.__price = None self.__priceObj = None
@property @property
def attributes(self): def attributes(self):
@@ -446,34 +446,33 @@ class Item(EqBase):
@property @property
def price(self): def price(self):
# todo: use `from sqlalchemy import inspect` instead (mac-deprecated doesn't have inspect(), was imp[lemented in 0.8) # todo: use `from sqlalchemy import inspect` instead (mac-deprecated doesn't have inspect(), was imp[lemented in 0.8)
if self.__price is not None and getattr(self.__price, '_sa_instance_state', None) and self.__price._sa_instance_state.deleted: if self.__priceObj is not None and getattr(self.__priceObj, '_sa_instance_state', None) and self.__priceObj._sa_instance_state.deleted:
pyfalog.debug("Price data for {} was deleted (probably from a cache reset), resetting object".format(self.ID)) pyfalog.debug("Price data for {} was deleted (probably from a cache reset), resetting object".format(self.ID))
self.__price = None self.__priceObj = None
if self.__price is None: if self.__priceObj is None:
db_price = eos.db.getPrice(self.ID) db_price = eos.db.getPrice(self.ID)
# do not yet have a price in the database for this item, create one # do not yet have a price in the database for this item, create one
if db_price is None: if db_price is None:
pyfalog.debug("Creating a price for {}".format(self.ID)) pyfalog.debug("Creating a price for {}".format(self.ID))
self.__price = types_Price(self.ID) self.__priceObj = types_Price(self.ID)
eos.db.add(self.__price) eos.db.add(self.__priceObj)
eos.db.commit() eos.db.flush()
else: else:
self.__price = db_price self.__priceObj = db_price
return self.__price return self.__priceObj
@property @property
def isAbyssal(self): def isAbyssal(self):
if Item.ABYSSAL_TYPES is None: if Item.ABYSSAL_TYPES is None:
Item.getAbyssalYypes() Item.getAbyssalTypes()
return self.ID in Item.ABYSSAL_TYPES return self.ID in Item.ABYSSAL_TYPES
@classmethod @classmethod
def getAbyssalYypes(cls): def getAbyssalTypes(cls):
cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes() cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes()
@property @property

View File

@@ -215,6 +215,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
if force is not None: if force is not None:
if cappingValue is not None: if cappingValue is not None:
force = min(force, cappingValue) force = min(force, cappingValue)
if key in (50, 30, 48, 11):
force = round(force, 2)
return force return force
# Grab our values if they're there, otherwise we'll take default values # Grab our values if they're there, otherwise we'll take default values
preIncrease = self.__preIncreases.get(key, 0) preIncrease = self.__preIncreases.get(key, 0)
@@ -268,7 +270,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
# Cap value if we have cap defined # Cap value if we have cap defined
if cappingValue is not None: if cappingValue is not None:
val = min(val, cappingValue) val = min(val, cappingValue)
if key in (50, 30, 48, 11):
val = round(val, 2)
return val return val
def __handleSkill(self, skillName): def __handleSkill(self, skillName):

View File

@@ -1016,11 +1016,11 @@ class Fit(object):
@property @property
def pgUsed(self): def pgUsed(self):
return self.getItemAttrOnlineSum(self.modules, "power") return round(self.getItemAttrOnlineSum(self.modules, "power"), 2)
@property @property
def cpuUsed(self): def cpuUsed(self):
return self.getItemAttrOnlineSum(self.modules, "cpu") return round(self.getItemAttrOnlineSum(self.modules, "cpu"), 2)
@property @property
def droneBandwidthUsed(self): def droneBandwidthUsed(self):

View File

@@ -18,24 +18,30 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>. # along with eos. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================== # ===============================================================================
import time
from sqlalchemy.orm import reconstructor import time
from enum import IntEnum, unique
from logbook import Logger from logbook import Logger
pyfalog = Logger(__name__) pyfalog = Logger(__name__)
@unique
class PriceStatus(IntEnum):
notFetched = 0
success = 1
fail = 2
notSupported = 3
class Price(object): class Price(object):
def __init__(self, typeID): def __init__(self, typeID):
self.typeID = typeID self.typeID = typeID
self.time = 0 self.time = 0
self.__price = 0 self.__price = 0
self.failed = None self.status = PriceStatus.notFetched
@reconstructor
def init(self):
self.__item = None
@property @property
def isValid(self): def isValid(self):
@@ -43,7 +49,10 @@ class Price(object):
@property @property
def price(self): def price(self):
return self.__price or 0.0 if self.status != PriceStatus.success:
return 0
else:
return self.__price or 0
@price.setter @price.setter
def price(self, price): def price(self, price):

View File

@@ -13,6 +13,8 @@ class FillWithModule(ContextMenu):
self.settings = ContextMenuSettings.getInstance() self.settings = ContextMenuSettings.getInstance()
def display(self, srcContext, selection): def display(self, srcContext, selection):
if not self.settings.get('moduleFill'):
return False
return srcContext in ("fittingModule") return srcContext in ("fittingModule")
def getText(self, itmContext, selection): def getText(self, itmContext, selection):

View File

@@ -26,7 +26,10 @@ class MarketJump(ContextMenu):
sMkt = Market.getInstance() sMkt = Market.getInstance()
item = getattr(selection[0], "item", selection[0]) item = getattr(selection[0], "item", selection[0])
isMutated = getattr(selection[0], "isMutated", False)
mktGrp = sMkt.getMarketGroupByItem(item) mktGrp = sMkt.getMarketGroupByItem(item)
if mktGrp is None and isMutated:
mktGrp = sMkt.getMarketGroupByItem(selection[0].baseItem)
# 1663 is Special Edition Festival Assets, we don't have root group for it # 1663 is Special Edition Festival Assets, we don't have root group for it
if mktGrp is None or mktGrp.ID == 1663: if mktGrp is None or mktGrp.ID == 1663:
@@ -43,7 +46,10 @@ class MarketJump(ContextMenu):
if srcContext in ("fittingCharge", "projectedCharge"): if srcContext in ("fittingCharge", "projectedCharge"):
item = selection[0].charge item = selection[0].charge
elif hasattr(selection[0], "item"): elif hasattr(selection[0], "item"):
item = selection[0].item if getattr(selection[0], "isMutated", False):
item = selection[0].baseItem
else:
item = selection[0].item
else: else:
item = selection[0] item = selection[0]

View File

@@ -58,7 +58,6 @@ class AttributeSlider(wx.Panel):
self.UserMinValue = minValue self.UserMinValue = minValue
self.UserMaxValue = maxValue self.UserMaxValue = maxValue
print(self.UserMinValue, self.UserMaxValue)
self.inverse = inverse self.inverse = inverse

View File

@@ -8,6 +8,10 @@ from service.attribute import Attribute
from gui.utils.numberFormatter import formatAmount from gui.utils.numberFormatter import formatAmount
def defaultSort(item):
return (item.attributes['metaLevel'].value if 'metaLevel' in item.attributes else 0, item.name)
class ItemCompare(wx.Panel): class ItemCompare(wx.Panel):
def __init__(self, parent, stuff, item, items, context=None): def __init__(self, parent, stuff, item, items, context=None):
# Start dealing with Price stuff to get that thread going # Start dealing with Price stuff to get that thread going
@@ -27,8 +31,7 @@ class ItemCompare(wx.Panel):
self.currentSort = None self.currentSort = None
self.sortReverse = False self.sortReverse = False
self.item = item self.item = item
self.items = sorted(items, self.items = sorted(items, key=defaultSort)
key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else 0)
self.attrs = {} self.attrs = {}
# get a dict of attrName: attrInfo of all unique attributes across all items # get a dict of attrName: attrInfo of all unique attributes across all items
@@ -126,10 +129,15 @@ class ItemCompare(wx.Panel):
# starts at 0 while the list has the item name as column 0. # starts at 0 while the list has the item name as column 0.
attr = str(list(self.attrs.keys())[sort - 1]) attr = str(list(self.attrs.keys())[sort - 1])
func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0 func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0
# Clicked on a column that's not part of our array (price most likely)
except IndexError: except IndexError:
# Clicked on a column that's not part of our array (price most likely) # Price
self.sortReverse = False if sort == len(self.attrs) + 1:
func = lambda _val: _val.attributes['metaLevel'].value if 'metaLevel' in _val.attributes else 0.0 func = lambda i: i.price.price if i.price.price != 0 else float("Inf")
# Something else
else:
self.sortReverse = False
func = defaultSort
self.items = sorted(self.items, key=func, reverse=self.sortReverse) self.items = sorted(self.items, key=func, reverse=self.sortReverse)
@@ -160,7 +168,7 @@ class ItemCompare(wx.Panel):
self.paramList.SetItem(i, x + 1, valueUnit) self.paramList.SetItem(i, x + 1, valueUnit)
# Add prices # Add prices
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True)) self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True) if item.price.price else "")
self.paramList.RefreshRows() self.paramList.RefreshRows()
self.Layout() self.Layout()

View File

@@ -15,7 +15,6 @@ class ItemDescription(wx.Panel):
fgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) fgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self.description = wx.html.HtmlWindow(self) self.description = wx.html.HtmlWindow(self)
if not item.description: if not item.description:
return return

View File

@@ -22,8 +22,23 @@ class ItemMutator(wx.Panel):
self.item = item self.item = item
self.timer = None self.timer = None
self.activeFit = gui.mainFrame.MainFrame.getInstance().getActiveFit() self.activeFit = gui.mainFrame.MainFrame.getInstance().getActiveFit()
font = parent.GetFont()
font.SetWeight(wx.BOLD)
mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer = wx.BoxSizer(wx.VERTICAL)
sourceItemsSizer = wx.BoxSizer(wx.HORIZONTAL)
sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.item.iconID, self, "icons"), 0, wx.LEFT, 5)
sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.mutaplasmid.item.iconID, self, "icons"), 0, wx.LEFT, 0)
sourceItemShort = "{} {}".format(stuff.mutaplasmid.item.name.split(" ")[0], stuff.baseItem.name)
sourceItemText = wx.StaticText(self, wx.ID_ANY, sourceItemShort)
sourceItemText.SetFont(font)
sourceItemsSizer.Add(sourceItemText, 0, wx.LEFT, 10)
mainSizer.Add(sourceItemsSizer, 0, wx.TOP | wx.EXPAND, 10)
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.ALL | wx.EXPAND, 5)
self.goodColor = wx.Colour(96, 191, 0) self.goodColor = wx.Colour(96, 191, 0)
self.badColor = wx.Colour(255, 64, 0) self.badColor = wx.Colour(255, 64, 0)
@@ -58,9 +73,6 @@ class ItemMutator(wx.Panel):
headingSizer = wx.BoxSizer(wx.HORIZONTAL) headingSizer = wx.BoxSizer(wx.HORIZONTAL)
font = parent.GetFont()
font.SetWeight(wx.BOLD)
headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.iconID, self, "icons"), 0, wx.RIGHT, 10) headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.iconID, self, "icons"), 0, wx.RIGHT, 10)
displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName) displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName)

View File

@@ -81,6 +81,11 @@ class PFContextMenuPref(PreferenceView):
rbSizerRow3.Add(self.rbBox7, 1, wx.TOP | wx.RIGHT, 5) rbSizerRow3.Add(self.rbBox7, 1, wx.TOP | wx.RIGHT, 5)
self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change) self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change)
self.rbBox8 = wx.RadioBox(panel, -1, "Fill with module", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS)
self.rbBox8.SetSelection(self.settings.get('moduleFill'))
rbSizerRow3.Add(self.rbBox8, 1, wx.TOP | wx.RIGHT, 5)
self.rbBox8.Bind(wx.EVT_RADIOBOX, self.OnSetting8Change)
mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0) mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0)
panel.SetSizer(mainSizer) panel.SetSizer(mainSizer)
@@ -107,6 +112,9 @@ class PFContextMenuPref(PreferenceView):
def OnSetting7Change(self, event): def OnSetting7Change(self, event):
self.settings.set('project', event.GetInt()) self.settings.set('project', event.GetInt())
def OnSetting8Change(self, event):
self.settings.set('moduleFill', event.GetInt())
def getImage(self): def getImage(self):
return BitmapLoader.getBitmap("settings_menu", "gui") return BitmapLoader.getBitmap("settings_menu", "gui")

View File

@@ -22,6 +22,7 @@ import wx
from eos.saveddata.cargo import Cargo from eos.saveddata.cargo import Cargo
from eos.saveddata.drone import Drone from eos.saveddata.drone import Drone
from eos.saveddata.price import PriceStatus
from service.price import Price as ServicePrice from service.price import Price as ServicePrice
from gui.viewColumn import ViewColumn from gui.viewColumn import ViewColumn
from gui.bitmap_loader import BitmapLoader from gui.bitmap_loader import BitmapLoader
@@ -45,13 +46,16 @@ class Price(ViewColumn):
if stuff.isEmpty: if stuff.isEmpty:
return "" return ""
price = stuff.item.price priceObj = stuff.item.price
if not price or not price.isValid: if not priceObj.isValid:
return False return False
# Fetch actual price as float to not modify its value on Price object # Fetch actual price as float to not modify its value on Price object
price = price.price price = priceObj.price
if price == 0:
return ""
if isinstance(stuff, Drone) or isinstance(stuff, Cargo): if isinstance(stuff, Drone) or isinstance(stuff, Cargo):
price *= stuff.amount price *= stuff.amount
@@ -63,10 +67,12 @@ class Price(ViewColumn):
def callback(item): def callback(item):
price = item[0] price = item[0]
text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else "" textItems = []
if price.failed: if price.price:
text += " (!)" textItems.append(formatAmount(price.price, 3, 3, 9, currency=True))
colItem.SetText(text) if price.status == PriceStatus.fail:
textItems.append("(!)")
colItem.SetText(" ".join(textItems))
display.SetItem(colItem) display.SetItem(colItem)

View File

@@ -91,7 +91,7 @@ class ItemStatsDialog(wx.Dialog):
self.SetMinSize((300, 200)) self.SetMinSize((300, 200))
if "wxGTK" in wx.PlatformInfo: # GTK has huge tab widgets, give it a bit more room if "wxGTK" in wx.PlatformInfo: # GTK has huge tab widgets, give it a bit more room
self.SetSize((580, 500)) self.SetSize((630, 550))
else: else:
self.SetSize((550, 500)) self.SetSize((550, 500))
# self.SetMaxSize((500, -1)) # self.SetMaxSize((500, -1))
@@ -168,8 +168,9 @@ class ItemStatsContainer(wx.Panel):
self.mutator = ItemMutator(self.nbContainer, stuff, item) self.mutator = ItemMutator(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.mutator, "Mutations") self.nbContainer.AddPage(self.mutator, "Mutations")
self.desc = ItemDescription(self.nbContainer, stuff, item) if item.description:
self.nbContainer.AddPage(self.desc, "Description") self.desc = ItemDescription(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.desc, "Description")
self.params = ItemParams(self.nbContainer, stuff, item, context) self.params = ItemParams(self.nbContainer, stuff, item, context)
self.nbContainer.AddPage(self.params, "Attributes") self.nbContainer.AddPage(self.params, "Attributes")

View File

@@ -22,6 +22,7 @@ from xml.dom import minidom
from logbook import Logger from logbook import Logger
from eos.saveddata.price import PriceStatus
from service.network import Network from service.network import Network
from service.price import Price, TIMEOUT, VALIDITY from service.price import Price, TIMEOUT, VALIDITY
@@ -52,6 +53,7 @@ class EveMarketData(object):
price = float(type_.firstChild.data) price = float(type_.firstChild.data)
except (TypeError, ValueError): except (TypeError, ValueError):
pyfalog.warning("Failed to get price for: {0}", type_) pyfalog.warning("Failed to get price for: {0}", type_)
continue
# Fill price data # Fill price data
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
@@ -61,11 +63,10 @@ class EveMarketData(object):
if price != 0: if price != 0:
priceobj.price = price priceobj.price = price
priceobj.time = time.time() + VALIDITY priceobj.time = time.time() + VALIDITY
priceobj.status = PriceStatus.success
else: else:
priceobj.time = time.time() + TIMEOUT priceobj.time = time.time() + TIMEOUT
priceobj.failed = None
# delete price from working dict # delete price from working dict
del priceMap[typeID] del priceMap[typeID]

View File

@@ -22,13 +22,14 @@ from xml.dom import minidom
from logbook import Logger from logbook import Logger
from eos.saveddata.price import PriceStatus
from service.network import Network from service.network import Network
from service.price import Price, VALIDITY from service.price import Price, VALIDITY
pyfalog = Logger(__name__) pyfalog = Logger(__name__)
class EveCentral(object): class EveMarketer(object):
name = "evemarketer" name = "evemarketer"
@@ -61,10 +62,10 @@ class EveCentral(object):
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
priceobj.price = percprice priceobj.price = percprice
priceobj.time = time.time() + VALIDITY priceobj.time = time.time() + VALIDITY
priceobj.failed = None priceobj.status = PriceStatus.success
# delete price from working dict # delete price from working dict
del priceMap[typeID] del priceMap[typeID]
Price.register(EveCentral) Price.register(EveMarketer)

View File

@@ -26,6 +26,7 @@ import wx
from logbook import Logger from logbook import Logger
from eos import db from eos import db
from eos.saveddata.price import PriceStatus
from service.fit import Fit from service.fit import Fit
from service.market import Market from service.market import Market
from service.network import TimeoutError from service.network import TimeoutError
@@ -85,13 +86,18 @@ class Price(object):
toRequest = set() toRequest = set()
# Compose list of items we're going to request # Compose list of items we're going to request
for typeID in priceMap: for typeID in tuple(priceMap):
# Get item object # Get item object
item = db.getItem(typeID) item = db.getItem(typeID)
# We're not going to request items only with market group, as eve-central # We're not going to request items only with market group, as eve-central
# doesn't provide any data for items not on the market # doesn't provide any data for items not on the market
if item is not None and item.marketGroupID: if item is None:
toRequest.add(typeID) continue
if not item.marketGroupID:
priceMap[typeID].status = PriceStatus.notSupported
del priceMap[typeID]
continue
toRequest.add(typeID)
# Do not waste our time if all items are not on the market # Do not waste our time if all items are not on the market
if len(toRequest) == 0: if len(toRequest) == 0:
@@ -117,11 +123,10 @@ class Price(object):
except TimeoutError: except TimeoutError:
# Timeout error deserves special treatment # Timeout error deserves special treatment
pyfalog.warning("Price fetch timout") pyfalog.warning("Price fetch timout")
for typeID in priceMap.keys(): for typeID in tuple(priceMap):
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
priceobj.time = time.time() + TIMEOUT priceobj.time = time.time() + TIMEOUT
priceobj.failed = True priceobj.status = PriceStatus.fail
del priceMap[typeID] del priceMap[typeID]
except Exception as ex: except Exception as ex:
# something happened, try another source # something happened, try another source
@@ -134,7 +139,7 @@ class Price(object):
for typeID in priceMap.keys(): for typeID in priceMap.keys():
priceobj = priceMap[typeID] priceobj = priceMap[typeID]
priceobj.time = time.time() + REREQUEST priceobj.time = time.time() + REREQUEST
priceobj.failed = True priceobj.status = PriceStatus.fail
@classmethod @classmethod
def fitItemsList(cls, fit): def fitItemsList(cls, fit):
@@ -197,6 +202,7 @@ class Price(object):
class PriceWorkerThread(threading.Thread): class PriceWorkerThread(threading.Thread):
def __init__(self): def __init__(self):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.name = "PriceWorker" self.name = "PriceWorker"

View File

@@ -525,6 +525,7 @@ class ContextMenuSettings(object):
"tacticalMode" : 1, "tacticalMode" : 1,
"targetResists" : 1, "targetResists" : 1,
"whProjector" : 1, "whProjector" : 1,
"moduleFill" : 1,
} }
self.ContextMenuDefaultSettings = SettingsProvider.getInstance().getSettings("pyfaContextMenuSettings", ContextMenuDefaultSettings) self.ContextMenuDefaultSettings = SettingsProvider.getInstance().getSettings("pyfaContextMenuSettings", ContextMenuDefaultSettings)