Files
payphone/payphone/cogs/mods/modals.py
T

131 lines
3.9 KiB
Python

from datetime import datetime, timezone
import discord
from discord import errors
from tortoise import transactions
from payphone import bot
from payphone.db import models
from payphone.core import formatting
from payphone.cogs.mods import embeds, views
class BanNotificationModal(discord.ui.Modal):
"""Modal sent to users to appeal their ban."""
def __init__(self, bot: bot.Payphone) -> None:
"""Initializes the modal."""
self.bot = bot
super().__init__(
discord.ui.InputText(
custom_id="ban-notification-appeal:appeal",
label="Appeal",
placeholder="",
max_length=500,
required=True,
style=discord.InputTextStyle.long,
),
title="Ban Appeal",
custom_id="ban-notification-appeal",
timeout=None,
)
@transactions.atomic()
async def callback(self, interaction: discord.Interaction):
ban = await models.Ban.get(notification_message_id=interaction.message.id)
await interaction.response.defer()
ban.appeal = self.children[0].value
ban.status = models.BanStatus.ON_REVIEW
await ban.save()
await interaction.message.edit(
embed=embeds.BanNotificationEmbed(self.bot, ban),
view=views.BanNotificationView(self.bot, ban),
)
class BanUserModal(discord.ui.Modal):
"""Modal sent to ban a user."""
def __init__(
self, bot: bot.Payphone, profile: models.Profile, report_id: int | None = None
) -> None:
"""Initializes the modal.
Args:
bot (bot.Bot): The bot.
report_id (int, optional): The ID of the report, if any.
profile (models.Profile): The profile of the user to ban.
"""
self.bot = bot
self.profile = profile
self.report_id = report_id
super().__init__(
discord.ui.InputText(
style=discord.InputTextStyle.long,
label="Reason",
max_length=500,
required=False,
),
discord.ui.InputText(
label="Duration", placeholder="30d", value="30d", required=False
),
title=f"Ban {profile.name}",
)
@transactions.atomic()
async def callback(self, interaction: discord.Interaction):
await interaction.response.defer()
duration = None
if self.children[1].value:
try:
duration = formatting.parse_timedelta(self.children[1].value)
except ValueError:
await interaction.response.send_message(
f"❌ The ban's duration (`{self.children[1].value}`) is not a valid time. Time must be formatted like `28d 3h 5s`."
)
return
ban = await self.bot.ban(
self.profile.user_id,
duration,
self.children[0].value,
interaction.user.id,
)
try:
notification_message = await (
await self.bot.get_or_fetch_user(self.profile.user_id)
).send(
embed=embeds.BanNotificationEmbed(self.bot, ban),
view=views.BanNotificationView(self.bot, ban),
)
ban.notification_message_id = notification_message.id
await ban.save()
except errors.DiscordException:
pass
message = f"✅ **{self.profile.name}** (User ID: {self.profile.user_id}) was banned by {interaction.user.mention}"
if ban.expires_at is not None:
message += f"{f" for `{formatting.time_to_text(duration)}`" if duration is not None else ""} until <t:{int(ban.expires_at.timestamp())}:F> (<t:{int(ban.expires_at.timestamp())}:R>)"
else:
message += " permanently"
message += "."
await interaction.channel.send(message)