diff --git a/gui/builtinPreferenceViews/pyfaHTMLExportPreferences.py b/gui/builtinPreferenceViews/pyfaHTMLExportPreferences.py
index e028ef478..1701e670b 100644
--- a/gui/builtinPreferenceViews/pyfaHTMLExportPreferences.py
+++ b/gui/builtinPreferenceViews/pyfaHTMLExportPreferences.py
@@ -14,9 +14,10 @@ class PFHTMLExportPref ( PreferenceView):
desc = "HTML Export (File > Export HTML) allows you to export your entire fitting "+\
"database into an HTML file at the specified location. This file can be "+\
"used in the in-game browser to easily open and import your fits, or used "+\
- "in a regular web browser to open them at NULL-SEC.com."
+ "in a regular web browser to open them at NULL-SEC.com or Osmium."
desc2 = "Enabling automatic exporting will update the HTML file after any change "+\
"to a fit is made. Under certain circumstance, this may cause performance issues."
+ desc3 = "Preferred website to view fits while not using in-game browser can be selected below."
def populatePanel( self, panel ):
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -57,6 +58,24 @@ class PFHTMLExportPref ( PreferenceView):
self.exportEnabled.Bind(wx.EVT_CHECKBOX, self.OnExportEnabledChange)
mainSizer.Add( self.exportEnabled, 0, wx.ALL|wx.EXPAND, 5 )
+ self.stDesc3 = wx.StaticText( panel, wx.ID_ANY, self.desc3, wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.stDesc3.Wrap(dlgWidth - 50)
+ mainSizer.Add( self.stDesc3, 0, wx.ALL, 5 )
+
+ websiteSizer = wx.BoxSizer( wx.HORIZONTAL )
+
+ self.stWebsite = wx.StaticText( panel, wx.ID_ANY, u"Website:", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.stWebsite.Wrap( -1 )
+ websiteSizer.Add( self.stWebsite, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
+
+ self.chWebsiteChoices = [ "o.smium.org", "null-sec.com" ]
+ self.chWebsiteType = wx.Choice( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, self.chWebsiteChoices, 0 )
+ self.chWebsiteType.SetStringSelection( self.HTMLExportSettings.getWebsite() )
+ websiteSizer.Add( self.chWebsiteType, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
+ self.chWebsiteType.Bind(wx.EVT_CHOICE, self.OnCHWebsiteTypeSelect)
+
+ mainSizer.Add( websiteSizer, 0, wx.EXPAND, 5 )
+
panel.SetSizer( mainSizer )
panel.Layout()
@@ -75,6 +94,10 @@ class PFHTMLExportPref ( PreferenceView):
def OnExportEnabledChange(self, event):
self.HTMLExportSettings.setEnabled(self.exportEnabled.GetValue())
+ def OnCHWebsiteTypeSelect(self, event):
+ choice = self.chWebsiteType.GetStringSelection()
+ self.HTMLExportSettings.setWebsite(choice)
+
def getImage(self):
return BitmapLoader.getBitmap("prefs_html", "gui")
diff --git a/gui/utils/exportHtml.py b/gui/utils/exportHtml.py
index d7e25c04a..8de0f35eb 100644
--- a/gui/utils/exportHtml.py
+++ b/gui/utils/exportHtml.py
@@ -45,6 +45,12 @@ class exportHtmlThread(threading.Thread):
timestamp = time.localtime(time.time())
localDate = "%d/%02d/%02d %02d:%02d" % (timestamp[0], timestamp[1], timestamp[2], timestamp[3], timestamp[4])
+
+ website = settings.getWebsite()
+ if website == "o.smium.org":
+ dnaUrl = "https://o.smium.org/loadout/dna/"
+ elif website == "null-sec.com":
+ dnaUrl = "https://null-sec.com/hangar/?dna="
HTML = """
@@ -126,7 +132,7 @@ class exportHtmlThread(threading.Thread):
if (typeof CCPEVE !== 'undefined') { // inside IGB
$(this).attr('href', 'javascript:CCPEVE.showFitting("'+dna+'");'); }
else { // outside IGB
- $(this).attr('href', 'https://null-sec.com/hangar/?dna='+dna); }
+ $(this).attr('href', '%s'+dna); }
});
});
@@ -139,7 +145,7 @@ class exportHtmlThread(threading.Thread):
Last updated: %s ()
-""" % (time.time(), localDate)
+""" % (time.time(), dnaUrl, localDate)
HTML += '
\n'
categoryList = list(sMkt.getShipRoot())
categoryList.sort(key=lambda ship: ship.name)
diff --git a/service/port.py b/service/port.py
index 8f922ac8d..cc6d11d17 100644
--- a/service/port.py
+++ b/service/port.py
@@ -103,7 +103,7 @@ class Port(object):
item['type']['id'] = cargo.item.ID
item['type']['name'] = ''
fit['items'].append(item)
-
+
for drone in ofit.drones:
item = nested_dict()
item['flag'] = INV_FLAG_DRONEBAY
@@ -128,7 +128,7 @@ class Port(object):
else:
return "XML", cls.importXml(string, callback)
- # If JSON-style start, parse os CREST/JSON
+ # If JSON-style start, parse as CREST/JSON
if firstLine[0] == '{':
return "JSON", (cls.importCrest(string),)
@@ -162,6 +162,8 @@ class Port(object):
items = fit['items']
items.sort(key=lambda k: k['flag'])
+
+ moduleList = []
for module in items:
try:
item = sMkt.getItem(module['type']['id'], eager="group.category")
@@ -179,16 +181,26 @@ class Port(object):
# When item can't be added to any slot (unknown item or just charge), ignore it
except ValueError:
continue
- if m.fits(f):
- m.owner = f
+ # Add subsystems before modules to make sure T3 cruisers have subsystems installed
+ if item.category.name == "Subsystem":
+ if m.fits(f):
+ f.modules.append(m)
+ else:
if m.isValidState(State.ACTIVE):
m.state = State.ACTIVE
- f.modules.append(m)
+ moduleList.append(m)
except:
continue
+ # Recalc to get slot numbers correct for T3 cruisers
+ service.Fit.getInstance().recalc(f)
+
+ for module in moduleList:
+ if module.fits(f):
+ f.modules.append(module)
+
return f
@staticmethod
@@ -208,6 +220,7 @@ class Port(object):
logger.exception("Couldn't import ship data %r", [ logtransform(s) for s in info ])
return None
+ moduleList = []
for itemInfo in info[1:]:
if itemInfo:
itemID, amount = itemInfo.split(";")
@@ -225,13 +238,27 @@ class Port(object):
for i in xrange(int(amount)):
try:
m = Module(item)
+ except:
+ continue
+ # Add subsystems before modules to make sure T3 cruisers have subsystems installed
+ if item.category.name == "Subsystem":
if m.fits(f):
f.modules.append(m)
- except:
- pass
- m.owner = f
- if m.isValidState(State.ACTIVE):
- m.state = State.ACTIVE
+ else:
+ m.owner = f
+ if m.isValidState(State.ACTIVE):
+ m.state = State.ACTIVE
+ moduleList.append(m)
+
+ # Recalc to get slot numbers correct for T3 cruisers
+ service.Fit.getInstance().recalc(f)
+
+ for module in moduleList:
+ if module.fits(f):
+ module.owner = f
+ if module.isValidState(State.ACTIVE):
+ module.state = State.ACTIVE
+ f.modules.append(module)
return f
@@ -262,6 +289,7 @@ class Port(object):
# maintain map of drones and their quantities
droneMap = {}
cargoMap = {}
+ moduleList = []
for i in range(1, len(lines)):
ammoName = None
extraAmount = None
@@ -310,28 +338,49 @@ class Port(object):
cargoMap[modName] += extraAmount
elif item.category.name == "Implant":
fit.implants.append(Implant(item))
+ # elif item.category.name == "Subsystem":
+ # try:
+ # subsystem = Module(item)
+ # except ValueError:
+ # continue
+ #
+ # if subsystem.fits(fit):
+ # fit.modules.append(subsystem)
else:
try:
m = Module(item)
except ValueError:
continue
- if ammoName:
- try:
- ammo = sMkt.getItem(ammoName)
- if m.isValidCharge(ammo) and m.charge is None:
- m.charge = ammo
- except:
- pass
+ # Add subsystems before modules to make sure T3 cruisers have subsystems installed
+ if item.category.name == "Subsystem":
+ if m.fits(fit):
+ fit.modules.append(m)
+ else:
+ if ammoName:
+ try:
+ ammo = sMkt.getItem(ammoName)
+ if m.isValidCharge(ammo) and m.charge is None:
+ m.charge = ammo
+ except:
+ pass
- if m.fits(fit):
- m.owner = fit
if setOffline is True and m.isValidState(State.OFFLINE):
m.state = State.OFFLINE
elif m.isValidState(State.ACTIVE):
m.state = State.ACTIVE
- fit.modules.append(m)
+ moduleList.append(m)
+ # Recalc to get slot numbers correct for T3 cruisers
+ service.Fit.getInstance().recalc(fit)
+
+ for m in moduleList:
+ if m.fits(fit):
+ m.owner = fit
+ if not m.isValidState(m.state):
+ print "Error: Module", m, "cannot have state", m.state
+
+ fit.modules.append(m)
for droneName in droneMap:
d = Drone(sMkt.getItem(droneName))
@@ -388,6 +437,7 @@ class Port(object):
# Assign ship to fitting
f.ship = Ship(sMkt.getItem(shipname))
+ moduleList = []
for x in range(1, len(fitLines)):
line = fitLines[x]
if not line:
@@ -476,22 +526,35 @@ class Port(object):
except:
continue
- # Create module and activate it if it's activable
+ # Create module
m = Module(modItem)
- m.owner = f
- if m.isValidState(State.ACTIVE):
- m.state = State.ACTIVE
- # Add charge to mod if applicable, on any errors just don't add anything
- if chargeName:
- try:
- chargeItem = sMkt.getItem(chargeName, eager="group.category")
- if chargeItem.category.name == "Charge":
- m.charge = chargeItem
- except:
- pass
- # Append module to fit
- if m.fits(f):
- f.modules.append(m)
+
+ # Add subsystems before modules to make sure T3 cruisers have subsystems installed
+ if modItem.category.name == "Subsystem":
+ if m.fits(f):
+ f.modules.append(m)
+ else:
+ m.owner = f
+ # Activate mod if it is activable
+ if m.isValidState(State.ACTIVE):
+ m.state = State.ACTIVE
+ # Add charge to mod if applicable, on any errors just don't add anything
+ if chargeName:
+ try:
+ chargeItem = sMkt.getItem(chargeName, eager="group.category")
+ if chargeItem.category.name == "Charge":
+ m.charge = chargeItem
+ except:
+ pass
+ # Append module to fit
+ moduleList.append(m)
+
+ # Recalc to get slot numbers correct for T3 cruisers
+ service.Fit.getInstance().recalc(f)
+
+ for module in moduleList:
+ if module.fits(f):
+ f.modules.append(module)
# Append fit to list of fits
fits.append(f)
@@ -523,6 +586,7 @@ class Port(object):
except:
continue
hardwares = fitting.getElementsByTagName("hardware")
+ moduleList = []
for hardware in hardwares:
try:
moduleName = hardware.getAttribute("type")
@@ -548,16 +612,28 @@ class Port(object):
# When item can't be added to any slot (unknown item or just charge), ignore it
except ValueError:
continue
- if m.fits(f):
- m.owner = f
+ # Add subsystems before modules to make sure T3 cruisers have subsystems installed
+ if item.category.name == "Subsystem":
+ if m.fits(f):
+ m.owner = f
+ f.modules.append(m)
+ else:
if m.isValidState(State.ACTIVE):
m.state = State.ACTIVE
- f.modules.append(m)
+ moduleList.append(m)
except KeyboardInterrupt:
continue
+ # Recalc to get slot numbers correct for T3 cruisers
+ service.Fit.getInstance().recalc(f)
+
+ for module in moduleList:
+ if module.fits(f):
+ module.owner = f
+ f.modules.append(module)
+
fits.append(f)
if callback:
wx.CallAfter(callback, None)
diff --git a/service/settings.py b/service/settings.py
index 5b4bd003b..60627e6b8 100644
--- a/service/settings.py
+++ b/service/settings.py
@@ -221,7 +221,7 @@ class HTMLExportSettings():
return cls._instance
def __init__(self):
- serviceHTMLExportDefaultSettings = {"enabled": False, "path": config.pyfaPath + os.sep + 'pyfaFits.html' }
+ serviceHTMLExportDefaultSettings = {"enabled": False, "path": config.pyfaPath + os.sep + 'pyfaFits.html', "website": "null-sec.com" }
self.serviceHTMLExportSettings = SettingsProvider.getInstance().getSettings("pyfaServiceHTMLExportSettings", serviceHTMLExportDefaultSettings)
def getEnabled(self):
@@ -236,6 +236,12 @@ class HTMLExportSettings():
def setPath(self, path):
self.serviceHTMLExportSettings["path"] = path
+ def getWebsite(self):
+ return self.serviceHTMLExportSettings["website"]
+
+ def setWebsite(self, website):
+ self.serviceHTMLExportSettings["website"] = website
+
"""
Settings used by update notification
"""