Merge branch 'master' into development
Conflicts: gui/builtinViewColumns/baseName.py
This commit is contained in:
@@ -85,8 +85,7 @@ class DatabaseCleanup:
|
||||
logger.error("More than one uniform damage pattern found.")
|
||||
else:
|
||||
uniform_damage_pattern_id = rows[0]['ID']
|
||||
update_query = "UPDATE 'fits' SET 'damagePatternID' = " + str(uniform_damage_pattern_id) + \
|
||||
" WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
|
||||
update_query = "UPDATE 'fits' SET 'damagePatternID' = {} WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL".format(uniform_damage_pattern_id)
|
||||
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", update_results.rowcount)
|
||||
|
||||
@@ -160,3 +159,75 @@ class DatabaseCleanup:
|
||||
query = "DELETE FROM targetResists WHERE name IS NULL OR name = ''"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def OrphanedFitIDItemID(saveddata_engine):
|
||||
# Orphaned items that are missing the fit ID or item ID.
|
||||
# See issue #954
|
||||
for table in ['drones', 'cargo', 'fighters']:
|
||||
logger.debug("Running database cleanup for orphaned %s items.", table)
|
||||
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
|
||||
for table in ['modules']:
|
||||
logger.debug("Running database cleanup for orphaned %s items.", table)
|
||||
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def NullDamageTargetPatternValues(saveddata_engine):
|
||||
# Find patterns that have null values
|
||||
# See issue #954
|
||||
for profileType in ['damagePatterns', 'targetResists']:
|
||||
for damageType in ['em', 'thermal', 'kinetic', 'explosive']:
|
||||
logger.debug("Running database cleanup for null %s values. (%s)", profileType, damageType)
|
||||
query = "SELECT COUNT(*) AS num FROM {0} WHERE {1}Amount IS NULL OR {1}Amount = ''".format(profileType, damageType)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num']:
|
||||
query = "UPDATE '{0}' SET '{1}Amount' = '0' WHERE {1}Amount IS NULL OR Amount = ''".format(profileType, damageType)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def DuplicateSelectedAmmoName(saveddata_engine):
|
||||
# Orphaned items that are missing the fit ID or item ID.
|
||||
# See issue #954
|
||||
logger.debug("Running database cleanup for duplicated selected ammo profiles.")
|
||||
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num'] > 1:
|
||||
query = "DELETE FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
|
||||
@@ -15,8 +15,6 @@ def handler(fit, module, context):
|
||||
|
||||
# Skip if there is no damage pattern. Example: projected ships or fleet boosters
|
||||
if damagePattern:
|
||||
# logger.debug("Damage Pattern: %f/%f/%f/%f", damagePattern.emAmount, damagePattern.thermalAmount, damagePattern.kineticAmount, damagePattern.explosiveAmount)
|
||||
# logger.debug("Original Armor Resists: %f/%f/%f/%f", fit.ship.getModifiedItemAttr('armorEmDamageResonance'), fit.ship.getModifiedItemAttr('armorThermalDamageResonance'), fit.ship.getModifiedItemAttr('armorKineticDamageResonance'), fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'))
|
||||
|
||||
# Populate a tuple with the damage profile modified by current armor resists.
|
||||
baseDamageTaken = (
|
||||
@@ -50,7 +48,6 @@ def handler(fit, module, context):
|
||||
(2, baseDamageTaken[2] * RAHResistance[2], RAHResistance[2]),
|
||||
(1, baseDamageTaken[1] * RAHResistance[1], RAHResistance[1]),
|
||||
]
|
||||
# logger.debug("Damage taken this cycle: %f/%f/%f/%f", damagePattern_tuples[0][1], damagePattern_tuples[3][1], damagePattern_tuples[2][1], damagePattern_tuples[1][1])
|
||||
|
||||
# Sort the tuple to drop the highest damage value to the bottom
|
||||
sortedDamagePattern_tuples = sorted(damagePattern_tuples, key=lambda damagePattern: damagePattern[1])
|
||||
|
||||
@@ -3,4 +3,7 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command Specialist"), "commandBonusHidden", src.getModifiedItemAttr("eliteBonusCommandDestroyer1"), skill="Command Destroyers")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Information Command Specialist"),
|
||||
"commandBonusHidden",
|
||||
src.getModifiedItemAttr("eliteBonusCommandDestroyer1"),
|
||||
skill="Command Destroyers")
|
||||
|
||||
@@ -6,5 +6,11 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"falloffEffectiveness",
|
||||
src.getModifiedItemAttr("eliteBonusLogistics1"),
|
||||
skill="Logistics Cruisers")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"maxRange",
|
||||
src.getModifiedItemAttr("eliteBonusLogistics1"),
|
||||
skill="Logistics Cruisers")
|
||||
|
||||
@@ -6,5 +6,9 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "falloffEffectiveness", src.getModifiedItemAttr("roleBonusRepairRange"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "maxRange", src.getModifiedItemAttr("roleBonusRepairRange"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"falloffEffectiveness",
|
||||
src.getModifiedItemAttr("roleBonusRepairRange"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"maxRange",
|
||||
src.getModifiedItemAttr("roleBonusRepairRange"))
|
||||
|
||||
@@ -6,8 +6,18 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "buffDuration", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or mod.item.requiresSkill("Information Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or
|
||||
mod.item.requiresSkill("Information Command"),
|
||||
"warfareBuff4Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or
|
||||
mod.item.requiresSkill("Information Command"),
|
||||
"warfareBuff3Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or
|
||||
mod.item.requiresSkill("Information Command"),
|
||||
"warfareBuff1Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or
|
||||
mod.item.requiresSkill("Information Command"),
|
||||
"buffDuration", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command") or
|
||||
mod.item.requiresSkill("Information Command"),
|
||||
"warfareBuff2Value", src.getModifiedItemAttr("shipBonusForceAuxiliaryA4"), skill="Amarr Carrier")
|
||||
|
||||
@@ -243,9 +243,11 @@ class Item(EqBase):
|
||||
|
||||
return self.__attributes
|
||||
|
||||
def getAttribute(self, key):
|
||||
def getAttribute(self, key, default=None):
|
||||
if key in self.attributes:
|
||||
return self.attributes[key].value
|
||||
else:
|
||||
return default
|
||||
|
||||
def isType(self, type):
|
||||
for effect in self.effects.itervalues():
|
||||
|
||||
@@ -25,19 +25,19 @@ cappingAttrKeyCache = {}
|
||||
|
||||
|
||||
class ItemAttrShortcut(object):
|
||||
def getModifiedItemAttr(self, key):
|
||||
def getModifiedItemAttr(self, key, default=None):
|
||||
if key in self.itemModifiedAttributes:
|
||||
return self.itemModifiedAttributes[key]
|
||||
else:
|
||||
return None
|
||||
return default
|
||||
|
||||
|
||||
class ChargeAttrShortcut(object):
|
||||
def getModifiedChargeAttr(self, key):
|
||||
def getModifiedChargeAttr(self, key, default=None):
|
||||
if key in self.chargeModifiedAttributes:
|
||||
return self.chargeModifiedAttributes[key]
|
||||
else:
|
||||
return None
|
||||
return default
|
||||
|
||||
|
||||
class ModifiedAttributeDict(collections.MutableMapping):
|
||||
|
||||
@@ -489,10 +489,12 @@ class Fit(object):
|
||||
self.ship.boostItemAttr("armor%sDamageResonance" % damageType, value)
|
||||
|
||||
if warfareBuffID == 14: # Armor Burst: Rapid Repair: Repair Duration/Capacitor
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or mod.item.requiresSkill("Repair Systems"),
|
||||
"capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or mod.item.requiresSkill("Repair Systems"), "duration",
|
||||
value)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems"),
|
||||
"capacitorNeed", value)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
|
||||
mod.item.requiresSkill("Repair Systems"),
|
||||
"duration", value)
|
||||
|
||||
if warfareBuffID == 15: # Armor Burst: Armor Reinforcement: Armor HP
|
||||
self.ship.boostItemAttr("armorHP", value, stackingPenalties=True)
|
||||
@@ -626,7 +628,8 @@ class Fit(object):
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Emission Systems"), "shieldBonus", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 53: # Leviathan Effect Generator : Armor RR penalty
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"), "armorDamageAmount", value, stackingPenalties=True)
|
||||
self.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems"),
|
||||
"armorDamageAmount", value, stackingPenalties=True)
|
||||
|
||||
if warfareBuffID == 54: # Ragnarok Effect Generator : Laser and Hybrid Optimal penalty
|
||||
groups = ("Energy Weapon", "Hybrid Weapon")
|
||||
|
||||
@@ -24,7 +24,8 @@ from eos.saveddata.implant import Implant
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.module import Module, Slot, Rack
|
||||
from service.fit import Fit
|
||||
from eos.saveddata.fit import Fit
|
||||
from service.fit import Fit as FitSvc
|
||||
from gui.viewColumn import ViewColumn
|
||||
import gui.mainFrame
|
||||
|
||||
@@ -57,7 +58,7 @@ class BaseName(ViewColumn):
|
||||
else:
|
||||
return "%s (%s)" % (stuff.name, stuff.ship.item.name)
|
||||
elif isinstance(stuff, Rack):
|
||||
if Fit.getInstance().serviceFittingOptions["rackLabels"]:
|
||||
if FitSvc.getInstance().serviceFittingOptions["rackLabels"]:
|
||||
if stuff.slot == Slot.MODE:
|
||||
return u'─ Tactical Mode ─'
|
||||
else:
|
||||
@@ -74,7 +75,7 @@ class BaseName(ViewColumn):
|
||||
else:
|
||||
item = getattr(stuff, "item", stuff)
|
||||
|
||||
if Fit.getInstance().serviceFittingOptions["showMarketShortcuts"]:
|
||||
if FitSvc.getInstance().serviceFittingOptions["showMarketShortcuts"]:
|
||||
marketShortcut = getattr(item, "marketShortcut", None)
|
||||
|
||||
if marketShortcut:
|
||||
|
||||
@@ -450,30 +450,69 @@ class Miscellanea(ViewColumn):
|
||||
return text, item.name
|
||||
else:
|
||||
return "", None
|
||||
elif itemGroup in ("Ancillary Armor Repairer", "Ancillary Shield Booster"):
|
||||
hp = stuff.hpBeforeReload
|
||||
cycles = stuff.numShots
|
||||
cycleTime = stuff.rawCycleTime
|
||||
elif itemGroup in (
|
||||
"Ancillary Armor Repairer",
|
||||
"Ancillary Shield Booster",
|
||||
"Capacitor Booster",
|
||||
"Ancillary Remote Armor Repairer",
|
||||
"Ancillary Remote Shield Booster",
|
||||
):
|
||||
if "Armor" in itemGroup or "Shield" in itemGroup:
|
||||
boosted_attribute = "HP"
|
||||
reload_time = item.getAttribute("reloadTime", 0) / 1000
|
||||
elif "Capacitor" in itemGroup:
|
||||
boosted_attribute = "Cap"
|
||||
reload_time = 10
|
||||
else:
|
||||
boosted_attribute = ""
|
||||
reload_time = 0
|
||||
|
||||
cycles = max(stuff.numShots, 0)
|
||||
cycleTime = max(stuff.rawCycleTime, 0)
|
||||
|
||||
# Get HP or boosted amount
|
||||
stuff_hp = max(stuff.hpBeforeReload, 0)
|
||||
armor_hp = stuff.getModifiedItemAttr("armorDamageAmount", 0)
|
||||
capacitor_hp = stuff.getModifiedChargeAttr("capacitorBonus", 0)
|
||||
shield_hp = stuff.getModifiedItemAttr("shieldBonus", 0)
|
||||
hp = max(stuff_hp, armor_hp * cycles, capacitor_hp * cycles, shield_hp * cycles, 0)
|
||||
|
||||
if not hp or not cycleTime or not cycles:
|
||||
return "", None
|
||||
|
||||
fit = Fit.getInstance().getFit(self.mainFrame.getActiveFit())
|
||||
ehpTotal = fit.ehp
|
||||
hpTotal = fit.hp
|
||||
useEhp = self.mainFrame.statsPane.nameViewMap["resistancesViewFull"].showEffective
|
||||
tooltip = "HP restored over duration using charges"
|
||||
if useEhp:
|
||||
if itemGroup == "Ancillary Armor Repairer":
|
||||
tooltip = "{0} restored over duration using charges (plus reload)".format(boosted_attribute)
|
||||
|
||||
if useEhp and boosted_attribute == "HP" and "Remote" not in itemGroup:
|
||||
if "Ancillary Armor Repairer" in itemGroup:
|
||||
hpRatio = ehpTotal["armor"] / hpTotal["armor"]
|
||||
else:
|
||||
hpRatio = ehpTotal["shield"] / hpTotal["shield"]
|
||||
tooltip = "E{0}".format(tooltip)
|
||||
else:
|
||||
hpRatio = 1
|
||||
if itemGroup == "Ancillary Armor Repairer":
|
||||
hpRatio *= 3
|
||||
|
||||
if "Ancillary" in itemGroup and "Armor" in itemGroup:
|
||||
hpRatio *= stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1)
|
||||
|
||||
ehp = hp * hpRatio
|
||||
|
||||
duration = cycles * cycleTime / 1000
|
||||
text = "{0} / {1}s".format(formatAmount(ehp, 3, 0, 9), formatAmount(duration, 3, 0, 3))
|
||||
for number_of_cycles in {5, 10, 25}:
|
||||
tooltip = "{0}\n{1} charges lasts {2} seconds ({3} cycles)".format(
|
||||
tooltip,
|
||||
formatAmount(number_of_cycles*cycles, 3, 0, 3),
|
||||
formatAmount((duration+reload_time)*number_of_cycles, 3, 0, 3),
|
||||
formatAmount(number_of_cycles, 3, 0, 3)
|
||||
)
|
||||
text = "{0} / {1}s (+{2}s)".format(
|
||||
formatAmount(ehp, 3, 0, 9),
|
||||
formatAmount(duration, 3, 0, 3),
|
||||
formatAmount(reload_time, 3, 0, 3)
|
||||
)
|
||||
|
||||
return text, tooltip
|
||||
elif itemGroup == "Armor Resistance Shift Hardener":
|
||||
|
||||
@@ -26,6 +26,7 @@ import wx
|
||||
import time
|
||||
|
||||
from codecs import open
|
||||
from wx._core import PyDeadObjectError
|
||||
|
||||
from wx.lib.wordwrap import wordwrap
|
||||
|
||||
@@ -70,6 +71,9 @@ from service.port import Port
|
||||
from service.settings import HTMLExportSettings
|
||||
|
||||
from time import gmtime, strftime
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import threading
|
||||
import webbrowser
|
||||
@@ -349,6 +353,13 @@ class MainFrame(wx.Frame):
|
||||
info = wx.AboutDialogInfo()
|
||||
info.Name = "pyfa"
|
||||
info.Version = gui.aboutData.versionString
|
||||
|
||||
try:
|
||||
import matplotlib
|
||||
matplotlib_version = matplotlib.__version__
|
||||
except:
|
||||
matplotlib_version = None
|
||||
|
||||
info.Description = wordwrap(gui.aboutData.description + "\n\nDevelopers:\n\t" +
|
||||
"\n\t".join(gui.aboutData.developers) +
|
||||
"\n\nAdditional credits:\n\t" +
|
||||
@@ -358,7 +369,8 @@ class MainFrame(wx.Frame):
|
||||
"\n\nEVE Data: \t" + gamedata_version +
|
||||
"\nPython: \t\t" + '{}.{}.{}'.format(v.major, v.minor, v.micro) +
|
||||
"\nwxPython: \t" + wx.__version__ +
|
||||
"\nSQLAlchemy: \t" + sqlalchemy.__version__,
|
||||
"\nSQLAlchemy: \t" + sqlalchemy.__version__ +
|
||||
"\nmatplotlib: \t {}".format(matplotlib_version if matplotlib_version else "Not Installed"),
|
||||
500, wx.ClientDC(self))
|
||||
if "__WXGTK__" in wx.PlatformInfo:
|
||||
forumUrl = "http://forums.eveonline.com/default.aspx?g=posts&t=466425"
|
||||
@@ -381,7 +393,10 @@ class MainFrame(wx.Frame):
|
||||
def showDamagePatternEditor(self, event):
|
||||
dlg = DmgPatternEditorDlg(self)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
|
||||
|
||||
def showImplantSetEditor(self, event):
|
||||
ImplantSetEditorDlg(self)
|
||||
@@ -406,14 +421,20 @@ class MainFrame(wx.Frame):
|
||||
path += ".xml"
|
||||
else:
|
||||
print("oops, invalid fit format %d" % format_)
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
return
|
||||
|
||||
with open(path, "w", encoding="utf-8") as openfile:
|
||||
openfile.write(output)
|
||||
openfile.close()
|
||||
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
|
||||
def showPreferenceDialog(self, event):
|
||||
dlg = PreferenceDialog(self)
|
||||
@@ -724,7 +745,10 @@ class MainFrame(wx.Frame):
|
||||
|
||||
CopySelectDict[selected]()
|
||||
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
|
||||
|
||||
def exportSkillsNeeded(self, event):
|
||||
""" Exports skills needed for active fit and active character """
|
||||
@@ -778,7 +802,10 @@ class MainFrame(wx.Frame):
|
||||
self.progressDialog.message = None
|
||||
sPort.importFitsThreaded(dlg.GetPaths(), self.fileImportCallback)
|
||||
self.progressDialog.ShowModal()
|
||||
dlg.Destroy()
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
|
||||
|
||||
def backupToXml(self, event):
|
||||
""" Back up all fits to EVE XML file """
|
||||
|
||||
@@ -230,7 +230,7 @@ class exportHtmlThread(threading.Thread):
|
||||
HTML += (
|
||||
' <li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">\n'
|
||||
' <h2>' + group.groupName + ' <span class="ui-li-count">' + str(groupFits) + '</span></h2>\n'
|
||||
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n' + HTMLgroup +
|
||||
' <ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">\n' + HTMLgroup +
|
||||
' </ul>\n'
|
||||
' </li>'
|
||||
)
|
||||
|
||||
3
pyfa.py
3
pyfa.py
@@ -82,7 +82,8 @@ if not hasattr(sys, 'frozen'):
|
||||
betaFlag = True if saMatch.group(3) == "b" else False
|
||||
saBuild = int(saMatch.group(4)) if not betaFlag else 0
|
||||
if saMajor == 0 and (saMinor < 5 or (saMinor == 5 and saBuild < 8)):
|
||||
print("Pyfa requires sqlalchemy 0.5.8 at least but current sqlalchemy version is %s\nYou can download sqlalchemy (0.5.8+) from http://www.sqlalchemy.org/".format(sqlalchemy.__version__))
|
||||
print("Pyfa requires sqlalchemy 0.5.8 at least but current sqlalchemy version is %s\n"
|
||||
"You can download sqlalchemy (0.5.8+) from http://www.sqlalchemy.org/".format(sqlalchemy.__version__))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Unknown sqlalchemy version string format, skipping check")
|
||||
|
||||
@@ -56,6 +56,9 @@ if config.saveDB and os.path.isfile(config.saveDB):
|
||||
database_cleanup_instance.OrphanedFitDamagePatterns(db.saveddata_engine)
|
||||
database_cleanup_instance.NullDamagePatternNames(db.saveddata_engine)
|
||||
database_cleanup_instance.NullTargetResistNames(db.saveddata_engine)
|
||||
database_cleanup_instance.OrphanedFitIDItemID(db.saveddata_engine)
|
||||
database_cleanup_instance.NullDamageTargetPatternValues(db.saveddata_engine)
|
||||
database_cleanup_instance.DuplicateSelectedAmmoName(db.saveddata_engine)
|
||||
logging.debug("Completed database validation.")
|
||||
|
||||
else:
|
||||
|
||||
4
tox.ini
4
tox.ini
@@ -12,4 +12,6 @@ commands = py.test -vv --cov Pyfa tests/
|
||||
|
||||
[testenv:pep8]
|
||||
deps = flake8
|
||||
commands = flake8 --exclude=.svn,CVS,.bzr,.hg,.git,__pycache__,venv,tests,.tox,build,dist,__init__.py --ignore=E126,E127,E128,E501,E731,F401,F403,F405 service gui eos utils config.py pyfa.py --max-line-length=130
|
||||
# TODO: Remove F class exceptions once all imports are fixed
|
||||
# TODO: Remove E731 and convert lambdas to defs
|
||||
commands = flake8 --exclude=.svn,CVS,.bzr,.hg,.git,__pycache__,venv,tests,.tox,build,dist,__init__.py --ignore=E126,E127,E128,E731,F401,F403,F405 service gui eos utils config.py pyfa.py --max-line-length=165
|
||||
|
||||
Reference in New Issue
Block a user