mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:03:12 +00:00
feat: Add fully functional help command
This commit is contained in:
parent
c9688ed0e0
commit
bfe718b50a
30 changed files with 281 additions and 73 deletions
|
@ -41,6 +41,12 @@ async def log_command_error(
|
||||||
log_msg = f"{user_name} executed {command_type}{command_name or 'Unknown'}"
|
log_msg = f"{user_name} executed {command_type}{command_name or 'Unknown'}"
|
||||||
|
|
||||||
log_msg += " in DMs" if guild_id is None else f" | guild: {guild_id}"
|
log_msg += " in DMs" if guild_id is None else f" | guild: {guild_id}"
|
||||||
|
|
||||||
|
if CONST.INSTANCE == "dev":
|
||||||
|
logger.exception(
|
||||||
|
f"{log_msg} | {error.__module__}.{error.__class__.__name__} | {''.join(traceback.format_exception(type(error), error, error.__traceback__))}",
|
||||||
|
)
|
||||||
|
else:
|
||||||
logger.error(f"{log_msg} | {error.__module__}.{error.__class__.__name__}")
|
logger.error(f"{log_msg} | {error.__module__}.{error.__class__.__name__}")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import inspect
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
@ -140,3 +142,57 @@ def format_seconds_to_duration_string(seconds: int) -> str:
|
||||||
return f"{hours}h{minutes}m" if minutes > 0 else f"{hours}h"
|
return f"{hours}h{minutes}m" if minutes > 0 else f"{hours}h"
|
||||||
|
|
||||||
return f"{minutes}m"
|
return f"{minutes}m"
|
||||||
|
|
||||||
|
|
||||||
|
def generate_usage(
|
||||||
|
command: commands.Command[Any, Any, Any],
|
||||||
|
flag_converter: type[commands.FlagConverter] | None = None,
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Generate a usage string for a command with flags.
|
||||||
|
Credit to https://github.com/allthingslinux/tux (thanks kaizen ;p)
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
command : commands.Command
|
||||||
|
The command for which to generate the usage string.
|
||||||
|
flag_converter : type[commands.FlagConverter]
|
||||||
|
The flag converter class for the command.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
The usage string for the command. Example: "ban [target] -[reason] -<silent>"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get the name of the command
|
||||||
|
command_name = command.qualified_name
|
||||||
|
|
||||||
|
# Start the usage string with the command name
|
||||||
|
usage = f"{command_name}"
|
||||||
|
|
||||||
|
# Get the parameters of the command (excluding the `ctx` and `flags` parameters)
|
||||||
|
parameters: dict[str, commands.Parameter] = command.clean_params
|
||||||
|
|
||||||
|
flag_prefix = getattr(flag_converter, "__commands_flag_prefix__", "-")
|
||||||
|
flags: dict[str, commands.Flag] = flag_converter.get_flags() if flag_converter else {}
|
||||||
|
|
||||||
|
# Add non-flag arguments to the usage string
|
||||||
|
for param_name, param in parameters.items():
|
||||||
|
# Ignore these parameters
|
||||||
|
if param_name in ["ctx", "flags"]:
|
||||||
|
continue
|
||||||
|
# Determine if the parameter is required
|
||||||
|
is_required = param.default == inspect.Parameter.empty
|
||||||
|
# Add the parameter to the usage string with required or optional wrapping
|
||||||
|
usage += f" <{param_name}>" if is_required else f" [{param_name}]"
|
||||||
|
|
||||||
|
# Add flag arguments to the usage string
|
||||||
|
for flag_name, flag_obj in flags.items():
|
||||||
|
# Determine if the flag is required or optional
|
||||||
|
if flag_obj.required:
|
||||||
|
usage += f" {flag_prefix}<{flag_name}>"
|
||||||
|
else:
|
||||||
|
usage += f" {flag_prefix}[{flag_name}]"
|
||||||
|
|
||||||
|
return usage
|
||||||
|
|
207
lib/help.py
207
lib/help.py
|
@ -3,81 +3,178 @@ from collections.abc import Mapping
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
|
||||||
|
|
||||||
class LumiHelp(commands.HelpCommand):
|
class LuminaraHelp(commands.HelpCommand):
|
||||||
def __init__(self, **options: Any) -> None:
|
def __init__(self):
|
||||||
super().__init__(**options)
|
"""Initializes the LuminaraHelp command with necessary attributes."""
|
||||||
self.verify_checks: bool = True
|
super().__init__(
|
||||||
self.command_attrs: dict[str, list[str] | str | bool] = {
|
command_attrs={
|
||||||
|
"help": "Lists all commands and sub-commands.",
|
||||||
"aliases": ["h"],
|
"aliases": ["h"],
|
||||||
"help": "Show a list of commands, or information about a specific command when an argument is passed.",
|
"usage": "$help <command> or <sub-command>",
|
||||||
"name": "help",
|
},
|
||||||
"hidden": True,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_command_qualified_name(self, command: commands.Command[Any, Any, Any]) -> str:
|
|
||||||
return f"`{self.context.clean_prefix}{command.qualified_name}`"
|
|
||||||
|
|
||||||
async def send_bot_help(self, mapping: Mapping[commands.Cog | None, list[commands.Command[Any, ..., Any]]]) -> None:
|
|
||||||
embed = Builder.create_embed(
|
|
||||||
theme="success",
|
|
||||||
author_text="Help Command",
|
|
||||||
user_name=self.context.author.name,
|
|
||||||
hide_name_in_description=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
modules_dir = Path(__file__).parent.parent / "modules"
|
async def _get_prefix(self) -> str:
|
||||||
module_names = [name for name in os.listdir(modules_dir) if Path(modules_dir / name).is_dir()]
|
"""
|
||||||
|
Dynamically fetches the prefix from the context or uses a default prefix constant.
|
||||||
|
|
||||||
for module_name in module_names:
|
Returns
|
||||||
module_commands: list[commands.Command[Any, ..., Any]] = []
|
-------
|
||||||
for cog, lumi_commands in mapping.items():
|
str
|
||||||
if cog and cog.__module__.startswith(f"modules.{module_name}"):
|
The prefix used to invoke the bot.
|
||||||
filtered = await self.filter_commands(lumi_commands, sort=True)
|
"""
|
||||||
module_commands.extend(filtered)
|
return "."
|
||||||
|
|
||||||
|
def _embed_base(self, author: str, description: str | None = None) -> discord.Embed:
|
||||||
|
"""
|
||||||
|
Creates a base embed with uniform styling.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
title : str
|
||||||
|
The title of the embed.
|
||||||
|
description : str | None
|
||||||
|
The description of the embed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
discord.Embed
|
||||||
|
The created embed.
|
||||||
|
"""
|
||||||
|
return Builder.create_embed(
|
||||||
|
theme="info",
|
||||||
|
author_text=author,
|
||||||
|
description=description,
|
||||||
|
footer_text=CONST.STRINGS["help_footer"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_cog_groups(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Retrieves a list of cog groups from the 'modules' folder.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
list[str]
|
||||||
|
A list of cog groups.
|
||||||
|
"""
|
||||||
|
cog_groups = sorted(
|
||||||
|
[
|
||||||
|
d
|
||||||
|
for d in os.listdir("./modules")
|
||||||
|
if Path(f"./modules/{d}").is_dir() and d not in ("__pycache__", "admin")
|
||||||
|
],
|
||||||
|
)
|
||||||
|
if "moderation" in cog_groups:
|
||||||
|
cog_groups.remove("moderation")
|
||||||
|
cog_groups.insert(0, "moderation")
|
||||||
|
return cog_groups
|
||||||
|
|
||||||
|
async def send_bot_help(
|
||||||
|
self,
|
||||||
|
mapping: Mapping[commands.Cog | None, list[commands.Command[Any, Any, Any]]],
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Sends an overview of all commands in a single embed, grouped by module.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
mapping : Mapping[commands.Cog | None, list[commands.Command[Any, Any, Any]]]
|
||||||
|
The mapping of cogs to commands.
|
||||||
|
"""
|
||||||
|
embed = self._embed_base("Luminara Help Overview")
|
||||||
|
|
||||||
|
cog_groups = self._get_cog_groups()
|
||||||
|
for group in cog_groups:
|
||||||
|
group_commands: list[commands.Command[Any, Any, Any]] = []
|
||||||
|
for cog, commands_list in mapping.items():
|
||||||
|
if cog and commands_list and cog.__module__.startswith(f"modules.{group}"):
|
||||||
|
group_commands.extend(commands_list)
|
||||||
|
if group_commands:
|
||||||
|
command_list = ", ".join(f"`{c.name}`" for c in group_commands)
|
||||||
|
embed.add_field(name=group.capitalize(), value=command_list, inline=False)
|
||||||
|
|
||||||
|
await self.get_destination().send(embed=embed)
|
||||||
|
|
||||||
|
async def _add_command_help_fields(self, embed: discord.Embed, command: commands.Command[Any, Any, Any]) -> None:
|
||||||
|
"""
|
||||||
|
Adds fields with usage and alias information for a command to an embed.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
embed : discord.Embed
|
||||||
|
The embed to which the fields will be added.
|
||||||
|
command : commands.Command[Any, Any, Any]
|
||||||
|
The command whose details are to be added.
|
||||||
|
"""
|
||||||
|
prefix = await self._get_prefix()
|
||||||
|
|
||||||
if module_commands:
|
|
||||||
command_signatures = [self.get_command_qualified_name(c) for c in module_commands]
|
|
||||||
unique_command_signatures = list(set(command_signatures))
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name=module_name.capitalize(),
|
name="Usage",
|
||||||
value=", ".join(sorted(unique_command_signatures)),
|
value=f"`{prefix}{command.usage or 'No usage.'}`",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
channel = self.get_destination()
|
|
||||||
await channel.send(embed=embed)
|
|
||||||
|
|
||||||
async def send_command_help(self, command: commands.Command[Any, Any, Any]) -> None:
|
async def send_command_help(self, command: commands.Command[Any, Any, Any]) -> None:
|
||||||
embed = Builder.create_embed(
|
"""
|
||||||
theme="success",
|
Sends a help message for a specific command.
|
||||||
author_text=f"{self.context.clean_prefix}{command.qualified_name}",
|
|
||||||
description=command.description,
|
Parameters
|
||||||
user_name=self.context.author.name,
|
----------
|
||||||
hide_name_in_description=True,
|
command : commands.Command[Any, Any, Any]
|
||||||
|
The command for which the help message is to be sent.
|
||||||
|
"""
|
||||||
|
prefix = await self._get_prefix()
|
||||||
|
|
||||||
|
author = f"{prefix}{command.qualified_name}"
|
||||||
|
author += f" ({', '.join(command.aliases)})" if command.aliases else ""
|
||||||
|
|
||||||
|
embed = self._embed_base(
|
||||||
|
author=author,
|
||||||
|
description=f"> {command.help}" or "No description available.",
|
||||||
)
|
)
|
||||||
|
|
||||||
usage_value: str = f"`{self.context.clean_prefix}{command.usage}`"
|
await self._add_command_help_fields(embed, command)
|
||||||
embed.add_field(name="Usage", value=usage_value, inline=False)
|
await self.get_destination().send(embed=embed)
|
||||||
|
|
||||||
channel = self.get_destination()
|
|
||||||
await channel.send(embed=embed)
|
|
||||||
|
|
||||||
async def send_error_message(self, error: str) -> None:
|
|
||||||
raise LumiException(error)
|
|
||||||
|
|
||||||
async def send_group_help(self, group: commands.Group[Any, Any, Any]) -> None:
|
async def send_group_help(self, group: commands.Group[Any, Any, Any]) -> None:
|
||||||
raise LumiException(
|
"""
|
||||||
CONST.STRINGS["error_command_not_found"].format(group.qualified_name),
|
Sends a help message for a specific command group.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
group : commands.Group[Any, Any, Any]
|
||||||
|
The group for which the help message is to be sent.
|
||||||
|
"""
|
||||||
|
prefix = await self._get_prefix()
|
||||||
|
embed = self._embed_base(
|
||||||
|
author=f"{prefix}{group.qualified_name}",
|
||||||
|
description=group.help or "No description available.",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_cog_help(self, cog: commands.Cog) -> None:
|
for command in group.commands:
|
||||||
raise LumiException(
|
embed.add_field(name=command.name, value=command.short_doc or "No description available.", inline=False)
|
||||||
CONST.STRINGS["error_command_not_found"].format(cog.qualified_name),
|
|
||||||
|
await self.get_destination().send(embed=embed)
|
||||||
|
|
||||||
|
async def send_error_message(self, error: str) -> None:
|
||||||
|
"""
|
||||||
|
Sends an error message.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
error : str
|
||||||
|
The error message to be sent.
|
||||||
|
"""
|
||||||
|
embed = Builder.create_embed(
|
||||||
|
theme="error",
|
||||||
|
title="Error in help command",
|
||||||
|
description=error,
|
||||||
)
|
)
|
||||||
|
await self.get_destination().send(embed=embed, delete_after=30)
|
||||||
|
|
|
@ -190,6 +190,7 @@
|
||||||
"give_success": "you gave **${1}** to {2}.",
|
"give_success": "you gave **${1}** to {2}.",
|
||||||
"greet_default_description": "_ _\n**Welcome** to **{0}**",
|
"greet_default_description": "_ _\n**Welcome** to **{0}**",
|
||||||
"greet_template_description": "\u2193\u2193\u2193\n{0}",
|
"greet_template_description": "\u2193\u2193\u2193\n{0}",
|
||||||
|
"help_footer": "Help Service",
|
||||||
"help_use_prefix": "Please use Lumi's prefix to get help. Type `{0}help`",
|
"help_use_prefix": "Please use Lumi's prefix to get help. Type `{0}help`",
|
||||||
"info_api_version": "**discord.py:** v{0}\n",
|
"info_api_version": "**discord.py:** v{0}\n",
|
||||||
"info_database_records": "**Database:** {0} records",
|
"info_database_records": "**Database:** {0} records",
|
||||||
|
|
3
main.py
3
main.py
|
@ -7,6 +7,7 @@ from loguru import logger
|
||||||
|
|
||||||
from lib.client import Luminara
|
from lib.client import Luminara
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
|
from lib.help import LuminaraHelp
|
||||||
from services.config_service import GuildConfig
|
from services.config_service import GuildConfig
|
||||||
|
|
||||||
logger.remove()
|
logger.remove()
|
||||||
|
@ -30,7 +31,7 @@ async def main() -> None:
|
||||||
allowed_mentions=discord.AllowedMentions(everyone=False),
|
allowed_mentions=discord.AllowedMentions(everyone=False),
|
||||||
case_insensitive=True,
|
case_insensitive=True,
|
||||||
strip_after_prefix=True,
|
strip_after_prefix=True,
|
||||||
help_command=None,
|
help_command=LuminaraHelp(),
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from db import database
|
from db import database
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.format import shorten
|
from lib.format import shorten
|
||||||
|
@ -10,6 +11,8 @@ from ui.embeds import Builder
|
||||||
class Sql(commands.Cog):
|
class Sql(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.select_cmd.usage = lib.format.generate_usage(self.select_cmd)
|
||||||
|
self.inject_cmd.usage = lib.format.generate_usage(self.inject_cmd)
|
||||||
|
|
||||||
@commands.command(name="sqlselect", aliases=["sqls"])
|
@commands.command(name="sqlselect", aliases=["sqls"])
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
@ -9,6 +10,7 @@ from ui.embeds import Builder
|
||||||
class Award(commands.Cog):
|
class Award(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.award_command.usage = lib.format.generate_usage(self.award_command)
|
||||||
|
|
||||||
@commands.command(name="award", aliases=["aw"])
|
@commands.command(name="award", aliases=["aw"])
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from services.blacklist_service import BlacklistUserService
|
from services.blacklist_service import BlacklistUserService
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
@ -9,6 +10,7 @@ from ui.embeds import Builder
|
||||||
class Blacklist(commands.Cog):
|
class Blacklist(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.blacklist_command.usage = lib.format.generate_usage(self.blacklist_command)
|
||||||
|
|
||||||
@commands.command(name="blacklist")
|
@commands.command(name="blacklist")
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
|
|
||||||
|
|
||||||
class Dev(commands.Cog):
|
class Dev(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.sync.usage = lib.format.generate_usage(self.sync)
|
||||||
|
self.clear.usage = lib.format.generate_usage(self.clear)
|
||||||
|
|
||||||
@commands.group(name="dev", description="Lumi developer commands")
|
@commands.group(name="dev", description="Lumi developer commands")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -44,7 +47,7 @@ class Dev(commands.Cog):
|
||||||
name="clear_tree",
|
name="clear_tree",
|
||||||
aliases=["clear"],
|
aliases=["clear"],
|
||||||
)
|
)
|
||||||
async def sync_global(
|
async def clear(
|
||||||
self,
|
self,
|
||||||
ctx: commands.Context[commands.Bot],
|
ctx: commands.Context[commands.Bot],
|
||||||
guild: discord.Guild | None = None,
|
guild: discord.Guild | None = None,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
@ -8,13 +9,14 @@ from ui.embeds import Builder
|
||||||
class Balance(commands.Cog):
|
class Balance(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.balance.usage = lib.format.generate_usage(self.balance)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="balance",
|
name="balance",
|
||||||
aliases=["bal", "$"],
|
aliases=["bal", "$"],
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
async def daily(
|
async def balance(
|
||||||
self,
|
self,
|
||||||
ctx: commands.Context[commands.Bot],
|
ctx: commands.Context[commands.Bot],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
from lib.exceptions import LumiException
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
|
@ -22,6 +23,7 @@ Hand = list[Card]
|
||||||
class Blackjack(commands.Cog):
|
class Blackjack(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.blackjack.usage = lib.format.generate_usage(self.blackjack)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="blackjack",
|
name="blackjack",
|
||||||
|
|
|
@ -4,6 +4,7 @@ from zoneinfo import ZoneInfo
|
||||||
from discord import Embed
|
from discord import Embed
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
from services.daily_service import Dailies
|
from services.daily_service import Dailies
|
||||||
|
@ -25,6 +26,7 @@ def seconds_until(hours: int, minutes: int) -> int:
|
||||||
class Daily(commands.Cog):
|
class Daily(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.daily.usage = lib.format.generate_usage(self.daily)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="daily",
|
name="daily",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
from lib.exceptions import LumiException
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
|
@ -10,6 +11,7 @@ from ui.embeds import Builder
|
||||||
class Give(commands.Cog):
|
class Give(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.give.usage = lib.format.generate_usage(self.give)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="give",
|
name="give",
|
||||||
|
|
|
@ -7,6 +7,7 @@ from zoneinfo import ZoneInfo
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
from lib.exceptions import LumiException
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
|
@ -18,6 +19,7 @@ est = ZoneInfo("US/Eastern")
|
||||||
class Slots(commands.Cog):
|
class Slots(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.slots.usage = lib.format.generate_usage(self.slots)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="slots",
|
name="slots",
|
||||||
|
|
|
@ -3,6 +3,7 @@ from typing import cast
|
||||||
from discord import Embed, Guild, Member
|
from discord import Embed, Guild, Member
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
from ui.views.leaderboard import LeaderboardCommandOptions, LeaderboardCommandView
|
from ui.views.leaderboard import LeaderboardCommandOptions, LeaderboardCommandView
|
||||||
|
@ -11,6 +12,7 @@ from ui.views.leaderboard import LeaderboardCommandOptions, LeaderboardCommandVi
|
||||||
class Leaderboard(commands.Cog):
|
class Leaderboard(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
|
self.leaderboard.usage = lib.format.generate_usage(self.leaderboard)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="leaderboard",
|
name="leaderboard",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from discord import Embed
|
from discord import Embed
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from services.xp_service import XpService
|
from services.xp_service import XpService
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
@ -9,12 +10,13 @@ from ui.embeds import Builder
|
||||||
class Level(commands.Cog):
|
class Level(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.level.usage = lib.format.generate_usage(self.level)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="level",
|
name="level",
|
||||||
aliases=["rank", "lvl", "xp"],
|
aliases=["rank", "lvl", "xp"],
|
||||||
)
|
)
|
||||||
async def ping(self, ctx: commands.Context[commands.Bot]) -> None:
|
async def level(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||||
"""
|
"""
|
||||||
Get the level of the user.
|
Get the level of the user.
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ import httpx
|
||||||
from discord import File
|
from discord import File
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
|
|
||||||
|
|
||||||
async def create_avatar_file(url: str) -> File:
|
async def create_avatar_file(url: str) -> File:
|
||||||
"""
|
"""
|
||||||
|
@ -32,6 +34,7 @@ async def create_avatar_file(url: str) -> File:
|
||||||
class Avatar(commands.Cog):
|
class Avatar(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.avatar.usage = lib.format.generate_usage(self.avatar)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="avatar",
|
name="avatar",
|
||||||
|
@ -45,7 +48,7 @@ class Avatar(commands.Cog):
|
||||||
"""
|
"""
|
||||||
Get the avatar of a member.
|
Get the avatar of a member.
|
||||||
|
|
||||||
Parameters:
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
ctx : ApplicationContext
|
ctx : ApplicationContext
|
||||||
The discord context object.
|
The discord context object.
|
||||||
|
|
|
@ -90,11 +90,6 @@ class Backup(commands.Cog):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
await asyncio.sleep(30)
|
await asyncio.sleep(30)
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def backup(self, ctx: commands.Context[commands.Bot]) -> None:
|
|
||||||
await backup()
|
|
||||||
await ctx.send("Backup successful.")
|
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot: commands.Bot) -> None:
|
async def setup(bot: commands.Bot) -> None:
|
||||||
await bot.add_cog(Backup(bot))
|
await bot.add_cog(Backup(bot))
|
||||||
|
|
|
@ -5,6 +5,7 @@ import discord
|
||||||
import psutil
|
import psutil
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ from ui.embeds import Builder
|
||||||
class Info(commands.Cog):
|
class Info(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.info.usage = lib.format.generate_usage(self.info)
|
||||||
|
|
||||||
@commands.hybrid_command(
|
@commands.hybrid_command(
|
||||||
name="info",
|
name="info",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
from ui.views.introduction import (
|
from ui.views.introduction import (
|
||||||
|
@ -12,6 +13,7 @@ from ui.views.introduction import (
|
||||||
class Introduction(commands.Cog):
|
class Introduction(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.introduction.usage = lib.format.generate_usage(self.introduction)
|
||||||
|
|
||||||
@commands.hybrid_command(name="introduction", aliases=["intro"])
|
@commands.hybrid_command(name="introduction", aliases=["intro"])
|
||||||
async def introduction(self, ctx: commands.Context[commands.Bot]) -> None:
|
async def introduction(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
from ui.views.invite import InviteButton
|
from ui.views.invite import InviteButton
|
||||||
|
@ -8,6 +9,7 @@ from ui.views.invite import InviteButton
|
||||||
class Invite(commands.Cog):
|
class Invite(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.invite.usage = lib.format.generate_usage(self.invite)
|
||||||
|
|
||||||
@commands.hybrid_command(name="invite", aliases=["inv"])
|
@commands.hybrid_command(name="invite", aliases=["inv"])
|
||||||
async def invite(self, ctx: commands.Context[commands.Bot]) -> None:
|
async def invite(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
|
||||||
|
@ -7,6 +8,7 @@ from ui.embeds import Builder
|
||||||
class Ping(commands.Cog):
|
class Ping(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.ping.usage = lib.format.generate_usage(self.ping)
|
||||||
|
|
||||||
@commands.hybrid_command(name="ping")
|
@commands.hybrid_command(name="ping")
|
||||||
async def ping(self, ctx: commands.Context[commands.Bot]) -> None:
|
async def ping(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||||
|
|
|
@ -4,6 +4,7 @@ import discord
|
||||||
from discord import Embed
|
from discord import Embed
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from ui.embeds import Builder
|
from ui.embeds import Builder
|
||||||
|
|
||||||
|
@ -12,8 +13,9 @@ class Uptime(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot) -> None:
|
def __init__(self, bot: commands.Bot) -> None:
|
||||||
self.bot: commands.Bot = bot
|
self.bot: commands.Bot = bot
|
||||||
self.start_time: datetime = discord.utils.utcnow()
|
self.start_time: datetime = discord.utils.utcnow()
|
||||||
|
self.uptime.usage = lib.format.generate_usage(self.uptime)
|
||||||
|
|
||||||
@commands.hybrid_command(name="uptime", aliases=["ut"])
|
@commands.hybrid_command(name="uptime")
|
||||||
async def uptime(self, ctx: commands.Context[commands.Bot]) -> None:
|
async def uptime(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||||
"""
|
"""
|
||||||
Uptime command.
|
Uptime command.
|
||||||
|
|
|
@ -15,8 +15,10 @@ from ui.embeds import Builder
|
||||||
class Ban(commands.Cog):
|
class Ban(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.ban.usage = lib.format.generate_usage(self.ban)
|
||||||
|
self.unban.usage = lib.format.generate_usage(self.unban)
|
||||||
|
|
||||||
@commands.hybrid_command(name="ban")
|
@commands.hybrid_command(name="ban", aliases=["b"])
|
||||||
@commands.has_permissions(ban_members=True)
|
@commands.has_permissions(ban_members=True)
|
||||||
@commands.bot_has_permissions(ban_members=True)
|
@commands.bot_has_permissions(ban_members=True)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
|
|
@ -4,6 +4,7 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from reactionmenu import ViewButton, ViewMenu
|
from reactionmenu import ViewButton, ViewMenu
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.case_handler import edit_case_modlog
|
from lib.case_handler import edit_case_modlog
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
from lib.exceptions import LumiException
|
||||||
|
@ -46,6 +47,10 @@ def create_case_view_menu(ctx: commands.Context[commands.Bot]) -> ViewMenu:
|
||||||
class Cases(commands.Cog):
|
class Cases(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.view_case_by_number.usage = lib.format.generate_usage(self.view_case_by_number)
|
||||||
|
self.view_all_cases_in_guild.usage = lib.format.generate_usage(self.view_all_cases_in_guild)
|
||||||
|
self.view_all_cases_by_mod.usage = lib.format.generate_usage(self.view_all_cases_by_mod)
|
||||||
|
self.edit_case_reason.usage = lib.format.generate_usage(self.edit_case_reason)
|
||||||
|
|
||||||
@commands.hybrid_command(name="case", aliases=["c", "ca"])
|
@commands.hybrid_command(name="case", aliases=["c", "ca"])
|
||||||
@commands.has_permissions(manage_messages=True)
|
@commands.has_permissions(manage_messages=True)
|
||||||
|
|
|
@ -14,6 +14,7 @@ from ui.embeds import Builder
|
||||||
class Kick(commands.Cog):
|
class Kick(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.kick.usage = lib.format.generate_usage(self.kick)
|
||||||
|
|
||||||
@commands.hybrid_command(name="kick", aliases=["k"])
|
@commands.hybrid_command(name="kick", aliases=["k"])
|
||||||
@commands.has_permissions(kick_members=True)
|
@commands.has_permissions(kick_members=True)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import discord
|
||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
from lib.exceptions import LumiException
|
from lib.exceptions import LumiException
|
||||||
from lib.format import format_duration_to_seconds
|
from lib.format import format_duration_to_seconds
|
||||||
|
@ -12,6 +13,7 @@ from lib.format import format_duration_to_seconds
|
||||||
class Slowmode(commands.Cog):
|
class Slowmode(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.slowmode.usage = lib.format.generate_usage(self.slowmode)
|
||||||
|
|
||||||
async def _set_slowmode(
|
async def _set_slowmode(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import cast
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
import lib.format as formatter
|
import lib.format
|
||||||
from lib.actionable import async_actionable
|
from lib.actionable import async_actionable
|
||||||
from lib.case_handler import create_case
|
from lib.case_handler import create_case
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
|
@ -14,6 +14,7 @@ from ui.embeds import Builder
|
||||||
class Softban(commands.Cog):
|
class Softban(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.softban.usage = lib.format.generate_usage(self.softban)
|
||||||
|
|
||||||
@commands.hybrid_command(name="softban", aliases=["sb"])
|
@commands.hybrid_command(name="softban", aliases=["sb"])
|
||||||
@commands.has_permissions(ban_members=True)
|
@commands.has_permissions(ban_members=True)
|
||||||
|
@ -67,7 +68,7 @@ class Softban(commands.Cog):
|
||||||
target,
|
target,
|
||||||
reason=CONST.STRINGS["mod_reason"].format(
|
reason=CONST.STRINGS["mod_reason"].format(
|
||||||
ctx.author.name,
|
ctx.author.name,
|
||||||
formatter.shorten(output_reason, 200),
|
lib.format.shorten(output_reason, 200),
|
||||||
),
|
),
|
||||||
delete_message_seconds=86400,
|
delete_message_seconds=86400,
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,8 @@ from ui.embeds import Builder
|
||||||
class Timeout(commands.Cog):
|
class Timeout(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.timeout.usage = lib.format.generate_usage(self.timeout)
|
||||||
|
self.untimeout.usage = lib.format.generate_usage(self.untimeout)
|
||||||
|
|
||||||
@commands.hybrid_command(name="timeout", aliases=["t", "to"])
|
@commands.hybrid_command(name="timeout", aliases=["t", "to"])
|
||||||
@commands.has_permissions(moderate_members=True)
|
@commands.has_permissions(moderate_members=True)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from typing import cast
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
import lib.format
|
||||||
from lib.actionable import async_actionable
|
from lib.actionable import async_actionable
|
||||||
from lib.case_handler import create_case
|
from lib.case_handler import create_case
|
||||||
from lib.const import CONST
|
from lib.const import CONST
|
||||||
|
@ -14,6 +15,7 @@ from ui.embeds import Builder
|
||||||
class Warn(commands.Cog):
|
class Warn(commands.Cog):
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.warn.usage = lib.format.generate_usage(self.warn)
|
||||||
|
|
||||||
@commands.hybrid_command(name="warn", aliases=["w"])
|
@commands.hybrid_command(name="warn", aliases=["w"])
|
||||||
@commands.has_permissions(manage_messages=True)
|
@commands.has_permissions(manage_messages=True)
|
||||||
|
|
Loading…
Reference in a new issue