mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Help] formatting additions (#3339)
* formatting additions * I really need to redo this module later * fix some casing
This commit is contained in:
parent
a7987a83fd
commit
3c53b89040
@ -4,6 +4,7 @@ This module contains extended classes and functions which are intended to
|
|||||||
replace those from the `discord.ext.commands` module.
|
replace those from the `discord.ext.commands` module.
|
||||||
"""
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
|
import re
|
||||||
import weakref
|
import weakref
|
||||||
from typing import Awaitable, Callable, Dict, List, Optional, Tuple, Union, TYPE_CHECKING
|
from typing import Awaitable, Callable, Dict, List, Optional, Tuple, Union, TYPE_CHECKING
|
||||||
|
|
||||||
@ -57,6 +58,49 @@ class CogCommandMixin:
|
|||||||
checks=getattr(decorated, "__requires_checks__", []),
|
checks=getattr(decorated, "__requires_checks__", []),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def format_help_for_context(self, ctx: "Context") -> str:
|
||||||
|
"""
|
||||||
|
This formats the help string based on values in context
|
||||||
|
|
||||||
|
The steps are (currently, roughly) the following:
|
||||||
|
|
||||||
|
- get the localized help
|
||||||
|
- substitute ``[p]`` with ``ctx.clean_prefix``
|
||||||
|
- substitute ``[botname]`` with ``ctx.me.display_name``
|
||||||
|
|
||||||
|
More steps may be added at a later time.
|
||||||
|
|
||||||
|
Cog creators may override this in their own command classes
|
||||||
|
as long as the method signature stays the same.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
ctx: Context
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
Localized help with some formatting
|
||||||
|
"""
|
||||||
|
|
||||||
|
help_str = self.help
|
||||||
|
if not help_str:
|
||||||
|
# Short circuit out on an empty help string
|
||||||
|
return help_str
|
||||||
|
|
||||||
|
formatting_pattern = re.compile(r"\[p\]|\[botname\]")
|
||||||
|
|
||||||
|
def replacement(m: re.Match) -> str:
|
||||||
|
s = m.group(0)
|
||||||
|
if s == "[p]":
|
||||||
|
return ctx.clean_prefix
|
||||||
|
if s == "[botname]":
|
||||||
|
return ctx.me.display_name
|
||||||
|
# We shouldnt get here:
|
||||||
|
return s
|
||||||
|
|
||||||
|
return formatting_pattern.sub(replacement, help_str)
|
||||||
|
|
||||||
def allow_for(self, model_id: Union[int, str], guild_id: int) -> None:
|
def allow_for(self, model_id: Union[int, str], guild_id: int) -> None:
|
||||||
"""Actively allow this command for the given model.
|
"""Actively allow this command for the given model.
|
||||||
|
|
||||||
|
|||||||
@ -162,10 +162,10 @@ class RedHelpFormatter:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_default_tagline(ctx: Context):
|
def get_default_tagline(ctx: Context):
|
||||||
return (
|
return T_(
|
||||||
f"Type {ctx.clean_prefix}help <command> for more info on a command. "
|
"Type {ctx.clean_prefix}help <command> for more info on a command. "
|
||||||
f"You can also type {ctx.clean_prefix}help <category> for more info on a category."
|
"You can also type {ctx.clean_prefix}help <category> for more info on a category."
|
||||||
)
|
).format(ctx=ctx)
|
||||||
|
|
||||||
async def format_command_help(self, ctx: Context, obj: commands.Command):
|
async def format_command_help(self, ctx: Context, obj: commands.Command):
|
||||||
|
|
||||||
@ -187,7 +187,9 @@ class RedHelpFormatter:
|
|||||||
|
|
||||||
description = command.description or ""
|
description = command.description or ""
|
||||||
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
||||||
signature = f"`Syntax: {ctx.clean_prefix}{command.qualified_name} {command.signature}`"
|
signature = (
|
||||||
|
f"`{T_('Syntax')}: {ctx.clean_prefix}{command.qualified_name} {command.signature}`"
|
||||||
|
)
|
||||||
subcommands = None
|
subcommands = None
|
||||||
|
|
||||||
if hasattr(command, "all_commands"):
|
if hasattr(command, "all_commands"):
|
||||||
@ -203,10 +205,11 @@ class RedHelpFormatter:
|
|||||||
emb["footer"]["text"] = tagline
|
emb["footer"]["text"] = tagline
|
||||||
emb["embed"]["description"] = signature
|
emb["embed"]["description"] = signature
|
||||||
|
|
||||||
if command.help:
|
command_help = command.format_help_for_context(ctx)
|
||||||
splitted = command.help.split("\n\n")
|
if command_help:
|
||||||
|
splitted = command_help.split("\n\n")
|
||||||
name = splitted[0]
|
name = splitted[0]
|
||||||
value = "\n\n".join(splitted[1:]).replace("[p]", ctx.clean_prefix)
|
value = "\n\n".join(splitted[1:])
|
||||||
if not value:
|
if not value:
|
||||||
value = EMPTY_STRING
|
value = EMPTY_STRING
|
||||||
field = EmbedField(name[:250], value[:1024], False)
|
field = EmbedField(name[:250], value[:1024], False)
|
||||||
@ -225,9 +228,9 @@ class RedHelpFormatter:
|
|||||||
)
|
)
|
||||||
for i, page in enumerate(pagify(subtext, page_length=500, shorten_by=0)):
|
for i, page in enumerate(pagify(subtext, page_length=500, shorten_by=0)):
|
||||||
if i == 0:
|
if i == 0:
|
||||||
title = "**__Subcommands:__**"
|
title = T_("**__Subcommands:__**")
|
||||||
else:
|
else:
|
||||||
title = "**__Subcommands:__** (continued)"
|
title = T_("**__Subcommands:__** (continued)")
|
||||||
field = EmbedField(title, page, False)
|
field = EmbedField(title, page, False)
|
||||||
emb["fields"].append(field)
|
emb["fields"].append(field)
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ class RedHelpFormatter:
|
|||||||
subtext = None
|
subtext = None
|
||||||
subtext_header = None
|
subtext_header = None
|
||||||
if subcommands:
|
if subcommands:
|
||||||
subtext_header = "Subcommands:"
|
subtext_header = T_("Subcommands:")
|
||||||
max_width = max(discord.utils._string_width(name) for name in subcommands.keys())
|
max_width = max(discord.utils._string_width(name) for name in subcommands.keys())
|
||||||
|
|
||||||
def width_maker(cmds):
|
def width_maker(cmds):
|
||||||
@ -261,7 +264,7 @@ class RedHelpFormatter:
|
|||||||
(
|
(
|
||||||
description,
|
description,
|
||||||
signature[1:-1],
|
signature[1:-1],
|
||||||
command.help.replace("[p]", ctx.clean_prefix),
|
command.format_help_for_context(ctx),
|
||||||
subtext_header,
|
subtext_header,
|
||||||
subtext,
|
subtext,
|
||||||
),
|
),
|
||||||
@ -301,7 +304,10 @@ class RedHelpFormatter:
|
|||||||
page_char_limit = await ctx.bot._config.help.page_char_limit()
|
page_char_limit = await ctx.bot._config.help.page_char_limit()
|
||||||
page_char_limit = min(page_char_limit, 5500) # Just in case someone was manually...
|
page_char_limit = min(page_char_limit, 5500) # Just in case someone was manually...
|
||||||
|
|
||||||
author_info = {"name": f"{ctx.me.display_name} Help Menu", "icon_url": ctx.me.avatar_url}
|
author_info = {
|
||||||
|
"name": f"{ctx.me.display_name} {T_('Help Menu')}",
|
||||||
|
"icon_url": ctx.me.avatar_url,
|
||||||
|
}
|
||||||
|
|
||||||
# Offset calculation here is for total embed size limit
|
# Offset calculation here is for total embed size limit
|
||||||
# 20 accounts for# *Page {i} of {page_count}*
|
# 20 accounts for# *Page {i} of {page_count}*
|
||||||
@ -346,7 +352,9 @@ class RedHelpFormatter:
|
|||||||
embed = discord.Embed(color=color, **embed_dict["embed"])
|
embed = discord.Embed(color=color, **embed_dict["embed"])
|
||||||
|
|
||||||
if page_count > 1:
|
if page_count > 1:
|
||||||
description = f"*Page {i} of {page_count}*\n{embed.description}"
|
description = T_(
|
||||||
|
"*Page {page_num} of {page_count}*\n{content_description}"
|
||||||
|
).format(content_description=embed.description, page_num=i, page_count=page_count)
|
||||||
embed.description = description
|
embed.description = description
|
||||||
|
|
||||||
embed.set_author(**author_info)
|
embed.set_author(**author_info)
|
||||||
@ -366,7 +374,7 @@ class RedHelpFormatter:
|
|||||||
if not (coms or await ctx.bot._config.help.verify_exists()):
|
if not (coms or await ctx.bot._config.help.verify_exists()):
|
||||||
return
|
return
|
||||||
|
|
||||||
description = obj.help
|
description = obj.format_help_for_context(ctx)
|
||||||
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
||||||
|
|
||||||
if await ctx.embed_requested():
|
if await ctx.embed_requested():
|
||||||
@ -376,7 +384,7 @@ class RedHelpFormatter:
|
|||||||
if description:
|
if description:
|
||||||
splitted = description.split("\n\n")
|
splitted = description.split("\n\n")
|
||||||
name = splitted[0]
|
name = splitted[0]
|
||||||
value = "\n\n".join(splitted[1:]).replace("[p]", ctx.clean_prefix)
|
value = "\n\n".join(splitted[1:])
|
||||||
if not value:
|
if not value:
|
||||||
value = EMPTY_STRING
|
value = EMPTY_STRING
|
||||||
field = EmbedField(name[:252], value[:1024], False)
|
field = EmbedField(name[:252], value[:1024], False)
|
||||||
@ -395,9 +403,9 @@ class RedHelpFormatter:
|
|||||||
)
|
)
|
||||||
for i, page in enumerate(pagify(command_text, page_length=500, shorten_by=0)):
|
for i, page in enumerate(pagify(command_text, page_length=500, shorten_by=0)):
|
||||||
if i == 0:
|
if i == 0:
|
||||||
title = "**__Commands:__**"
|
title = T_("**__Commands:__**")
|
||||||
else:
|
else:
|
||||||
title = "**__Commands:__** (continued)"
|
title = T_("**__Commands:__** (continued)")
|
||||||
field = EmbedField(title, page, False)
|
field = EmbedField(title, page, False)
|
||||||
emb["fields"].append(field)
|
emb["fields"].append(field)
|
||||||
|
|
||||||
@ -407,7 +415,7 @@ class RedHelpFormatter:
|
|||||||
subtext = None
|
subtext = None
|
||||||
subtext_header = None
|
subtext_header = None
|
||||||
if coms:
|
if coms:
|
||||||
subtext_header = "Commands:"
|
subtext_header = T_("Commands:")
|
||||||
max_width = max(discord.utils._string_width(name) for name in coms.keys())
|
max_width = max(discord.utils._string_width(name) for name in coms.keys())
|
||||||
|
|
||||||
def width_maker(cmds):
|
def width_maker(cmds):
|
||||||
@ -449,7 +457,7 @@ class RedHelpFormatter:
|
|||||||
if cog_name:
|
if cog_name:
|
||||||
title = f"**__{cog_name}:__**"
|
title = f"**__{cog_name}:__**"
|
||||||
else:
|
else:
|
||||||
title = f"**__No Category:__**"
|
title = f"**__{T_('No Category')}:__**"
|
||||||
|
|
||||||
def shorten_line(a_line: str) -> str:
|
def shorten_line(a_line: str) -> str:
|
||||||
if len(a_line) < 70: # embed max width needs to be lower
|
if len(a_line) < 70: # embed max width needs to be lower
|
||||||
@ -462,7 +470,7 @@ class RedHelpFormatter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
for i, page in enumerate(pagify(cog_text, page_length=1000, shorten_by=0)):
|
for i, page in enumerate(pagify(cog_text, page_length=1000, shorten_by=0)):
|
||||||
title = title if i < 1 else f"{title} (continued)"
|
title = title if i < 1 else f"{title} {T_('(continued)')}"
|
||||||
field = EmbedField(title, page, False)
|
field = EmbedField(title, page, False)
|
||||||
emb["fields"].append(field)
|
emb["fields"].append(field)
|
||||||
|
|
||||||
@ -478,7 +486,7 @@ class RedHelpFormatter:
|
|||||||
names.extend(list(v.name for v in v.values()))
|
names.extend(list(v.name for v in v.values()))
|
||||||
|
|
||||||
max_width = max(
|
max_width = max(
|
||||||
discord.utils._string_width((name or "No Category:")) for name in names
|
discord.utils._string_width((name or T_("No Category:"))) for name in names
|
||||||
)
|
)
|
||||||
|
|
||||||
def width_maker(cmds):
|
def width_maker(cmds):
|
||||||
@ -492,7 +500,7 @@ class RedHelpFormatter:
|
|||||||
|
|
||||||
for cog_name, data in coms:
|
for cog_name, data in coms:
|
||||||
|
|
||||||
title = f"{cog_name}:" if cog_name else "No Category:"
|
title = f"{cog_name}:" if cog_name else T_("No Category:")
|
||||||
to_join.append(title)
|
to_join.append(title)
|
||||||
|
|
||||||
for name, doc, width in width_maker(sorted(data.items())):
|
for name, doc, width in width_maker(sorted(data.items())):
|
||||||
@ -543,7 +551,9 @@ class RedHelpFormatter:
|
|||||||
if fuzzy_commands:
|
if fuzzy_commands:
|
||||||
ret = await format_fuzzy_results(ctx, fuzzy_commands, embed=use_embeds)
|
ret = await format_fuzzy_results(ctx, fuzzy_commands, embed=use_embeds)
|
||||||
if use_embeds:
|
if use_embeds:
|
||||||
ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url)
|
ret.set_author(
|
||||||
|
name=f"{ctx.me.display_name} {T_('Help Menu')}", icon_url=ctx.me.avatar_url
|
||||||
|
)
|
||||||
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
||||||
ret.set_footer(text=tagline)
|
ret.set_footer(text=tagline)
|
||||||
await ctx.send(embed=ret)
|
await ctx.send(embed=ret)
|
||||||
@ -553,7 +563,9 @@ class RedHelpFormatter:
|
|||||||
ret = T_("Help topic for *{command_name}* not found.").format(command_name=help_for)
|
ret = T_("Help topic for *{command_name}* not found.").format(command_name=help_for)
|
||||||
if use_embeds:
|
if use_embeds:
|
||||||
ret = discord.Embed(color=(await ctx.embed_color()), description=ret)
|
ret = discord.Embed(color=(await ctx.embed_color()), description=ret)
|
||||||
ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url)
|
ret.set_author(
|
||||||
|
name=f"{ctx.me.display_name} {T_('Help Menu')}", icon_url=ctx.me.avatar_url
|
||||||
|
)
|
||||||
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
||||||
ret.set_footer(text=tagline)
|
ret.set_footer(text=tagline)
|
||||||
await ctx.send(embed=ret)
|
await ctx.send(embed=ret)
|
||||||
@ -569,7 +581,9 @@ class RedHelpFormatter:
|
|||||||
)
|
)
|
||||||
if await ctx.embed_requested():
|
if await ctx.embed_requested():
|
||||||
ret = discord.Embed(color=(await ctx.embed_color()), description=ret)
|
ret = discord.Embed(color=(await ctx.embed_color()), description=ret)
|
||||||
ret.set_author(name=f"{ctx.me.display_name} Help Menu", icon_url=ctx.me.avatar_url)
|
ret.set_author(
|
||||||
|
name=f"{ctx.me.display_name} {T_('Help Menu')}", icon_url=ctx.me.avatar_url
|
||||||
|
)
|
||||||
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
tagline = (await ctx.bot._config.help.tagline()) or self.get_default_tagline(ctx)
|
||||||
ret.set_footer(text=tagline)
|
ret.set_footer(text=tagline)
|
||||||
await ctx.send(embed=ret)
|
await ctx.send(embed=ret)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user