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
1 change: 1 addition & 0 deletions ModuBotDiscord/checks/owner/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .check import *
73 changes: 73 additions & 0 deletions ModuBotDiscord/checks/owner/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import functools
from typing import Awaitable, Callable, TypeVar, Union

from discord import Interaction
from ModuBotDiscord.config import DiscordConfig
from ModuBotDiscord.utils.messages import ErrorType, send_error

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


def check_bot_owner() -> Callable[[T], T]:
def decorator(func: T) -> T:
@functools.wraps(func)
async def wrapper(*args, **kwargs):
interaction: Union[Interaction, None] = None

for arg in args:
if isinstance(arg, Interaction):
interaction = arg
break

if interaction is None:
interaction = kwargs.get("interaction")

if interaction is None:
raise TypeError("No Interaction found for bot owner check.")

if interaction.user.id != DiscordConfig.OWNER_ID:
await send_error(
interaction,
title=ErrorType.ACTION_NOT_ALLOWED,
description="You must be the bot owner to use this command.",
)
return None
return await func(*args, **kwargs)

return wrapper

return decorator


def check_guild_owner() -> Callable[[T], T]:
def decorator(func: T) -> T:
@functools.wraps(func)
async def wrapper(*args, **kwargs):
interaction: Union[Interaction, None] = None

for arg in args:
if isinstance(arg, Interaction):
interaction = arg
break

if interaction is None:
interaction = kwargs.get("interaction")

if interaction is None:
raise TypeError("No Interaction found for guild owner check.")

if (
not interaction.guild
or interaction.user.id != interaction.guild.owner_id
):
await send_error(
interaction,
title=ErrorType.ACTION_NOT_ALLOWED,
description="You must be the server owner to use this command.",
)
return None
return await func(*args, **kwargs)

return wrapper

return decorator
2 changes: 2 additions & 0 deletions ModuBotDiscord/checks/permissions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .check import *
from .enum import *
93 changes: 93 additions & 0 deletions ModuBotDiscord/checks/permissions/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import functools
from typing import Awaitable, Callable, TypeVar, Union

from discord import Interaction
from ModuBotDiscord.utils.messages import ErrorType, send_error

from .enum import Permission

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


def check_permission(*permissions: Permission) -> Callable[[T], T]:
def decorator(func: T) -> T:
@functools.wraps(func)
async def wrapper(*args, **kwargs):
interaction: Union[Interaction, None] = None

for arg in args:
if isinstance(arg, Interaction):
interaction = arg
break

if interaction is None:
interaction = kwargs.get("interaction")

if interaction is None:
raise ValueError("No Interaction found for user permission check.")

missing = [
perm.value
for perm in permissions
if not getattr(interaction.user.guild_permissions, perm.value, False)
]
if missing:
missing_permissions = ", ".join(f"`{m}`" for m in missing)
await send_error(
interaction,
title=ErrorType.ACTION_NOT_ALLOWED,
description=f"You are missing the following permissions: {missing_permissions}",
)
return None
return await func(*args, **kwargs)

return wrapper

return decorator


def check_bot_permission(*permissions: Permission) -> Callable[[T], T]:
def decorator(func: T) -> T:
@functools.wraps(func)
async def wrapper(*args, **kwargs):
interaction: Union[Interaction, None] = None

for arg in args:
if isinstance(arg, Interaction):
interaction = arg
break

if interaction is None:
interaction = kwargs.get("interaction")

if interaction is None:
raise ValueError("No Interaction found for bot permission check.")

if not interaction.guild:
await send_error(
interaction,
title=ErrorType.ACTION_NOT_ALLOWED,
description="This command can only be used in a server.",
)
return None

bot_permissions = interaction.guild.me.guild_permissions
missing = [
perm.value
for perm in permissions
if not getattr(bot_permissions, perm.value, False)
]
if missing:
missing_permissions = ", ".join(f"`{m}`" for m in missing)
await send_error(
interaction,
title=ErrorType.ACTION_NOT_ALLOWED,
description=f"The bot is missing the following permissions: {missing_permissions}",
)
return None

return await func(*args, **kwargs)

return wrapper

return decorator
61 changes: 61 additions & 0 deletions ModuBotDiscord/checks/permissions/enum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from enum import Enum


class Permission(str, Enum):
ADD_REACTIONS = "add_reactions"
ADMINISTRATOR = "administrator"
ATTACH_FILES = "attach_files"
BAN_MEMBERS = "ban_members"
CHANGE_NICKNAME = "change_nickname"
CONNECT = "connect"
CREATE_EVENTS = "create_events"
CREATE_EXPRESSIONS = "create_expressions"
CREATE_INSTANT_INVITE = "create_instant_invite"
CREATE_POLLS = "create_polls"
CREATE_PRIVATE_THREADS = "create_private_threads"
CREATE_PUBLIC_THREADS = "create_public_threads"
DEAFEN_MEMBERS = "deafen_members"
EMBED_LINKS = "embed_links"
EXTERNAL_EMOJIS = "external_emojis"
EXTERNAL_STICKERS = "external_stickers"
KICK_MEMBERS = "kick_members"
MANAGE_CHANNELS = "manage_channels"
MANAGE_EMOJIS = "manage_emojis"
MANAGE_EMOJIS_AND_STICKERS = "manage_emojis_and_stickers"
MANAGE_EVENTS = "manage_events"
MANAGE_EXPRESSIONS = "manage_expressions"
MANAGE_GUILD = "manage_guild"
MANAGE_MESSAGES = "manage_messages"
MANAGE_NICKNAMES = "manage_nicknames"
MANAGE_PERMISSIONS = "manage_permissions"
MANAGE_ROLES = "manage_roles"
MANAGE_THREADS = "manage_threads"
MANAGE_WEBHOOKS = "manage_webhooks"
MENTION_EVERYONE = "mention_everyone"
MODERATE_MEMBERS = "moderate_members"
MOVE_MEMBERS = "move_members"
MUTE_MEMBERS = "mute_members"
PRIORITY_SPEAKER = "priority_speaker"
READ_MESSAGE_HISTORY = "read_message_history"
READ_MESSAGES = "read_messages"
REQUEST_TO_SPEAK = "request_to_speak"
SEND_MESSAGES = "send_messages"
SEND_MESSAGES_IN_THREADS = "send_messages_in_threads"
SEND_POLLS = "send_polls"
SEND_TTS_MESSAGES = "send_tts_messages"
SEND_VOICE_MESSAGES = "send_voice_messages"
SPEAK = "speak"
STREAM = "stream"
USE_APPLICATION_COMMANDS = "use_application_commands"
USE_EMBEDDED_ACTIVITIES = "use_embedded_activities"
USE_EXTERNAL_APPS = "use_external_apps"
USE_EXTERNAL_EMOJIS = "use_external_emojis"
USE_EXTERNAL_SOUNDS = "use_external_sounds"
USE_EXTERNAL_STICKERS = "use_external_stickers"
USE_SOUNDBOARD = "use_soundboard"
USE_VOICE_ACTIVATION = "use_voice_activation"
VALUE = "value"
VIEW_AUDIT_LOG = "view_audit_log"
VIEW_CHANNEL = "view_channel"
VIEW_CREATOR_MONETIZATION_ANALYTICS = "view_creator_monetization_analytics"
VIEW_GUILD_INSIGHTS = "view_guild_insights"
Loading
Loading