Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self):
content_frame.pack(fill=tk.BOTH, expand=True)
main_frm.pack(fill=tk.BOTH, expand=True)

self.solutions = dict()
self.__check_result_queue()
self.protocol("WM_DELETE_WINDOW", self.on_closing)

Expand Down Expand Up @@ -153,6 +154,7 @@ def _path_button_cb(self):
command = 'get_solutions'
cmd_args = (input_path,)
self.task_queue.put((command, cmd_args))
self.solutions.clear()

self.status_bar.set_text(f'Looking for projects in {input_path}. Please wait ...')
self.settings.set('general', 'solution_path', input_path)
Expand All @@ -163,6 +165,7 @@ def __check_result_queue(self):
while True:
message, data = self.result_queue.get_nowait()
if message == 'get_solutions':
self.solutions = {solution.uuid: solution for solution in data}
self.projects_tv.update_projects(data)
self.status_bar.set_text(f'{len(data)} projects found')
elif message == 'get_vars_from_solution':
Expand Down Expand Up @@ -210,7 +213,7 @@ def on_project_tv_double_click(self, event):
solutions_path = self.path_entry_var.get()
project_uuid = self.projects_tv.item(tv_selection[0], "text")
command = 'get_vars_from_solution'
cmd_args = (solutions_path, project_uuid)
cmd_args = (self.solutions[project_uuid].solutions_path, project_uuid)
self.task_queue.put((command, cmd_args))
self.projects_tv.disable_selection()

Expand Down
42 changes: 34 additions & 8 deletions src/sysmac_solution.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
import logging
import os.path
import xml.etree.ElementTree as ET
from datetime import datetime
from os import PathLike
Expand All @@ -24,6 +25,8 @@ def __init__(self, solutions_path, uuid):
self._last_modified = datetime.fromtimestamp(0)
self.global_vars = []

if not os.path.exists(self.solutions_path / f'{self._uuid}.xml'):
self._set_uuid_from_solution(self.solutions_path)
self._get_properties()

@property
Expand All @@ -48,11 +51,11 @@ def uuid(self):

def get_global_vars(self) -> List[SysmacDataType]:
project_oem_file = f'{self._uuid}.oem'
tree = ET.parse(self.solutions_path / self._uuid / project_oem_file)
tree = ET.parse(self.solutions_path / project_oem_file)
root = tree.getroot()
global_vars_filename = root.find(".//Entity[@type='Variables'][@subtype='Global']").attrib.get('id')
self.global_vars = [SysmacDataType.import_from_slwd(symbol)
for symbol in parse_slwd(self.solutions_path / self._uuid / f"{global_vars_filename}.xml")]
for symbol in parse_slwd(self.solutions_path / f"{global_vars_filename}.xml")]
return self.global_vars

def get_published_symbols(self) -> List[SysmacDataType]:
Expand Down Expand Up @@ -147,7 +150,7 @@ def get_published_symbols(self) -> List[SysmacDataType]:

def _get_data_types(self) -> Dict[str, SysmacDataType]:
project_oem_file = f'{self._uuid}.oem'
tree = ET.parse(self.solutions_path / self._uuid / project_oem_file)
tree = ET.parse(self.solutions_path / project_oem_file)
root = tree.getroot()

dt = {}
Expand All @@ -162,7 +165,7 @@ def _get_data_types(self) -> Dict[str, SysmacDataType]:

def _get_data_from_namespace(self, datatype_id, namespace=None) -> Dict[str, SysmacDataType]:
datatype_file = f"{datatype_id}.xml"
tree = ET.parse(self.solutions_path / self._uuid / datatype_file)
tree = ET.parse(self.solutions_path / datatype_file)
root = tree.getroot()

data = get_struct_from_namespace(root, namespace)
Expand All @@ -171,23 +174,46 @@ def _get_data_from_namespace(self, datatype_id, namespace=None) -> Dict[str, Sys

def _get_properties(self):
try:
tree = ET.parse(self.solutions_path / self._uuid / f'{self._uuid}.xml')
tree = ET.parse(self.solutions_path / f'{self._uuid}.xml')
except FileNotFoundError as e:
return
root = tree.getroot()

self._project_type = root.find('.//ProjectType').text
self._author = root.find('.//Author').text
self._last_modified = datetime.fromisoformat(root.find('.//DateModified').text)
date_last_modified = root.find('.//DateModified')
if date_last_modified:
self._last_modified = datetime.fromisoformat(date_last_modified.text)

tree = ET.parse(self.solutions_path / self._uuid / f'{self._uuid}.oem')
tree = ET.parse(self.solutions_path / f'{self._uuid}.oem')
root = tree.getroot()
solution_element = root.find(".//Entity[@type='Solution']")
self._name = solution_element.attrib.get('name') if solution_element is not None else ''

def _set_uuid_from_solution(self, solution_dir: str | bytes | PathLike):
"""Sets the UUID of this solution, based on its .oem filename.
Handles local solutions, temporary solutions and Team solutions.
Leaves UUID unchanged if none could be found"""

found_uuid = ""
candidates = (
Path(solution_dir),
(Path(solution_dir) / "Project"),
)

for candidate in candidates:
found_file = next(candidate.glob('*.oem'), None)
if not found_file:
continue

found_uuid = os.path.splitext(os.path.basename(found_file))[0]
self._uuid = found_uuid
self.solutions_path = candidate
break


def get_solutions(solutions_path: str | bytes | PathLike) -> List[SysmacSolution]:
solutions = [SysmacSolution(solutions_path, s.stem) for s in Path(solutions_path).glob('*/')]
solutions = [SysmacSolution(f"{solutions_path}/{s.stem}", s.stem) for s in Path(solutions_path).glob('*/')]
# Sort the project by last modification date by descending (most recently modified first)
return sorted(solutions, key=lambda x: x.last_modified, reverse=True)

Expand Down