Add modcase list command
This commit is contained in:
parent
3eee7aa2a3
commit
085b2325a7
1 changed files with 172 additions and 0 deletions
172
jarvis/cogs/admin/modcase.py
Normal file
172
jarvis/cogs/admin/modcase.py
Normal file
|
@ -0,0 +1,172 @@
|
|||
"""JARVIS Moderation Case management."""
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from jarvis_core.db import q
|
||||
from jarvis_core.db.models import Modlog, actions
|
||||
from naff import Client, Cog, InteractionContext, Permissions
|
||||
from naff.ext.paginators import Paginator
|
||||
from naff.models.discord.embed import Embed, EmbedField
|
||||
from naff.models.discord.user import Member
|
||||
from naff.models.naff.application_commands import (
|
||||
OptionTypes,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
from naff.models.naff.command import check
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
from jarvis.utils import build_embed
|
||||
from jarvis.utils.permissions import admin_or_permissions
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from naff.models.discord.guild import Guild
|
||||
|
||||
ACTIONS_LOOKUP = {
|
||||
"ban": actions.Ban,
|
||||
"kick": actions.Kick,
|
||||
"mute": actions.Mute,
|
||||
"unban": actions.Unban,
|
||||
"warning": actions.Warning,
|
||||
}
|
||||
|
||||
|
||||
class CaseCog(Cog):
|
||||
"""JARVIS CaseCog."""
|
||||
|
||||
async def get_embed(self, mod_case: Modlog, guild: "Guild") -> Embed:
|
||||
"""
|
||||
Get Moderation case embed.
|
||||
|
||||
Args:
|
||||
mod_case: Moderation case
|
||||
guild: Originating guild
|
||||
"""
|
||||
action_table = Table(title="Actions", show_header=False)
|
||||
action_table.add_column(header="Type", justify="left", style="orange4", no_wrap=True)
|
||||
action_table.add_column(
|
||||
header="Admin", justify="left", style="light_sky_blue1", no_wrap=True
|
||||
)
|
||||
action_table.add_column(header="Reason", justify="left", style="white")
|
||||
|
||||
note_table = Table(title="Notes")
|
||||
note_table.add_column(header="Admin", justify="left", style="light_sky_blue1", no_wrap=True)
|
||||
note_table.add_column(header="Content", justify="left", style="white")
|
||||
|
||||
console = Console()
|
||||
|
||||
action_output = ""
|
||||
for action in mod_case.actions:
|
||||
parent_action = await ACTIONS_LOOKUP[action.action_type].find_one(q(id=action.parent))
|
||||
if not parent_action:
|
||||
action.orphaned = True
|
||||
action_table.add_row(action.action_type.title(), "N/A", "N/A")
|
||||
else:
|
||||
admin = await self.bot.fetch_user(parent_action.admin)
|
||||
admin_text = "Deleted User"
|
||||
if admin:
|
||||
admin_text = f"{admin.username}#{admin.discriminator}"
|
||||
action_table.add_row(action.action_type.title(), admin_text, parent_action.reason)
|
||||
with console.capture() as cap:
|
||||
console.print(action_table)
|
||||
|
||||
tmp_output = cap.get()
|
||||
if len(tmp_output) >= 1000:
|
||||
break
|
||||
|
||||
action_output = tmp_output
|
||||
|
||||
note_output = ""
|
||||
for note in sorted(mod_case.notes, lambda x: x.created_at):
|
||||
admin = await self.bot.fetch_user(note.admin)
|
||||
admin_text = "N/A"
|
||||
if not admin:
|
||||
admin_text = f"{admin.username}#{admin.discriminator}"
|
||||
note_table.add_row(admin_text, note.content)
|
||||
|
||||
with console.capture() as cap:
|
||||
console.print(note_table)
|
||||
|
||||
tmp_output = cap.get()
|
||||
if len(tmp_output) >= 1000:
|
||||
break
|
||||
|
||||
note_output = tmp_output
|
||||
|
||||
status = "Open" if mod_case.open else "Closed"
|
||||
|
||||
user = await self.bot.fetch_user(mod_case.user)
|
||||
username = "Deleted User"
|
||||
user_text = "Deleted User"
|
||||
if user:
|
||||
username = f"{user.username}#{user.discriminator}"
|
||||
user_text = user.mention
|
||||
|
||||
admin = await self.bot.fetch_user(mod_case.admin)
|
||||
admin_text = "[N/A]"
|
||||
if admin:
|
||||
admin_text = admin.mention
|
||||
|
||||
ts = int(mod_case.created_at.timestamp())
|
||||
|
||||
action_output = f"```ansi\n{action_output}\n```"
|
||||
note_output = f"```ansi\n{note_output}\n```"
|
||||
|
||||
fields = (
|
||||
EmbedField(name="Opened By", value=admin_text),
|
||||
EmbedField(name="Opened At", value=f"<t:{ts}:F>"),
|
||||
EmbedField(name="Actions", value=action_output),
|
||||
EmbedField(name="Notes", value=note_output),
|
||||
)
|
||||
|
||||
embed = build_embed(
|
||||
title="Moderation Case", description=f"{status} case against {user_text}", fields=fields
|
||||
)
|
||||
icon_url = None
|
||||
if user:
|
||||
icon_url = user.avatar.url
|
||||
|
||||
embed.set_author(name=username, icon_url=icon_url)
|
||||
embed.set_footer(text=str(mod_case.user))
|
||||
|
||||
await mod_case.commit()
|
||||
return embed
|
||||
|
||||
cases = SlashCommand(name="cases", description="Manage moderation cases")
|
||||
|
||||
@cases.subcommand(sub_cmd_name="list", sub_cmd_description="List moderation cases")
|
||||
@slash_option(
|
||||
name="user",
|
||||
description="User to filter cases to",
|
||||
opt_type=OptionTypes.USER,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="closed",
|
||||
description="Include closed cases",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _cases_list(
|
||||
self, ctx: InteractionContext, user: Optional[Member] = None, closed: bool = False
|
||||
) -> None:
|
||||
query = q(guild=ctx.guild.id)
|
||||
if not closed:
|
||||
query.update(q(open=True))
|
||||
if user:
|
||||
query.update(q(user=user.id))
|
||||
cases = await Modlog.find(query).sort("created_at", -1).to_list(None)
|
||||
|
||||
if len(cases) == 0:
|
||||
await ctx.send("No cases to view", ephemeral=True)
|
||||
return
|
||||
|
||||
pages = [await self.get_embed(c, ctx.guild) for c in cases]
|
||||
paginator = Paginator.create_from_embeds(self.bot, *pages, timeout=300)
|
||||
await paginator.send(ctx)
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
"""Add CaseCog to JARVIS"""
|
||||
CaseCog(bot)
|
Loading…
Add table
Reference in a new issue