Made it so stats communicates with the website and inf search will say no infractions if there a no infractions

This commit is contained in:
Lilac-Rose
2025-10-27 19:02:18 +01:00
parent c4867bec55
commit f0fc33050e
2 changed files with 117 additions and 6 deletions

View File

@@ -4,14 +4,19 @@ from discord import app_commands
from datetime import datetime, timezone
import sqlite3
import os
import aiohttp
from aiohttp import web
import json
import asyncio
import aiofiles
BASE_DIR = os.path.dirname(__file__)
DB_PATH = os.path.join(BASE_DIR, "stats.db")
class Stats(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.guild_id = 876772600704020530 # Your guild ID
# Bot start time
if not hasattr(self.bot, "start_time"):
@@ -19,6 +24,13 @@ class Stats(commands.Cog):
# Initialize the database
self.init_db()
# Stats file path (same directory as stats.py)
self.stats_file = os.path.join(BASE_DIR, "bot_stats.json")
# Start background tasks
self.bot.loop.create_task(self.update_stats_file())
self.bot.loop.create_task(self.start_mini_api())
# -----------------------------
# Database methods
@@ -51,15 +63,109 @@ class Stats(commands.Cog):
return total
# -----------------------------
# Prefix command listener
# Stats file management
# -----------------------------
async def cleanup_old_stats_files(self):
"""Remove any old stats files to prevent accumulation"""
try:
stats_dir = BASE_DIR
for filename in os.listdir(stats_dir):
if filename.startswith("bot_stats") and filename.endswith(".json"):
file_path = os.path.join(stats_dir, filename)
# Keep only the current stats file
if file_path != self.stats_file:
os.remove(file_path)
print(f"Removed old stats file: {filename}")
except Exception as e:
print(f"Error cleaning up old stats files: {e}")
async def update_stats_file(self):
"""Update stats JSON file every 30 seconds"""
await self.bot.wait_until_ready()
# Clean up old files on startup
await self.cleanup_old_stats_files()
while not self.bot.is_closed():
try:
stats = await self.gather_stats()
async with aiofiles.open(self.stats_file, 'w') as f:
await f.write(json.dumps(stats, indent=2, default=str))
print(f"Updated stats file at {datetime.now()}")
except Exception as e:
print(f"Error updating stats file: {e}")
await asyncio.sleep(30) # Update every 30 seconds
async def gather_stats(self):
"""Gather real-time statistics"""
guild = self.bot.get_guild(self.guild_id)
if not guild:
return {'error': 'Guild not found', 'guild_id': self.guild_id}
# Calculate uptime
uptime = datetime.now(timezone.utc) - self.bot.start_time
hours, remainder = divmod(int(uptime.total_seconds()), 3600)
minutes, seconds = divmod(remainder, 60)
# Count channels
text_channels = len([c for c in guild.channels if isinstance(c, discord.TextChannel)])
voice_channels = len([c for c in guild.channels if isinstance(c, discord.VoiceChannel)])
categories = len([c for c in guild.channels if isinstance(c, discord.CategoryChannel)])
return {
'server': {
'memberCount': guild.member_count,
'createdDate': guild.created_at.strftime('%b %d, %Y'),
'textChannels': text_channels,
'voiceChannels': voice_channels,
'categories': categories,
'boostLevel': guild.premium_tier,
'boostCount': guild.premium_subscription_count,
'iconUrl': str(guild.icon.url) if guild.icon else None,
'bannerUrl': str(guild.banner.url) if guild.banner else None,
'guildName': guild.name
},
'bot': {
'uptime': f"{hours}h {minutes}m {seconds}s",
'totalCommands': self.get_usage(),
'serverCount': len(self.bot.guilds),
'botUsers': len(self.bot.users),
'latency': round(self.bot.latency * 1000),
'developer': 'Lilac Aria Rose',
'lastUpdated': datetime.now(timezone.utc).isoformat()
}
}
# -----------------------------
# Mini API Server
# -----------------------------
async def start_mini_api(self):
"""Start a simple HTTP server for real-time stats"""
await self.bot.wait_until_ready()
app = web.Application()
async def handle_stats(request):
stats = await self.gather_stats()
return web.json_response(stats)
app.router.add_get('/stats', handle_stats)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, 'localhost', 8765)
await site.start()
print("Bot stats API running on port 8765")
# -----------------------------
# Discord event listeners
# -----------------------------
@commands.Cog.listener()
async def on_command(self, ctx):
self.increment_usage()
# -----------------------------
# Slash command listener
# -----------------------------
@commands.Cog.listener()
async def on_interaction(self, interaction: discord.Interaction):
# Only count application commands (slash commands)
@@ -67,7 +173,7 @@ class Stats(commands.Cog):
self.increment_usage()
# -----------------------------
# Slash command
# Discord slash command
# -----------------------------
@app_commands.command(name="stats", description="Shows server and bot statistics")
async def stats(self, interaction: discord.Interaction):

View File

@@ -33,6 +33,11 @@ class InfractionCommand(ModerationBase):
await ctx.send(f"Database error: {e}")
return
if not results:
await ctx.send("This user has no infractions.")
return
elif action == "list":
try:
self.c.execute("""