jarvis-bot/jarvis/cogs/admin/warning.py

156 lines
5.8 KiB
Python

"""J.A.R.V.I.S. WarningCog."""
from dis_snek import InteractionContext, Permissions
from dis_snek.client.utils.misc_utils import get_all
from dis_snek.ext.paginators import Paginator
from dis_snek.models.discord.embed import EmbedField
from dis_snek.models.discord.user import User
from dis_snek.models.snek.application_commands import (
OptionTypes,
SlashCommandChoice,
slash_command,
slash_option,
)
from dis_snek.models.snek.command import check
from jarvis_core.db.models import Warning
from jarvis.utils import build_embed
from jarvis.utils.cogs import ModcaseCog
from jarvis.utils.embeds import warning_embed
from jarvis.utils.permissions import admin_or_permissions
class WarningCog(ModcaseCog):
"""J.A.R.V.I.S. WarningCog."""
@slash_command(name="warn", description="Warn a user")
@slash_option(name="user", description="User to warn", opt_type=OptionTypes.USER, required=True)
@slash_option(
name="reason",
description="Reason for warning",
opt_type=OptionTypes.STRING,
required=True,
)
@slash_option(
name="duration",
description="Duration of warning in hours, default 24",
opt_type=OptionTypes.INTEGER,
required=False,
)
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _warn(
self, ctx: InteractionContext, user: User, reason: str, duration: int = 24
) -> None:
if len(reason) > 100:
await ctx.send("Reason must be < 100 characters", ephemeral=True)
return
if duration <= 0:
await ctx.send("Duration must be > 0", ephemeral=True)
return
elif duration >= 120:
await ctx.send("Duration must be < 5 days", ephemeral=True)
return
await ctx.defer()
await Warning(
user=user.id,
reason=reason,
admin=ctx.author.id,
guild=ctx.guild.id,
duration=duration,
active=True,
).commit()
embed = warning_embed(user, reason)
await ctx.send(embed=embed)
@slash_command(name="warnings", description="Get count of user warnings")
@slash_option(name="user", description="User to view", opt_type=OptionTypes.USER, required=True)
@slash_option(
name="active",
description="View active only",
opt_type=OptionTypes.INTEGER,
required=False,
choices=[
SlashCommandChoice(name="Yes", value=1),
SlashCommandChoice(name="No", value=0),
],
)
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _warnings(self, ctx: InteractionContext, user: User, active: bool = 1) -> None:
active = bool(active)
warnings = (
await Warning.find(
user=user.id,
guild=ctx.guild.id,
)
.sort("created_at", -1)
.to_list(None)
)
active_warns = get_all(warnings, active=True)
pages = []
if active:
if len(active_warns) == 0:
embed = build_embed(
title="Warnings",
description=f"{warnings.count()} total | 0 currently active",
fields=[],
)
embed.set_author(name=user.username, icon_url=user.display_avatar.url)
embed.set_thumbnail(url=ctx.guild.icon.url)
pages.append(embed)
else:
fields = []
for warn in active_warns:
admin = await ctx.guild.get_member(warn.admin)
admin_name = "||`[redacted]`||"
if admin:
admin_name = f"{admin.username}#{admin.discriminator}"
fields.append(
EmbedField(
name=warn.created_at.strftime("%Y-%m-%d %H:%M:%S UTC"),
value=f"{warn.reason}\nAdmin: {admin_name}\n\u200b",
inline=False,
)
)
for i in range(0, len(fields), 5):
embed = build_embed(
title="Warnings",
description=(
f"{len(warnings)} total | {len(active_warns)} currently active"
),
fields=fields[i : i + 5],
)
embed.set_author(
name=user.username + "#" + user.discriminator,
icon_url=user.display_avatar.url,
)
embed.set_thumbnail(url=ctx.guild.icon.url)
embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}")
pages.append(embed)
else:
fields = []
for warn in warnings:
title = "[A] " if warn.active else "[I] "
title += warn.created_at.strftime("%Y-%m-%d %H:%M:%S UTC")
fields.append(
EmbedField(
name=title,
value=warn.reason + "\n\u200b",
inline=False,
)
)
for i in range(0, len(fields), 5):
embed = build_embed(
title="Warnings",
description=(f"{len(warnings)} total | {len(active_warns)} currently active"),
fields=fields[i : i + 5],
)
embed.set_author(
name=user.username + "#" + user.discriminator, icon_url=user.display_avatar.url
)
embed.set_thumbnail(url=ctx.guild.icon.url)
pages.append(embed)
paginator = Paginator(bot=self.bot, *pages, timeout=300)
await paginator.send(ctx)