mirror of
https://gitlab.com/pancakes1234/wdiscordbotserver.git
synced 2025-06-16 07:14:21 -06:00
Enhance sysinfo command to provide detailed system and bot information, including CPU, RAM, GPU, and uptime metrics. Improve error handling and response deferral to prevent timeouts. Add motherboard info retrieval for Windows and Linux systems.
This commit is contained in:
parent
560fe5cae7
commit
6d19da7d11
231
cogs/core.py
231
cogs/core.py
@ -10,23 +10,222 @@ import subprocess
|
||||
import sys
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
import GPUtil
|
||||
import distro
|
||||
|
||||
# Import wmi for Windows motherboard info
|
||||
try:
|
||||
import wmi
|
||||
WMI_AVAILABLE = True
|
||||
except ImportError:
|
||||
WMI_AVAILABLE = False
|
||||
|
||||
class Core(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
|
||||
@app_commands.command(name="sysinfo", description="Shows the hardware information of the server.")
|
||||
@app_commands.command(name="sysinfo", description="Shows detailed system and bot information.")
|
||||
async def sysinfo(self, interaction: discord.Interaction):
|
||||
# (The CPU, RAM, and other details are hard-coded here as an example.)
|
||||
embed = discord.Embed(title="Kasanes pc >.<", color=discord.Color.blue())
|
||||
embed.add_field(name="System", value="PowerEdge R7715 ラックサーバー", inline=False)
|
||||
embed.add_field(name="OS", value="ubuntu 24.10", inline=False)
|
||||
embed.add_field(name="Processor", value="AMD EPYC 9175F 4.20GHz", inline=False)
|
||||
embed.add_field(name="RAM", value="768 GB", inline=False)
|
||||
embed.add_field(name="Disk Space", value="480 GB", inline=False)
|
||||
embed.add_field(name="Server Name", value="Freaky teto :3", inline=False)
|
||||
|
||||
await interaction.response.send_message(embed=embed)
|
||||
"""Check the bot and system status."""
|
||||
# Defer the response to prevent interaction timeout
|
||||
await interaction.response.defer(thinking=True)
|
||||
try:
|
||||
embed = await self._system_check_logic(interaction)
|
||||
await interaction.followup.send(embed=embed)
|
||||
except Exception as e:
|
||||
print(f"Error in sysinfo command: {e}")
|
||||
await interaction.followup.send(f"An error occurred while checking system status: {e}")
|
||||
|
||||
async def _system_check_logic(self, context_or_interaction):
|
||||
"""Return detailed bot and system information as a Discord embed."""
|
||||
# Bot information
|
||||
bot_user = self.bot.user
|
||||
guild_count = len(self.bot.guilds)
|
||||
|
||||
# More efficient member counting - use cached members when available
|
||||
# This avoids API calls that can cause timeouts
|
||||
user_ids = set()
|
||||
for guild in self.bot.guilds:
|
||||
try:
|
||||
# Use members that are already cached
|
||||
for member in guild.members:
|
||||
if not member.bot:
|
||||
user_ids.add(member.id)
|
||||
except Exception as e:
|
||||
print(f"Error counting members in guild {guild.name}: {e}")
|
||||
user_count = len(user_ids)
|
||||
|
||||
# System information
|
||||
system = platform.system()
|
||||
os_info = f"{system} {platform.release()}"
|
||||
hostname = platform.node()
|
||||
distro_info_str = "" # Renamed variable
|
||||
|
||||
if system == "Linux":
|
||||
try:
|
||||
# Use distro library for better Linux distribution detection
|
||||
distro_name = distro.name(pretty=True)
|
||||
distro_info_str = f"\n**Distro:** {distro_name}"
|
||||
except ImportError:
|
||||
distro_info_str = "\n**Distro:** (Install 'distro' package for details)"
|
||||
except Exception as e:
|
||||
distro_info_str = f"\n**Distro:** (Error getting info: {e})"
|
||||
elif system == "Windows":
|
||||
# Add Windows version details if possible
|
||||
try:
|
||||
win_ver = platform.version() # e.g., '10.0.19041'
|
||||
win_build = platform.win32_ver()[1] # e.g., '19041'
|
||||
os_info = f"Windows {win_ver} (Build {win_build})"
|
||||
except Exception as e:
|
||||
print(f"Could not get detailed Windows version: {e}")
|
||||
# Keep the basic os_info
|
||||
|
||||
uptime_seconds = time.time() - psutil.boot_time()
|
||||
days, remainder = divmod(uptime_seconds, 86400)
|
||||
hours, remainder = divmod(remainder, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
|
||||
uptime_str = ""
|
||||
if days > 0:
|
||||
uptime_str += f"{int(days)}d "
|
||||
uptime_str += f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"
|
||||
uptime = uptime_str.strip()
|
||||
|
||||
# Hardware information - use a shorter interval for CPU usage
|
||||
cpu_usage = psutil.cpu_percent(interval=0.1)
|
||||
|
||||
# Get CPU info with a timeout to prevent hanging
|
||||
try:
|
||||
# Use a simpler approach for CPU name to avoid potential slowdowns
|
||||
if platform.system() == "Windows":
|
||||
cpu_name = platform.processor()
|
||||
elif platform.system() == "Linux":
|
||||
try:
|
||||
with open("/proc/cpuinfo", "r") as f:
|
||||
for line in f:
|
||||
if line.startswith("model name"):
|
||||
cpu_name = line.split(":")[1].strip()
|
||||
break
|
||||
else:
|
||||
cpu_name = "Unknown CPU"
|
||||
except:
|
||||
cpu_name = platform.processor() or "Unknown CPU"
|
||||
else:
|
||||
cpu_name = platform.processor() or "Unknown CPU"
|
||||
except Exception as e:
|
||||
print(f"Error getting CPU info: {e}")
|
||||
cpu_name = "N/A"
|
||||
|
||||
# Get motherboard information
|
||||
motherboard_info = self._get_motherboard_info()
|
||||
|
||||
memory = psutil.virtual_memory()
|
||||
ram_usage = f"{memory.used // (1024 ** 2)} MB / {memory.total // (1024 ** 2)} MB ({memory.percent}%)"
|
||||
|
||||
# GPU Information (using GPUtil for cross-platform consistency if available)
|
||||
gpu_info_lines = []
|
||||
try:
|
||||
gpus = GPUtil.getGPUs()
|
||||
if gpus:
|
||||
for gpu in gpus:
|
||||
gpu_info_lines.append(
|
||||
f"{gpu.name} ({gpu.load*100:.1f}% Load, {gpu.memoryUsed:.0f}/{gpu.memoryTotal:.0f} MB VRAM)"
|
||||
)
|
||||
gpu_info = "\n".join(gpu_info_lines)
|
||||
else:
|
||||
gpu_info = "No dedicated GPU detected by GPUtil."
|
||||
except ImportError:
|
||||
gpu_info = "GPUtil library not installed. Cannot get detailed GPU info."
|
||||
except Exception as e:
|
||||
print(f"Error getting GPU info via GPUtil: {e}")
|
||||
gpu_info = f"Error retrieving GPU info: {e}"
|
||||
|
||||
# Determine user and avatar URL based on context type
|
||||
if isinstance(context_or_interaction, commands.Context):
|
||||
user = context_or_interaction.author
|
||||
avatar_url = user.display_avatar.url
|
||||
elif isinstance(context_or_interaction, discord.Interaction):
|
||||
user = context_or_interaction.user
|
||||
avatar_url = user.display_avatar.url
|
||||
else:
|
||||
# Fallback or handle error if needed
|
||||
user = self.bot.user # Or some default
|
||||
avatar_url = self.bot.user.display_avatar.url if self.bot.user else None
|
||||
|
||||
# Create embed
|
||||
embed = discord.Embed(title="📊 System Status", color=discord.Color.blue())
|
||||
if bot_user:
|
||||
embed.set_thumbnail(url=bot_user.display_avatar.url)
|
||||
|
||||
# Bot Info Field
|
||||
if bot_user:
|
||||
embed.add_field(
|
||||
name="🤖 Bot Information",
|
||||
value=f"**Name:** {bot_user.name}\n"
|
||||
f"**ID:** {bot_user.id}\n"
|
||||
f"**Servers:** {guild_count}\n"
|
||||
f"**Unique Users:** {user_count}",
|
||||
inline=False
|
||||
)
|
||||
else:
|
||||
embed.add_field(
|
||||
name="🤖 Bot Information",
|
||||
value="Bot user information not available.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
# System Info Field
|
||||
embed.add_field(
|
||||
name="🖥️ System Information",
|
||||
value=f"**OS:** {os_info}{distro_info_str}\n" # Use renamed variable
|
||||
f"**Hostname:** {hostname}\n"
|
||||
f"**Uptime:** {uptime}",
|
||||
inline=False
|
||||
)
|
||||
|
||||
# Hardware Info Field
|
||||
embed.add_field(
|
||||
name="⚙️ Hardware Information",
|
||||
value=f"**Device Model:** {motherboard_info}\n"
|
||||
f"**CPU:** {cpu_name}\n"
|
||||
f"**CPU Usage:** {cpu_usage}%\n"
|
||||
f"**RAM Usage:** {ram_usage}\n"
|
||||
f"**GPU Info:**\n{gpu_info}",
|
||||
inline=False
|
||||
)
|
||||
|
||||
if user:
|
||||
embed.set_footer(text=f"Requested by: {user.display_name}", icon_url=avatar_url)
|
||||
|
||||
embed.timestamp = discord.utils.utcnow()
|
||||
return embed
|
||||
|
||||
def _get_motherboard_info(self):
|
||||
"""Get motherboard information based on the operating system."""
|
||||
system = platform.system()
|
||||
try:
|
||||
if system == "Windows":
|
||||
if WMI_AVAILABLE:
|
||||
w = wmi.WMI()
|
||||
for board in w.Win32_BaseBoard():
|
||||
return f"{board.Manufacturer} {board.Product}"
|
||||
return "WMI module not available"
|
||||
elif system == "Linux":
|
||||
# Read motherboard product name from sysfs
|
||||
try:
|
||||
with open("/sys/devices/virtual/dmi/id/product_name", "r") as f:
|
||||
product_name = f.read().strip()
|
||||
return product_name if product_name else "Unknown motherboard"
|
||||
except FileNotFoundError:
|
||||
return "/sys/devices/virtual/dmi/id/product_name not found"
|
||||
except Exception as e:
|
||||
return f"Error reading motherboard info: {e}"
|
||||
else:
|
||||
return f"Unsupported OS: {system}"
|
||||
except Exception as e:
|
||||
print(f"Error getting motherboard info: {e}")
|
||||
return "Error retrieving motherboard info"
|
||||
|
||||
@app_commands.command(name="status", description="Sets the bot's status to the provided text.")
|
||||
async def status(self, interaction: discord.Interaction, text: str):
|
||||
@ -57,7 +256,7 @@ class Core(commands.Cog):
|
||||
color=discord.Color.blurple()
|
||||
)
|
||||
commands_list = [
|
||||
("/sysinfo", "Shows the hardware information of the server."),
|
||||
("/sysinfo", "Shows detailed system and bot information."),
|
||||
("/status", "Sets the bot's status to the provided text."),
|
||||
("/user", "Changes the bot's nickname."),
|
||||
("/ping", "Pings a server and returns the result."),
|
||||
@ -139,7 +338,7 @@ class Core(commands.Cog):
|
||||
os.execv(sys.executable, [sys.executable, restart_script])
|
||||
await interaction.response.send_message("Bot has updated to the latest commit and is restarting...")
|
||||
|
||||
|
||||
|
||||
@app_commands.command(name="temps", description="Runs the 'sensors' command and sends its output to chat.")
|
||||
async def temps(self, interaction: discord.Interaction):
|
||||
"""Executes the sensors command and returns the output."""
|
||||
@ -179,10 +378,10 @@ class Core(commands.Cog):
|
||||
async def supportserver(self, interaction: discord.Interaction):
|
||||
await interaction.response.send_message("https://discord.gg/9CFwFRPNH4")
|
||||
|
||||
@app_commands.command(name="contactsupport", description="support emails")
|
||||
@app_commands.command(name="contactsupport", description="support emails")
|
||||
async def contactsupport(self, interaction: discord.Interaction):
|
||||
await interaction.response.send_message("For general support, please email:help@learnhelp,cc\nFor security issues, please email:securityoffice@auditoffice.learnhelp.cc\nFor staff issues, please email:contact@admin.office.learnhelp.cc")
|
||||
|
||||
await interaction.response.send_message("For general support, please email:help@learnhelp,cc\nFor security issues, please email:securityoffice@auditoffice.learnhelp.cc\nFor staff issues, please email:contact@admin.office.learnhelp.cc")
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot):
|
||||
await bot.add_cog(Core(bot))
|
Loading…
x
Reference in New Issue
Block a user