#!/usr/bin/env python3 import sys import json from hysteria2_api import Hysteria2Client import time from init_paths import * from paths import * def get_secret() -> str: if not CONFIG_FILE.exists(): print("Error: config.json file not found!", file=sys.stderr) sys.exit(1) with CONFIG_FILE.open() as f: data = json.load(f) secret = data.get("trafficStats", {}).get("secret") if not secret: print("Error: secret not found in config.json!", file=sys.stderr) sys.exit(1) return secret def convert_bytes(bytes_val: int) -> str: units = [("TB", 1 << 40), ("GB", 1 << 30), ("MB", 1 << 20), ("KB", 1 << 10)] for unit, factor in units: if bytes_val >= factor: return f"{bytes_val / factor:.2f} {unit}" return f"{bytes_val} B" def get_cpu_usage(interval: float = 0.1) -> float: def read_cpu_times(): with open("/proc/stat") as f: line = f.readline() fields = list(map(int, line.strip().split()[1:])) idle, total = fields[3], sum(fields) return idle, total idle1, total1 = read_cpu_times() time.sleep(interval) idle2, total2 = read_cpu_times() idle_delta = idle2 - idle1 total_delta = total2 - total1 cpu_usage = 100.0 * (1 - idle_delta / total_delta) if total_delta else 0.0 return round(cpu_usage, 1) def get_memory_usage() -> tuple[int, int]: with open("/proc/meminfo") as f: lines = f.readlines() mem_total = int(next(line for line in lines if "MemTotal" in line).split()[1]) // 1024 mem_available = int(next(line for line in lines if "MemAvailable" in line).split()[1]) // 1024 mem_used = mem_total - mem_available return mem_total, mem_used def get_online_user_count(secret: str) -> int: try: client = Hysteria2Client( base_url=API_BASE_URL, secret=secret ) online_users = client.get_online_clients() return sum(1 for user in online_users.values() if user.is_online) except Exception as e: print(f"Error getting online users: {e}", file=sys.stderr) return 0 def get_total_traffic() -> tuple[int, int]: if not USERS_FILE.exists(): return 0, 0 try: with USERS_FILE.open() as f: users = json.load(f) total_upload = 0 total_download = 0 for user_data in users.values(): total_upload += int(user_data.get("upload_bytes", 0) or 0) total_download += int(user_data.get("download_bytes", 0) or 0) return total_upload, total_download except Exception as e: print(f"Error parsing traffic data: {e}", file=sys.stderr) return 0, 0 def main(): secret = get_secret() cpu_usage = get_cpu_usage() mem_total, mem_used = get_memory_usage() online_users = get_online_user_count(secret) print(f"📈 CPU Usage: {cpu_usage}") print(f"📋 Total RAM: {mem_total}MB") print(f"💻 Used RAM: {mem_used}MB") print(f"👥 Online Users: {online_users}") print() total_upload, total_download = get_total_traffic() print(f"🔼 Uploaded Traffic: {convert_bytes(total_upload)}") print(f"🔽 Downloaded Traffic: {convert_bytes(total_download)}") print(f"📊 Total Traffic: {convert_bytes(total_upload + total_download)}") if __name__ == "__main__": main()