Skip to content

Commit

Permalink
Export placeholers json if ddck folders missing (#505)
Browse files Browse the repository at this point in the history
* Warn, but don't abort, if some ddck folders are missing when exporting the placeholders JSON.

* Moved export of placeholders json out of editor entirely.

---------

Co-authored-by: ahobeost <[email protected]>
  • Loading branch information
zuckerruebe and ahobeost authored Apr 10, 2024
1 parent 425bfce commit 4bed07d
Show file tree
Hide file tree
Showing 20 changed files with 371 additions and 254 deletions.
7 changes: 4 additions & 3 deletions tests/trnsysGUI/diagram/testEditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
import trnsysGUI.connection.singlePipeConnection as _spc
import trnsysGUI.diagram.Editor as _de
import trnsysGUI.mainWindow as _mw
import trnsysGUI.menus.projectMenu.exportPlaceholders as _eph
import trnsysGUI.project as _prj
import trnsysGUI.storageTank.widget as _stw
import trnsysGUI.errors as _err
import trnsysGUI.warningsAndErrors as _werrors
from . import _testHelper as _th


Expand Down Expand Up @@ -119,7 +120,7 @@ def dummyInformation(*_, **__):
_qtw.QMessageBox, _qtw.QMessageBox.information.__name__, dummyInformation # pylint: disable=no-member
)

result = editor.exportDdckPlaceHolderValuesJsonFile()
result = _eph.exportDdckPlaceHolderValuesJsonFile(editor)

assert not _res.isError(result), _res.error(result).message

Expand All @@ -137,7 +138,7 @@ def dummyShowErrorMessageBox(errorMessage: str, title: str = "Error") -> None:
failMessage = f"{title}: {errorMessage}"
_pt.fail(failMessage)

monkeypatch.setattr(_err, _err.showErrorMessageBox.__name__, dummyShowErrorMessageBox)
monkeypatch.setattr(_werrors, _werrors.showMessageBox.__name__, dummyShowErrorMessageBox)

mainWindow.exportDck()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import PyQt5.QtWidgets as _qtw

import trnsysGUI.dialogs.connections.doublePipe as _dpcdlg
import trnsysGUI.errors as _errors
import trnsysGUI.warningsAndErrors as _werrors


_SHOW_ERROR_FUNCTION_NAME = f"{_errors.__name__}.{_errors.showErrorMessageBox.__name__}"
_SHOW_ERROR_FUNCTION_NAME = f"{_werrors.__name__}.{_werrors.showMessageBox.__name__}"


class TestDoublePipeConnectionPropertiesDialog: # pylint: disable = attribute-defined-outside-init
Expand Down
39 changes: 36 additions & 3 deletions tests/trnsysGUI/placeholders/testPlaceholders.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import logging as _log
import pathlib as _pl

import pytrnsys.utils.result as _res
import trnsysGUI.BlockItem as _bi
import trnsysGUI.diagram.Editor as _de
import trnsysGUI.internalPiping as _ip
import trnsysGUI.menus.projectMenu.exportPlaceholders as _eph
import trnsysGUI.menus.projectMenu.placeholders as _ph

_DATA_DIR_ = _pl.Path(__file__).parent / "data"

Expand All @@ -17,14 +20,44 @@ def testPlaceholders(self, qtbot):
editor = self._createEditor(actualDirPath)
qtbot.addWidget(editor)

result = editor.encodeDdckPlaceHolderValuesToJson(actualJsonFilePath)
assert not _res.isError(result)
valueWithWarnings = _eph.encodeDdckPlaceHolderValuesToJson(
editor.projectFolder, actualJsonFilePath, editor.trnsysObj, editor.hydraulicLoops
)
assert not valueWithWarnings.hasWarnings()

actualJsonText = actualJsonFilePath.read_text() # pylint: disable=bad-option-value,unspecified-encoding
expectedJsonText = expectedJsonFilePath.read_text() # pylint: disable=bad-option-value,unspecified-encoding

assert actualJsonText == expectedJsonText

def testPlaceholdersMissingDdckDirCreatesWarning(self, qtbot):
# leaving this for now to show simultaneous working of both.
actualDirPath = _DATA_DIR_ / "TRIHP_dualSource"

editor = self._createEditor(actualDirPath)
qtbot.addWidget(editor)

blockItems = [
o for o in editor.trnsysObj if isinstance(o, _ip.HasInternalPiping) and isinstance(o, _bi.BlockItem)
]

ddckDirNames = [b.getDisplayName() for b in blockItems]
ddckDirNames.remove("HP")

valueWithWarnings = _ph.getPlaceholderValues(ddckDirNames, blockItems, editor.hydraulicLoops)

actualWarning = valueWithWarnings.toWarningMessage()
expectedWarning = """\
The following components didn't have a corresponding directory of the same name in the ddck folder:
HP
This can happen if you're using a "template" ddck under a different name as its containing directory
(i.e. "PROJECT$ path\\to\\your\\template.ddck as different_name") - in which case you can ignore this warning
for that particular component - or it could indicate a missing ddck file.
"""
assert actualWarning == expectedWarning

