From 1be0d306bbbcb1c45a6d3832ca97eb4316fddc2b Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Tue, 26 Oct 2021 11:29:25 +0300 Subject: [PATCH] Allow imports of mutated drone groups via ctrl-v and additions panel context menus --- gui/builtinContextMenus/additionsImport.py | 9 +++-- gui/fitCommands/gui/cargo/imprt.py | 2 +- gui/fitCommands/gui/localDrone/imprt.py | 18 ++++++--- gui/fitCommands/gui/localFighter/imprt.py | 2 +- gui/mainFrame.py | 10 ++--- service/port/eft.py | 47 +++++++++++++--------- service/port/port.py | 4 +- 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/gui/builtinContextMenus/additionsImport.py b/gui/builtinContextMenus/additionsImport.py index 25ad929a8..bafda6a59 100644 --- a/gui/builtinContextMenus/additionsImport.py +++ b/gui/builtinContextMenus/additionsImport.py @@ -5,7 +5,7 @@ from gui import fitCommands as cmd from gui.contextMenu import ContextMenuUnconditional from gui.utils.clipboard import fromClipboard from service.fit import Fit -from service.port.eft import parseAdditions +from service.port.eft import parseAdditions, importGetMutationData, lineIter _t = wx.GetTranslation @@ -41,9 +41,12 @@ class AdditionsImport(ContextMenuUnconditional): def activate(self, callingWindow, fullContext, i): text = fromClipboard() - items = parseAdditions(text) + lines = list(lineIter(text)) + mutaData = importGetMutationData(lines) + text = '\n'.join(lines) + items = parseAdditions(text, mutaData=mutaData) filterFunc = self.viewSpecMap[self.srcContext][1] - items = [(i.ID, a) for i, a in items if filterFunc(i)] + items = [(i.ID, a, m) for i, a, m in items if filterFunc(i)] if not items: return command = self.viewSpecMap[self.srcContext][2] diff --git a/gui/fitCommands/gui/cargo/imprt.py b/gui/fitCommands/gui/cargo/imprt.py index 9a8e153e9..4f9bd675c 100644 --- a/gui/fitCommands/gui/cargo/imprt.py +++ b/gui/fitCommands/gui/cargo/imprt.py @@ -14,7 +14,7 @@ class GuiImportCargosCommand(wx.Command): self.internalHistory = InternalCommandHistory() self.fitID = fitID self.cargos = {} - for itemID, amount in cargos: + for itemID, amount, mutation in cargos: if itemID not in self.cargos: self.cargos[itemID] = 0 self.cargos[itemID] += amount diff --git a/gui/fitCommands/gui/localDrone/imprt.py b/gui/fitCommands/gui/localDrone/imprt.py index d049aa64a..625e0f5f9 100644 --- a/gui/fitCommands/gui/localDrone/imprt.py +++ b/gui/fitCommands/gui/localDrone/imprt.py @@ -18,11 +18,19 @@ class GuiImportLocalDronesCommand(wx.Command): def Do(self): results = [] - for itemID, amount in self.drones: - cmd = CalcAddLocalDroneCommand( - fitID=self.fitID, - droneInfo=DroneInfo(itemID=itemID, amount=amount, amountActive=0), - forceNewStack=True) + for itemID, amount, mutation in self.drones: + if mutation: + mutaplasmid, attrs = mutation + info = DroneInfo( + itemID=mutaplasmid.resultingItem.ID, + amount=amount, + amountActive=0, + baseItemID=itemID, + mutaplasmidID=mutaplasmid.ID, + mutations=attrs) + else: + info = DroneInfo(itemID=itemID, amount=amount, amountActive=0) + cmd = CalcAddLocalDroneCommand(fitID=self.fitID, droneInfo=info, forceNewStack=True) results.append(self.internalHistory.submit(cmd)) success = any(results) eos.db.flush() diff --git a/gui/fitCommands/gui/localFighter/imprt.py b/gui/fitCommands/gui/localFighter/imprt.py index dd8f494cc..9ad5d39d4 100644 --- a/gui/fitCommands/gui/localFighter/imprt.py +++ b/gui/fitCommands/gui/localFighter/imprt.py @@ -18,7 +18,7 @@ class GuiImportLocalFightersCommand(wx.Command): def Do(self): results = [] - for itemID, amount in self.fighters: + for itemID, amount, mutation in self.fighters: cmd = CalcAddLocalFighterCommand(fitID=self.fitID, fighterInfo=FighterInfo(itemID=itemID, amount=amount, state=False)) results.append(self.internalHistory.submit(cmd)) success = any(results) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index eaf369d28..28f4a6eb2 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -772,23 +772,23 @@ class MainFrame(wx.Frame): self.command.Submit(cmd.GuiAddLocalModuleCommand(activeFit, baseItem.ID)) return if importType == "AdditionsDrones": - if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): + if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])): self.additionsPane.select("Drones") return if importType == "AdditionsFighters": - if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): + if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])): self.additionsPane.select("Fighters") return if importType == "AdditionsImplants": - if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): + if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])): self.additionsPane.select("Implants") return if importType == "AdditionsBoosters": - if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): + if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])): self.additionsPane.select("Boosters") return if importType == "AdditionsCargo": - if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): + if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])): self.additionsPane.select("Cargo") return except (KeyboardInterrupt, SystemExit): diff --git a/service/port/eft.py b/service/port/eft.py index 31ea7007e..1596e0352 100644 --- a/service/port/eft.py +++ b/service/port/eft.py @@ -225,7 +225,7 @@ def importEft(lines): return aFit = AbstractFit() - aFit.mutations = _importGetMutationData(lines) + aFit.mutations = importGetMutationData(lines) stubPattern = '^\[.+?\]$' modulePattern = '^(?P{0}+?)(,\s*(?P{0}+?))?(?P\s*{1})?(\s*\[(?P\d+?)\])?$'.format(NAME_CHARS, OFFLINE_SUFFIX) @@ -572,8 +572,7 @@ def _importPrepare(lines): mutantHeaderPattern = re.compile('^\[(?P\d+)\](?P.*)') -def _importGetMutationData(lines): - data = {} +def importGetMutationData(lines): # Format: {ref: [lines]} mutaLinesMap = {} currentMutaRef = None @@ -943,7 +942,7 @@ class AbstractFit: self.cargo[itemSpec.item].amount += itemSpec.amount -def _lineIter(text): +def lineIter(text): """Iterate over non-blank lines.""" for line in text.splitlines(): line = line.strip() @@ -951,11 +950,11 @@ def _lineIter(text): yield line -def parseAdditions(text): +def parseAdditions(text, mutaData=None): items = [] sMkt = Market.getInstance() - pattern = '^(?P{}+?)( x(?P\d+?))?$'.format(NAME_CHARS) - for line in _lineIter(text): + pattern = '^(?P{}+?)( x(?P\d+?))?(\s*\[(?P\d+?)\])?$'.format(NAME_CHARS) + for line in lineIter(text): m = re.match(pattern, line) if not m: continue @@ -964,19 +963,27 @@ def parseAdditions(text): continue amount = m.group('amount') amount = 1 if amount is None else int(amount) - items.append((item, amount)) + mutaRef = int(m.group('mutaref')) if m.group('mutaref') else None + if mutaRef and mutaData and mutaRef in mutaData: + mutation = mutaData[mutaRef] + else: + mutation = None + items.append((item, amount, mutation)) return items def isValidDroneImport(text): - pattern = 'x\d+$' - for line in _lineIter(text): + lines = list(lineIter(text)) + mutaData = importGetMutationData(lines) + text = '\n'.join(lines) + pattern = 'x\d+(\s*\[\d+\])?$' + for line in lineIter(text): if not re.search(pattern, line): return False, () - itemData = parseAdditions(text) + itemData = parseAdditions(text, mutaData=mutaData) if not itemData: return False, () - for item, amount in itemData: + for item, amount, mutation in itemData: if not item.isDrone: return False, () return True, itemData @@ -984,13 +991,13 @@ def isValidDroneImport(text): def isValidFighterImport(text): pattern = 'x\d+$' - for line in _lineIter(text): + for line in lineIter(text): if not re.search(pattern, line): return False, () itemData = parseAdditions(text) if not itemData: return False, () - for item, amount in itemData: + for item, amount, mutation in itemData: if not item.isFighter: return False, () return True, itemData @@ -998,13 +1005,13 @@ def isValidFighterImport(text): def isValidCargoImport(text): pattern = 'x\d+$' - for line in _lineIter(text): + for line in lineIter(text): if not re.search(pattern, line): return False, () itemData = parseAdditions(text) if not itemData: return False, () - for item, amount in itemData: + for item, amount, mutation in itemData: if item.isAbyssal: return False, () return True, itemData @@ -1012,13 +1019,13 @@ def isValidCargoImport(text): def isValidImplantImport(text): pattern = 'x\d+$' - for line in _lineIter(text): + for line in lineIter(text): if re.search(pattern, line): return False, () itemData = parseAdditions(text) if not itemData: return False, () - for item, amount in itemData: + for item, amount, mutation in itemData: if not item.isImplant: return False, () return True, itemData @@ -1026,13 +1033,13 @@ def isValidImplantImport(text): def isValidBoosterImport(text): pattern = 'x\d+$' - for line in _lineIter(text): + for line in lineIter(text): if re.search(pattern, line): return False, () itemData = parseAdditions(text) if not itemData: return False, () - for item, amount in itemData: + for item, amount, mutation in itemData: if not item.isBooster: return False, () return True, itemData diff --git a/service/port/port.py b/service/port/port.py index f11a3e6af..2e20d95e4 100644 --- a/service/port/port.py +++ b/service/port/port.py @@ -232,14 +232,14 @@ class Port: # If we've got source file name which is used to describe ship name # and first line contains something like [setup name], detect as eft config file - if re.match("\[.*\]", firstLine) and path is not None: + if re.match("^\s*\[.*\]", firstLine) and path is not None: filename = os.path.split(path)[1] shipName = filename.rsplit('.')[0] return "EFT Config", True, cls.importEftCfg(shipName, lines, iportuser) # If no file is specified and there's comma between brackets, # consider that we have [ship, setup name] and detect like eft export format - if re.match("\[.*,.*\]", firstLine): + if re.match("^\s*\[.*,.*\]", firstLine): return "EFT", True, (cls.importEft(lines),) # Check if string is in DNA format