""" 工具类模块 - 提供命令执行、输出格式化等工具函数 """ import os import subprocess import sys class Colors: """控制台颜色""" # 基础颜色 HEADER = '\033[95m' # 紫色 BLUE = '\033[94m' # 蓝色 CYAN = '\033[96m' # 青色 GREEN = '\033[92m' # 绿色 YELLOW = '\033[93m' # 黄色 RED = '\033[91m' # 红色 MAGENTA = '\033[35m' # 品红 WHITE = '\033[97m' # 白色 # 亮色系 BRIGHT_CYAN = '\033[96m\033[1m' # 亮青色 BRIGHT_GREEN = '\033[92m\033[1m' # 亮绿色 BRIGHT_YELLOW = '\033[93m\033[1m' # 亮黄色 BRIGHT_RED = '\033[91m\033[1m' # 亮红色 BRIGHT_BLUE = '\033[94m\033[1m' # 亮蓝色 BRIGHT_MAGENTA = '\033[95m\033[1m' # 亮品红 # 背景色 BG_BLUE = '\033[44m' BG_GREEN = '\033[42m' BG_YELLOW = '\033[43m' BG_RED = '\033[41m' BG_CYAN = '\033[46m' BG_MAGENTA = '\033[45m' # 样式 BOLD = '\033[1m' UNDERLINE = '\033[4m' REVERSE = '\033[7m' ENDC = '\033[0m' # 兼容旧代码 WARNING = '\033[93m' FAIL = '\033[91m' class CommandExecutor: """命令执行器""" @staticmethod def run(command: str, show_output: bool = True) -> tuple[bool, str]: """ 执行命令 Args: command: 要执行的命令 show_output: 是否显示输出 Returns: (是否成功, 输出内容) """ try: result = subprocess.run( command, shell=True, capture_output=True, text=True, encoding='utf-8', errors='ignore' ) output = result.stdout + result.stderr if show_output and output.strip(): print(output) return result.returncode == 0, output except Exception as e: OutputFormatter.error(f"命令执行失败: {str(e)}") return False, str(e) class OutputFormatter: """输出格式化器""" @staticmethod def header(text: str): """打印标题 - 顶部大标题""" line = "=" * 60 print(f"\n{Colors.BRIGHT_CYAN}{line}") print(f"{Colors.BRIGHT_MAGENTA}{Colors.BOLD}>> {text}") print(f"{Colors.BRIGHT_CYAN}{line}{Colors.ENDC}") @staticmethod def section(text: str): """打印分节标题""" print(f"\n{Colors.BRIGHT_YELLOW}{'=' * 60}") print(f"{Colors.BRIGHT_BLUE}{Colors.BOLD}>> {text}") print(f"{Colors.BRIGHT_YELLOW}{'=' * 60}{Colors.ENDC}") @staticmethod def divider(): """打印分割线""" print(f"{Colors.CYAN}{'-' * 60}{Colors.ENDC}") @staticmethod def thin_divider(): """打印细分割线""" print(f"{Colors.CYAN}{'·' * 60}{Colors.ENDC}") @staticmethod def success(text: str): """打印成功信息""" print(f"{Colors.BRIGHT_GREEN}[√]{Colors.ENDC} {Colors.GREEN}{text}{Colors.ENDC}") @staticmethod def error(text: str): """打印错误信息""" print(f"{Colors.BRIGHT_RED}[×]{Colors.ENDC} {Colors.RED}{text}{Colors.ENDC}") @staticmethod def info(text: str): """打印提示信息""" print(f"{Colors.BRIGHT_CYAN}[i]{Colors.ENDC} {Colors.CYAN}{text}{Colors.ENDC}") @staticmethod def warning(text: str): """打印警告信息""" print(f"{Colors.BRIGHT_YELLOW}[!]{Colors.ENDC} {Colors.YELLOW}{text}{Colors.ENDC}") @staticmethod def step(num: int, text: str): """打印步骤信息""" print(f"{Colors.BRIGHT_BLUE}[{num}]{Colors.ENDC} {Colors.WHITE}{text}{Colors.ENDC}") @staticmethod def menu_item(num: int, text: str, icon: str = ">>"): """打印菜单项""" print(f"{Colors.BRIGHT_CYAN}[{num}]{Colors.ENDC} {Colors.WHITE}{text}{Colors.ENDC}") @staticmethod def key_value(key: str, value: str, key_color=None, value_color=None): """打印键值对""" if key_color is None: key_color = Colors.BRIGHT_CYAN if value_color is None: value_color = Colors.WHITE print(f"{key_color}{key}:{Colors.ENDC} {value_color}{value}{Colors.ENDC}") @staticmethod def status(status_type: str, text: str): """打印状态信息""" icons = { 'pending': f"{Colors.YELLOW}[·]{Colors.ENDC}", 'running': f"{Colors.BRIGHT_CYAN}[>]{Colors.ENDC}", 'success': f"{Colors.BRIGHT_GREEN}[√]{Colors.ENDC}", 'error': f"{Colors.BRIGHT_RED}[×]{Colors.ENDC}", } icon = icons.get(status_type, "[·]") print(f"{icon} {text}") class PlatformUtils: """跨平台工具类""" @staticmethod def clear_screen(): """清屏 - 跨平台兼容""" # Windows if os.name == 'nt': os.system('cls') # Linux/macOS else: os.system('clear') @staticmethod def is_windows() -> bool: """检查是否为 Windows 系统""" return os.name == 'nt' @staticmethod def is_linux() -> bool: """检查是否为 Linux 系统""" return sys.platform.startswith('linux') @staticmethod def is_mac() -> bool: """检查是否为 macOS 系统""" return sys.platform == 'darwin' @staticmethod def get_platform_name() -> str: """获取平台名称""" if PlatformUtils.is_windows(): return "Windows" elif PlatformUtils.is_linux(): return "Linux" elif PlatformUtils.is_mac(): return "macOS" else: return "Unknown" class InputValidator: """输入验证器""" @staticmethod def get_choice(prompt: str, valid_range: range) -> int: """ 获取用户选择(数字) Args: prompt: 提示信息 valid_range: 有效范围 Returns: 用户选择的数字 """ while True: try: choice = input(prompt).strip() choice_num = int(choice) if choice_num in valid_range: return choice_num else: OutputFormatter.error(f"请输入 {valid_range.start}-{valid_range.stop-1} 之间的数字") except ValueError: OutputFormatter.error("请输入有效的数字") @staticmethod def get_input(prompt: str, allow_empty: bool = False) -> str: """ 获取用户输入 Args: prompt: 提示信息 allow_empty: 是否允许空输入 Returns: 用户输入的字符串 """ while True: user_input = input(prompt).strip() if user_input or allow_empty: return user_input else: OutputFormatter.error("输入不能为空") @staticmethod def confirm(prompt: str, default: bool = False) -> bool: """ 获取用户确认 Args: prompt: 提示信息 default: 默认值 Returns: 用户确认结果 """ suffix = " [Y/n]: " if default else " [y/N]: " user_input = input(prompt + suffix).strip().lower() if not user_input: return default return user_input in ['y', 'yes']