Ruby-Cogs/tickettool/utils.py
2025-04-02 22:57:51 -04:00

270 lines
10 KiB
Python

import discord # isort:skip
import typing # isort:skip
from redbot.core import commands # isort:skip
from redbot.core.i18n import Translator # isort:skip
import re
import yaml
try:
from emoji import EMOJI_DATA # emoji>=2.0.0
except ImportError:
from emoji import UNICODE_EMOJI_ENGLISH as EMOJI_DATA # emoji<2.0.0
_: Translator = Translator("TicketTool", __file__)
class utils:
async def get_overwrites(self, ticket):
config = await ticket.bot.get_cog("TicketTool").get_config(ticket.guild, ticket.profile)
overwrites = {
ticket.owner: discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
send_messages=True,
attach_files=True,
use_application_commands=True,
),
ticket.guild.me: discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
send_messages=True,
attach_files=True,
manage_messages=True,
manage_channels=True,
),
ticket.guild.default_role: discord.PermissionOverwrite(
view_channel=False,
),
}
if ticket.claim is not None:
overwrites[ticket.claim] = discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
send_messages=True,
attach_files=True,
use_application_commands=True,
)
if config["admin_roles"]:
for role in config["admin_roles"]:
overwrites[role] = discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
send_messages=True,
attach_files=True,
manage_messages=True,
use_application_commands=True,
)
if config["support_roles"]:
for role in config["support_roles"]:
overwrites[role] = discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
send_messages=True,
attach_files=True,
use_application_commands=True,
)
if config["view_roles"] is not None:
for role in config["view_roles"]:
overwrites[role] = discord.PermissionOverwrite(
view_channel=True,
read_messages=True,
read_message_history=True,
add_reactions=False,
use_application_commands=False,
)
return overwrites
class Emoji(commands.EmojiConverter):
async def convert(
self, ctx: commands.Context, argument: str
) -> typing.Union[str, discord.Emoji]:
# argument = argument.strip("\N{VARIATION SELECTOR-16}")
if argument in EMOJI_DATA:
return argument
if argument in {
"🇦",
"🇧",
"🇨",
"🇩",
"🇪",
"🇫",
"🇬",
"🇭",
"🇮",
"🇯",
"🇰",
"🇱",
"🇲",
"🇳",
"🇴",
"🇵",
"🇶",
"🇷",
"🇸",
"🇹",
"🇺",
"🇻",
"🇼",
"🇽",
"🇾",
"🇿",
}:
return argument
return await super().convert(ctx, argument=argument)
class EmojiLabelDescriptionValueConverter(commands.Converter):
async def convert(
self, ctx: commands.Context, argument: str
) -> typing.Tuple[str, typing.Union[discord.PartialEmoji, str]]:
arg_split = re.split(r"[;|\-]", argument)
try:
try:
emoji, label, description, value = arg_split
except ValueError:
try:
emoji, label, description = arg_split
value = label
except ValueError:
emoji, label = arg_split
description = None
value = label
except ValueError:
raise commands.BadArgument(
_(
"Emoji Label must be An emoji followed by a label, and optionnaly by a description and a value (for rename ticket channel), separated by either `;`, `,`, `|`, or `-`."
)
)
emoji = await Emoji().convert(ctx, emoji)
label = str(label)
return emoji, label, description, value
class CustomModalConverter(commands.Converter):
async def convert(
self, ctx: commands.Context, argument: str
) -> typing.Dict[str, typing.Union[str, bool, typing.Dict, typing.List]]:
try:
argument_dict = yaml.safe_load(argument)
except yaml.YAMLError:
raise commands.BadArgument(
_(
"Error parsing YAML. Please make sure the format is valid (a YAML validator may help)"
)
)
required_arguments = ["label"]
optional_arguments = [
"style",
"required",
"default",
"placeholder",
"min_length",
"max_length",
]
if len(argument_dict) > 5:
raise commands.BadArgument(_("You can only have 5 text inputs."))
for count, input in enumerate(argument_dict, start=1):
count += 1
for arg in required_arguments:
if arg not in input:
raise commands.BadArgument(
_("The argument `/{count}/{arg}` is required in the YAML.").format(
count=count, arg=arg
)
)
for arg in input:
if arg not in required_arguments + optional_arguments:
raise commands.BadArgument(
_(
"The argument `/{count}/{arg}` is invalid in the YAML. Check the spelling."
).format(count=count, arg=arg)
)
if len(input["label"]) > 45:
raise commands.BadArgument(
_(
"The argument `/modal/{count}/label` must be less than 45 characters long."
).format(count=count, arg=arg)
)
if "style" in input:
input["style"] = str(input["style"])
try:
style = int(input["style"])
except ValueError:
raise commands.BadArgument(
_(
"The argument `/{count}/style` must be a number between 1 and 2."
).format(count=count)
)
if not 1 <= style <= 2:
raise commands.BadArgument(
_(
"The argument `/{count}/style` must be a number between 1 and 2."
).format(count=count)
)
input["style"] = style
else:
input["style"] = 2
if "required" in input:
def convert_to_bool(argument: str) -> bool:
lowered = argument.lower()
if lowered in {"yes", "y", "true", "t", "1", "enable", "on"}:
return True
elif lowered in {"no", "n", "false", "f", "0", "disable", "off"}:
return False
else:
raise commands.BadBoolArgument(lowered)
input["required"] = str(input["required"])
try:
input["required"] = convert_to_bool(input["required"])
except commands.BadBoolArgument:
raise commands.BadArgument(
_(
"The argument `/{count}/required` must be a boolean (True or False)."
).format(count=count)
)
else:
input["required"] = True
if "default" not in input or input["default"] == "None":
input["default"] = ""
if len(input["default"]) > 4000:
raise commands.BadArgument(
_(
"The argument `/modal/{count}/default` must be less than 4000 characters long."
).format(count=count, arg=arg)
)
if "placeholder" not in input or input["placeholder"] == "None":
input["placeholder"] = ""
if len(input["placeholder"]) > 100:
raise commands.BadArgument(
_(
"The argument `/modal/{count}/placeholder` must be less than 100 characters long."
).format(count=count, arg=arg)
)
if "min_length" not in input or input["min_length"] == "None":
input["min_length"] = None
elif not 0 <= input["min_length"] <= 4000:
raise commands.BadArgument(
_(
"The argument `/modal/{count}/min_length` must be between 0 and 4000."
).format(count=count, arg=arg)
)
if "max_length" not in input or input["max_length"] == "None":
input["max_length"] = None
elif not 1 <= input["max_length"] <= 4000:
raise commands.BadArgument(
_(
"The argument `/modal/{count}/max_length` must be between 0 and 4000."
).format(count=count, arg=arg)
)
return argument_dict