Migrate admin/mute, change to use built-in timeout functionality, ref #91

This commit is contained in:
Zeva Rose 2022-02-02 19:46:34 -07:00
parent a10d297e4e
commit 97c83aa370

View file

@ -1,48 +1,56 @@
"""J.A.R.V.I.S. MuteCog.""" """J.A.R.V.I.S. MuteCog."""
from discord import Member from datetime import datetime
from discord.ext import commands
from discord.utils import get from dis_snek import InteractionContext, Permissions, Scale, Snek
from discord_slash import SlashContext, cog_ext from dis_snek.models.discord.embed import EmbedField
from discord_slash.utils.manage_commands import create_option from dis_snek.models.discord.user import Member
from dis_snek.models.snek.application_commands import (
OptionTypes,
SlashCommandChoice,
slash_command,
slash_option,
)
from jarvis.db.models import Mute, Setting
from jarvis.utils import build_embed from jarvis.utils import build_embed
from jarvis.utils.field import Field
from jarvis.utils.permissions import admin_or_permissions from jarvis.utils.permissions import admin_or_permissions
class MuteCog(commands.Cog): class MuteCog(Scale):
"""J.A.R.V.I.S. MuteCog.""" """J.A.R.V.I.S. MuteCog."""
def __init__(self, bot: commands.Bot): def __init__(self, bot: Snek):
self.bot = bot self.bot = bot
@cog_ext.cog_slash( @slash_command(name="mute", description="Mute a user")
name="mute", @slash_option(name="user", description="User to mute", option_type=OptionTypes.USER, required=True)
description="Mute a user", @slash_option(
options=[ name="reason",
create_option( description="Reason for mute",
name="user", option_type=OptionTypes.STRING,
description="User to mute", required=True,
option_type=6, )
required=True, @slash_option(
), name="time",
create_option( description="Duration of mute, default 1",
name="reason", option_type=OptionTypes.INTEGER,
description="Reason for mute", required=False,
option_type=3, )
required=True, @slash_option(
), name="scale",
create_option( description="Time scale, default Hour(s)",
name="duration", option_type=OptionTypes.INTEGER,
description="Duration of mute in minutes, default 30", required=False,
option_type=4, choices=[
required=False, SlashCommandChoice(name="Minute(s)", value=1),
), SlashCommandChoice(name="Hour(s)", value=60),
SlashCommandChoice(name="Day(s)", value=3600),
SlashCommandChoice(name="Week(s)", value=604800),
], ],
) )
@admin_or_permissions(mute_members=True) @admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS)
async def _mute(self, ctx: SlashContext, user: Member, reason: str, duration: int = 30) -> None: async def _timeout(
self, ctx: InteractionContext, user: Member, reason: str, time: int = 1, scale: int = 60
) -> None:
if user == ctx.author: if user == ctx.author:
await ctx.send("You cannot mute yourself.", hidden=True) await ctx.send("You cannot mute yourself.", hidden=True)
return return
@ -52,81 +60,45 @@ class MuteCog(commands.Cog):
if len(reason) > 100: if len(reason) > 100:
await ctx.send("Reason must be < 100 characters", hidden=True) await ctx.send("Reason must be < 100 characters", hidden=True)
return return
mute_setting = Setting.objects(guild=ctx.guild.id, setting="mute").first()
if not mute_setting: # Max 4 weeks (2419200 seconds) per API
await ctx.send( duration = time * scale
"Please configure a mute role with /settings mute <role> first", if duration > 2419200:
hidden=True, await ctx.send("Mute must be less than 4 weeks (2419200 seconds)", hidden=True)
)
return return
role = get(ctx.guild.roles, id=mute_setting.value)
if role in user.roles: await user.timeout(communication_disabled_until=duration, reason=reason)
await ctx.send("User already muted", hidden=True)
return
await user.add_roles(role, reason=reason)
if duration < 0 or duration > 300:
duration = -1
_ = Mute(
user=user.id,
reason=reason,
admin=ctx.author.id,
guild=ctx.guild.id,
duration=duration,
active=True if duration >= 0 else False,
).save()
embed = build_embed( embed = build_embed(
title="User Muted", title="User Muted",
description=f"{user.mention} has been muted", description=f"{user.mention} has been muted",
fields=[Field(name="Reason", value=reason)], fields=[EmbedField(name="Reason", value=reason)],
) )
embed.set_author( embed.set_author(
name=user.nick if user.nick else user.name, name=user.display_name,
icon_url=user.avatar_url, icon_url=user.avatar_url,
) )
embed.set_thumbnail(url=user.avatar_url) embed.set_thumbnail(url=user.avatar_url)
embed.set_footer(text=f"{user.name}#{user.discriminator} | {user.id}") embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}")
await ctx.send(embed=embed) await ctx.send(embed=embed)
@cog_ext.cog_slash( @slash_command(name="unmute", description="Unmute a user")
name="unmute", @slash_option(name="user", description="User to unmute", option_type=OptionTypes.USER, required=True)
description="Unmute a user", @admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS)
options=[ async def _unmute(self, ctx: InteractionContext, user: Member) -> None:
create_option( if not user.communication_disabled_until or user.communication_disabled_until < datetime.now():
name="user", await ctx.send("User is not muted", hidden=True)
description="User to unmute",
option_type=6,
required=True,
)
],
)
@admin_or_permissions(mute_members=True)
async def _unmute(self, ctx: SlashContext, user: Member) -> None:
mute_setting = Setting.objects(guild=ctx.guild.id, setting="mute").first()
if not mute_setting:
await ctx.send(
"Please configure a mute role with /settings mute <role> first.",
hidden=True,
)
return return
role = get(ctx.guild.roles, id=mute_setting.value)
if role in user.roles:
await user.remove_roles(role, reason="Unmute")
else:
await ctx.send("User is not muted.", hidden=True)
return
_ = Mute.objects(guild=ctx.guild.id, user=user.id).update(set__active=False)
embed = build_embed( embed = build_embed(
title="User Unmuted", title="User Unmuted",
description=f"{user.mention} has been unmuted", description=f"{user.mention} has been unmuted",
fields=[], fields=[],
) )
embed.set_author( embed.set_author(
name=user.nick if user.nick else user.name, name=user.display_name,
icon_url=user.avatar_url, icon_url=user.avatar_url,
) )
embed.set_thumbnail(url=user.avatar_url) embed.set_thumbnail(url=user.avatar_url)
embed.set_footer(text=f"{user.name}#{user.discriminator} | {user.id}") embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}")
await ctx.send(embed=embed) await ctx.send(embed=embed)