Skip to main content
Glama

Voice Mode

by mbailey
package_managers.py•5.12 kB
"""Package manager abstraction for cross-platform dependency installation.""" from abc import ABC, abstractmethod from typing import List, Tuple import subprocess import shutil import logging logger = logging.getLogger(__name__) class PackageManager(ABC): """Base class for package managers.""" @abstractmethod def check_available(self) -> bool: """Check if this package manager is available.""" pass @abstractmethod def check_package(self, package_name: str) -> bool: """Check if a package is installed.""" pass @abstractmethod def install_packages(self, package_names: List[str], verbose: bool = False) -> Tuple[bool, str]: """Install packages. Returns (success, message).""" pass class BrewManager(PackageManager): """Homebrew package manager (macOS).""" def check_available(self) -> bool: return shutil.which("brew") is not None def check_package(self, package_name: str) -> bool: try: result = subprocess.run( ["brew", "list", package_name], capture_output=True, text=True, timeout=5 ) return result.returncode == 0 except (subprocess.SubprocessError, OSError) as e: logger.debug(f"Error checking package {package_name}: {e}") return False def install_packages(self, package_names: List[str], verbose: bool = False) -> Tuple[bool, str]: cmd = ["brew", "install"] + package_names try: if verbose: result = subprocess.run(cmd, text=True, timeout=300) return result.returncode == 0, "" else: result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) return result.returncode == 0, result.stderr or result.stdout except (subprocess.SubprocessError, OSError) as e: return False, str(e) class AptManager(PackageManager): """APT package manager (Debian/Ubuntu).""" def check_available(self) -> bool: return shutil.which("apt-get") is not None def check_package(self, package_name: str) -> bool: try: result = subprocess.run( ["dpkg", "-l", package_name], capture_output=True, text=True, timeout=5 ) return result.returncode == 0 and "ii" in result.stdout except (subprocess.SubprocessError, OSError) as e: logger.debug(f"Error checking package {package_name}: {e}") return False def install_packages(self, package_names: List[str], verbose: bool = False) -> Tuple[bool, str]: # Need sudo for apt cmd = ["sudo", "apt-get", "install", "-y"] + package_names try: if verbose: result = subprocess.run(cmd, text=True, timeout=600) return result.returncode == 0, "" else: result = subprocess.run(cmd, capture_output=True, text=True, timeout=600) return result.returncode == 0, result.stderr or result.stdout except (subprocess.SubprocessError, OSError) as e: return False, str(e) class DnfManager(PackageManager): """DNF package manager (Fedora/RHEL).""" def check_available(self) -> bool: return shutil.which("dnf") is not None def check_package(self, package_name: str) -> bool: try: result = subprocess.run( ["rpm", "-q", package_name], capture_output=True, text=True, timeout=5 ) return result.returncode == 0 except (subprocess.SubprocessError, OSError) as e: logger.debug(f"Error checking package {package_name}: {e}") return False def install_packages(self, package_names: List[str], verbose: bool = False) -> Tuple[bool, str]: # Need sudo for dnf cmd = ["sudo", "dnf", "install", "-y"] + package_names try: if verbose: result = subprocess.run(cmd, text=True, timeout=600) return result.returncode == 0, "" else: result = subprocess.run(cmd, capture_output=True, text=True, timeout=600) return result.returncode == 0, result.stderr or result.stdout except (subprocess.SubprocessError, OSError) as e: return False, str(e) def get_package_manager() -> PackageManager: """Detect and return appropriate package manager for current platform. Returns: PackageManager: The detected package manager instance Raises: RuntimeError: If no supported package manager is found """ managers = [BrewManager(), DnfManager(), AptManager()] for manager in managers: if manager.check_available(): logger.debug(f"Detected package manager: {manager.__class__.__name__}") return manager raise RuntimeError("No supported package manager found (tried brew, dnf, apt-get)")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mbailey/voicemode'

If you have feedback or need assistance with the MCP directory API, please join our Discord server