@staticmethod
def _createEditor(projectFolderPath): # pylint: disable=duplicate-code
logger = _log.Logger("root")
Expand Down
4 changes: 2 additions & 2 deletions trnsysGUI/MassFlowVisualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import trnsysGUI.connection.doublePipeConnection as _dpc
import trnsysGUI.connection.names as _cnames
import trnsysGUI.connection.singlePipeConnection as _spc
import trnsysGUI.errors as _err
import trnsysGUI.warningsAndErrors as _werrors
import trnsysGUI.massFlowSolver.names as _mnames
import trnsysGUI.massFlowSolver.networkModel as _mfn

Expand Down Expand Up @@ -153,7 +153,7 @@ def _onTimeStepIncreaseLineEditEditingFinished(self) -> None:

if timeStepIncrease is None or not (1 <= timeStepIncrease <= self.maxTimeStep):
errorMessage = f"The time-step increase must be an integer between 1 and {self.maxTimeStep}, inclusive."
_err.showErrorMessageBox(errorMessage=errorMessage, title="Invalid value")
_werrors.showMessageBox(errorMessage, title="Invalid value")
self._timeStepIncreaseLineEdit.setText(str(self._timeStepIncrease))
return

Expand Down
4 changes: 2 additions & 2 deletions trnsysGUI/connection/addSinglePipeConnectionCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import pytrnsys.utils.result as _res
import trnsysGUI.connection.singlePipeConnection as _spc
import trnsysGUI.errors as _err
import trnsysGUI.warningsAndErrors as _werrors
import trnsysGUI.hydraulicLoops.merge as _hlmerge
import trnsysGUI.hydraulicLoops.split as _hlsplit
import trnsysGUI.names.undo as _nu
Expand Down Expand Up @@ -43,7 +43,7 @@ def redo(self):
if cancellable == "cancelled" or _res.isError(cancellable):
if _res.isError(cancellable):
error = _res.error(cancellable)
_err.showErrorMessageBox(error.message, "Cannot create connection")
_werrors.showMessageBox(error.message, "Cannot create connection")

self._connection.deleteConnection()
self.setObsolete(True)
Expand Down
75 changes: 6 additions & 69 deletions trnsysGUI/diagram/Editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import trnsysGUI.connection.names as _cnames
import trnsysGUI.console as _con
import trnsysGUI.diagram.Encoder as _enc
import trnsysGUI.errors as _err
import trnsysGUI.errors as _errs
import trnsysGUI.hydraulicLoops.edit as _hledit
import trnsysGUI.hydraulicLoops.migration as _hlmig
import trnsysGUI.hydraulicLoops.model as _hlm
Expand All @@ -32,9 +30,10 @@
import trnsysGUI.names.manager as _nm
import trnsysGUI.names.rename as _rename
import trnsysGUI.names.undo as _nu
import trnsysGUI.placeholders as _ph
import trnsysGUI.menus.projectMenu.placeholders as _ph
import trnsysGUI.segments.segmentItemBase as _sib
import trnsysGUI.storageTank.widget as _stwidget
import trnsysGUI.warningsAndErrors as _werrs
from trnsysGUI.BlockDlg import BlockDlg
from trnsysGUI.BlockItem import BlockItem
from trnsysGUI.Export import Export
Expand Down Expand Up @@ -439,7 +438,7 @@ def _showOverlappingPortItemsNotSupportedErrorMessage():
"Overlapping port items are not supported. Please move the containing components so that the "
"port items don't overlap if you want to connect them."
)
_err.showErrorMessageBox(errorMessage, title="Not implemented")
_werrs.showMessageBox(errorMessage, title="Not implemented")

