Files
2022-02-14 05:56:18 +00:00

94 lines
3.2 KiB
Python
Executable File

from __future__ import annotations
from typing import TYPE_CHECKING, Any, Optional
import revolt
from revolt.utils import maybe_coroutine
from .command import Command
from .group import Group
if TYPE_CHECKING:
from .client import CommandsClient
from .view import StringView
__all__ = (
"Context",
)
class Context(revolt.Messageable):
"""Stores metadata the commands execution.
Attributes
-----------
command: Optional[:class:`Command`]
The command, this can be `None` when no command was found and the error handler is being executed
invoked_with: :class:`str`
The command name that was used, this can be an alias, the commands name or a command that doesnt exist
message: :class:`Message`
The message that was sent to invoke the command
channel: :class:`Messageable`
The channel the command was invoked in
server: :class:`Server`
The server the command was invoked in
author: Union[:class:`Member`, :class:`User`]
The user or member that invoked the commad, will be :class:`User` in DMs
args: list[:class:`str`]
The positional arguments being passed to the command
kwargs: dict[:class:`str`, Any]
The keyword arguments being passed to the command
client: :class:`CommandsClient`
The revolt client
"""
__slots__ = ("command", "invoked_with", "args", "message", "server", "channel", "author", "view", "kwargs", "state", "client")
async def _get_channel_id(self) -> str:
return self.channel.id
def __init__(self, command: Optional[Command], invoked_with: str, view: StringView, message: revolt.Message, client: CommandsClient):
self.command = command
self.invoked_with = invoked_with
self.view = view
self.message = message
self.client = client
self.args = []
self.kwargs = {}
self.server = message.server
self.channel = message.channel
self.author = message.author
self.state = message.state
async def invoke(self) -> Any:
"""Invokes the command.
.. note:: If the command is `None`, this function will do nothing.
Parameters
-----------
args: list[:class:`str`]
The args being passed to the command
"""
if command := self.command:
if isinstance(command, Group):
try:
subcommand_name = self.view.get_next_word()
except StopIteration:
pass
else:
if subcommand := command.subcommands.get(subcommand_name):
self.command = command = subcommand
return await self.invoke()
self.view.undo()
await command.parse_arguments(self)
return await command.invoke(self, *self.args, **self.kwargs)
async def can_run(self, command: Optional[Command] = None) -> bool:
"""Runs all of the commands checks, and returns true if all of them pass"""
command = command or self.command
return all([await maybe_coroutine(check, self) for check in (command.checks if command else [])])