mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
* [V3 Core] add settings for whether to use embeds or not * Implement commands to toggle embed settings * Add a function to context for finding whether to use embeds or not * Hide [p]embedset for now * Move embed_requested to bot * Add a simple helper in context
140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
"""
|
|
The purpose of this module is to allow for Red to further customise the command
|
|
invocation context provided by discord.py.
|
|
"""
|
|
import asyncio
|
|
from typing import Iterable, List
|
|
|
|
import discord
|
|
from discord.ext import commands
|
|
|
|
from redbot.core.utils.chat_formatting import box
|
|
|
|
__all__ = ["RedContext"]
|
|
|
|
TICK = "\N{WHITE HEAVY CHECK MARK}"
|
|
|
|
|
|
class RedContext(commands.Context):
|
|
"""Command invocation context for Red.
|
|
|
|
All context passed into commands will be of this type.
|
|
|
|
This class inherits from `commands.Context <discord.ext.commands.Context>`.
|
|
"""
|
|
|
|
async def send_help(self) -> List[discord.Message]:
|
|
"""Send the command help message.
|
|
|
|
Returns
|
|
-------
|
|
`list` of `discord.Message`
|
|
A list of help messages which were sent to the user.
|
|
|
|
"""
|
|
command = self.invoked_subcommand or self.command
|
|
embeds = await self.bot.formatter.format_help_for(self, command)
|
|
destination = self
|
|
ret = []
|
|
for embed in embeds:
|
|
try:
|
|
m = await destination.send(embed=embed)
|
|
except discord.HTTPException:
|
|
destination = self.author
|
|
m = await destination.send(embed=embed)
|
|
ret.append(m)
|
|
|
|
return ret
|
|
|
|
async def tick(self) -> bool:
|
|
"""Add a tick reaction to the command message.
|
|
|
|
Returns
|
|
-------
|
|
bool
|
|
:code:`True` if adding the reaction succeeded.
|
|
|
|
"""
|
|
try:
|
|
await self.message.add_reaction(TICK)
|
|
except discord.HTTPException:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
async def send_interactive(self,
|
|
messages: Iterable[str],
|
|
box_lang: str=None,
|
|
timeout: int=15) -> List[discord.Message]:
|
|
"""Send multiple messages interactively.
|
|
|
|
The user will be prompted for whether or not they would like to view
|
|
the next message, one at a time. They will also be notified of how
|
|
many messages are remaining on each prompt.
|
|
|
|
Parameters
|
|
----------
|
|
messages : `iterable` of `str`
|
|
The messages to send.
|
|
box_lang : str
|
|
If specified, each message will be contained within a codeblock of
|
|
this language.
|
|
timeout : int
|
|
How long the user has to respond to the prompt before it times out.
|
|
After timing out, the bot deletes its prompt message.
|
|
|
|
"""
|
|
messages = tuple(messages)
|
|
ret = []
|
|
|
|
more_check = lambda m: (m.author == self.author and
|
|
m.channel == self.channel and
|
|
m.content.lower() == "more")
|
|
|
|
for idx, page in enumerate(messages, 1):
|
|
if box_lang is None:
|
|
msg = await self.send(page)
|
|
else:
|
|
msg = await self.send(box(page, lang=box_lang))
|
|
ret.append(msg)
|
|
n_remaining = len(messages) - idx
|
|
if n_remaining > 0:
|
|
if n_remaining == 1:
|
|
plural = ""
|
|
is_are = "is"
|
|
else:
|
|
plural = "s"
|
|
is_are = "are"
|
|
query = await self.send(
|
|
"There {} still {} message{} remaining. "
|
|
"Type `more` to continue."
|
|
"".format(is_are, n_remaining, plural))
|
|
try:
|
|
resp = await self.bot.wait_for(
|
|
'message', check=more_check, timeout=timeout)
|
|
except asyncio.TimeoutError:
|
|
await query.delete()
|
|
break
|
|
else:
|
|
try:
|
|
await self.channel.delete_messages((query, resp))
|
|
except (discord.HTTPException, AttributeError):
|
|
# In case the bot can't delete other users' messages,
|
|
# or is not a bot account
|
|
# or chanel is a DM
|
|
await query.delete()
|
|
return ret
|
|
|
|
async def embed_requested(self):
|
|
"""
|
|
Simple helper to call bot.embed_requested
|
|
|
|
Returns
|
|
-------
|
|
bool:
|
|
:code:`True` if an embed is requested
|
|
"""
|
|
return await self.bot.embed_requested(
|
|
self.channel, self.author, command=self.command
|
|
)
|