From 057d5a94fcc9b4aabe22719905381bdecb7d499e Mon Sep 17 00:00:00 2001 From: rambros Date: Thu, 12 Mar 2026 21:50:06 +0530 Subject: [PATCH] add network monitor (global uasge only) --- requirements.txt | 1 + src/ui/widgets.py | 64 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8036581..cb8bb7d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ pydantic # Data validation using Python type hints lottie # Lottie file manipulation and conversion Pillow # Image processing (required for GIF rendering) cairosvg # SVG rendering (required for Lottie conversion) +psutil \ No newline at end of file diff --git a/src/ui/widgets.py b/src/ui/widgets.py index cec7bfd..67295ad 100644 --- a/src/ui/widgets.py +++ b/src/ui/widgets.py @@ -1,35 +1,59 @@ +import psutil +import time from textual.widgets import Static import logging logger = logging.getLogger(__name__) class RamDisplay(Static): - """Widget to display current RAM usage.""" + """Widget to display current RAM usage and Network speed.""" def on_mount(self) -> None: - self.update_ram() - self.set_interval(1.0, self.update_ram) + self._prev_net_io = psutil.net_io_counters() + self._prev_time = time.time() + self.update_stats() + self.set_interval(1.0, self.update_stats) - def update_ram(self) -> None: - """Fetch and display RAM usage (RSS).""" + def _format_speed(self, bytes_per_sec: float) -> str: + if bytes_per_sec < 1024: + return f"{bytes_per_sec:.1f} B/s" + elif bytes_per_sec < 1024 * 1024: + return f"{bytes_per_sec / 1024:.1f} KB/s" + else: + return f"{bytes_per_sec / (1024 * 1024):.1f} MB/s" + + def update_stats(self) -> None: + """Fetch and display RAM and Network speed.""" try: - # RSS is in KB in /proc/self/status on Linux - with open("/proc/self/status", "r") as f: - for line in f: - if line.startswith("VmRSS:"): - rss_kb = int(line.split()[1]) - break - else: - rss_kb = 0 - - if rss_kb > 1024 * 1024: - usage = f"{rss_kb / (1024 * 1024):.2f} GB" + # 1. RAM Usage + process = psutil.Process() + rss = process.memory_info().rss + if rss > 1024 * 1024 * 1024: + ram_usage = f"{rss / (1024 * 1024 * 1024):.2f} GB" else: - usage = f"{rss_kb / 1024:.2f} MB" + ram_usage = f"{rss / (1024 * 1024):.2f} MB" + + # 2. Network Speed + curr_net_io = psutil.net_io_counters() + curr_time = time.time() - self.update(f" RAM: [yellow]{usage}[/yellow]") - except Exception: - self.update(" RAM: [bold red]N/A[/bold red]") + delta_time = curr_time - self._prev_time + if delta_time <= 0: + delta_time = 1.0 + + sent_speed = (curr_net_io.bytes_sent - self._prev_net_io.bytes_sent) / delta_time + recv_speed = (curr_net_io.bytes_recv - self._prev_net_io.bytes_recv) / delta_time + + # Simple combined speed display or separately + speed_str = self._format_speed(sent_speed + recv_speed) + + self._prev_net_io = curr_net_io + self._prev_time = curr_time + + self.update(f" RAM: [yellow]{ram_usage}[/yellow] | Net: [cyan]{speed_str}[/cyan]") + except Exception as e: + logger.error(f"Error updating stats: {e}") + self.update(" Stats: [bold red]N/A[/bold red]") class Footnote(Static): """Widget to display branding text at the bottom right."""