[Help] formatting additions (#3339)

* formatting additions

* I really need to redo this module later

* fix some casing
This commit is contained in:
Michael H 2020-01-13 11:50:45 -05:00 committed by GitHub
parent a7987a83fd
commit 3c53b89040
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 26 deletions

View File

@ -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.

View File

@ -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)