Skip to main content
Glama
components.py6.25 kB
""" Reusable UI components for Proxmox MCP output. """ from typing import List, Optional from .colors import ProxmoxColors from .theme import ProxmoxTheme class ProxmoxComponents: """Reusable UI components for formatted output.""" @staticmethod def create_table(headers: List[str], rows: List[List[str]], title: Optional[str] = None) -> str: """Create an ASCII table with optional title. Args: headers: List of column headers rows: List of row data title: Optional table title Returns: Formatted table string """ # Calculate column widths considering multi-line content widths = [len(header) for header in headers] for row in rows: for i, cell in enumerate(row): cell_lines = str(cell).split('\n') max_line_length = max(len(line) for line in cell_lines) widths[i] = max(widths[i], max_line_length) # Create separator line separator = "+" + "+".join("-" * (w + 2) for w in widths) + "+" # Calculate total width for title total_width = sum(widths) + len(widths) + 1 # Build table result = [] # Add title if provided if title: # Center the title title_str = ProxmoxColors.colorize(title, ProxmoxColors.CYAN, ProxmoxColors.BOLD) padding = (total_width - len(title) - 2) // 2 # -2 for the border chars title_separator = "+" + "-" * (total_width - 2) + "+" result.extend([ title_separator, "|" + " " * padding + title_str + " " * (total_width - padding - len(title) - 2) + "|", title_separator ]) # Add headers header = "|" + "|".join(f" {ProxmoxColors.colorize(h, ProxmoxColors.CYAN):<{w}} " for w, h in zip(widths, headers)) + "|" result.extend([separator, header, separator]) # Add rows with multi-line cell support for row in rows: # Split each cell into lines cell_lines = [str(cell).split('\n') for cell in row] max_lines = max(len(lines) for lines in cell_lines) # Pad cells with fewer lines padded_cells = [] for lines in cell_lines: if len(lines) < max_lines: lines.extend([''] * (max_lines - len(lines))) padded_cells.append(lines) # Create row strings for each line for line_idx in range(max_lines): line_parts = [] for col_idx, cell_lines in enumerate(padded_cells): line = cell_lines[line_idx] line_parts.append(f" {line:<{widths[col_idx]}} ") result.append("|" + "|".join(line_parts) + "|") # Add separator after each row except the last if row != rows[-1]: result.append(separator) result.append(separator) return "\n".join(result) @staticmethod def create_progress_bar(value: float, total: float, width: int = 20) -> str: """Create a progress bar with percentage. Args: value: Current value total: Maximum value width: Width of progress bar in characters Returns: Formatted progress bar string """ percentage = min(100, (value / total * 100) if total > 0 else 0) filled = int(width * percentage / 100) color = ProxmoxColors.metric_color(percentage) bar = "█" * filled + "░" * (width - filled) return f"{ProxmoxColors.colorize(bar, color)} {percentage:.1f}%" @staticmethod def create_resource_usage(used: float, total: float, label: str, emoji: str) -> str: """Create a resource usage display with progress bar. Args: used: Used amount total: Total amount label: Resource label emoji: Resource emoji Returns: Formatted resource usage string """ from .formatters import ProxmoxFormatters percentage = (used / total * 100) if total > 0 else 0 progress = ProxmoxComponents.create_progress_bar(used, total) return ( f"{emoji} {label}:\n" f" {progress}\n" f" {ProxmoxFormatters.format_bytes(used)} / {ProxmoxFormatters.format_bytes(total)}" ) @staticmethod def create_key_value_grid(data: dict, columns: int = 2) -> str: """Create a grid of key-value pairs. Args: data: Dictionary of key-value pairs columns: Number of columns in grid Returns: Formatted grid string """ # Calculate max widths for each column items = list(data.items()) rows = [items[i:i + columns] for i in range(0, len(items), columns)] key_widths = [0] * columns val_widths = [0] * columns for row in rows: for i, (key, val) in enumerate(row): key_widths[i] = max(key_widths[i], len(str(key))) val_widths[i] = max(val_widths[i], len(str(val))) # Format rows result = [] for row in rows: formatted_items = [] for i, (key, val) in enumerate(row): key_str = ProxmoxColors.colorize(f"{key}:", ProxmoxColors.CYAN) formatted_items.append(f"{key_str:<{key_widths[i] + 10}} {val:<{val_widths[i]}}") result.append(" ".join(formatted_items)) return "\n".join(result) @staticmethod def create_status_badge(status: str) -> str: """Create a status badge with emoji. Args: status: Status string Returns: Formatted status badge string """ status = status.lower() emoji = ProxmoxTheme.get_status_emoji(status) return f"{emoji} {status.upper()}"

Latest Blog Posts

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/RekklesNA/ProxmoxMCP-Plus'

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