""" arma_modlist_tools.compat ~~~~~~~~~~~~~~~~~~~~~~~~~ OS detection and cross-platform utilities shared by all CLI scripts. Supported platforms: - Windows / Windows Server (sys.platform == "win32") - Ubuntu / Ubuntu Server (sys.platform == "linux") Typical usage:: from arma_modlist_tools.compat import is_windows, get_os_label, fix_console_encoding fix_console_encoding() # call once at script start on Windows print(get_os_label()) # "Windows Server", "Ubuntu", etc. """ from __future__ import annotations import io import platform import sys # --------------------------------------------------------------------------- # Platform detection # --------------------------------------------------------------------------- def is_windows() -> bool: """Return ``True`` on Windows and Windows Server.""" return sys.platform == "win32" def is_linux() -> bool: """Return ``True`` on Linux (Ubuntu, Ubuntu Server, and other distros).""" return sys.platform == "linux" def get_os_label() -> str: """ Return a human-readable OS label. Possible values: ``"Windows"``, ``"Windows Server"``, ``"Ubuntu"``, ``"Ubuntu Server"``, ``"Linux"``, ``"Unknown"``. """ if is_windows(): ver = platform.version() # Windows Server versions contain "Server" in the version string # e.g. "10.0.17763 ... Windows Server 2019 ..." if "Server" in platform.version() or "Server" in platform.uname().version: return "Windows Server" return "Windows" if is_linux(): # Read /etc/os-release for distro name os_release = _read_os_release() name = os_release.get("NAME", "").lower() if "ubuntu" in name: # Distinguish desktop vs server: server images have no display server if _is_headless(): return "Ubuntu Server" return "Ubuntu" return "Linux" return "Unknown" def _read_os_release() -> dict[str, str]: """Parse /etc/os-release into a dict (Linux only).""" result: dict[str, str] = {} try: with open("/etc/os-release", encoding="utf-8") as f: for line in f: line = line.strip() if "=" in line and not line.startswith("#"): k, _, v = line.partition("=") result[k] = v.strip('"') except OSError: pass return result def _is_headless() -> bool: """Return True if no graphical display server is detected (headless/server).""" import os # Check for common display environment variables return not (os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY")) # --------------------------------------------------------------------------- # Console encoding # --------------------------------------------------------------------------- def fix_console_encoding() -> None: """ Force UTF-8 output on Windows terminals that default to cp1252. Call once at the top of any CLI script that uses Unicode characters (checkmarks, arrows, etc.). No-op on Linux. """ if not is_windows(): return if sys.stdout.encoding and sys.stdout.encoding.lower() == "utf-8": return sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")