def _getRelevantHitPortItems(
self, mousePosition: _qtc.QPointF, fromPort: PortItemBase
Expand All @@ -453,7 +452,7 @@ def _getRelevantHitPortItems(
def exportHydraulics(self, exportTo=_tp.Literal["ddck", "mfs"]):
assert exportTo in ["ddck", "mfs"]

if not self._isHydraulicConnected():
if not self.isHydraulicConnected():
messageBox = _qtw.QMessageBox()
messageBox.setWindowTitle("Hydraulic not connected")
messageBox.setText("You need to connect all port items before you can export the hydraulics.")
Expand Down Expand Up @@ -594,7 +593,7 @@ def exportHydraulics(self, exportTo=_tp.Literal["ddck", "mfs"]):
_du.checkEquationsAndConstants(lines, exportPath)
except Exception as error:
errorMessage = f"An error occurred while exporting the system hydraulics: {error}"
_errs.showErrorMessageBox(errorMessage)
_werrs.showMessageBox(errorMessage)
return None

return exportPath
Expand All @@ -615,7 +614,7 @@ def _getMassFlowContributors(self) -> _tp.Sequence[_ip.HasInternalPiping]:
massFlowContributors = [o for o in self.trnsysObj if isinstance(o, _ip.HasInternalPiping)]
return massFlowContributors

def _isHydraulicConnected(self) -> bool:
def isHydraulicConnected(self) -> bool:
for obj in self.trnsysObj:
if not isinstance(obj, _ip.HasInternalPiping):
continue
Expand Down Expand Up @@ -858,57 +857,6 @@ def _setHydraulicLoopsOnStorageTanks(self) -> None:

storageTank.setHydraulicLoops(self.hydraulicLoops)

def exportDdckPlaceHolderValuesJsonFile(self) -> _res.Result[None]:
if not self._isHydraulicConnected():
return _res.Error("You need to connect all port items before you can export the hydraulics.")

jsonFilePath = _pl.Path(self.projectFolder) / "DdckPlaceHolderValues.json"

if jsonFilePath.is_dir():
_qtw.QMessageBox.information(
self,
"Folder already exists",
f"A folder already exits at f{jsonFilePath}. Chose a different location or delete the folder first.",
)
return None

if jsonFilePath.is_file():
pressedButton = _qtw.QMessageBox.question(
self,
"Overwrite file?",
f"The file {jsonFilePath} already exists. Do you want to overwrite it or cancel?",
buttons=(_qtw.QMessageBox.Save | _qtw.QMessageBox.Cancel),
defaultButton=_qtw.QMessageBox.Cancel,
)

if pressedButton != _qtw.QMessageBox.Save:
return None

result = self.encodeDdckPlaceHolderValuesToJson(jsonFilePath)
if _res.isError(result):
return _res.error(result)

_qtw.QMessageBox.information(
self,
"Saved successfully",
f"Saved place holder values JSON file at {jsonFilePath}.",
buttons=_qtw.QMessageBox.Ok,
)

return None

def encodeDdckPlaceHolderValuesToJson(self, filePath: _pl.Path) -> _res.Result[None]:
ddckDirNames = self._getDdckDirNames()

result = _ph.getPlaceholderValues(ddckDirNames, self.trnsysObj, self.hydraulicLoops)
if _res.isError(result):
return _res.error(result)

ddckPlaceHolderValuesDictionary = _res.value(result)

jsonContent = json.dumps(ddckPlaceHolderValuesDictionary, indent=4, sort_keys=True)
filePath.write_text(jsonContent)

# Saving related
def save(self, showWarning=True):
"""
Expand Down Expand Up @@ -1199,14 +1147,3 @@ def editHydraulicLoop(self, singlePipeConnection: SinglePipeConnection):
def _updateGradientsInHydraulicLoop(hydraulicLoop: _hlm.HydraulicLoop) -> None:
for connection in hydraulicLoop.connections:
connection.updateSegmentGradients()

def _getDdckDirNames(self) -> _tp.Sequence[str]:
ddckDirPath = _pl.Path(self.projectFolder) / "ddck"

componentDdckDirPaths = list(ddckDirPath.iterdir())

ddckDirNames = []
for componentDirPath in componentDdckDirPaths:
ddckDirNames.append(componentDirPath.name)

return ddckDirNames
4 changes: 2 additions & 2 deletions trnsysGUI/dialogs/connections/doublePipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import PyQt5.QtCore as _qtc
import PyQt5.QtWidgets as _qtw

import trnsysGUI.errors as _error
import trnsysGUI.warningsAndErrors as _werrors

import trnsysGUI.dialogs as _dlgs

Expand Down Expand Up @@ -42,7 +42,7 @@ def setLengthOrShowError() -> None:
lengthInM = _parsePositiveFloat(lengthText)
self.model.lengthInM = lengthInM
except ValueError:
_error.showErrorMessageBox("Could not parse the length. Please make sure it's a non-negative number.")
_werrors.showMessageBox("Could not parse the length. Please make sure it's a non-negative number.")
self.lengthInMLineEdit.setText(str(self.model.lengthInM))

self.lengthInMLineEdit.editingFinished.connect(setLengthOrShowError)
Expand Down
9 changes: 0 additions & 9 deletions trnsysGUI/errors.py

This file was deleted.

4 changes: 2 additions & 2 deletions trnsysGUI/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pytrnsys.utils.log as _ulog
import pytrnsys.utils.result as _res
import trnsysGUI.arguments as _args
import trnsysGUI.errors as _err
import trnsysGUI.warningsAndErrors as _werrors
import trnsysGUI.pyinstaller as _pyinst
import trnsysGUI.setup as _setup

Expand All @@ -29,7 +29,7 @@ def main():
app.setApplicationName("Diagram Creator")

if errorMessage:
_err.showErrorMessageBox(errorMessage, title="Missing requirements")
_werrors.showMessageBox(errorMessage, title="Missing requirements")
return

import trnsysGUI.common.cancelled as _ccl # pylint: disable=import-outside-toplevel
Expand Down
Loading

0 comments on commit 4bed07d

Please sign in to comment.