mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
[V3] Custom context class (#988)
* Create custom context class * Documentation * Remove old help method, replace with new * Update from rebase
This commit is contained in:
parent
36b3fbd5bc
commit
86b18c702c
10
docs/framework_context.rst
Normal file
10
docs/framework_context.rst
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.. red invocation context documentation
|
||||||
|
|
||||||
|
==========================
|
||||||
|
Command Invocation Context
|
||||||
|
==========================
|
||||||
|
|
||||||
|
.. automodule:: redbot.core.context
|
||||||
|
|
||||||
|
.. autoclass:: redbot.core.RedContext
|
||||||
|
:members:
|
||||||
@ -20,6 +20,7 @@ Welcome to Red - Discord Bot's documentation!
|
|||||||
framework_cogmanager
|
framework_cogmanager
|
||||||
framework_config
|
framework_config
|
||||||
framework_downloader
|
framework_downloader
|
||||||
|
framework_context
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
|
|||||||
@ -167,7 +167,7 @@ class Admin:
|
|||||||
async def editrole(self, ctx: commands.Context):
|
async def editrole(self, ctx: commands.Context):
|
||||||
"""Edits roles settings"""
|
"""Edits roles settings"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@editrole.command(name="colour", aliases=["color", ])
|
@editrole.command(name="colour", aliases=["color", ])
|
||||||
async def editrole_colour(self, ctx: commands.Context, role: discord.Role,
|
async def editrole_colour(self, ctx: commands.Context, role: discord.Role,
|
||||||
|
|||||||
@ -184,7 +184,7 @@ class Alias:
|
|||||||
async def alias(self, ctx: commands.Context):
|
async def alias(self, ctx: commands.Context):
|
||||||
"""Manage per-server aliases for commands"""
|
"""Manage per-server aliases for commands"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@alias.group(name="global")
|
@alias.group(name="global")
|
||||||
async def global_(self, ctx: commands.Context):
|
async def global_(self, ctx: commands.Context):
|
||||||
@ -193,7 +193,7 @@ class Alias:
|
|||||||
"""
|
"""
|
||||||
if ctx.invoked_subcommand is None or \
|
if ctx.invoked_subcommand is None or \
|
||||||
isinstance(ctx.invoked_subcommand, commands.Group):
|
isinstance(ctx.invoked_subcommand, commands.Group):
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@alias.command(name="add")
|
@alias.command(name="add")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
|||||||
@ -54,7 +54,7 @@ class Bank:
|
|||||||
async def bankset(self, ctx: commands.Context):
|
async def bankset(self, ctx: commands.Context):
|
||||||
"""Base command for bank settings"""
|
"""Base command for bank settings"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@bankset.command(name="toggleglobal")
|
@bankset.command(name="toggleglobal")
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
|
|||||||
@ -164,7 +164,7 @@ class CustomCommands:
|
|||||||
ctx: commands.Context):
|
ctx: commands.Context):
|
||||||
"""Custom commands management"""
|
"""Custom commands management"""
|
||||||
if not ctx.invoked_subcommand:
|
if not ctx.invoked_subcommand:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@customcom.group(name="add")
|
@customcom.group(name="add")
|
||||||
@checks.mod_or_permissions(administrator=True)
|
@checks.mod_or_permissions(administrator=True)
|
||||||
@ -176,7 +176,7 @@ class CustomCommands:
|
|||||||
"""
|
"""
|
||||||
if not ctx.invoked_subcommand or isinstance(ctx.invoked_subcommand,
|
if not ctx.invoked_subcommand or isinstance(ctx.invoked_subcommand,
|
||||||
commands.Group):
|
commands.Group):
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@cc_add.command(name='random')
|
@cc_add.command(name='random')
|
||||||
@checks.mod_or_permissions(administrator=True)
|
@checks.mod_or_permissions(administrator=True)
|
||||||
|
|||||||
@ -179,7 +179,7 @@ class Downloader:
|
|||||||
Command group for managing Downloader repos.
|
Command group for managing Downloader repos.
|
||||||
"""
|
"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@repo.command(name="add")
|
@repo.command(name="add")
|
||||||
@install_agreement()
|
@install_agreement()
|
||||||
@ -231,7 +231,7 @@ class Downloader:
|
|||||||
Command group for managing installable Cogs.
|
Command group for managing installable Cogs.
|
||||||
"""
|
"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@cog.command(name="install")
|
@cog.command(name="install")
|
||||||
async def _cog_install(self, ctx, repo_name: Repo, cog_name: str):
|
async def _cog_install(self, ctx, repo_name: Repo, cog_name: str):
|
||||||
|
|||||||
@ -141,7 +141,7 @@ class Economy:
|
|||||||
async def _bank(self, ctx: commands.Context):
|
async def _bank(self, ctx: commands.Context):
|
||||||
"""Bank operations"""
|
"""Bank operations"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@_bank.command()
|
@_bank.command()
|
||||||
async def balance(self, ctx: commands.Context, user: discord.Member = None):
|
async def balance(self, ctx: commands.Context, user: discord.Member = None):
|
||||||
@ -405,7 +405,7 @@ class Economy:
|
|||||||
"""Changes economy module settings"""
|
"""Changes economy module settings"""
|
||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
if await bank.is_global():
|
if await bank.is_global():
|
||||||
slot_min = await self.config.SLOT_MIN()
|
slot_min = await self.config.SLOT_MIN()
|
||||||
slot_max = await self.config.SLOT_MAX()
|
slot_max = await self.config.SLOT_MAX()
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class Image:
|
|||||||
Make sure to set the client ID using
|
Make sure to set the client ID using
|
||||||
[p]imgurcreds"""
|
[p]imgurcreds"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@_imgur.command(name="search")
|
@_imgur.command(name="search")
|
||||||
async def imgur_search(self, ctx, *, term: str):
|
async def imgur_search(self, ctx, *, term: str):
|
||||||
@ -70,7 +70,7 @@ class Image:
|
|||||||
await ctx.send(_("Only 'new' and 'top' are a valid sort type."))
|
await ctx.send(_("Only 'new' and 'top' are a valid sort type."))
|
||||||
return
|
return
|
||||||
elif window not in ("day", "week", "month", "year", "all"):
|
elif window not in ("day", "week", "month", "year", "all"):
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
if sort_type == "new":
|
if sort_type == "new":
|
||||||
@ -120,7 +120,7 @@ class Image:
|
|||||||
if keywords:
|
if keywords:
|
||||||
keywords = "+".join(keywords)
|
keywords = "+".join(keywords)
|
||||||
else:
|
else:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
url = ("http://api.giphy.com/v1/gifs/search?&api_key={}&q={}"
|
url = ("http://api.giphy.com/v1/gifs/search?&api_key={}&q={}"
|
||||||
@ -142,7 +142,7 @@ class Image:
|
|||||||
if keywords:
|
if keywords:
|
||||||
keywords = "+".join(keywords)
|
keywords = "+".join(keywords)
|
||||||
else:
|
else:
|
||||||
await self.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
url = ("http://api.giphy.com/v1/gifs/random?&api_key={}&tag={}"
|
url = ("http://api.giphy.com/v1/gifs/random?&api_key={}&tag={}"
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
from .config import Config
|
from .config import Config
|
||||||
|
from .context import RedContext
|
||||||
|
|
||||||
__all__ = ["Config", "__version__"]
|
__all__ = ["Config", "RedContext", "__version__"]
|
||||||
|
|
||||||
__version__ = version = pkg_resources.require("Red-DiscordBot")[0].version
|
__version__ = version = pkg_resources.require("Red-DiscordBot")[0].version
|
||||||
|
|||||||
@ -10,8 +10,7 @@ from discord.ext import commands
|
|||||||
from discord.ext.commands import GroupMixin
|
from discord.ext.commands import GroupMixin
|
||||||
|
|
||||||
from .cog_manager import CogManager
|
from .cog_manager import CogManager
|
||||||
from . import Config
|
from . import Config, i18n, RedContext
|
||||||
from . import i18n
|
|
||||||
|
|
||||||
|
|
||||||
class Red(commands.Bot):
|
class Red(commands.Bot):
|
||||||
@ -84,15 +83,8 @@ class Red(commands.Bot):
|
|||||||
return True
|
return True
|
||||||
return await super().is_owner(user)
|
return await super().is_owner(user)
|
||||||
|
|
||||||
async def send_cmd_help(self, ctx):
|
async def get_context(self, message, *, cls=RedContext):
|
||||||
if ctx.invoked_subcommand:
|
return await super().get_context(message, cls=cls)
|
||||||
pages = await self.formatter.format_help_for(ctx, ctx.invoked_subcommand)
|
|
||||||
for page in pages:
|
|
||||||
await ctx.send(page)
|
|
||||||
else:
|
|
||||||
pages = await self.formatter.format_help_for(ctx, ctx.command)
|
|
||||||
for page in pages:
|
|
||||||
await ctx.send(page)
|
|
||||||
|
|
||||||
async def shutdown(self, *, restart=False):
|
async def shutdown(self, *, restart=False):
|
||||||
"""Gracefully quits Red with exit code 0
|
"""Gracefully quits Red with exit code 0
|
||||||
|
|||||||
42
redbot/core/context.py
Normal file
42
redbot/core/context.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""The purpose of this module is to allow for Red to
|
||||||
|
further customise the command invocation context provided
|
||||||
|
by discord.py.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
__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
|
||||||
|
:py:class:`commands.Context <discord.ext.commands.Context>`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def send_help(self):
|
||||||
|
"""Send the command help message."""
|
||||||
|
command = self.invoked_subcommand or self.command
|
||||||
|
pages = await self.bot.formatter.format_help_for(self, command)
|
||||||
|
for page in pages:
|
||||||
|
await self.send(page)
|
||||||
|
|
||||||
|
async def tick(self):
|
||||||
|
"""Add a tick reaction to the command message.
|
||||||
|
|
||||||
|
:return: ``True`` if adding the reaction succeeded.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
await self.message.add_reaction(TICK)
|
||||||
|
except discord.HTTPException:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
@ -136,7 +136,7 @@ class Core:
|
|||||||
async def _set(self, ctx):
|
async def _set(self, ctx):
|
||||||
"""Changes Red's settings"""
|
"""Changes Red's settings"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
|
|
||||||
@_set.command()
|
@_set.command()
|
||||||
@checks.guildowner()
|
@checks.guildowner()
|
||||||
@ -207,7 +207,7 @@ class Core:
|
|||||||
try:
|
try:
|
||||||
status = statuses[status.lower()]
|
status = statuses[status.lower()]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
await ctx.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
else:
|
else:
|
||||||
await ctx.bot.change_presence(status=status,
|
await ctx.bot.change_presence(status=status,
|
||||||
game=game)
|
game=game)
|
||||||
@ -229,7 +229,7 @@ class Core:
|
|||||||
game = discord.Game(type=1, url=streamer, name=stream_title)
|
game = discord.Game(type=1, url=streamer, name=stream_title)
|
||||||
await ctx.bot.change_presence(game=game, status=status)
|
await ctx.bot.change_presence(game=game, status=status)
|
||||||
elif streamer is not None:
|
elif streamer is not None:
|
||||||
await ctx.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
await ctx.bot.change_presence(game=None, status=status)
|
await ctx.bot.change_presence(game=None, status=status)
|
||||||
@ -267,7 +267,7 @@ class Core:
|
|||||||
async def prefix(self, ctx, *prefixes):
|
async def prefix(self, ctx, *prefixes):
|
||||||
"""Sets Red's global prefix(es)"""
|
"""Sets Red's global prefix(es)"""
|
||||||
if not prefixes:
|
if not prefixes:
|
||||||
await ctx.bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
prefixes = sorted(prefixes, reverse=True)
|
prefixes = sorted(prefixes, reverse=True)
|
||||||
await ctx.bot.db.prefix.set(prefixes)
|
await ctx.bot.db.prefix.set(prefixes)
|
||||||
|
|||||||
@ -74,9 +74,9 @@ def init_events(bot, cli_flags):
|
|||||||
@bot.event
|
@bot.event
|
||||||
async def on_command_error(ctx, error):
|
async def on_command_error(ctx, error):
|
||||||
if isinstance(error, commands.MissingRequiredArgument):
|
if isinstance(error, commands.MissingRequiredArgument):
|
||||||
await bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
elif isinstance(error, commands.BadArgument):
|
elif isinstance(error, commands.BadArgument):
|
||||||
await bot.send_cmd_help(ctx)
|
await ctx.send_help()
|
||||||
elif isinstance(error, commands.DisabledCommand):
|
elif isinstance(error, commands.DisabledCommand):
|
||||||
await ctx.send("That command is disabled.")
|
await ctx.send("That command is disabled.")
|
||||||
elif isinstance(error, commands.CommandInvokeError):
|
elif isinstance(error, commands.CommandInvokeError):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user