fmu-manipulation-toolbox 1.8.4.3b0__py3-none-any.whl → 1.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. fmu_manipulation_toolbox/__init__.py +0 -1
  2. fmu_manipulation_toolbox/__main__.py +1 -1
  3. fmu_manipulation_toolbox/__version__.py +1 -1
  4. fmu_manipulation_toolbox/assembly.py +21 -12
  5. fmu_manipulation_toolbox/checker.py +11 -8
  6. fmu_manipulation_toolbox/cli/__init__.py +0 -0
  7. fmu_manipulation_toolbox/cli/fmucontainer.py +105 -0
  8. fmu_manipulation_toolbox/cli/fmusplit.py +48 -0
  9. fmu_manipulation_toolbox/cli/fmutool.py +127 -0
  10. fmu_manipulation_toolbox/cli/utils.py +36 -0
  11. fmu_manipulation_toolbox/container.py +534 -247
  12. fmu_manipulation_toolbox/gui.py +47 -55
  13. fmu_manipulation_toolbox/gui_style.py +8 -0
  14. fmu_manipulation_toolbox/help.py +3 -0
  15. fmu_manipulation_toolbox/operations.py +251 -179
  16. fmu_manipulation_toolbox/remoting.py +107 -0
  17. fmu_manipulation_toolbox/resources/darwin64/container.dylib +0 -0
  18. fmu_manipulation_toolbox/resources/linux32/client_sm.so +0 -0
  19. fmu_manipulation_toolbox/resources/linux32/server_sm +0 -0
  20. fmu_manipulation_toolbox/resources/linux64/client_sm.so +0 -0
  21. fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
  22. fmu_manipulation_toolbox/resources/linux64/server_sm +0 -0
  23. fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
  24. fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
  25. fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
  26. fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
  27. fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
  28. fmu_manipulation_toolbox/split.py +67 -34
  29. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/METADATA +1 -1
  30. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/RECORD +34 -27
  31. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/WHEEL +0 -0
  32. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/entry_points.txt +0 -0
  33. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/licenses/LICENSE.txt +0 -0
  34. {fmu_manipulation_toolbox-1.8.4.3b0.dist-info → fmu_manipulation_toolbox-1.9.dist-info}/top_level.txt +0 -0
@@ -2,22 +2,26 @@ import os.path
2
2
  import sys
3
3
  import textwrap
4
4
 
5
- from PySide6.QtCore import Qt, QObject, QUrl, QDir, Signal, QPoint, QModelIndex
5
+ from PySide6.QtCore import Qt, QUrl, QDir, Signal, QPoint, QModelIndex
6
6
  from PySide6.QtWidgets import (QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QPushButton, QFileDialog,
7
7
  QTextBrowser, QInputDialog, QMenu, QTreeView, QAbstractItemView, QTabWidget, QTableView,
8
8
  QCheckBox)
9
9
  from PySide6.QtGui import (QPixmap, QTextCursor, QStandardItem, QIcon, QDesktopServices, QAction,
10
10
  QPainter, QColor, QImage, QStandardItemModel)
11
11
  from functools import partial
12
- from typing import Optional
13
12
 
14
- from .gui_style import gui_style
13
+
14
+ from .gui_style import gui_style, log_color
15
15
  from .operations import *
16
+ from .remoting import (OperationAddRemotingWin32, OperationAddRemotingWin64, OperationAddFrontendWin32,
17
+ OperationAddFrontendWin64)
16
18
  from .assembly import Assembly, AssemblyNode
17
19
  from .checker import checker_list
18
20
  from .help import Help
19
21
  from .version import __version__ as version
20
22
 
23
+ logger = logging.getLogger("fmu_manipulation_toolbox")
24
+
21
25
 
22
26
  class DropZoneWidget(QLabel):
23
27
  WIDTH = 150
@@ -51,7 +55,7 @@ class DropZoneWidget(QLabel):
51
55
  try:
52
56
  file_path = event.mimeData().urls()[0].toLocalFile()
53
57
  except IndexError:
54
- print("Please select a regular file.")
58
+ logger.error("Please select a regular file.")
55
59
  return
56
60
  self.set_fmu(file_path)
57
61
  event.accept()
@@ -98,54 +102,41 @@ class DropZoneWidget(QLabel):
98
102
  self.fmu = FMU(filename)
99
103
  self.set_image(os.path.join(self.fmu.tmp_directory, "model.png"))
100
104
  except Exception as e:
101
- print(f"ERROR: Cannot load this FMU: {e}")
105
+ logger.error(f"Cannot load this FMU: {e}")
102
106
  self.set_image(None)
