100 lines
3.7 KiB
Python
100 lines
3.7 KiB
Python
"""
|
|
Python path handling for KiCad modules.
|
|
"""
|
|
import os
|
|
import sys
|
|
import glob
|
|
import platform
|
|
from kicad_mcp.utils.logger import Logger
|
|
|
|
# Create logger for this module
|
|
logger = Logger()
|
|
|
|
def setup_kicad_python_path():
|
|
"""
|
|
Add KiCad Python modules to the Python path by detecting the appropriate version.
|
|
|
|
Returns:
|
|
bool: True if successful, False otherwise
|
|
"""
|
|
system = platform.system()
|
|
logger.info(f"Setting up KiCad Python path for {system}")
|
|
|
|
# Define search paths based on operating system
|
|
if system == "Darwin": # macOS
|
|
from kicad_mcp.config import KICAD_APP_PATH
|
|
|
|
if not os.path.exists(KICAD_APP_PATH):
|
|
logger.error(f"KiCad application not found at {KICAD_APP_PATH}")
|
|
return False
|
|
|
|
# Base path to Python framework
|
|
python_base = os.path.join(KICAD_APP_PATH, "Contents/Frameworks/Python.framework/Versions")
|
|
|
|
# First try 'Current' symlink
|
|
current_path = os.path.join(python_base, "Current/lib/python*/site-packages")
|
|
site_packages = glob.glob(current_path)
|
|
|
|
# If 'Current' symlink doesn't work, find all available Python versions
|
|
if not site_packages:
|
|
logger.debug("'Current' symlink not found, searching for numbered versions")
|
|
# Look for numbered versions like 3.9, 3.10, etc.
|
|
version_dirs = glob.glob(os.path.join(python_base, "[0-9]*"))
|
|
for version_dir in version_dirs:
|
|
potential_path = os.path.join(version_dir, "lib/python*/site-packages")
|
|
site_packages.extend(glob.glob(potential_path))
|
|
|
|
elif system == "Windows":
|
|
# Windows path - typically in Program Files
|
|
kicad_app_path = r"C:\Program Files\KiCad"
|
|
python_dirs = glob.glob(os.path.join(kicad_app_path, "lib", "python*"))
|
|
site_packages = []
|
|
|
|
for python_dir in python_dirs:
|
|
potential_path = os.path.join(python_dir, "site-packages")
|
|
if os.path.exists(potential_path):
|
|
site_packages.append(potential_path)
|
|
|
|
elif system == "Linux":
|
|
# Common Linux installation paths
|
|
site_packages = [
|
|
"/usr/lib/python3/dist-packages", # Debian/Ubuntu
|
|
"/usr/lib/python3.*/site-packages", # Red Hat/Fedora
|
|
"/usr/local/lib/python3.*/site-packages" # Source install
|
|
]
|
|
|
|
# Expand glob patterns
|
|
expanded_packages = []
|
|
for pattern in site_packages:
|
|
if "*" in pattern:
|
|
expanded_packages.extend(glob.glob(pattern))
|
|
else:
|
|
expanded_packages.append(pattern)
|
|
|
|
site_packages = expanded_packages
|
|
|
|
else:
|
|
logger.error(f"Unsupported operating system: {system}")
|
|
return False
|
|
|
|
# Pick the first valid path found
|
|
for path in site_packages:
|
|
if os.path.exists(path):
|
|
# Check if pcbnew module exists in this path
|
|
pcbnew_path = os.path.join(path, "pcbnew.so")
|
|
if not os.path.exists(pcbnew_path):
|
|
# On Windows it might be pcbnew.pyd instead
|
|
pcbnew_path = os.path.join(path, "pcbnew.pyd")
|
|
|
|
if os.path.exists(pcbnew_path):
|
|
if path not in sys.path:
|
|
sys.path.append(path)
|
|
logger.info(f"Added KiCad Python path: {path}")
|
|
logger.info(f"Found pcbnew module at: {pcbnew_path}")
|
|
return True
|
|
else:
|
|
logger.debug(f"Found site-packages at {path} but no pcbnew module")
|
|
|
|
logger.error("Could not find a valid KiCad Python site-packages directory with pcbnew module")
|
|
return False
|