Files
2026-01-29 21:53:58 -05:00

144 lines
4.8 KiB
Python

"""UI utilities for dropkit - display functions and prompts."""
from collections.abc import Callable
from typing import Any
from rich.console import Console
from rich.prompt import Prompt
from rich.table import Table
console = Console()
def display_regions(regions: list[dict[str, Any]]) -> None:
"""Display available regions in a table, sorted alphabetically by slug."""
table = Table(title="Available Regions", show_header=True)
table.add_column("Slug", style="cyan", no_wrap=True)
table.add_column("Name", style="white")
table.add_column("Features", style="dim")
# Sort regions alphabetically by slug
sorted_regions = sorted(regions, key=lambda r: r.get("slug", ""))
for region in sorted_regions:
slug = region.get("slug", "")
name = region.get("name", "")
features = ", ".join(region.get("features", [])[:3]) # Show first 3 features
if len(region.get("features", [])) > 3:
features += "..."
table.add_row(slug, name, features)
console.print(table)
def display_sizes(sizes: list[dict[str, Any]]) -> None:
"""Display available droplet sizes in a table, sorted by price."""
table = Table(title="Available Droplet Sizes", show_header=True)
table.add_column("Slug", style="cyan", no_wrap=True)
table.add_column("Memory", style="white", justify="right")
table.add_column("vCPUs", style="white", justify="right")
table.add_column("Disk", style="white", justify="right")
table.add_column("Transfer", style="white", justify="right")
table.add_column("Price/mo", style="green", justify="right")
# Sort sizes by price (monthly) ascending
sorted_sizes = sorted(sizes, key=lambda s: s.get("price_monthly", 0))
for size in sorted_sizes:
slug = size.get("slug", "")
memory = f"{size.get('memory', 0)} MB"
vcpus = str(size.get("vcpus", 0))
disk = f"{size.get('disk', 0)} GB"
transfer = f"{size.get('transfer', 0)} TB"
price = f"${size.get('price_monthly', 0):.2f}"
table.add_row(slug, memory, vcpus, disk, transfer, price)
console.print(table)
def display_images(images: list[dict[str, Any]]) -> None:
"""Display available images in a table, sorted by distribution and name."""
table = Table(title="Available Images", show_header=True)
table.add_column("Slug", style="cyan", no_wrap=True)
table.add_column("Name", style="white")
table.add_column("Distribution", style="dim")
# Sort images by distribution, then by name
sorted_images = sorted(
images, key=lambda img: (img.get("distribution", ""), img.get("name", ""))
)
for image in sorted_images:
slug = image.get("slug", "")
name = image.get("name", "")
distribution = image.get("distribution", "")
# Only show images with slugs (not snapshots)
if slug:
table.add_row(slug, name, distribution)
console.print(table)
def display_projects(projects: list[dict[str, Any]]) -> None:
"""Display available projects in a table, sorted alphabetically by name."""
table = Table(title="Available Projects", show_header=True)
table.add_column("ID", style="dim", no_wrap=True)
table.add_column("Name", style="cyan")
table.add_column("Purpose", style="white")
table.add_column("Description", style="dim")
# Sort projects alphabetically by name
sorted_projects = sorted(projects, key=lambda p: p.get("name", "").lower())
for project in sorted_projects:
project_id = project.get("id", "")
name = project.get("name", "")
purpose = project.get("purpose", "")
description = project.get("description", "")
# Truncate description if too long
if len(description) > 50:
description = description[:47] + "..."
table.add_row(project_id, name, purpose, description)
console.print(table)
def prompt_with_help(
prompt_text: str,
default: str,
display_func: Callable[[list[dict[str, Any]]], None] | None = None,
data: list[dict[str, Any]] | None = None,
) -> str:
"""
Prompt user for input with optional help via '?'.
Args:
prompt_text: The prompt to display (without the default/? part)
default: Default value
display_func: Function to call when user enters '?'
data: Data to pass to display_func
Returns:
User's input value
"""
while True:
value = Prompt.ask(
f"[cyan]{prompt_text} (? for help)[/cyan]",
default=default,
)
if value == "?":
if display_func and data is not None:
console.print()
display_func(data)
console.print()
else:
console.print("[yellow]No help available[/yellow]")
else:
return value