Merge remote-tracking branch 'origin/master' into blitzmann_CIUpdates
# Conflicts: # dist_assets/mac/pyfa.spec
This commit is contained in:
@@ -22,6 +22,7 @@ from xml.dom import minidom
|
||||
|
||||
from logbook import Logger
|
||||
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.network import Network
|
||||
from service.price import Price, TIMEOUT, VALIDITY
|
||||
|
||||
@@ -52,6 +53,7 @@ class EveMarketData(object):
|
||||
price = float(type_.firstChild.data)
|
||||
except (TypeError, ValueError):
|
||||
pyfalog.warning("Failed to get price for: {0}", type_)
|
||||
continue
|
||||
|
||||
# Fill price data
|
||||
priceobj = priceMap[typeID]
|
||||
@@ -61,11 +63,10 @@ class EveMarketData(object):
|
||||
if price != 0:
|
||||
priceobj.price = price
|
||||
priceobj.time = time.time() + VALIDITY
|
||||
priceobj.status = PriceStatus.success
|
||||
else:
|
||||
priceobj.time = time.time() + TIMEOUT
|
||||
|
||||
priceobj.failed = None
|
||||
|
||||
# delete price from working dict
|
||||
del priceMap[typeID]
|
||||
|
||||
|
||||
@@ -22,13 +22,14 @@ from xml.dom import minidom
|
||||
|
||||
from logbook import Logger
|
||||
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.network import Network
|
||||
from service.price import Price, VALIDITY
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class EveCentral(object):
|
||||
class EveMarketer(object):
|
||||
|
||||
name = "evemarketer"
|
||||
|
||||
@@ -61,10 +62,10 @@ class EveCentral(object):
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.price = percprice
|
||||
priceobj.time = time.time() + VALIDITY
|
||||
priceobj.failed = None
|
||||
priceobj.status = PriceStatus.success
|
||||
|
||||
# delete price from working dict
|
||||
del priceMap[typeID]
|
||||
|
||||
|
||||
Price.register(EveCentral)
|
||||
Price.register(EveMarketer)
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import inspect
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import json
|
||||
import eos.db
|
||||
|
||||
from math import log
|
||||
from numbers import Number
|
||||
from config import version as pyfaVersion
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
@@ -15,9 +10,11 @@ from eos.enum import Enum
|
||||
from eos.saveddata.module import Hardpoint, Slot, Module, State
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.effectHandlerHelpers import HandledList
|
||||
from eos.db import gamedata_session, getItemsByCategory, getCategory, getAttributeInfo, getGroup
|
||||
from eos.gamedata import Category, Group, Item, Traits, Attribute, Effect, ItemEffect
|
||||
from eos.db import gamedata_session, getCategory, getAttributeInfo, getGroup
|
||||
from eos.gamedata import Attribute, Effect, Group, Item, ItemEffect
|
||||
from eos.utils.spoolSupport import SpoolType, SpoolOptions
|
||||
from gui.fitCommands.calc.fitAddModule import FitAddModuleCommand
|
||||
from gui.fitCommands.calc.fitRemoveModule import FitRemoveModuleCommand
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -30,9 +27,9 @@ class RigSize(Enum):
|
||||
CAPITAL = 4
|
||||
|
||||
|
||||
class EfsPort():
|
||||
class EfsPort:
|
||||
wepTestSet = {}
|
||||
version = 0.02
|
||||
version = 0.03
|
||||
|
||||
@staticmethod
|
||||
def attrDirectMap(values, target, source):
|
||||
@@ -72,12 +69,12 @@ class EfsPort():
|
||||
|
||||
if propID is None:
|
||||
return None
|
||||
sFit.appendModule(fitID, propID)
|
||||
FitAddModuleCommand(fitID, propID).Do()
|
||||
sFit.recalc(fit)
|
||||
fit = eos.db.getFit(fitID)
|
||||
mwdPropSpeed = fit.maxSpeed
|
||||
mwdPosition = list(filter(lambda mod: mod.item and mod.item.ID == propID, fit.modules))[0].position
|
||||
sFit.removeModule(fitID, mwdPosition)
|
||||
FitRemoveModuleCommand(fitID, [mwdPosition]).Do()
|
||||
sFit.recalc(fit)
|
||||
fit = eos.db.getFit(fitID)
|
||||
return mwdPropSpeed
|
||||
@@ -115,6 +112,9 @@ class EfsPort():
|
||||
"Titan Phenomena Generator", "Non-Repeating Hardeners"
|
||||
]
|
||||
projectedMods = list(filter(lambda mod: mod.item and mod.item.group.name in modGroupNames, fit.modules))
|
||||
# Sort projections to prevent the order needlessly changing as pyfa updates.
|
||||
projectedMods.sort(key=lambda mod: mod.item.ID)
|
||||
projectedMods.sort(key=lambda mod: mod.item.group.ID)
|
||||
projections = []
|
||||
for mod in projectedMods:
|
||||
maxRangeDefault = 0
|
||||
@@ -191,7 +191,7 @@ class EfsPort():
|
||||
return projections
|
||||
|
||||
# Note that unless padTypeIDs is True all 0s will be removed from modTypeIDs in the return.
|
||||
# They always are added initally for the sake of brevity, as this option may not be retained long term.
|
||||
# They always are added initially for the sake of brevity, as this option may not be retained long term.
|
||||
@staticmethod
|
||||
def getModuleInfo(fit, padTypeIDs=False):
|
||||
moduleNames = []
|
||||
@@ -303,9 +303,9 @@ class EfsPort():
|
||||
def getWeaponSystemData(fit):
|
||||
weaponSystems = []
|
||||
groups = {}
|
||||
# TODO: fetch spoolup option
|
||||
# Export at maximum spool for consistency, spoolup data is exported anyway.
|
||||
defaultSpoolValue = 1
|
||||
spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)
|
||||
spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, True)
|
||||
for mod in fit.modules:
|
||||
if mod.getDps(spoolOptions=spoolOptions).total > 0:
|
||||
# Group weapon + ammo combinations that occur more than once
|
||||
@@ -344,7 +344,7 @@ class EfsPort():
|
||||
aoeFieldRange = stats.getModifiedItemAttr("empFieldRange")
|
||||
# This also covers non-bomb weapons with dps values and no hardpoints, most notably targeted doomsdays.
|
||||
typeing = "SmartBomb"
|
||||
# Targeted DDs are the only non drone/fighter weapon without an explict max range
|
||||
# Targeted DDs are the only non drone/fighter weapon without an explicit max range
|
||||
if stats.item.group.name == 'Super Weapon' and stats.maxRange is None:
|
||||
maxRange = 300000
|
||||
else:
|
||||
@@ -515,7 +515,7 @@ class EfsPort():
|
||||
|
||||
# Since the effect modules are fairly opaque a mock test fit is used to test the impact of traits.
|
||||
# standin class used to prevent . notation causing issues when used as an arg
|
||||
class standin():
|
||||
class standin:
|
||||
pass
|
||||
tf = standin()
|
||||
tf.modules = HandledList(turrets + launchers)
|
||||
@@ -551,7 +551,7 @@ class EfsPort():
|
||||
|
||||
@staticmethod
|
||||
def getShipSize(groupID):
|
||||
# Size groupings are somewhat arbitrary but allow for a more managable number of top level groupings in a tree structure.
|
||||
# Size groupings are somewhat arbitrary but allow for a more manageable number of top level groupings in a tree structure.
|
||||
frigateGroupNames = ["Frigate", "Shuttle", "Corvette", "Assault Frigate", "Covert Ops", "Interceptor",
|
||||
"Stealth Bomber", "Electronic Attack Ship", "Expedition Frigate", "Logistics Frigate"]
|
||||
destroyerGroupNames = ["Destroyer", "Interdictor", "Tactical Destroyer", "Command Destroyer"]
|
||||
@@ -625,9 +625,29 @@ class EfsPort():
|
||||
}
|
||||
resonance = {"hull": hullResonance, "armor": armorResonance, "shield": shieldResonance}
|
||||
shipSize = EfsPort.getShipSize(fit.ship.item.groupID)
|
||||
# TODO: fetch spoolup option
|
||||
# Export at maximum spool for consistency, spoolup data is exported anyway.
|
||||
defaultSpoolValue = 1
|
||||
spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)
|
||||
spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, True)
|
||||
|
||||
def roundNumbers(data, digits):
|
||||
if isinstance(data, str):
|
||||
return
|
||||
if isinstance(data, dict):
|
||||
for key in data:
|
||||
if isinstance(data[key], Number):
|
||||
data[key] = round(data[key], digits)
|
||||
else:
|
||||
roundNumbers(data[key], digits)
|
||||
if isinstance(data, list) or isinstance(data, tuple):
|
||||
for val in data:
|
||||
roundNumbers(val, digits)
|
||||
if isinstance(data, Number):
|
||||
rounded = round(data, digits)
|
||||
if data != rounded:
|
||||
pyfalog.error("Error rounding numbers for EFS export, export may be inconsistent."
|
||||
"This suggests the format has been broken somewhere.")
|
||||
return
|
||||
|
||||
try:
|
||||
dataDict = {
|
||||
"name": fitName, "ehp": fit.ehp, "droneDPS": fit.getDroneDps().total,
|
||||
@@ -650,9 +670,12 @@ class EfsPort():
|
||||
"modTypeIDs": modTypeIDs, "moduleNames": moduleNames,
|
||||
"pyfaVersion": pyfaVersion, "efsExportVersion": EfsPort.version
|
||||
}
|
||||
except TypeError:
|
||||
# Recursively round any numbers in dicts to 6 decimal places.
|
||||
# This prevents meaningless rounding errors from changing the output whenever pyfa changes.
|
||||
roundNumbers(dataDict, 6)
|
||||
except TypeError as e:
|
||||
pyfalog.error("Error parsing fit:" + str(fit))
|
||||
pyfalog.error(TypeError)
|
||||
pyfalog.error(e)
|
||||
dataDict = {"name": fitName + "Fit could not be correctly parsed"}
|
||||
export = json.dumps(dataDict, skipkeys=True)
|
||||
return export
|
||||
|
||||
@@ -26,6 +26,7 @@ import wx
|
||||
from logbook import Logger
|
||||
|
||||
from eos import db
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
from service.network import TimeoutError
|
||||
@@ -85,13 +86,18 @@ class Price(object):
|
||||
toRequest = set()
|
||||
|
||||
# Compose list of items we're going to request
|
||||
for typeID in priceMap:
|
||||
for typeID in tuple(priceMap):
|
||||
# Get item object
|
||||
item = db.getItem(typeID)
|
||||
# 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
|
||||
if item is not None and item.marketGroupID:
|
||||
toRequest.add(typeID)
|
||||
if item is None:
|
||||
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
|
||||
if len(toRequest) == 0:
|
||||
@@ -117,11 +123,10 @@ class Price(object):
|
||||
except TimeoutError:
|
||||
# Timeout error deserves special treatment
|
||||
pyfalog.warning("Price fetch timout")
|
||||
for typeID in priceMap.keys():
|
||||
for typeID in tuple(priceMap):
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.time = time.time() + TIMEOUT
|
||||
priceobj.failed = True
|
||||
|
||||
priceobj.status = PriceStatus.fail
|
||||
del priceMap[typeID]
|
||||
except Exception as ex:
|
||||
# something happened, try another source
|
||||
@@ -134,7 +139,7 @@ class Price(object):
|
||||
for typeID in priceMap.keys():
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.time = time.time() + REREQUEST
|
||||
priceobj.failed = True
|
||||
priceobj.status = PriceStatus.fail
|
||||
|
||||
@classmethod
|
||||
def fitItemsList(cls, fit):
|
||||
@@ -172,8 +177,8 @@ class Price(object):
|
||||
def getPrices(self, objitems, callback, waitforthread=False):
|
||||
"""Get prices for multiple typeIDs"""
|
||||
requests = []
|
||||
sMkt = Market.getInstance()
|
||||
for objitem in objitems:
|
||||
sMkt = Market.getInstance()
|
||||
item = sMkt.getItem(objitem)
|
||||
requests.append(item.price)
|
||||
|
||||
@@ -197,6 +202,7 @@ class Price(object):
|
||||
|
||||
|
||||
class PriceWorkerThread(threading.Thread):
|
||||
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.name = "PriceWorker"
|
||||
|
||||
@@ -525,6 +525,7 @@ class ContextMenuSettings(object):
|
||||
"tacticalMode" : 1,
|
||||
"targetResists" : 1,
|
||||
"whProjector" : 1,
|
||||
"moduleFill" : 1,
|
||||
}
|
||||
|
||||
self.ContextMenuDefaultSettings = SettingsProvider.getInstance().getSettings("pyfaContextMenuSettings", ContextMenuDefaultSettings)
|
||||
|
||||
Reference in New Issue
Block a user