103
107
  self.fmu = None
104
108
  self.clicked.emit()
105
109
 
106
110
 
111
+ class LogHandler(logging.Handler):
112
+ LOG_COLOR = {
113
+ logging.DEBUG: QColor(log_color["DEBUG"]),
114
+ logging.INFO: QColor(log_color["INFO"]),
115
+ logging.WARNING: QColor(log_color["WARNING"]),
116
+ logging.ERROR: QColor(log_color["ERROR"]),
117
+ logging.CRITICAL: QColor(log_color["CRITICAL"]),
118
+ }
119
+
120
+ def __init__(self, text_browser, level):
121
+ super().__init__(level)
122
+ self.text_browser: QTextBrowser = text_browser
123
+ logger.addHandler(self)
124
+ logger.setLevel(level)
125
+
126
+ def emit(self, record) -> None:
127
+ self.text_browser.setTextColor(self.LOG_COLOR[record.levelno])
128
+ self.text_browser.insertPlainText(record.msg+"\n")
129
+
130
+
107
131
  class LogWidget(QTextBrowser):
108
- class XStream(QObject):
109
- _stdout = None
110
- _stderr = None
111
- messageWritten = Signal(str)
112
-
113
- def __init__(self):
114
- super().__init__()
115
-
116
- def flush(self):
117
- pass
118
-
119
- @staticmethod
120
- def fileno():
121
- return -1
122
-
123
- def write(self, msg):
124
- if not self.signalsBlocked():
125
- self.messageWritten.emit(msg)
126
-
127
- @staticmethod
128
- def stdout():
129
- if not LogWidget.XStream._stdout:
130
- LogWidget.XStream._stdout = LogWidget.XStream()
131
- sys.stdout = LogWidget.XStream._stdout
132
- return LogWidget.XStream._stdout
133
-
134
- @staticmethod
135
- def stderr():
136
- if not LogWidget.XStream._stderr:
137
- LogWidget.XStream._stderr = LogWidget.XStream()
138
- sys.stderr = LogWidget.XStream._stderr
139
- return LogWidget.XStream._stderr
132
+ def __init__(self, parent=None, level=logging.INFO):
133
+ super().__init__(parent)
140
134
 
141
- def __init__(self):
142
- super().__init__()
143
135
  self.setMinimumWidth(900)
144
136
  self.setMinimumHeight(500)
145
137
  self.setSearchPaths([os.path.join(os.path.dirname(__file__), "resources")])
146
138
  self.insertHtml('<center><img src="fmu_manipulation_toolbox.png"/></center><br/>')
147
- LogWidget.XStream.stdout().messageWritten.connect(self.insertPlainText)
148
- LogWidget.XStream.stderr().messageWritten.connect(self.insertPlainText)
139
+ self.log_handler = LogHandler(self, logging.DEBUG)
149
140
 
150
141
  def loadResource(self, _, name):
151
142
  image_path = os.path.join(os.path.dirname(__file__), "resources", name.toString())
@@ -255,10 +246,10 @@ class AssemblyTreeWidget(QTreeView):
255
246
 
256
247
  def removeRows(self, row, count, parent=QModelIndex()):
257
248
  if not self.dnd_target_node:
258
- print("NO DROP NODE!?")
249
+ logger.error("NO DROP NODE!?")
259
250
 
260
251
  source_index = self.itemFromIndex(parent).child(row, 0).data(role=Qt.ItemDataRole.UserRole+1)
261
- print(f"{source_index} ==> {self.dnd_target_node.name}")
252
+ logger.debug(f"{source_index} ==> {self.dnd_target_node.name}")
262
253
 
263
254
  self.dnd_target_node = None
264
255
  return super().removeRows(row, count, parent)
@@ -289,7 +280,7 @@ class AssemblyTreeWidget(QTreeView):
289
280
 
290
281
  def setTopIndex(self):
291
282
  topIndex = self.model.index(0, 0, self.rootIndex())
292
- print(topIndex.isValid(), topIndex.model())
283
+ logger.debug(topIndex.isValid(), topIndex.model())
293
284
  if topIndex.isValid():
294
285
  self.setCurrentIndex(topIndex)
295
286
  if self.layoutCheck:
@@ -318,9 +309,9 @@ class AssemblyTreeWidget(QTreeView):
318
309
  try:
319
310
  file_path = event.mimeData().urls()[0].toLocalFile()
320
311
  except IndexError:
321
- print("Please select a regular file.")
312
+ logger.error("Please select a regular file.")
322
313
  return
