# backend/core/script_manager.py from pathlib import Path import importlib.util import inspect from typing import Dict, List, Any, Optional import json class ScriptManager: """Manages script discovery and execution""" def __init__(self, script_groups_dir: Path): self.script_groups_dir = script_groups_dir def discover_groups(self) -> List[Dict[str, Any]]: """Discover all script groups""" groups = [] for group_dir in self.script_groups_dir.iterdir(): if group_dir.is_dir() and not group_dir.name.startswith('_'): group_info = self._analyze_group(group_dir) if group_info: groups.append(group_info) return groups def _analyze_group(self, group_dir: Path) -> Optional[Dict[str, Any]]: """Analyze a script group directory""" scripts = [] for script_file in group_dir.glob('x[0-9].py'): try: script_info = self._analyze_script(script_file) if script_info: scripts.append(script_info) except Exception as e: print(f"Error analyzing script {script_file}: {e}") if scripts: return { "id": group_dir.name, "name": group_dir.name.replace('_', ' ').title(), "scripts": sorted(scripts, key=lambda x: x['id']) } return None def _analyze_script(self, script_file: Path) -> Optional[Dict[str, Any]]: """Analyze a single script file""" try: # Import script module spec = importlib.util.spec_from_file_location( script_file.stem, script_file ) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # Find script class script_class = None for name, obj in inspect.getmembers(module): if (inspect.isclass(obj) and obj.__module__ == module.__name__ and hasattr(obj, 'run')): script_class = obj break if script_class: return { "id": script_file.stem, "name": script_class.__doc__.split('\n')[0].strip() if script_class.__doc__ else script_file.stem, "description": inspect.getdoc(script_class), "file": str(script_file.relative_to(self.script_groups_dir)) } except Exception as e: print(f"Error loading script {script_file}: {e}") return None def execute_script(self, group_id: str, script_id: str, work_dir: str, profile: Dict[str, Any]) -> Dict[str, Any]: """Execute a specific script""" script_file = self.script_groups_dir / group_id / f"{script_id}.py" if not script_file.exists(): raise ValueError(f"Script {script_id} not found in group {group_id}") try: # Import script module spec = importlib.util.spec_from_file_location(script_id, script_file) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # Find and instantiate script class script_class = None for name, obj in inspect.getmembers(module): if (inspect.isclass(obj) and obj.__module__ == module.__name__ and hasattr(obj, 'run')): script_class = obj break if not script_class: raise ValueError(f"No valid script class found in {script_id}") script = script_class() return script.run(work_dir, profile) except Exception as e: return { "status": "error", "error": str(e) }