From 1f50e7cb51ca6789f7f733903ba7adf51babc94c Mon Sep 17 00:00:00 2001 From: MaruMaruOO Date: Tue, 29 Jan 2019 02:17:55 -0500 Subject: [PATCH] Merge missing changes from #1755, efs version bump and minor linting. --- service/port/efs.py | 67 ++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/service/port/efs.py b/service/port/efs.py index 0e021902c..51ff5c518 100755 --- a/service/port/efs.py +++ b/service/port/efs.py @@ -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