moved to a better sysinfo method
This commit is contained in:
1 parent
b7a2338de8
commit
973330d21a
3 files changed
+58
-36
No files matched your search
@@ -53,7 +53,7 @@ async def _fetch_portrait(session: aiohttp.ClientSession, student: dict) -> Opti
|
||||
# 1. Try the face icon
|
||||
icon_url = db.cdn_icon(student)
|
||||
try:
|
||||
async with session.get(icon_url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
async with session.get(icon_url, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.read()
|
||||
return Image.open(io.BytesIO(data)).convert("RGBA")
|
||||
@@ -63,7 +63,7 @@ async def _fetch_portrait(session: aiohttp.ClientSession, student: dict) -> Opti
|
||||
# 2. Fallback: skill portrait (full-body character art)
|
||||
sp_url = db.cdn_skill_portrait(student)
|
||||
try:
|
||||
async with session.get(sp_url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
async with session.get(sp_url, timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.read()
|
||||
img = Image.open(io.BytesIO(data)).convert("RGBA")
|
||||
@@ -149,7 +149,7 @@ async def render_pull(
|
||||
_draw_footer(draw, spark_count)
|
||||
|
||||
# ── Fetch all portraits ─────────────────────────────────────────────
|
||||
timeout = aiohttp.ClientTimeout(total=60, connect=10)
|
||||
timeout = aiohttp.ClientTimeout(total=30, connect=5)
|
||||
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||
portrait_tasks = [_fetch_portrait(session, p) for p in pulls]
|
||||
portraits = await asyncio.gather(*portrait_tasks, return_exceptions=True)
|
||||
|
||||
+47
-26
@@ -1,50 +1,75 @@
|
||||
import subprocess
|
||||
from discord.ext import commands
|
||||
import asyncio
|
||||
import logging
|
||||
import re
|
||||
from discord.ext import commands
|
||||
import psutil
|
||||
import aiohttp
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SysInfo(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
def strip_ansi(self, text):
|
||||
@staticmethod
|
||||
def _strip_ansi(text: str) -> str:
|
||||
return re.sub(r'\x1b\[[0-9;]*[a-zA-Z]|\[[0-9]+[A-Z]', '', text)
|
||||
|
||||
#this command lists all the sysinfo commands, not an actualy sysinfo command##
|
||||
@staticmethod
|
||||
async def _run_command(*args: str, timeout: float = 8) -> str:
|
||||
"""Run a shell command asynchronously, return stdout or '' on failure."""
|
||||
try:
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.DEVNULL,
|
||||
)
|
||||
stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
||||
return stdout.decode().strip()
|
||||
except Exception:
|
||||
log.debug("Command failed: %s", args, exc_info=True)
|
||||
return ""
|
||||
|
||||
# ── commands ────────────────────────────────────────────────────────
|
||||
|
||||
@commands.command()
|
||||
async def sysinfo(self, ctx):
|
||||
sys_commands = [f'!{cmd.name}' for cmd in self.get_commands()]
|
||||
await ctx.reply('\n'.join(sys_commands))
|
||||
######################################################################
|
||||
"""List available sysinfo commands."""
|
||||
cmds = [f'!{cmd.name}' for cmd in self.get_commands()]
|
||||
await ctx.reply('\n'.join(cmds))
|
||||
|
||||
|
||||
|
||||
async def fetch(self, ctx):
|
||||
result = subprocess.run(['fastfetch', '--pipe', '--logo', 'none'], capture_output=True, text=True)
|
||||
clean = self.strip_ansi(result.stdout)
|
||||
@commands.command(name="fetch")
|
||||
async def fetch_cmd(self, ctx):
|
||||
"""Show system info via fastfetch."""
|
||||
out = await self._run_command("fastfetch", "--pipe", "--logo", "none")
|
||||
if not out:
|
||||
return await ctx.reply("fastfetch not available")
|
||||
clean = self._strip_ansi(out)
|
||||
await ctx.reply(f'```\n{clean}\n```')
|
||||
|
||||
@commands.command()
|
||||
async def uptime(self, ctx):
|
||||
result = subprocess.run(['uptime', '-p'], capture_output=True, text=True)
|
||||
await ctx.reply(f'⏱️ {result.stdout.strip()}')
|
||||
out = await self._run_command("uptime", "-p")
|
||||
await ctx.reply(f'⏱️ {out}' if out else "uptime not available")
|
||||
|
||||
@commands.command()
|
||||
async def temps(self, ctx):
|
||||
result = subprocess.run(['sensors'], capture_output=True, text=True)
|
||||
await ctx.reply(f'```\n{result.stdout}\n```')
|
||||
out = await self._run_command("sensors")
|
||||
await ctx.reply(f'```\n{out}\n```' if out else "sensors not available")
|
||||
|
||||
@commands.command()
|
||||
async def gpu(self, ctx):
|
||||
result = subprocess.run(['envycontrol', '--query'], capture_output=True, text=True)
|
||||
await ctx.reply(f'I am on {result.stdout.strip()} mode esef!')
|
||||
out = await self._run_command("envycontrol", "--query")
|
||||
await ctx.reply(f'I am on {out} mode esef!' if out else "envycontrol not available")
|
||||
|
||||
@commands.command()
|
||||
async def top(self, ctx):
|
||||
result = subprocess.run(['ps', 'aux', '--sort=-%cpu'], capture_output=True, text=True)
|
||||
lines = result.stdout.splitlines()
|
||||
top5 = '\n'.join(lines[:6]) # header + 5 processes
|
||||
out = await self._run_command("ps", "aux", "--sort=-%cpu")
|
||||
if not out:
|
||||
return await ctx.reply("ps not available")
|
||||
lines = out.splitlines()
|
||||
top5 = '\n'.join(lines[:6])
|
||||
await ctx.reply(f'```\n{top5}\n```')
|
||||
|
||||
@commands.command()
|
||||
@@ -76,7 +101,7 @@ class SysInfo(commands.Cog):
|
||||
@commands.command()
|
||||
async def processes(self, ctx):
|
||||
processes = psutil.pids()
|
||||
await ctx.reply(f'Processes: {len(processes)} running processes ')
|
||||
await ctx.reply(f'Processes: {len(processes)} running processes')
|
||||
|
||||
@commands.command()
|
||||
async def stats(self, ctx):
|
||||
@@ -86,10 +111,6 @@ class SysInfo(commands.Cog):
|
||||
reply = f'CPU: {cpu}% | RAM: {ram}% | Disk: {disk}%'
|
||||
await ctx.reply(reply)
|
||||
|
||||
#this command fetches the current player count for Strinova from the Steam API
|
||||
#it's a game i play and want to show off to my friends, not an actual sysinfo command##
|
||||
#i know this is a bit of a weird place for it but i dont want to make a whole new cog just for one command
|
||||
#holy shit vscode autocomplete knew exactly what i was gonna say wtf;?
|
||||
@commands.command()
|
||||
async def strinova(self, ctx):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import aiohttp
|
||||
@@ -101,7 +100,7 @@ class SysInfoSync:
|
||||
"netSent": {"stringValue": _fmt_bytes(net.bytes_sent)},
|
||||
"netRecv": {"stringValue": _fmt_bytes(net.bytes_recv)},
|
||||
"processes": {"integerValue": len(psutil.pids())},
|
||||
"fetch": {"stringValue": self._get_fastfetch()},
|
||||
"fetch": {"stringValue": await self._get_fastfetch()},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,14 +110,16 @@ class SysInfoSync:
|
||||
log.debug("Firestore PATCH %d: %s", resp.status, body[:200])
|
||||
|
||||
@staticmethod
|
||||
def _get_fastfetch() -> str:
|
||||
async def _get_fastfetch() -> str:
|
||||
"""Run fastfetch --pipe --logo none, strip ANSI, return first 15 lines."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["fastfetch", "--pipe", "--logo", "none"],
|
||||
capture_output=True, text=True, timeout=5,
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"fastfetch", "--pipe", "--logo", "none",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.DEVNULL,
|
||||
)
|
||||
clean = re.sub(r"\x1b\[[0-9;]*[a-zA-Z]|\[[0-9]+[A-Z]", "", result.stdout)
|
||||
stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=5)
|
||||
clean = re.sub(r"\x1b\[[0-9;]*[a-zA-Z]|\[[0-9]+[A-Z]", "", stdout.decode())
|
||||
lines = [l for l in clean.strip().splitlines() if l.strip()]
|
||||
return "\n".join(lines[:15])
|
||||
except Exception:
|
||||
|
||||
Reference in new issue
Block a user