summaryrefslogtreecommitdiff
path: root/panel.py
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2024-02-19 23:34:51 -0800
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2024-02-19 23:34:51 -0800
commitd8fb197876f30f8f539a9d8f0b7f0c0a77ec2752 (patch)
treec15551bc5a9ff13083afc745c9a7895cc104d1d4 /panel.py
parent3d5bf4bcf4cc512884be010bc9ef9525e0acb14e (diff)
downloadpanel-d8fb197876f30f8f539a9d8f0b7f0c0a77ec2752.tar.gz
panel-d8fb197876f30f8f539a9d8f0b7f0c0a77ec2752.tar.xz
add network interface, cpu and memory modules
These are all refreshed from a shared thread. When the next update time for multiple such modules overlaps, repainting the panel is triggered only once.
Diffstat (limited to 'panel.py')
-rwxr-xr-xpanel.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/panel.py b/panel.py
index aad51eb..b67d2f2 100755
--- a/panel.py
+++ b/panel.py
@@ -3,9 +3,11 @@
# Copyright 2024 David Vazgenovich Shakaryan
import os
+import psutil
import queue
import subprocess
import threading
+import time
from datetime import datetime
from zoneinfo import ZoneInfo
@@ -32,6 +34,10 @@ class Fmt:
return cls.fg('#7b51ca', s)
@classmethod
+ def labelled(cls, label, s):
+ return cls.label(label) + cls.spacer() + s
+
+ @classmethod
def spacer(cls, n=1):
return f'%{{O{n * 7}}}'
@@ -298,6 +304,63 @@ class ModInputAvail(Mod):
self.out = None
self.repaint()
+class IntervalTimer():
+ def __init__(self):
+ self.t = None
+ self.lock = threading.Lock()
+ self.func_intervals = {}
+ self.func_next_time = {}
+ self.e_repaint = None
+
+ def run(self):
+ with self.lock:
+ if self.t is None:
+ self.t = threading.Thread(target=self.work, daemon=True)
+ self.t.start()
+
+ def work(self):
+ while True:
+ now = time.time()
+ for func, ival in self.func_intervals.items():
+ if now > self.func_next_time.get(func, 0):
+ func()
+ self.func_next_time[func] = now - (now % ival) + ival
+ self.e_repaint.set()
+ time.sleep(min(self.func_next_time.values()) - time.time())
+
+class ModInterval(Mod):
+ timer = IntervalTimer()
+
+ def __init__(self, interval=1, **kwargs):
+ super().__init__(**kwargs)
+ self.timer.func_intervals[self.refresh] = interval
+
+ def run(self):
+ if not self.timer.e_repaint:
+ self.timer.e_repaint = self.e_repaint
+ self.timer.run()
+
+class ModNetIf(ModInterval):
+ def __init__(self, ifname, label=None, **kwargs):
+ super().__init__(**kwargs)
+ self.ifname = ifname
+ self.label = label or ifname
+
+ def refresh(self):
+ stats = psutil.net_if_stats().get(self.ifname)
+ state = 'up' if stats and stats.isup else 'down'
+ self.out = Fmt.labelled(self.label, state)
+
+class ModCPU(ModInterval):
+ def refresh(self):
+ percent = psutil.cpu_percent()
+ self.out = Fmt.labelled('CPU', f'{percent:.0f}%%')
+
+class ModMem(ModInterval):
+ def refresh(self):
+ percent = psutil.virtual_memory().percent
+ self.out = Fmt.labelled('MEM', f'{percent:.0f}%%')
+
class Panel:
def __init__(self, *mods):
self.e_repaint = threading.Event()
@@ -347,6 +410,9 @@ Panel(
ModInputAvail(
'/dev/input/by-id/usb-HID_Keyboard_HID_Keyboard-event-kbd',
unavail_text='NO KEYBOARD'),
+ ModNetIf('wg0', interval=1),
+ ModCPU(interval=0.5),
+ ModMem(interval=0.5),
ModDate(
fmts=('%Y-%m-%d %H:%M:%S', '%H:%M'),
tzs=({'id': None}, {'id': 'UTC'},