323
- print(f"DROP: {file_path}")
314
+ logger.debug(f"DROP: {file_path}")
324
315
  event.accept()
325
316
  else:
326
317
  event.ignore()
@@ -518,7 +509,7 @@ class MainWindow(WindowWithLayout):
518
509
  "FMU files (*.fmu)")
519
510
  if ok and filename:
520
511
  fmu.repack(filename)
521
- print(f"Modified version saved as {filename}.")
512
+ logger.info(f"Modified version saved as {filename}.")
522
513
 
523
514
  def save_log(self):
524
515
  if self.dropped_fmu.fmu:
@@ -533,7 +524,7 @@ class MainWindow(WindowWithLayout):
533
524
  with open(filename, "wt") as file:
534
525
  file.write(str(self.log_widget.toPlainText()))
535
526
  except Exception as e:
536
- print(f"ERROR: {e}")
527
+ logger.error(f"{e}")
537
528
 
538
529
  def add_operation(self, name, usage, severity, operation, x, y, prompt=None, prompt_file=None, arg=None,
539
530
  func=None):
@@ -603,18 +594,18 @@ class MainWindow(WindowWithLayout):
603
594
  if self.dropped_fmu.fmu:
604
595
  self.log_widget.moveCursor(QTextCursor.MoveOperation.End)
605
596
  fmu_filename = os.path.basename(self.dropped_fmu.fmu.fmu_filename)
606
- print('-' * 100)
597
+ logger.info('-' * 100)
607
598
  self.log_widget.insertHtml(f"<strong>{fmu_filename}: {operation}</strong><br>")
608
599
 
609
600
  apply_on = self.filter_list.get()
610
601
  if apply_on:
611
602
  self.log_widget.insertHtml(f"<i>Applied only for ports with causality = " +
612
603
  ", ".join(apply_on) + "</i><br>")
613
- print('-' * 100)
604
+ logger.info('-' * 100)
614
605
  try:
615
606
  self.dropped_fmu.fmu.apply_operation(operation, apply_on=apply_on)
616
607
  except Exception as e:
617
- print(f"ERROR: {e}")
608
+ logger.error(f"{e}")
618
609
 
619
610
  scroll_bar = self.log_widget.verticalScrollBar()
620
611
  scroll_bar.setValue(scroll_bar.maximum())
@@ -712,7 +703,7 @@ class ContainerWindow(WindowWithLayout):
712
703
  self.last_directory = os.path.dirname(filename)
713
704
  self.assembly_tree.load_container(filename)
714
705
  except Exception as e:
715
- print(e)
706
+ logger.error(e)
716
707
 
717
708
 
718
709
  class Application(QApplication):
@@ -724,8 +715,9 @@ Communicating with the FMU-developer and adapting the way the FMU is generated,
724
715
 
725
716
  """
726
717
  def __init__(self, *args, **kwargs):
727
- super().__init__(*args, **kwargs)
728
718
  self.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.RoundPreferFloor)
719
+ super().__init__(*args, **kwargs)
720
+
729
721
 
730
722
  QDir.addSearchPath('images', os.path.join(os.path.dirname(__file__), "resources"))
731
723
  self.setStyleSheet(gui_style)
@@ -747,8 +739,8 @@ Communicating with the FMU-developer and adapting the way the FMU is generated,
747
739
  def main():
748
740
  application = Application(sys.argv)
749
741
 
750
- print(" " * 80, f"Version {version}")
751
- print(application.__doc__)
742
+ logger.info(" " * 80 + f"Version {version}")
743
+ logger.info(application.__doc__)
752
744
 
753
745
  sys.exit(application.exec())
754
746
 
@@ -242,3 +242,11 @@ else:
242
242
  margin-left: 0;
243
243
  }
244
244
  """
245
+
246
+ log_color = {
247
+ "DEBUG": "#6E6B6B",
248
+ "INFO": "#b5bab9",
249
+ "WARNING": "#F7C61B",
250
+ "ERROR": "#F54927",
251
+ "CRITICAL": "#FF00FF",
252
+ }
@@ -73,6 +73,9 @@ class Help:
73
73
  '-only-outputs': "apply operation only on ports with causality = 'output'. This "
74
74
  "option is available from version 1.3.",
75
75
 
76
+ '-only-locals': "apply operation only on ports with causality = 'local'. This "
77
+ "option is available from version 1.9.",
78
+
76
79
  '-summary': "display useful information regarding the FMU.",
77
80
 
78
81
  '-check': "performs some check of FMU and display Errors or Warnings. This is useful to avoid later "