216 lines
7.4 KiB
Python
216 lines
7.4 KiB
Python
from datetime import datetime, timedelta
|
|
|
|
from ButtonPaginator import Paginator
|
|
from discord import User
|
|
from discord_slash import SlashContext, cog_ext
|
|
from discord_slash.model import ButtonStyle
|
|
from discord_slash.utils.manage_commands import create_choice, create_option
|
|
|
|
from jarvis.db.models import Warning
|
|
from jarvis.utils import build_embed
|
|
from jarvis.utils.cachecog import CacheCog
|
|
from jarvis.utils.field import Field
|
|
from jarvis.utils.permissions import admin_or_permissions
|
|
|
|
|
|
class WarningCog(CacheCog):
|
|
def __init__(self, bot):
|
|
super().__init__(bot)
|
|
|
|
@cog_ext.cog_slash(
|
|
name="warn",
|
|
description="Warn a user",
|
|
options=[
|
|
create_option(
|
|
name="user",
|
|
description="User to warn",
|
|
option_type=6,
|
|
required=True,
|
|
),
|
|
create_option(
|
|
name="reason",
|
|
description="Reason for warning",
|
|
option_type=3,
|
|
required=True,
|
|
),
|
|
create_option(
|
|
name="duration",
|
|
description="Duration of warning in hours, default 24",
|
|
option_type=4,
|
|
required=False,
|
|
),
|
|
],
|
|
)
|
|
@admin_or_permissions(manage_guild=True)
|
|
async def _warn(
|
|
self, ctx: SlashContext, user: User, reason: str, duration: int = 24
|
|
):
|
|
if len(reason) > 100:
|
|
await ctx.send("Reason must be < 100 characters", hidden=True)
|
|
return
|
|
if duration <= 0:
|
|
await ctx.send("Duration must be > 0", hidden=True)
|
|
return
|
|
elif duration >= 120:
|
|
await ctx.send("Duration must be < 5 days", hidden=True)
|
|
return
|
|
await ctx.defer()
|
|
_ = Warning(
|
|
user=user.id,
|
|
reason=reason,
|
|
admin=ctx.author.id,
|
|
guild=ctx.guild.id,
|
|
duration=duration,
|
|
active=True,
|
|
).save()
|
|
fields = [Field("Reason", reason, False)]
|
|
embed = build_embed(
|
|
title="Warning",
|
|
description=f"{user.mention} has been warned",
|
|
fields=fields,
|
|
)
|
|
embed.set_author(
|
|
name=user.nick if user.nick else user.name,
|
|
icon_url=user.avatar_url,
|
|
)
|
|
embed.set_footer(text=f"{user.name}#{user.discriminator} | {user.id}")
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
@cog_ext.cog_slash(
|
|
name="warnings",
|
|
description="Get count of user warnings",
|
|
options=[
|
|
create_option(
|
|
name="user",
|
|
description="User to view",
|
|
option_type=6,
|
|
required=True,
|
|
),
|
|
create_option(
|
|
name="active",
|
|
description="View only active",
|
|
option_type=4,
|
|
required=False,
|
|
choices=[
|
|
create_choice(name="Yes", value=1),
|
|
create_choice(name="No", value=0),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
@admin_or_permissions(manage_guild=True)
|
|
async def _warnings(self, ctx: SlashContext, user: User, active: bool = 1):
|
|
active = bool(active)
|
|
exists = self.check_cache(ctx, user_id=user.id, active=active)
|
|
if exists:
|
|
await ctx.defer(hidden=True)
|
|
await ctx.send(
|
|
"Please use existing interaction: "
|
|
+ f"{exists['paginator']._message.jump_url}",
|
|
hidden=True,
|
|
)
|
|
return
|
|
warnings = Warning.objects(
|
|
user=user.id,
|
|
guild=ctx.guild.id,
|
|
).order_by("-created_at")
|
|
active_warns = Warning.objects(
|
|
user=user.id, guild=ctx.guild.id, active=False
|
|
).order_by("-created_at")
|
|
|
|
pages = []
|
|
if active:
|
|
if active_warns.count() == 0:
|
|
embed = build_embed(
|
|
title="Warnings",
|
|
description=f"{warnings.count()} total | 0 currently active",
|
|
fields=[],
|
|
)
|
|
embed.set_author(name=user.name, icon_url=user.avatar_url)
|
|
embed.set_thumbnail(url=ctx.guild.icon_url)
|
|
pages.append(embed)
|
|
else:
|
|
fields = []
|
|
for warn in active_warns:
|
|
admin = ctx.guild.get_member(warn.admin)
|
|
admin_name = "||`[redacted]`||"
|
|
if admin:
|
|
admin_name = f"{admin.name}#{admin.discriminator}"
|
|
fields.append(
|
|
Field(
|
|
name=warn.created_at.strftime(
|
|
"%Y-%m-%d %H:%M:%S UTC"
|
|
),
|
|
value=f"{warn.reason}\n"
|
|
+ f"Admin: {admin_name}\n"
|
|
+ "\u200b",
|
|
inline=False,
|
|
)
|
|
)
|
|
for i in range(0, len(fields), 5):
|
|
embed = build_embed(
|
|
title="Warnings",
|
|
description=f"{warnings.count()} total | "
|
|
+ f"{active_warns.count()} currently active",
|
|
fields=fields[i : i + 5],
|
|
)
|
|
embed.set_author(
|
|
name=user.name + "#" + user.discriminator,
|
|
icon_url=user.avatar_url,
|
|
)
|
|
embed.set_thumbnail(url=ctx.guild.icon_url)
|
|
embed.set_footer(
|
|
text=f"{user.name}#{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(
|
|
Field(
|
|
name=title,
|
|
value=warn.reason + "\n\u200b",
|
|
inline=False,
|
|
)
|
|
)
|
|
for i in range(0, len(fields), 5):
|
|
embed = build_embed(
|
|
title="Warnings",
|
|
description=f"{warnings.count()} total | "
|
|
+ f"{active_warns.count()} currently active",
|
|
fields=fields[i : i + 5],
|
|
)
|
|
embed.set_author(
|
|
name=user.name + "#" + user.discriminator,
|
|
icon_url=user.avatar_url,
|
|
)
|
|
embed.set_thumbnail(url=ctx.guild.icon_url)
|
|
pages.append(embed)
|
|
|
|
paginator = Paginator(
|
|
bot=self.bot,
|
|
ctx=ctx,
|
|
embeds=pages,
|
|
only=ctx.author,
|
|
timeout=60 * 5, # 5 minute timeout
|
|
disable_after_timeout=True,
|
|
use_extend=len(pages) > 2,
|
|
left_button_style=ButtonStyle.grey,
|
|
right_button_style=ButtonStyle.grey,
|
|
basic_buttons=["◀", "▶"],
|
|
)
|
|
|
|
self.cache[hash(paginator)] = {
|
|
"guild": ctx.guild.id,
|
|
"user": ctx.author.id,
|
|
"timeout": datetime.utcnow() + timedelta(minutes=5),
|
|
"command": ctx.subcommand_name,
|
|
"user_id": user.id,
|
|
"active": active,
|
|
"paginator": paginator,
|
|
}
|
|
|
|
await paginator.start()
|