"""Contains Command class and bot commands as a global variable.
Also adds 'help' to print all added commands to bot_commands.
"""
from collections.abc import Callable
from typing import List
import discord
bot_commands = {}
[docs]class Command:
"""The Commands class, that contains the data needed for a discord
command."""
command_name: str = ""
callback: Callable
allowed_num_args: List[List[str]] = []
description: str = ""
var_args: bool = False
[docs]def add_command(
command_name: str,
callback: Callable,
allowed_num_args: List[List[str]],
description: str = "",
var_args: None | bool = None,
):
"""The interface/method to add commands to the bot. 'help' command gets
added when importing this module.
A basic example to add a command can be seen here:
# called with "next". No args allowed/required.
add_command("next",
_next,
allowed_num_args=[[]],
description="This plays the next song in the current playlist."
)
A more complex example is the following:
# This either requires 1 argument or 2 arguments.
# The described command removes a song,
# or when called with 2 arguments, it removes the song from the given playlist.
add_command("remove",
_remove,
allowed_num_args=[["song_name"], ["playlist", "song_name"]],
description="Removes selected song from chosen playlist."
)
:param command_name: name of the command, doesn't require any prefix.
:param callback: the function that gets called when the command is invoked.
:param allowed_num_args: array of string-arrays containing the argument name. See example can be seen above.
:param description: optional description to the command
:param var_args: allow multiple (unnamed) arguments
:return:
"""
if var_args is None:
var_args = False
cmd = Command()
cmd.command_name = command_name
cmd.callback = callback
cmd.allowed_num_args = allowed_num_args
cmd.description = description
cmd.var_args = var_args
bot_commands[command_name] = cmd
async def _help(message: discord.Message, _client: discord.Client, _args: list) -> None:
"""Replies/sends every command to the user's channel.
:param message: received discord message
:param _client: client
:param _args: received arguments
:return: None.
"""
msg = "Available commands: ```yaml\n"
for name, command in bot_commands.items():
if name == "help":
continue
msg += f'"{name}":'.ljust(20, " ")
msg += f"{command.description}\n"
if len(bot_commands) <= 1:
msg += "This bot has no commands.\n"
msg += "```"
await message.channel.send(msg)
add_command("help", _help, allowed_num_args=[[]], description="This prints all commands.")