import subprocess import os def _cmd(cmd: str) -> str: """ Safe shell command runner """ try: return subprocess.getoutput(cmd) except Exception as e: return f"ERROR: {e}" # ---------- SECURITY ---------- def security() -> str: out = _cmd("sshd -T | grep -i '^permitrootlogin'") if not out or "ERROR:" in out: return "šŸ” Security\n\nāš ļø permitrootlogin not found" lines = ["šŸ” Security\n"] if "no" in out.lower(): lines.append("🟢 Root login disabled") else: lines.append("šŸ”“ Root login ENABLED") pass_auth = _cmd("sshd -T | grep -i '^passwordauthentication'") if pass_auth and "ERROR:" not in pass_auth: lines.append("šŸ”“ Password auth enabled" if "yes" in pass_auth.lower() else "🟢 Password auth disabled") pubkey_auth = _cmd("sshd -T | grep -i '^pubkeyauthentication'") if pubkey_auth and "ERROR:" not in pubkey_auth: lines.append("🟢 Pubkey auth enabled" if "yes" in pubkey_auth.lower() else "šŸ”“ Pubkey auth disabled") sec_updates = _cmd("apt list --upgradable 2>/dev/null | grep -i security | wc -l") if sec_updates and "ERROR:" not in sec_updates: try: count = int(sec_updates.strip()) lines.append(f"šŸ”” Security updates: {count}") except ValueError: pass time_info = _cmd("timedatectl") if time_info and "ERROR:" not in time_info: tz = None ntp = None synced = None for line in time_info.splitlines(): if "Time zone:" in line: tz = line.split("Time zone:", 1)[1].strip() if "NTP service:" in line: ntp = line.split("NTP service:", 1)[1].strip() if "System clock synchronized:" in line: synced = line.split("System clock synchronized:", 1)[1].strip() if tz: lines.append(f"šŸ•’ Time zone: {tz}") if ntp: lines.append(f"šŸ”§ NTP service: {ntp}") if synced: lines.append(f"ā± Clock synced: {synced}") return "\n".join(lines) # ---------- DISKS ---------- def list_disks() -> list[str]: out = _cmd("lsblk -dn -o NAME,TYPE") disks = [] for line in out.splitlines(): parts = line.split() if len(parts) != 2: continue name, typ = parts if typ == "disk": disks.append(f"/dev/{name}") return disks def smart_health(dev: str) -> str: out = _cmd(f"smartctl -H {dev}") if not out or "ERROR:" in out: return "āš ļø ERROR" if "PASSED" in out: return "🟢 PASSED" if "FAILED" in out: return "šŸ”“ FAILED" return "āš ļø UNKNOWN" def disk_temperature(dev: str) -> str: out = _cmd(f"smartctl -A {dev}") if not out or "ERROR:" in out: return "n/a" # NVMe for line in out.splitlines(): if "Temperature:" in line and "Celsius" in line: try: temp = int("".join(filter(str.isdigit, line))) return f"{temp}°C" except Exception: pass # SATA attributes for line in out.splitlines(): if line.strip().startswith(("194", "190")): parts = line.split() for p in parts[::-1]: if p.isdigit(): return f"{p}°C" return "n/a" def disks() -> str: disks = list_disks() if not disks: return "šŸ’½ Disks\n\nāŒ No disks found" lines = ["šŸ’½ Disks (SMART)\n"] for d in disks: health = smart_health(d) temp = disk_temperature(d) icon = "🟢" if temp != "n/a": t = int(temp.replace("°C", "")) if t > 50: icon = "šŸ”“" elif t > 40: icon = "🟔" lines.append(f"{icon} {d} — {health}, 🌔 {temp}") return "\n".join(lines) def hardware() -> str: cpu_model = "n/a" try: with open("/proc/cpuinfo", "r") as f: for line in f: if line.lower().startswith("model name"): cpu_model = line.split(":", 1)[1].strip() break except Exception: pass mem_total = "n/a" swap_total = "n/a" try: with open("/proc/meminfo", "r") as f: for line in f: if line.startswith("MemTotal:"): mem_kb = int(line.split()[1]) mem_total = f"{mem_kb / (1024**2):.2f} GiB" if line.startswith("SwapTotal:"): swap_kb = int(line.split()[1]) swap_total = f"{swap_kb / (1024**2):.2f} GiB" except Exception: pass cores = os.cpu_count() or "n/a" uname = os.uname() lines = [ "🧱 Hardware", "", f"🧠 CPU: {cpu_model}", f"🧩 Cores: {cores}", f"šŸ’¾ RAM: {mem_total}", f"šŸŒ€ Swap: {swap_total}", f"🧬 Arch: {uname.machine}", f"🐧 Kernel: {uname.release}", ] return "\n".join(lines)