#!/usr/bin/env python3 import json import sys import time import requests import logging import subprocess from datetime import datetime logger = logging.getLogger(__name__) class Status: def status(self): return None class Cat(Status): index = 0 def status(self): cat_width = 200 index = self.index catwalk = "🐈🏳️‍🌈" + " " * index self.index = (index + 1) % cat_width return {"full_text": catwalk} class Space(Status): backoff = 0 c_status = None def status(self): backoff = self.backoff if self.backoff == 0: self.update() return {"full_text": self.c_status} def update(self): spacestatus_url = "https://status.stratum0.org/status.json" resp = requests.get(url=spacestatus_url) self.backoff = (self.backoff + 1) % 120 data = resp.json() if data["isOpen"]: since = datetime.strptime(data["since"], "%Y-%m-%dT%H:%M:%S.%f").strftime("%A at %H:%M") spacestatus = f"Space is open since {since}" else: spacestatus = "Space is closed" self.c_status = spacestatus class Battery(Status): capacity_file = open('/sys/class/power_supply/BAT0/capacity', 'r') status_file = open('/sys/class/power_supply/BAT0/status', 'r') def status(self): self.status_file.seek(0) status = self.status_file.read().rstrip() self.capacity_file.seek(0) capacity = self.capacity_file.read().rstrip() battery = f"{status} {capacity}%" return {"full_text": battery} class Time(Status): def status(self): now = datetime.now() match now.isocalendar().week % 10: case 1: th = "st" case 2: th = "nd" case 3: th = "rd" case _: th = "th" return {"full_text": now.strftime(f"%V{th} %A %H:%M") } class FailedUnits(Status): def status(self): proc = subprocess.run(["systemctl", "list-units", "--failed"], capture_output = True) stdout = proc.stdout.decode('utf-8') failed = 0 for line in stdout: if 'failed' in line: failed += 1 if failed == 0: return {"full_text": f"No failed units"} else: return {"full_text": f"There are {failed} failed units", "color": "#ff0000"} def print_header(): header = { "version": 1, "click_events": False, } print(json.dumps(header)) print("[") def run(interval, widgets): print_header() while True: body = [] for widget in widgets: try: status = widget.status() except Exception as e: logger.error(e) if status: body += status, print(json.dumps(body), ",", flush=True) ts = interval - (time.time() % interval) time.sleep(ts) if __name__ == "__main__": logging.basicConfig(level=logging.INFO) # Interval in seconds interval = 1.0 widgets = [Cat(), FailedUnits(), Space(), Battery(), Time()] run(interval, widgets)