Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 95 additions & 13 deletions ModuBotDiscord/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,102 @@
import functools
import logging
import warnings
from abc import ABC, abstractmethod
from typing import Awaitable, Callable, TypeVar
from typing import Awaitable, Callable, List, Optional, TypeVar

from discord import Interaction
import discord
from discord import Embed, Interaction
from ModuBotDiscord.config import DiscordConfig

from ..enums import PermissionEnum

T = TypeVar("T", bound=Callable[..., Awaitable[None]])

logger = logging.getLogger(__name__)


async def send_message(
interaction: Interaction, msg: str, ephemeral: bool = False
interaction: Interaction,
msg: Optional[str] = None,
content: Optional[str] = None,
*,
embed: Optional[Embed] = None,
embeds: Optional[List[Embed]] = None,
file: Optional[discord.File] = None,
files: Optional[List[discord.File]] = None,
view: Optional[discord.ui.View] = None,
tts: bool = False,
ephemeral: bool = False,
allowed_mentions: Optional[discord.AllowedMentions] = None,
suppress_embeds: bool = False,
silent: bool = False,
delete_after: Optional[float] = None,
poll=None,
) -> None:
if not interaction.response.is_done():
await interaction.response.send_message(msg, ephemeral=ephemeral)
if content is None and msg is not None:
warnings.warn(
"`msg` is deprecated, use `content` instead",
DeprecationWarning,
stacklevel=2,
)
content = msg

if not interaction.is_expired():
if not interaction.response.is_done():
await interaction.response.send_message(
content=content,
embed=embed,
embeds=embeds,
file=file,
files=files,
view=view,
tts=tts,
ephemeral=ephemeral,
allowed_mentions=allowed_mentions,
suppress_embeds=suppress_embeds,
silent=silent,
delete_after=delete_after,
poll=poll,
)
else:
await interaction.followup.send(
content=content,
embed=embed,
embeds=embeds,
file=file,
files=files,
view=view,
tts=tts,
ephemeral=ephemeral,
allowed_mentions=allowed_mentions,
suppress_embeds=suppress_embeds,
silent=silent,
delete_after=delete_after,
poll=poll,
)
else:
await interaction.followup.send(msg, ephemeral=ephemeral)
logger.warning("Interaction is expired. Skipping send_message().")


async def send_error(
interaction: Interaction, msg: str = "You are not allowed to use this command."
interaction: Interaction,
msg: Optional[str] = None,
title: str = "⚠️ An error occurred",
description: Optional[str] = None,
) -> None:
await send_message(interaction, msg, True)
if msg is not None:
warnings.warn(
"`msg` is deprecated, use `title` or `description` instead",
DeprecationWarning,
stacklevel=2,
)
if description is None:
description = msg
else:
title = msg

embed: Embed = Embed(title=title, description=description, color=0xFF0000)
await send_message(interaction, embed=embed, ephemeral=True)


def check_permission(*permissions: PermissionEnum) -> Callable[[T], T]:
Expand All @@ -38,7 +112,8 @@ async def wrapper(interaction: Interaction, *args, **kwargs):
missing_permissions = ", ".join(f"`{m}`" for m in missing)
await send_error(
interaction,
f"You are missing the following permissions: {missing_permissions}",
title="🚫 Action not allowed",
description=f"You are missing the following permissions: {missing_permissions}",
)
return None
return await func(interaction, *args, **kwargs)
Expand All @@ -54,7 +129,9 @@ def decorator(func: T) -> T:
async def wrapper(interaction: Interaction, *args, **kwargs):
if not interaction.guild:
await send_error(
interaction, "This command can only be used in a server."
interaction,
title="🚫 Action not allowed",
description="This command can only be used in a server.",
)
return None

Expand All @@ -68,7 +145,8 @@ async def wrapper(interaction: Interaction, *args, **kwargs):
missing_permissions = ", ".join(f"`{m}`" for m in missing)
await send_error(
interaction,
f"The bot is missing the following permissions: {missing_permissions}",
title="🚫 Action not allowed",
description=f"The bot is missing the following permissions: {missing_permissions}",
)
return None

Expand All @@ -85,7 +163,9 @@ def decorator(func: T) -> T:
async def wrapper(interaction: Interaction, *args, **kwargs):
if interaction.user.id != DiscordConfig.OWNER_ID:
await send_error(
interaction, "You must be the bot owner to use this command."
interaction,
title="🚫 Action not allowed",
description="You must be the bot owner to use this command.",
)
return None
return await func(interaction, *args, **kwargs)
Expand All @@ -104,7 +184,9 @@ async def wrapper(interaction: Interaction, *args, **kwargs):
or interaction.user.id != interaction.guild.owner_id
):
await send_error(
interaction, "You must be the server owner to use this command."
interaction,
title="🚫 Action not allowed",
description="You must be the server owner to use this command.",
)
return None
return await func(interaction, *args, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "ModuBotDiscord"
version = "0.2.0"
version = "0.3.0"
description = "Modular Discord bot framework built on top of ModuBotCore"
authors = [{ name = "Endkind", email = "endkind.ender@endkind.net" }]
readme = "README.md"
Expand Down
Loading