Files
Sean P. KaneandGitHub f14ab8177d Fix: rename workbench and prepare for release (#27)
* chore: rename workbench to FreecadRobustMCPBridge

* fix: stdio cleanup and bug fix for JSON RPC

* fix: update FreeCAD MCP bridge and tests

* test: Fix GUI Integration tests and other issues

* fix: unit tests in CI and a few other things

* docs: generate GitHub pages site and link to it.

* fix: General code improvements and DRY refactoring

* chore: General cleanup

* chore: small fixes

* docs: cleanup

* docs: fixes

* docs: small corrections

* docs: fix

* test: release check

* bump: workbench v0.6.0

* chore: bump macros to 0.6.0

* docs: Release improvements

* refactor: improve DRYness of code
2026-01-12 09:30:05 -08:00

120 lines
3.8 KiB
Python

"""Shared path utilities for the Robust MCP Bridge addon.
SPDX-License-Identifier: MIT
Copyright (c) 2025 Sean P. Kane (GitHub: spkane)
This module provides centralized path-finding functions for locating
the addon directory, icons, and other resources. All path-related
logic is consolidated here to avoid duplication across modules.
NOTE: Using os.path instead of pathlib throughout this module due to
FreeCAD's module loading behavior which can have issues with some
Python features at load time.
"""
from __future__ import annotations
import os # noqa: PTH
import FreeCAD
# Addon directory name - single source of truth for renames
_ADDON_DIRNAME = "FreecadRobustMCPBridge"
# Cache for addon path to avoid repeated filesystem lookups
_addon_path_cache: str | None = None
def get_addon_path() -> str:
"""Get the path to this addon's directory.
Uses multiple fallback methods to locate the addon directory:
1. __file__ if available
2. FreeCAD's Mod path + addon name
3. Versioned FreeCAD directory (FreeCAD 1.x: v1-*)
Returns:
The absolute path to the addon directory, or empty string if not found.
Once found, the path is cached for subsequent calls.
"""
global _addon_path_cache
if _addon_path_cache is not None:
return _addon_path_cache
# Method 1: Try __file__
try:
_addon_path_cache = os.path.dirname(os.path.abspath(__file__)) # noqa: PTH100, PTH120
return _addon_path_cache
except NameError:
pass
# Method 2: Use FreeCAD's Mod path + our addon name
try:
mod_path = os.path.join( # noqa: PTH118
FreeCAD.getUserAppDataDir(), "Mod", _ADDON_DIRNAME
)
if os.path.exists(mod_path): # noqa: PTH110
_addon_path_cache = mod_path
return _addon_path_cache
except (OSError, PermissionError) as e:
FreeCAD.Console.PrintWarning(f"Could not access Mod directory: {e}\n")
# Method 3: Try versioned FreeCAD directory (FreeCAD 1.x)
try:
base_path = FreeCAD.getUserAppDataDir()
for item in os.listdir(base_path): # noqa: PTH208
if item.startswith("v1-"):
versioned_mod = os.path.join( # noqa: PTH118
base_path, item, "Mod", _ADDON_DIRNAME
)
if os.path.exists(versioned_mod): # noqa: PTH110
_addon_path_cache = versioned_mod
return _addon_path_cache
except (OSError, PermissionError) as e:
FreeCAD.Console.PrintWarning(f"Could not scan versioned directories: {e}\n")
return ""
def get_icon_path(icon_name: str) -> str:
"""Get the full path to an icon file.
Args:
icon_name: The icon filename or relative path (e.g., "icons/mcp_start.svg")
Returns:
The absolute path to the icon file, or empty string if addon path not found.
"""
addon_path = get_addon_path()
if not addon_path:
return ""
return os.path.join(addon_path, icon_name) # noqa: PTH118
def get_icons_dir() -> str:
"""Get the path to the addon's icons directory.
Returns:
The absolute path to the icons directory, or empty string if not found.
"""
addon_path = get_addon_path()
if addon_path:
icons_dir = os.path.join(addon_path, "icons") # noqa: PTH118
if os.path.isdir(icons_dir): # noqa: PTH112
return icons_dir
return ""
def get_workbench_icon() -> str:
"""Get the path to the workbench's main icon (FreecadRobustMCPBridge.svg).
Returns:
The absolute path to the workbench icon, or empty string if not found.
"""
addon_path = get_addon_path()
if addon_path:
icon_path = os.path.join(addon_path, f"{_ADDON_DIRNAME}.svg") # noqa: PTH118
if os.path.exists(icon_path): # noqa: PTH110
return icon_path
return ""