mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-03 02:23:13 +00:00
164 lines
5.3 KiB
Python
164 lines
5.3 KiB
Python
import asyncio
|
|
import datetime
|
|
from typing import cast
|
|
|
|
import discord
|
|
from discord.ext import commands
|
|
|
|
import lib.format
|
|
from lib.actionable import async_actionable
|
|
from lib.case_handler import create_case
|
|
from lib.client import Luminara
|
|
from lib.const import CONST
|
|
from lib.exceptions import LumiException
|
|
from ui.embeds import Builder
|
|
|
|
|
|
class Timeout(commands.Cog):
|
|
def __init__(self, bot: Luminara):
|
|
self.bot = bot
|
|
self.timeout.usage = lib.format.generate_usage(self.timeout)
|
|
self.untimeout.usage = lib.format.generate_usage(self.untimeout)
|
|
|
|
@commands.hybrid_command(name="timeout", aliases=["t", "to"])
|
|
@commands.has_permissions(moderate_members=True)
|
|
@commands.bot_has_permissions(moderate_members=True)
|
|
@commands.guild_only()
|
|
async def timeout(
|
|
self,
|
|
ctx: commands.Context[Luminara],
|
|
target: discord.Member,
|
|
duration: str,
|
|
reason: str | None = None,
|
|
) -> None:
|
|
"""
|
|
Timeout a user in the guild.
|
|
|
|
Parameters
|
|
----------
|
|
target: discord.Member
|
|
The member to timeout.
|
|
duration: str
|
|
The duration of the timeout. Can be in the format of "1d2h3m4s".
|
|
reason: str | None
|
|
The reason for the timeout. Defaults to None.
|
|
"""
|
|
assert ctx.guild
|
|
assert ctx.author
|
|
assert ctx.bot.user
|
|
|
|
# Parse duration to minutes and validate
|
|
duration_int = lib.format.format_duration_to_seconds(duration)
|
|
duration_str = lib.format.format_seconds_to_duration_string(duration_int)
|
|
|
|
# if longer than 27 days, return LumiException
|
|
if duration_int > 2332800:
|
|
raise LumiException(CONST.STRINGS["mod_timeout_too_long"])
|
|
|
|
bot_member = await commands.MemberConverter().convert(ctx, str(ctx.bot.user.id))
|
|
await async_actionable(target, cast(discord.Member, ctx.author), bot_member)
|
|
|
|
output_reason = reason or CONST.STRINGS["mod_no_reason"]
|
|
|
|
await target.timeout(
|
|
datetime.timedelta(seconds=duration_int),
|
|
reason=CONST.STRINGS["mod_reason"].format(
|
|
ctx.author.name,
|
|
lib.format.shorten(output_reason, 200),
|
|
),
|
|
)
|
|
|
|
dm_task = target.send(
|
|
embed=Builder.create_embed(
|
|
Builder.WARNING,
|
|
user_name=target.name,
|
|
author_text=CONST.STRINGS["mod_timed_out_author"],
|
|
description=CONST.STRINGS["mod_timeout_dm"].format(
|
|
target.name,
|
|
ctx.guild.name,
|
|
duration_str,
|
|
output_reason,
|
|
),
|
|
hide_name_in_description=True,
|
|
),
|
|
)
|
|
|
|
respond_task = ctx.send(
|
|
embed=Builder.create_embed(
|
|
Builder.SUCCESS,
|
|
user_name=target.name,
|
|
author_text=CONST.STRINGS["mod_timed_out_author"],
|
|
description=CONST.STRINGS["mod_timed_out_user"].format(target.name),
|
|
),
|
|
)
|
|
|
|
create_case_task = create_case(ctx, cast(discord.User, target), "TIMEOUT", reason, duration_int)
|
|
|
|
await asyncio.gather(
|
|
dm_task,
|
|
respond_task,
|
|
create_case_task,
|
|
return_exceptions=True,
|
|
)
|
|
|
|
@commands.hybrid_command(name="untimeout", aliases=["ut", "rto"])
|
|
@commands.has_permissions(moderate_members=True)
|
|
@commands.bot_has_permissions(moderate_members=True)
|
|
@commands.guild_only()
|
|
async def untimeout(
|
|
self,
|
|
ctx: commands.Context[Luminara],
|
|
target: discord.Member,
|
|
reason: str | None = None,
|
|
) -> None:
|
|
"""
|
|
Untimeout a user in the guild.
|
|
|
|
Parameters
|
|
----------
|
|
target: discord.Member
|
|
The member to untimeout.
|
|
reason: str | None
|
|
The reason for the untimeout. Defaults to None.
|
|
"""
|
|
assert ctx.guild
|
|
assert ctx.author
|
|
assert ctx.bot.user
|
|
|
|
output_reason = reason or CONST.STRINGS["mod_no_reason"]
|
|
|
|
try:
|
|
await target.timeout(
|
|
None,
|
|
reason=CONST.STRINGS["mod_reason"].format(
|
|
ctx.author.name,
|
|
lib.format.shorten(output_reason, 200),
|
|
),
|
|
)
|
|
|
|
respond_task = ctx.send(
|
|
embed=Builder.create_embed(
|
|
Builder.SUCCESS,
|
|
user_name=ctx.author.name,
|
|
author_text=CONST.STRINGS["mod_untimed_out_author"],
|
|
description=CONST.STRINGS["mod_untimed_out"].format(target.name),
|
|
),
|
|
)
|
|
|
|
target_user = await commands.UserConverter().convert(ctx, str(target.id))
|
|
create_case_task = create_case(ctx, target_user, "UNTIMEOUT", reason)
|
|
await asyncio.gather(respond_task, create_case_task, return_exceptions=True)
|
|
|
|
except discord.HTTPException:
|
|
await ctx.send(
|
|
embed=Builder.create_embed(
|
|
Builder.WARNING,
|
|
user_name=ctx.author.name,
|
|
author_text=CONST.STRINGS["mod_not_timed_out_author"],
|
|
description=CONST.STRINGS["mod_not_timed_out"].format(target.name),
|
|
),
|
|
)
|
|
|
|
|
|
async def setup(bot: Luminara) -> None:
|
|
await bot.add_cog(Timeout(bot))
|