177 lines
5.8 KiB
Python
177 lines
5.8 KiB
Python
from typing import Optional
|
|
|
|
import psutil
|
|
from fabric.utils import GLib, invoke_repeater, logger
|
|
from fabric.widgets.box import Box
|
|
from fabric.widgets.circularprogressbar import CircularProgressBar
|
|
from fabric.widgets.label import Label
|
|
from fabric.widgets.overlay import Overlay
|
|
|
|
from window.desktop.registry import DesktopWidgetRegistry
|
|
|
|
SYSTEM_UPDATE_INTERVAL = 2000
|
|
|
|
|
|
class SystemInfoBase(Box):
|
|
@staticmethod
|
|
def create_progress_bar(name: str = "progress-bar", size: int = 80, **kwargs):
|
|
return CircularProgressBar(
|
|
name=name,
|
|
start_angle=270,
|
|
end_angle=630,
|
|
min_value=0,
|
|
max_value=100,
|
|
size=size,
|
|
**kwargs,
|
|
)
|
|
|
|
def __init__(self, name: str, **kwargs):
|
|
super().__init__(
|
|
layer="bottom",
|
|
title="sysinfo",
|
|
name=name,
|
|
visible=True,
|
|
size=(170, 170),
|
|
h_expand=True,
|
|
v_expand=True,
|
|
all_visible=True,
|
|
**kwargs,
|
|
)
|
|
self.progress = self.create_progress_bar(name="progress")
|
|
self.main_label = Label(
|
|
label="0%\nLoading", justification="center", name="progress-label"
|
|
)
|
|
self.info_container = Box(
|
|
name="info-container", orientation="v", spacing=2, h_align="center"
|
|
)
|
|
self.add(
|
|
Box(
|
|
name="progress-bar-container",
|
|
h_expand=True,
|
|
v_expand=True,
|
|
orientation="v",
|
|
spacing=12,
|
|
h_align="center",
|
|
v_align="center",
|
|
children=[
|
|
Box(
|
|
children=[
|
|
Overlay(
|
|
child=self.progress,
|
|
tooltip_text="",
|
|
overlays=self.main_label,
|
|
)
|
|
]
|
|
),
|
|
Box(
|
|
h_align="center",
|
|
justification="centre",
|
|
orientation="v",
|
|
children=[self.info_container],
|
|
),
|
|
],
|
|
)
|
|
)
|
|
|
|
def start_updates(self):
|
|
self.update()
|
|
self._system_timer_id = invoke_repeater(SYSTEM_UPDATE_INTERVAL, self.update)
|
|
|
|
def destroy(self):
|
|
"""Cleanup system info update timer"""
|
|
if hasattr(self, "_system_timer_id") and self._system_timer_id:
|
|
GLib.source_remove(self._system_timer_id)
|
|
self._system_timer_id = None
|
|
super().destroy()
|
|
|
|
def create_info_line(
|
|
self, indicator_name: str, info_text: str, value_text: str
|
|
) -> Box:
|
|
line = Box(
|
|
orientation="h",
|
|
spacing=4,
|
|
h_align="start",
|
|
children=[
|
|
Label(label="■", name=indicator_name),
|
|
Label(label=info_text, name="info-text"),
|
|
Label(label=value_text, name="info-value"),
|
|
],
|
|
)
|
|
line.value_label = line.get_children()[2]
|
|
return line
|
|
|
|
def update(self) -> bool:
|
|
raise NotImplementedError
|
|
|
|
|
|
class DesktopRamInfoWidget(SystemInfoBase):
|
|
def __init__(self, **kwargs):
|
|
super().__init__("info-box-widget", **kwargs)
|
|
self.used_line = self.create_info_line("used-color-indicator", "Used", "0.0GB")
|
|
self.free_line = self.create_info_line("free-color-indicator", "Free", "0.0GB")
|
|
self.info_container.add(self.used_line)
|
|
self.info_container.add(self.free_line)
|
|
self.start_updates()
|
|
|
|
def update(self) -> bool:
|
|
try:
|
|
mem = psutil.virtual_memory()
|
|
self.main_label.set_label(f" {round(mem.percent):<2} %\nRAM")
|
|
self.used_line.value_label.set_label(f"{round(mem.used / (1024**3), 1)}GB")
|
|
self.free_line.value_label.set_label(
|
|
f"{round(mem.available / (1024**3), 1)}GB"
|
|
)
|
|
GLib.idle_add(self.progress.set_value, mem.percent)
|
|
except Exception as e:
|
|
logger.error(f"Error: {e}")
|
|
return True
|
|
|
|
|
|
class DesktopCpuInfoWidget(SystemInfoBase):
|
|
def __init__(self, **kwargs):
|
|
super().__init__("info-box-widget", **kwargs)
|
|
self.temp_value = Label(label="0°C", name="info-value")
|
|
self.info_container.add(
|
|
Box(
|
|
orientation="h",
|
|
spacing=4,
|
|
h_align="start",
|
|
children=[Label(label="Temp", name="info-text"), self.temp_value],
|
|
)
|
|
)
|
|
self.start_updates()
|
|
|
|
def get_cpu_temp(self) -> Optional[float]:
|
|
try:
|
|
temps = psutil.sensors_temperatures()
|
|
for name, entries in temps.items():
|
|
if any(s in name.lower() for s in ["coretemp", "k10temp", "cpu"]):
|
|
for entry in entries:
|
|
if any(
|
|
p in (entry.label or "").lower()
|
|
for p in ["package id 0", "core 0", ""]
|
|
):
|
|
return round(entry.current, 1)
|
|
except Exception as e:
|
|
logger.error(f"An error occurred: {e}")
|
|
return None
|
|
|
|
def update(self) -> bool:
|
|
try:
|
|
cpu = psutil.cpu_percent()
|
|
self.main_label.set_label(f" {round(cpu):<2} %\nCPU")
|
|
temp = self.get_cpu_temp()
|
|
self.temp_value.set_label(f"{temp}°C" if temp else "N/A")
|
|
GLib.idle_add(self.progress.set_value, cpu)
|
|
except Exception as e:
|
|
logger.error(f"Error: {e}")
|
|
return True
|
|
|
|
|
|
DesktopWidgetRegistry.register(
|
|
"ram_info", DesktopRamInfoWidget, (174, 174), (0.90521, 0.82732)
|
|
)
|
|
DesktopWidgetRegistry.register(
|
|
"cpu_info", DesktopCpuInfoWidget, (174, 174), (0.81042, 0.82732)
|
|
)
|