Skip to content
Closed
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
8 changes: 6 additions & 2 deletions __main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import asyncio
import contextlib
import logging
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Any

Expand All @@ -28,6 +29,9 @@
from collections.abc import Generator


log = logging.getLogger(__name__)


@contextlib.contextmanager
def setup_logging() -> Generator[Any, Any, Any]:
discord.utils.setup_logging()
Expand All @@ -42,8 +46,8 @@ async def create_bot_pool() -> asyncpg.Pool[asyncpg.Record]:

if not pool or pool.is_closing():
msg = 'Failed to create a pool.'
raise RuntimeError(msg)

log.error(msg)
sys.exit()
with Path('schema.sql').open(encoding='utf-8') as file: # noqa: ASYNC230
await pool.execute(file.read())

Expand Down
3 changes: 1 addition & 2 deletions extensions/misc/AnicordGacha/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import contextlib
import datetime
import re
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -155,7 +154,7 @@ async def gacha_message_listener(self, message: discord.Message) -> None:
)

with contextlib.suppress(discord.HTTPException):
await message.add_reaction("<:ClockGuy:1384518877358198814>")
await message.add_reaction('<:ClockGuy:1384518877358198814>')

@commands.hybrid_group(name='gacha', description='Handles Anicord Gacha Bot', fallback='status')
@app_commands.allowed_contexts(guilds=True, dms=True, private_channels=True)
Expand Down
4 changes: 3 additions & 1 deletion utilities/bases/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import mystbin
from discord.ext import commands

from utilities.help_command import MafuHelpCommand

if TYPE_CHECKING:
from collections.abc import Iterable

Expand Down Expand Up @@ -53,7 +55,7 @@ def __init__(
intents=intents,
allowed_mentions=allowed_mentions,
enable_debug_events=True,
help_command=commands.MinimalHelpCommand(),
help_command=MafuHelpCommand(),
)

self.prefixes: dict[int, list[str]] = {}
Expand Down
1 change: 1 addition & 0 deletions utilities/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ class BotEmojis:
STATUS_ONLINE = discord.PartialEmoji(name='status_online', id=1328344385783468032)
PASS = discord.PartialEmoji(name='PASS', id=1339697021942108250)
SMASH = discord.PartialEmoji(name='SMASH', id=1339697033589559296)
SLASH = discord.PartialEmoji(name='Slash_command_white', id=1352388308046581880)
116 changes: 115 additions & 1 deletion utilities/help_command.py
Original file line number Diff line number Diff line change
@@ -1 +1,115 @@
# TODO(Depreca1ed): Kms
from __future__ import annotations

from typing import TYPE_CHECKING, Any

from discord.ext import commands

from utilities.constants import BotEmojis
from utilities.embed import Embed
from utilities.functions import fmt_str

if TYPE_CHECKING:
from discord.app_commands import AppCommandContext, AppInstallationType
from discord.ext.commands.hybrid import HybridAppCommand # pyright: ignore[reportMissingTypeStubs]


class MafuHelpCommand(commands.HelpCommand):
def _get_command_context(self, command: HybridAppCommand[Any, ..., Any]) -> AppCommandContext | None:
if command.allowed_contexts:
return command.allowed_contexts

parent = command.parent
while parent is not None:
c = parent.allowed_contexts
if c:
return c
parent = parent.parent
return None

def _get_command_installs(self, command: HybridAppCommand[Any, ..., Any]) -> AppInstallationType | None:
if command.allowed_installs:
return command.allowed_installs

parent = command.parent
while parent is not None:
c = parent.allowed_installs
if c:
return c
parent = parent.parent
return None

def _get_context_strings(self, context: AppCommandContext) -> list[str]:
return [
_
for _ in [
'Direct Messages' if context.dm_channel is True else None,
'Server Channels' if context.guild is True else None,
'Private Channels' if context.private_channel is True else None,
]
if _ is not None
]

def _get_installs_strings(self, installs: AppInstallationType) -> list[str]:
return [
_
for _ in [
'Users' if installs.user is True else None,
'Servers' if installs.guild is True else None,
]
if _ is not None
]

def get_command_signature(self, command: commands.Command[Any, ..., Any]) -> str:
parent: commands.Group[Any, ..., Any] | None = command.parent # pyright: ignore[reportAssignmentType]
entries: list[str] = []
while parent is not None:
if not parent.signature or parent.invoke_without_command:
entries.append(parent.name)
else:
entries.append(parent.name + ' ' + parent.signature)
parent = parent.parent # pyright: ignore[reportAssignmentType]
parent_sig = ' '.join(reversed(entries))

if len(command.aliases) > 0:
fmt = f'{command.name}'
if parent_sig:
fmt = parent_sig + ' ' + fmt
alias = fmt
else:
alias = command.name if not parent_sig else parent_sig + ' ' + command.name

return f'{self.context.clean_prefix}{alias} {command.signature}'

def command_embed(self, command: commands.Command[Any, ..., Any] | commands.HybridCommand[Any, ..., Any]) -> Embed:
is_hybrid = isinstance(command, commands.HybridCommand)

embed = Embed(title=command.qualified_name.title(), description=command.description)
if command.help:
embed.add_field(value=command.help)

if is_hybrid and command.with_app_command is True and command.app_command:
allowed_context = self._get_command_context(command.app_command)
allowed_installs = self._get_command_installs(command.app_command)
embed.add_field(
name=f'{BotEmojis.SLASH} | Slash command',
value=fmt_str(
[
'- **Can run in :** ' + ', '.join(self._get_context_strings(allowed_context))
if allowed_context
else None,
'- **Installable to :** ' + ', '.join(self._get_installs_strings(allowed_installs))
if allowed_installs
else None,
],
seperator='\n',
),
)
if command.aliases:
embed.add_field(name='Aliases:', value=','.join([f'`{alias}`' for alias in command.aliases]))

embed.add_field(name='Usage:', value=f'`{self.get_command_signature(command)}`')

return embed

async def send_command_help(self, command: commands.Command[Any, ..., Any]) -> None:
await self.context.reply(embed=self.command_embed(command))
Loading