From 19cbf6d140699983d377a81cc05e2c1fd3192fdd Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 6 Nov 2024 17:17:15 +0500 Subject: [PATCH] ifcfm - move preset searching logic from ifcm to bonsai So anyone using 'python -m ifcfm' will get more readable error for invalid presets. --- src/bonsai/bonsai/bim/module/fm/data.py | 12 ++++-------- src/ifcfm/ifcfm/__init__.py | 26 ++++++++++++++++++++----- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/fm/data.py b/src/bonsai/bonsai/bim/module/fm/data.py index 90e9a21906..fa4a9c4c6a 100644 --- a/src/bonsai/bonsai/bim/module/fm/data.py +++ b/src/bonsai/bonsai/bim/module/fm/data.py @@ -36,13 +36,9 @@ class FMData: cls.data["engine"] = cls.engine() @classmethod - def engine(cls): + def engine(cls) -> list[tuple[str, str, str]]: results = [] - fm_dir = os.path.dirname(ifcfm.__file__) - for f in os.listdir(fm_dir): - if f.endswith(".py") and not f.startswith("_"): - preset = os.path.splitext(f)[0] - module = importlib.import_module(f"ifcfm.{preset}") - config = getattr(module, "config") - results.append((preset, config["name"], config["description"])) + presets = ifcfm.get_presets_configs() + for preset, config in presets.items(): + results.append((preset, config["name"], config["description"])) return results diff --git a/src/ifcfm/ifcfm/__init__.py b/src/ifcfm/ifcfm/__init__.py index 30e041e78d..e6e6a628f6 100644 --- a/src/ifcfm/ifcfm/__init__.py +++ b/src/ifcfm/ifcfm/__init__.py @@ -49,6 +49,21 @@ __version__ = version = "0.0.0" ParserPreset = Literal["basic", "cobie24", "cobie24legacy"] +_parser_presets_configs = {} + + +def get_presets_configs() -> dict[ParserPreset, dict[str, Any]]: + global _parser_presets_configs + if not _parser_presets_configs: + fm_dir = Path(__file__).parent + for f in fm_dir.iterdir(): + if not f.suffix == ".py" or f.name.startswith("_"): + continue + preset = f.stem + module = importlib.import_module(f"ifcfm.{preset}") + config = getattr(module, "config") + _parser_presets_configs[preset] = config + return _parser_presets_configs class Parser: @@ -59,7 +74,7 @@ class Parser: ] duplicate_keys: list[tuple[dict[str, Any], dict[str, Any]]] - def __init__(self, preset: Union[ParserPreset, dict[str, Any]] = "basic"): + def __init__(self, preset: Union[str, ParserPreset, dict[str, Any]] = "basic"): self.file = None self.preset = preset self.categories = defaultdict(dict) @@ -67,8 +82,10 @@ class Parser: self.duplicate_keys = [] if isinstance(preset, str): - module = importlib.import_module(f"ifcfm.{preset}") - self.config = getattr(module, "config") + presets = get_presets_configs() + if preset not in presets: + raise Exception(f"Invalid preset '{preset}'. Available presets: {','.join(presets.keys())}.") + self.config = get_presets_configs()[preset] else: self.config = preset @@ -134,8 +151,7 @@ class Writer: def __init__(self, parser: Parser): self.parser = parser if isinstance(self.parser.preset, str): - module = importlib.import_module(f"ifcfm.{self.parser.preset}") - self.config = getattr(module, "config") + self.config = get_presets_configs()[self.parser.preset] elif isinstance(self.parser.preset, dict): self.config = self.parser.preset["config"] else: