.dotfiles/bin/sbar.py
2024-01-04 10:07:50 +01:00

168 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
import runpy
from datetime import datetime
from os import getenv, getpid
from signal import signal
from subprocess import CalledProcessError, check_output, run
from time import sleep, time
crypto = runpy.run_path(getenv("HOME", "") + "/bin/crypto")
def get_stdout(command: list[str]) -> str:
try:
return check_output(command).decode().rstrip()
except CalledProcessError:
return ""
def update_crypto():
try:
fees = crypto["get_btc_fees"]()
coins = crypto["get_coins_values"]()
except:
OUT["cryto"] = ""
return
OUT["crypto"] = f"{fees} {coins}"
def update_cpu():
loadavg: str
with open("/proc/loadavg") as f:
loadavg = f.read().split()[0]
OUT["cpu"] = f"{loadavg}"
def update_memory():
kbtot: int
kbavail: int
gbused: float
lines: list[str]
with open("/proc/meminfo") as f:
lines = f.read().split("\n")
kbtot = int(lines[0].split()[1])
kbavail = int(lines[2].split()[1])
gbused = (kbtot - kbavail) / 1024 / 1024
OUT["ram"] = f"{gbused:.1f}G"
def update_bat():
dir = "/sys/class/power_supply/BAT0"
status: str
capacity: str
with open(dir + "/status") as f:
status = "" if f.read() == "Charging\n" else ""
with open(dir + "/capacity") as f:
capacity = f.read().rstrip()
OUT["bat"] = f"{status} {capacity}%"
def update_vol():
vol = get_stdout(["wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@"])
while not vol:
vol = get_stdout(["wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@"])
sleep(1)
if "MUTED" in vol:
OUT["vol"] = "🔇"
else:
OUT["vol"] = f"{int(float(vol.split()[1]) * 100)}"
def update_wlp():
sig = 0
ssid = ""
lines: list[str]
with open("/proc/net/wireless") as f:
lines = f.read().split("\n")
for l in lines:
if l.startswith("wlp"):
sig = float(l.split()[2])
break
lines = get_stdout(["nmcli", "device", "wifi", "show-password"]).split("\n")
for l in lines:
if l.startswith("SSID: "):
ssid = l[6:]
break
# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/d9b06a95/src/libnmc-base/nm-client-utils.c#L628
if sig > 56: # 70 is max
OUT["wlp"] = f"▂▄▆█ {ssid}"
elif sig > 38:
OUT["wlp"] = f"▂▄▆_ {ssid}"
elif sig > 21:
OUT["wlp"] = f"▂▄__ {ssid}"
elif sig > 3:
OUT["wlp"] = f"▂___ {ssid}"
else:
OUT["wlp"] = f"____ {ssid}"
def update_time():
OUT["time"] = datetime.now().strftime("%a %m/%d %R")
def display():
s = f"{OUT.get('crypto')} | {OUT.get('cpu')} | {OUT.get('ram')} | {OUT.get('vol')} | {OUT.get('wlp')} | {OUT.get('bat')} | {OUT.get('time')}"
if getenv("XDG_SESSION_TYPE") == "wayland":
print(s)
else:
run(["xsetroot", "-name", s])
def handler(signum: int, _):
if signum == 34:
update_vol()
# elif signum == 35:
# pass
display()
def setup_sig():
cache_dir = getenv("XDG_CACHE_HOME") or f"{getenv('HOME')}/.cache"
with open(cache_dir + "/pidofbar", "w") as f:
f.write(str(getpid()))
# kill -m "$(cat ~/.cache/pidofbar)"
signal(34, handler)
OUT = dict()
def main():
sec = 0
setup_sig()
# modules that don't update on their own need to be run at the start for
# getting their initial value
update_vol()
# TODO async?
while True:
if not sec % 300:
update_crypto()
if not sec % 10:
update_time()
update_cpu()
update_memory()
update_bat()
update_wlp()
display()
sec += 10
sleep(10 - time() % 10)
if __name__ == "__main__":
main()