Created
June 16, 2025 12:50
-
-
Save TheCrazyGM/b8a7b11cf6c1c8642675fcf5d460009b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env -S uv run --quiet --script | |
# /// script | |
# requires-python = ">=3.13" | |
# dependencies = [ | |
# "rich", | |
# ] | |
# | |
# /// | |
""" | |
A pretty system fetch utility inspired by fetch.sh and fetch_pretty.sh, using the rich library for output. | |
""" | |
import os | |
import platform | |
import socket | |
import subprocess | |
from datetime import datetime, timedelta | |
from rich.console import Console | |
from rich.panel import Panel | |
from rich.table import Table | |
from rich.text import Text | |
console = Console() | |
def get_os(): | |
try: | |
if os.path.exists("/etc/os-release"): | |
with open("/etc/os-release") as f: | |
for line in f: | |
if line.startswith("PRETTY_NAME="): | |
return line.strip().split("=", 1)[1].strip('"') | |
return platform.system() | |
except Exception: | |
return platform.system() | |
def get_kernel(): | |
return platform.release() | |
def get_user_host(): | |
return f"{os.getenv('USER') or os.getenv('LOGNAME')}@{socket.gethostname()}" | |
def get_uptime(): | |
try: | |
with open("/proc/uptime") as f: | |
uptime_seconds = float(f.readline().split()[0]) | |
uptime_td = timedelta(seconds=int(uptime_seconds)) | |
days = uptime_td.days | |
hours, remainder = divmod(uptime_td.seconds, 3600) | |
minutes, _ = divmod(remainder, 60) | |
return f"{days}D {hours}H {minutes}M" | |
except Exception: | |
return "Unknown" | |
def get_shell(): | |
return os.path.basename(os.getenv("SHELL", "Unknown")) | |
def get_desktop(): | |
# Try common environment variables | |
for var in [ | |
"XDG_CURRENT_DESKTOP", | |
"DESKTOP_SESSION", | |
"DE", | |
"WM", | |
"XDG_SESSION_TYPE", | |
]: | |
val = os.getenv(var) | |
if val: | |
return val | |
# Try to detect from running processes | |
try: | |
for pid in os.listdir("/proc"): | |
if pid.isdigit(): | |
try: | |
with open(f"/proc/{pid}/comm") as f: | |
proc = f.read().strip() | |
if any( | |
wm in proc.lower() | |
for wm in [ | |
"awesome", | |
"xmonad", | |
"qtile", | |
"sway", | |
"i3", | |
"openbox", | |
"fluxbox", | |
"bspwm", | |
"wm", | |
] | |
): | |
return proc | |
except Exception: | |
continue | |
except Exception: | |
pass | |
return "Unknown" | |
def get_package_count(): | |
# Try dpkg (Debian/Ubuntu) | |
try: | |
result = subprocess.run(["dpkg", "-l"], capture_output=True, text=True) | |
count = sum(1 for line in result.stdout.splitlines() if line.startswith("ii")) | |
return str(count) | |
except Exception: | |
pass | |
# Try rpm (Fedora/openSUSE/RHEL) | |
try: | |
result = subprocess.run(["rpm", "-qa"], capture_output=True, text=True) | |
count = len(result.stdout.splitlines()) | |
return str(count) | |
except Exception: | |
pass | |
# Try pacman (Arch/Manjaro/Artix) | |
try: | |
result = subprocess.run(["pacman", "-Q"], capture_output=True, text=True) | |
count = len(result.stdout.splitlines()) | |
return str(count) | |
except Exception: | |
pass | |
return "N/A" | |
def get_memory(): | |
try: | |
with open("/proc/meminfo") as f: | |
lines = f.readlines() | |
mem_total = ( | |
int([line for line in lines if line.startswith("MemTotal:")][0].split()[1]) | |
// 1024 | |
) | |
mem_free = ( | |
int( | |
[line for line in lines if line.startswith("MemAvailable:")][0].split()[ | |
1 | |
] | |
) | |
// 1024 | |
) | |
return f"{mem_free}MiB / {mem_total}MiB" | |
except Exception: | |
return "Unknown" | |
def get_cpu(): | |
model = None | |
cores = 0 | |
try: | |
with open("/proc/cpuinfo") as f: | |
for line in f: | |
if line.startswith("model name") and model is None: | |
model = line.strip().split(":", 1)[1].strip() | |
if line.startswith("processor"): | |
cores += 1 | |
if model and cores: | |
return f"{model} (x {cores} cores)" | |
elif model: | |
return model | |
else: | |
return platform.processor() or "Unknown" | |
except Exception: | |
return "Unknown" | |
def get_gpu(): | |
try: | |
result = subprocess.run(["lspci"], capture_output=True, text=True) | |
gpus = [] | |
for line in result.stdout.splitlines(): | |
if any( | |
x in line.lower() | |
for x in ["vga compatible controller", "3d controller"] | |
): | |
# Get the part after the last colon (the model) | |
if ":" in line: | |
gpu_model = line.split(":")[-1].strip() | |
gpus.append(gpu_model) | |
if gpus: | |
return "; ".join(gpus) | |
else: | |
return "Unknown" | |
except Exception: | |
return "Unknown" | |
def main(): | |
info = { | |
"OS": get_os(), | |
"Kernel": get_kernel(), | |
"CPU": get_cpu(), | |
"GPU": get_gpu(), | |
"Uptime": get_uptime(), | |
"Shell": get_shell(), | |
"Desktop": get_desktop(), | |
"Packages": get_package_count(), | |
"Memory": get_memory(), | |
} | |
table = Table(show_header=False, show_edge=False, box=None, padding=(0, 1)) | |
colors = [ | |
"cyan", | |
"magenta", | |
"green", | |
"yellow", | |
"blue", | |
"red", | |
"white", | |
"bright_black", | |
] | |
for idx, (k, v) in enumerate(info.items()): | |
label = Text(f"{k}", style=f"bold {colors[idx % len(colors)]}") | |
value = Text(v, style="bold white") | |
table.add_row(label, value) | |
# Use the current local time | |
current_time = datetime.now().astimezone() | |
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S %Z") | |
panel = Panel( | |
table, | |
title=f"[bold green]{get_user_host()}[/bold green]", | |
border_style="bright_magenta", | |
padding=(0, 1), | |
width=80, | |
subtitle=f"[dim]{formatted_time}[/dim]", | |
) | |
console.print(panel) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment