"""J.A.R.V.I.S. MuteCog.""" from datetime import datetime from dis_snek import InteractionContext, Permissions, Scale, Snake from dis_snek.models.discord.embed import EmbedField from dis_snek.models.discord.user import Member from dis_snek.models.snek.application_commands import ( OptionTypes, SlashCommandChoice, slash_command, slash_option, ) from dis_snek.models.snek.command import check from jarvis.db.models import Mute from jarvis.utils import build_embed from jarvis.utils.permissions import admin_or_permissions class MuteCog(Scale): """J.A.R.V.I.S. MuteCog.""" def __init__(self, bot: Snake): self.bot = bot @slash_command(name="mute", description="Mute a user") @slash_option(name="user", description="User to mute", opt_type=OptionTypes.USER, required=True) @slash_option( name="reason", description="Reason for mute", opt_type=OptionTypes.STRING, required=True, ) @slash_option( name="time", description="Duration of mute, default 1", opt_type=OptionTypes.INTEGER, required=False, ) @slash_option( name="scale", description="Time scale, default Hour(s)", opt_type=OptionTypes.INTEGER, required=False, choices=[ SlashCommandChoice(name="Minute(s)", value=1), SlashCommandChoice(name="Hour(s)", value=60), SlashCommandChoice(name="Day(s)", value=3600), SlashCommandChoice(name="Week(s)", value=604800), ], ) @check( admin_or_permissions( Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS ) ) async def _timeout( self, ctx: InteractionContext, user: Member, reason: str, time: int = 1, scale: int = 60 ) -> None: if user == ctx.author: await ctx.send("You cannot mute yourself.", ephemeral=True) return if user == self.bot.user: await ctx.send("I'm afraid I can't let you do that", ephemeral=True) return if len(reason) > 100: await ctx.send("Reason must be < 100 characters", ephemeral=True) return # Max 4 weeks (2419200 seconds) per API duration = time * scale if duration > 2419200: await ctx.send("Mute must be less than 4 weeks (2419200 seconds)", ephemeral=True) return await user.timeout(communication_disabled_until=duration, reason=reason) _ = Mute( user=user.id, reason=reason, admin=ctx.author.id, guild=ctx.guild.id, duration=duration, active=True, ).save() embed = build_embed( title="User Muted", description=f"{user.mention} has been muted", fields=[EmbedField(name="Reason", value=reason)], ) embed.set_author( name=user.display_name, icon_url=user.display_avatar, ) embed.set_thumbnail(url=user.display_avatar) embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}") await ctx.send(embed=embed) @slash_command(name="unmute", description="Unmute a user") @slash_option( name="user", description="User to unmute", opt_type=OptionTypes.USER, required=True ) @check( admin_or_permissions( Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS ) ) async def _unmute(self, ctx: InteractionContext, user: Member) -> None: if ( not user.communication_disabled_until or user.communication_disabled_until < datetime.now() # noqa: W503 ): await ctx.send("User is not muted", ephemeral=True) return embed = build_embed( title="User Unmuted", description=f"{user.mention} has been unmuted", fields=[], ) embed.set_author( name=user.display_name, icon_url=user.display_avatar, ) embed.set_thumbnail(url=user.display_avatar) embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}") await ctx.send(embed=embed) embed.set_author( name=user.display_name, icon_url=user.display_avatar, ) embed.set_thumbnail(url=user.display_avatar) embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}") await ctx.send(embed=embed)