Updated infraction.py to fit the gearbot infraction table and update loader.py so it works with the new moderation command setup

This commit is contained in:
Lilac-Rose
2025-10-04 23:36:20 +02:00
parent 4d2ef6fa82
commit f166022009
4 changed files with 47 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
import discord
from discord.ext import commands
from .loader import ModerationBase
from datetime import datetime
class InfractionCommand(ModerationBase):
@@ -12,25 +13,55 @@ class InfractionCommand(ModerationBase):
if not user_id:
await ctx.send("You must provide a user ID to search.")
return
self.c.execute("""
SELECT id, type, reason, moderator_id, timestamp
SELECT id, user_id, type, reason, moderator_id, timestamp
FROM infractions
WHERE user_id=? AND guild_id=?
ORDER BY timestamp DESC
""", (user_id, ctx.guild.id))
results = self.c.fetchall()
if not results:
await ctx.send("No infractions found.")
await ctx.send("No infractions found for that user.")
return
lines = []
header = f"{'ID':<8} | {'User':<28} | {'Moderator':<28} | {'Timestamp':<19} | {'Type':<10} | Reason"
separator = "-" * len(header)
lines.append(header)
lines.append(separator)
for row in results:
lines.append(f"ID {row['id']}: {row['type']} by {row['moderator_id']} at {row['timestamp']} - Reason: {row['reason']}")
await ctx.send("Infractions:\n" + "\n".join(lines))
# Fetch user and moderator objects
user = await self.bot.fetch_user(row["user_id"])
moderator = await self.bot.fetch_user(row["moderator_id"])
# Format user and mod names
user_tag = f"{user.name}#{user.discriminator}"
mod_tag = f"{moderator.name}#{moderator.discriminator}"
# Shorten if needed for alignment
user_tag = user_tag[:27] + "" if len(user_tag) > 28 else user_tag
mod_tag = mod_tag[:27] + "" if len(mod_tag) > 28 else mod_tag
# Format timestamp
timestamp = row["timestamp"].replace("T", " ")[:19]
# Format reason (truncate if too long)
reason = row["reason"] or "None"
lines.append(f"{row['id']:<8} | {user_tag:<28} | {mod_tag:<28} | {timestamp:<19} | {row['type']:<10} | {reason}")
# Send in code block to preserve formatting
table = "```\n" + "\n".join(lines) + "\n```"
await ctx.send(table)
elif action.lower() == "delete":
if not inf_id:
await ctx.send("You must provide an infraction ID to delete.")
return
self.c.execute("DELETE FROM infractions WHERE id=? AND guild_id=?", (inf_id, ctx.guild.id))
self.conn.commit()
await ctx.send(f"Infraction {inf_id} deleted.")

View File

@@ -10,6 +10,7 @@ ADMIN_ROLE_ID = int(os.getenv("ADMIN_ROLE_ID"))
class ModerationBase(commands.Cog):
"""Base cog for moderation commands with shared DB and utilities"""
def __init__(self, bot: commands.Bot):
self.bot = bot
self.db_path = os.path.join(os.path.dirname(__file__), "moderation.db")
@@ -18,6 +19,10 @@ class ModerationBase(commands.Cog):
self.c = self.conn.cursor()
self.initialize_db()
def cog_unload(self):
"""Ensure database connection closes when the cog unloads."""
self.conn.close()
def initialize_db(self):
self.c.execute("""
CREATE TABLE IF NOT EXISTS infractions (
@@ -32,15 +37,18 @@ class ModerationBase(commands.Cog):
""")
self.conn.commit()
@staticmethod
def is_admin():
async def predicate(ctx):
"""Decorator that checks if the command author has the admin role."""
async def predicate(ctx: commands.Context):
if not any(role.id == ADMIN_ROLE_ID for role in ctx.author.roles):
await ctx.send("You do not have permission.", ephemeral=True)
await ctx.send("You do not have permission to use this command.")
return False
return True
return commands.check(predicate)
async def log_infraction(self, guild_id, user_id, mod_id, type_, reason):
async def log_infraction(self, guild_id: int, user_id: int, mod_id: int, type_: str, reason: str | None):
"""Log an infraction to the database."""
self.c.execute("""
INSERT INTO infractions (user_id, guild_id, type, reason, moderator_id, timestamp)
VALUES (?, ?, ?, ?, ?, ?)
@@ -48,4 +56,4 @@ class ModerationBase(commands.Cog):
self.conn.commit()
async def setup(bot: commands.Bot):
await bot.add_cog(ModerationBase(bot))
await bot.add_cog(ModerationBase(bot))

Binary file not shown.