Work on context menu muting

This commit is contained in:
Zeva Rose 2022-03-29 22:12:05 -06:00
parent f0502d65db
commit 2b11fea0cb
2 changed files with 100 additions and 26 deletions

View file

@ -16,7 +16,6 @@ except Exception:
__version__ = "0.0.0"
jconfig = JarvisConfig.from_yaml()
logger = get_logger("jarvis")
logger.setLevel(jconfig.log_level)
file_handler = logging.FileHandler(filename="jarvis.log", encoding="UTF-8", mode="w")
@ -28,8 +27,7 @@ logger.addHandler(file_handler)
intents = Intents.DEFAULT | Intents.MESSAGES | Intents.GUILD_MEMBERS | Intents.GUILD_MESSAGES
restart_ctx = None
jarvis = Jarvis(intents=intents, default_prefix="!", sync_interactions=jconfig.sync)
jarvis = Jarvis(intents=intents, sync_interactions=jconfig.sync)
async def run() -> None:

View file

@ -1,13 +1,19 @@
"""J.A.R.V.I.S. MuteCog."""
import asyncio
import logging
from datetime import datetime, timedelta, timezone
from dateparser import parse
from dateparser_data.settings import default_parsers
from dis_snek import InteractionContext, Permissions, Snake
from dis_snek.models.discord.embed import EmbedField
from dis_snek.models.discord.modal import InputText, Modal, TextStyles
from dis_snek.models.discord.user import Member
from dis_snek.models.snek.application_commands import (
CommandTypes,
OptionTypes,
SlashCommandChoice,
context_menu,
slash_command,
slash_option,
)
@ -26,6 +32,96 @@ class MuteCog(ModcaseCog):
super().__init__(bot)
self.logger = logging.getLogger(__name__)
async def _apply_timeout(
self, ctx: InteractionContext, user: Member, reason: str, until: datetime
) -> None:
await user.timeout(communication_disabled_until=until, reason=reason)
duration = int((until - datetime.now(tz=timezone.utc)).seconds / 60)
await Mute(
user=user.id,
reason=reason,
admin=ctx.author.id,
guild=ctx.guild.id,
duration=duration,
active=True,
).commit()
ts = int(until.timestamp())
embed = build_embed(
title="User Muted",
description=f"{user.mention} has been muted",
fields=[
EmbedField(name="Reason", value=reason),
EmbedField(name="Until", value=f"<t:{ts}:F> <t:{ts}:R>"),
],
)
embed.set_author(name=user.display_name, icon_url=user.display_avatar.url)
embed.set_thumbnail(url=user.display_avatar.url)
embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}")
return embed
@context_menu(name="Mute User", context_type=CommandTypes.USER)
@check(
admin_or_permissions(
Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS
)
)
async def _timeout_cm(self, ctx: InteractionContext) -> None:
modal = Modal(
title=f"Muting {ctx.target.mention}",
components=[
InputText(
label="Reason?",
placeholder="Spamming, harrassment, etc",
style=TextStyles.SHORT,
custom_id="reason",
max_length=100,
),
InputText(
label="Duration",
placeholder="1h 30m | in 5 minutes | in 4 weeks",
style=TextStyles.SHORT,
custom_id="until",
max_length=100,
),
],
)
await ctx.send_modal(modal)
try:
response = await self.bot.wait_for_modal(modal, author=ctx.author.id, timeout=60 * 5)
reason = response.responses.get("reason")
until = response.responses.get("until")
except asyncio.TimeoutError:
return
base_settings = {
"PREFER_DATES_FROM": "future",
"TIMEZONE": "UTC",
"RETURN_AS_TIMEZONE_AWARE": True,
}
rt_settings = base_settings.copy()
rt_settings["PARSERS"] = [
x for x in default_parsers if x not in ["absolute-time", "timestamp"]
]
rt_until = parse(until, settings=rt_settings)
at_settings = base_settings.copy()
at_settings["PARSERS"] = [x for x in default_parsers if x != "relative-time"]
at_until = parse(until, settings=at_settings)
if rt_until:
until = rt_until
elif at_until:
until = at_until
else:
self.logger.debug(f"Failed to parse delay: {until}")
await response.send(
f"`{until}` is not a parsable date, please try again", ephemeral=True
)
return
embed = await self._apply_timeout(ctx, ctx.target, reason, until)
await response.send(embed=embed)
@slash_command(name="mute", description="Mute a user")
@slash_option(name="user", description="User to mute", opt_type=OptionTypes.USER, required=True)
@slash_option(
@ -77,29 +173,7 @@ class MuteCog(ModcaseCog):
return
until = datetime.now(tz=timezone.utc) + timedelta(minutes=duration)
await user.timeout(communication_disabled_until=until, reason=reason)
m = Mute(
user=user.id,
reason=reason,
admin=ctx.author.id,
guild=ctx.guild.id,
duration=duration,
active=True,
)
await m.commit()
ts = int(until.timestamp())
embed = build_embed(
title="User Muted",
description=f"{user.mention} has been muted",
fields=[
EmbedField(name="Reason", value=reason),
EmbedField(name="Until", value=f"<t:{ts}:F> <t:{ts}:R>"),
],
)
embed.set_author(name=user.display_name, icon_url=user.display_avatar.url)
embed.set_thumbnail(url=user.display_avatar.url)
embed.set_footer(text=f"{user.username}#{user.discriminator} | {user.id}")
embed = await self._apply_timeout(ctx, user, reason, until)
await ctx.send(embed=embed)
@slash_command(name="unmute", description="Unmute a user")
@ -120,6 +194,8 @@ class MuteCog(ModcaseCog):
await ctx.send("User is not muted", ephemeral=True)
return
await user.timeout(communication_disabled_until=0)
embed = build_embed(
title="User Unmuted",
description=f"{user.mention} has been unmuted",