Files
plain-ub-overfork/app/plugins/system/sysinfo.py
overspend1 8fe355ed0c Update README and alive command for @overspend1 fork
- Updated README title to show OVERSPEND1 FORK
- Changed maintainer credit to @overspend1
- Updated alive command to show @overspend1 as creator instead of Meliodas
2025-07-25 20:27:05 +02:00

433 lines
15 KiB
Python

import platform
import psutil
import os
import subprocess
from datetime import datetime, timedelta
from app import BOT, Message
def is_termux():
"""Check if running on Termux (Android)"""
return os.path.exists("/data/data/com.termux") or "TERMUX_VERSION" in os.environ
def get_android_info():
"""Get Android-specific information"""
android_info = {}
try:
# Try to get Android version
if os.path.exists("/system/build.prop"):
with open("/system/build.prop", "r") as f:
for line in f:
if "ro.build.version.release" in line:
android_info["version"] = line.split("=")[1].strip()
elif "ro.product.model" in line:
android_info["model"] = line.split("=")[1].strip()
elif "ro.product.brand" in line:
android_info["brand"] = line.split("=")[1].strip()
except:
pass
# Try using getprop command
try:
result = subprocess.run(["getprop", "ro.build.version.release"],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
android_info["version"] = result.stdout.strip()
except:
pass
try:
result = subprocess.run(["getprop", "ro.product.model"],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
android_info["model"] = result.stdout.strip()
except:
pass
return android_info
@BOT.add_cmd(cmd="sysinfo")
async def system_info(bot: BOT, message: Message):
"""
CMD: SYSINFO
INFO: Get detailed system information including CPU, RAM, disk usage, and uptime.
USAGE: .sysinfo
"""
response = await message.reply("🔄 <b>Gathering system information...</b>")
try:
# Detect if running on Termux/Android
is_android = is_termux()
# System Info
system = platform.system()
node = platform.node()
release = platform.release()
version = platform.version()
machine = platform.machine()
processor = platform.processor() or "Unknown"
# Get Android-specific info if applicable
android_info = {}
if is_android:
android_info = get_android_info()
# CPU Info with fallbacks
try:
cpu_count = psutil.cpu_count(logical=False) or psutil.cpu_count(logical=True)
cpu_count_logical = psutil.cpu_count(logical=True)
except:
cpu_count = "Unknown"
cpu_count_logical = "Unknown"
try:
cpu_freq = psutil.cpu_freq()
if cpu_freq:
freq_current = cpu_freq.current
freq_max = cpu_freq.max
else:
freq_current = freq_max = None
except:
freq_current = freq_max = None
try:
cpu_percent = psutil.cpu_percent(interval=1)
except:
cpu_percent = "Unknown"
# Memory Info with fallbacks
try:
memory = psutil.virtual_memory()
except:
memory = None
try:
swap = psutil.swap_memory()
except:
swap = None
# Disk Info with fallbacks
try:
# Try different paths for Termux
if is_android:
# Termux typically uses /data/data/com.termux
disk_paths = ["/data/data/com.termux", "/", "/sdcard"]
disk = None
for path in disk_paths:
try:
if os.path.exists(path):
disk = psutil.disk_usage(path)
break
except:
continue
else:
disk = psutil.disk_usage('/')
except:
disk = None
# Boot time and uptime with fallbacks
try:
boot_time = psutil.boot_time()
boot_time_str = datetime.fromtimestamp(boot_time).strftime("%Y-%m-%d %H:%M:%S")
uptime = datetime.now() - datetime.fromtimestamp(boot_time)
uptime_str = str(uptime).split('.')[0] # Remove microseconds
except:
boot_time_str = "Unknown"
uptime_str = "Unknown"
# Load average (Unix systems) with fallbacks
try:
load_avg = psutil.getloadavg()
load_str = f"<b>Load Average:</b> {load_avg[0]:.2f}, {load_avg[1]:.2f}, {load_avg[2]:.2f}"
except (AttributeError, OSError):
load_str = "<b>Load Average:</b> Not available on this system"
# Format sizes
def bytes_to_gb(bytes_val):
return bytes_val / (1024**3)
# Build system info with Android detection
if is_android:
system_emoji = "📱"
system_title = "Android System Information (Termux)"
else:
system_emoji = "🖥️"
system_title = "System Information"
info_text = f"""{system_emoji} <b>{system_title}</b>
<b>🔧 System Details:</b>
<b>OS:</b> {system} {release}"""
# Add Android-specific info if available
if is_android and android_info:
if "version" in android_info:
info_text += f"\n<b>Android:</b> {android_info['version']}"
if "brand" in android_info and "model" in android_info:
info_text += f"\n<b>Device:</b> {android_info['brand']} {android_info['model']}"
elif "model" in android_info:
info_text += f"\n<b>Device:</b> {android_info['model']}"
info_text += f"""
<b>Hostname:</b> {node}
<b>Architecture:</b> {machine}
<b>Processor:</b> {processor}
<b>⚡ CPU Information:</b>"""
if cpu_count != "Unknown":
info_text += f"\n<b>Cores:</b> {cpu_count} physical, {cpu_count_logical} logical"
else:
info_text += f"\n<b>Cores:</b> {cpu_count_logical} logical"
if freq_current and freq_max:
info_text += f"\n<b>Frequency:</b> {freq_current:.0f} MHz (Max: {freq_max:.0f} MHz)"
elif freq_current:
info_text += f"\n<b>Frequency:</b> {freq_current:.0f} MHz"
else:
info_text += f"\n<b>Frequency:</b> Not available"
info_text += f"\n<b>Usage:</b> {cpu_percent}%"
info_text += f"\n\n<b>🧠 Memory Information:</b>"
if memory:
info_text += f"""
<b>Total RAM:</b> {bytes_to_gb(memory.total):.2f} GB
<b>Available:</b> {bytes_to_gb(memory.available):.2f} GB ({memory.percent}% used)"""
else:
info_text += f"\n<b>Memory:</b> Information not accessible"
if swap and swap.total > 0:
info_text += f"""
<b>Swap Total:</b> {bytes_to_gb(swap.total):.2f} GB
<b>Swap Used:</b> {bytes_to_gb(swap.used):.2f} GB ({swap.percent}% used)"""
elif is_android:
info_text += f"\n<b>Swap:</b> Not typically used on Android"
else:
info_text += f"\n<b>Swap:</b> Not available"
info_text += f"\n\n<b>💾 Disk Information:</b>"
if disk:
storage_path = "Termux Storage" if is_android else "Root"
info_text += f"""
<b>Path:</b> {storage_path}
<b>Total:</b> {bytes_to_gb(disk.total):.2f} GB
<b>Used:</b> {bytes_to_gb(disk.used):.2f} GB ({disk.percent}% used)
<b>Free:</b> {bytes_to_gb(disk.free):.2f} GB"""
else:
info_text += f"\n<b>Storage:</b> Information not accessible"
info_text += f"""
<b>⏱️ System Uptime:</b>
<b>Boot Time:</b> {boot_time_str}
<b>Uptime:</b> {uptime_str}
{load_str}"""
# Add Termux-specific note
if is_android:
info_text += f"\n\n<i>📱 Running on Android via Termux</i>"
await response.edit(info_text)
except Exception as e:
await response.edit(f"❌ <b>Error getting system info:</b>\n<code>{str(e)}</code>")
@BOT.add_cmd(cmd="disk")
async def disk_usage(bot: BOT, message: Message):
"""
CMD: DISK
INFO: Show disk usage for all mounted drives.
USAGE: .disk
"""
response = await message.reply("🔄 <b>Getting disk usage...</b>")
try:
is_android = is_termux()
if is_android:
# Special handling for Termux/Android
disk_info = "💾 <b>Storage Usage Information (Termux)</b>\n\n"
# Check common Termux paths
termux_paths = [
("/data/data/com.termux", "Termux App Storage"),
("/sdcard", "Internal Storage"),
("/storage/emulated/0", "Emulated Storage"),
("/", "Root")
]
for path, description in termux_paths:
try:
if os.path.exists(path):
usage = psutil.disk_usage(path)
total_gb = usage.total / (1024**3)
used_gb = usage.used / (1024**3)
free_gb = usage.free / (1024**3)
percent = (usage.used / usage.total) * 100 if usage.total > 0 else 0
# Create progress bar
bar_length = 15
filled_length = int(bar_length * percent / 100)
bar = "" * filled_length + "" * (bar_length - filled_length)
disk_info += f"""<b>📱 {description}</b>
<b>Path:</b> {path}
<b>Total:</b> {total_gb:.2f} GB
<b>Used:</b> {used_gb:.2f} GB ({percent:.1f}%)
<b>Free:</b> {free_gb:.2f} GB
{bar} {percent:.1f}%
"""
except (PermissionError, OSError):
disk_info += f"<b>📱 {description}</b>\n❌ Access denied or not mounted\n\n"
else:
# Regular disk usage for non-Android systems
try:
partitions = psutil.disk_partitions()
except:
partitions = []
disk_info = "💾 <b>Disk Usage Information</b>\n\n"
for partition in partitions:
try:
usage = psutil.disk_usage(partition.mountpoint)
total_gb = usage.total / (1024**3)
used_gb = usage.used / (1024**3)
free_gb = usage.free / (1024**3)
percent = (usage.used / usage.total) * 100
# Create a simple progress bar
bar_length = 15
filled_length = int(bar_length * percent / 100)
bar = "" * filled_length + "" * (bar_length - filled_length)
disk_info += f"""<b>📁 {partition.mountpoint}</b>
<b>Device:</b> {partition.device}
<b>Filesystem:</b> {partition.fstype}
<b>Total:</b> {total_gb:.2f} GB
<b>Used:</b> {used_gb:.2f} GB ({percent:.1f}%)
<b>Free:</b> {free_gb:.2f} GB
{bar} {percent:.1f}%
"""
except PermissionError:
disk_info += f"<b>📁 {partition.mountpoint}</b>\n❌ Permission denied\n\n"
await response.edit(disk_info)
except Exception as e:
await response.edit(f"❌ <b>Error getting disk usage:</b>\n<code>{str(e)}</code>")
@BOT.add_cmd(cmd="mem")
async def memory_info(bot: BOT, message: Message):
"""
CMD: MEM
INFO: Show detailed memory usage information.
USAGE: .mem
"""
response = await message.reply("🔄 <b>Getting memory information...</b>")
try:
memory = psutil.virtual_memory()
swap = psutil.swap_memory()
def bytes_to_gb(bytes_val):
return bytes_val / (1024**3)
def bytes_to_mb(bytes_val):
return bytes_val / (1024**2)
# Memory progress bar
mem_percent = memory.percent
bar_length = 20
filled_length = int(bar_length * mem_percent / 100)
mem_bar = "" * filled_length + "" * (bar_length - filled_length)
# Swap progress bar
swap_percent = swap.percent
swap_filled_length = int(bar_length * swap_percent / 100)
swap_bar = "" * swap_filled_length + "" * (bar_length - swap_filled_length)
mem_text = f"""🧠 <b>Memory Usage Information</b>
<b>📊 Virtual Memory:</b>
<b>Total:</b> {bytes_to_gb(memory.total):.2f} GB
<b>Available:</b> {bytes_to_gb(memory.available):.2f} GB
<b>Used:</b> {bytes_to_gb(memory.used):.2f} GB
<b>Cached:</b> {bytes_to_mb(memory.cached):.0f} MB
<b>Buffers:</b> {bytes_to_mb(memory.buffers):.0f} MB
<b>Usage:</b> {mem_percent}%
{mem_bar} {mem_percent}%
<b>💿 Swap Memory:</b>
<b>Total:</b> {bytes_to_gb(swap.total):.2f} GB
<b>Used:</b> {bytes_to_gb(swap.used):.2f} GB
<b>Free:</b> {bytes_to_gb(swap.free):.2f} GB
<b>Usage:</b> {swap_percent}%
{swap_bar} {swap_percent}%"""
await response.edit(mem_text)
except Exception as e:
await response.edit(f"❌ <b>Error getting memory info:</b>\n<code>{str(e)}</code>")
@BOT.add_cmd(cmd="cpu")
async def cpu_info(bot: BOT, message: Message):
"""
CMD: CPU
INFO: Show detailed CPU usage and information.
USAGE: .cpu
"""
response = await message.reply("🔄 <b>Getting CPU information...</b>")
try:
# Get CPU info
cpu_percent = psutil.cpu_percent(interval=1, percpu=True)
cpu_count_physical = psutil.cpu_count(logical=False)
cpu_count_logical = psutil.cpu_count(logical=True)
cpu_freq = psutil.cpu_freq()
# Overall CPU usage
overall_cpu = psutil.cpu_percent(interval=1)
# CPU progress bar
bar_length = 20
filled_length = int(bar_length * overall_cpu / 100)
cpu_bar = "" * filled_length + "" * (bar_length - filled_length)
cpu_text = f"""⚡ <b>CPU Usage Information</b>
<b>🖥️ General Info:</b>
<b>Physical Cores:</b> {cpu_count_physical}
<b>Logical Cores:</b> {cpu_count_logical}
<b>Current Frequency:</b> {cpu_freq.current:.0f} MHz
<b>Max Frequency:</b> {cpu_freq.max:.0f} MHz
<b>Min Frequency:</b> {cpu_freq.min:.0f} MHz
<b>📊 Overall Usage:</b> {overall_cpu}%
{cpu_bar} {overall_cpu}%
<b>🔄 Per-Core Usage:</b>"""
# Add per-core usage
for i, percent in enumerate(cpu_percent):
core_filled = int(10 * percent / 100) # Smaller bars for cores
core_bar = "" * core_filled + "" * (10 - core_filled)
cpu_text += f"\n<b>Core {i+1}:</b> {core_bar} {percent}%"
await response.edit(cpu_text)
except Exception as e:
await response.edit(f"❌ <b>Error getting CPU info:</b>\n<code>{str(e)}</code>")