forked from Shifty/pyserveX
111 lines
3.0 KiB
Python
111 lines
3.0 KiB
Python
"""
|
|
PyServe CLI Output utilities
|
|
|
|
Rich-based formatters and helpers for CLI output.
|
|
"""
|
|
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
from rich.theme import Theme
|
|
|
|
pyserve_theme = Theme(
|
|
{
|
|
"info": "cyan",
|
|
"warning": "yellow",
|
|
"error": "red bold",
|
|
"success": "green",
|
|
"service.running": "green",
|
|
"service.stopped": "dim",
|
|
"service.failed": "red",
|
|
"service.starting": "yellow",
|
|
}
|
|
)
|
|
|
|
console = Console(theme=pyserve_theme)
|
|
|
|
|
|
def print_error(message: str) -> None:
|
|
console.print(f"[error] {message}[/error]")
|
|
|
|
|
|
def print_warning(message: str) -> None:
|
|
console.print(f"[warning] {message}[/warning]")
|
|
|
|
|
|
def print_success(message: str) -> None:
|
|
console.print(f"[success] {message}[/success]")
|
|
|
|
|
|
def print_info(message: str) -> None:
|
|
console.print(f"[info] {message}[/info]")
|
|
|
|
|
|
def create_services_table() -> Table:
|
|
table = Table(
|
|
title=None,
|
|
show_header=True,
|
|
header_style="bold",
|
|
border_style="dim",
|
|
)
|
|
table.add_column("NAME", style="cyan", no_wrap=True)
|
|
table.add_column("STATUS", no_wrap=True)
|
|
table.add_column("PORTS", style="dim")
|
|
table.add_column("UPTIME", style="dim")
|
|
table.add_column("HEALTH", no_wrap=True)
|
|
table.add_column("PID", style="dim")
|
|
table.add_column("WORKERS", style="dim")
|
|
return table
|
|
|
|
|
|
def format_status(status: str) -> str:
|
|
status_styles = {
|
|
"running": "[service.running]● running[/service.running]",
|
|
"stopped": "[service.stopped]○ stopped[/service.stopped]",
|
|
"failed": "[service.failed]✗ failed[/service.failed]",
|
|
"starting": "[service.starting]◐ starting[/service.starting]",
|
|
"stopping": "[service.starting]◑ stopping[/service.starting]",
|
|
"restarting": "[service.starting]↻ restarting[/service.starting]",
|
|
"pending": "[service.stopped]○ pending[/service.stopped]",
|
|
}
|
|
return status_styles.get(status.lower(), status)
|
|
|
|
|
|
def format_health(health: str) -> str:
|
|
health_styles = {
|
|
"healthy": "[green] healthy[/green]",
|
|
"unhealthy": "[red] unhealthy[/red]",
|
|
"degraded": "[yellow] degraded[/yellow]",
|
|
"unknown": "[dim] unknown[/dim]",
|
|
"-": "[dim]-[/dim]",
|
|
}
|
|
return health_styles.get(health.lower(), health)
|
|
|
|
|
|
def format_uptime(seconds: float) -> str:
|
|
if seconds <= 0:
|
|
return "-"
|
|
|
|
if seconds < 60:
|
|
return f"{int(seconds)}s"
|
|
elif seconds < 3600:
|
|
minutes = int(seconds / 60)
|
|
secs = int(seconds % 60)
|
|
return f"{minutes}m {secs}s"
|
|
elif seconds < 86400:
|
|
hours = int(seconds / 3600)
|
|
minutes = int((seconds % 3600) / 60)
|
|
return f"{hours}h {minutes}m"
|
|
else:
|
|
days = int(seconds / 86400)
|
|
hours = int((seconds % 86400) / 3600)
|
|
return f"{days}d {hours}h"
|
|
|
|
|
|
def format_bytes(num_bytes: int) -> str:
|
|
value = float(num_bytes)
|
|
for unit in ["B", "KB", "MB", "GB", "TB"]:
|
|
if abs(value) < 1024.0:
|
|
return f"{value:.1f}{unit}"
|
|
value /= 1024.0
|
|
return f"{value:.1f}PB"
|