[Core/Core Cogs] Prevent translation errors and use formatting utils (#5435)

* Use proper syntax for inline formatting in core_commands

* use proper formating utils in core and core cogs wherever reasonable

* tests are awesome

* ensure "(continued)" is translated in help.py

* add colons to translatable strings for easier context comprehension by translators

* Thx flame :)

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* good point

Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
This commit is contained in:
Dav 2022-02-16 01:25:21 +00:00 committed by GitHub
parent 9ab307c1ef
commit c6517d5087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 90 deletions

View File

@ -12,6 +12,7 @@ from redbot.core import Config, modlog, commands
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced
from redbot.core.utils.chat_formatting import inline
from .events import Events from .events import Events
from .kickban import KickBanMixin from .kickban import KickBanMixin
from .names import ModInfo from .names import ModInfo
@ -141,8 +142,8 @@ class Mod(
if e["ignored"] is not False: if e["ignored"] is not False:
msg = _( msg = _(
"Ignored guilds and channels have been moved. " "Ignored guilds and channels have been moved. "
"Please use `[p]moveignoredchannels` to migrate the old settings." "Please use {command} to migrate the old settings."
) ).format(command=inline("[p]moveignoredchannels"))
self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
message_sent = True message_sent = True
break break
@ -151,8 +152,8 @@ class Mod(
if e["ignored"] is not False: if e["ignored"] is not False:
msg = _( msg = _(
"Ignored guilds and channels have been moved. " "Ignored guilds and channels have been moved. "
"Please use `[p]moveignoredchannels` to migrate the old settings." "Please use {command} to migrate the old settings."
) ).format(command=inline("[p]moveignoredchannels"))
self.bot.loop.create_task( self.bot.loop.create_task(
send_to_owners_with_prefix_replaced(self.bot, msg) send_to_owners_with_prefix_replaced(self.bot, msg)
) )
@ -163,8 +164,8 @@ class Mod(
if e["delete_delay"] != -1: if e["delete_delay"] != -1:
msg = _( msg = _(
"Delete delay settings have been moved. " "Delete delay settings have been moved. "
"Please use `[p]movedeletedelay` to migrate the old settings." "Please use {command} to migrate the old settings."
) ).format(command=inline("[p]movedeletedelay"))
self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
break break
await self.config.version.set("1.2.0") await self.config.version.set("1.2.0")

View File

@ -336,15 +336,15 @@ class ModSettings(MixinMeta):
if not cur_setting: if not cur_setting:
await self.config.guild(guild).reinvite_on_unban.set(True) await self.config.guild(guild).reinvite_on_unban.set(True)
await ctx.send( await ctx.send(
_("Users unbanned with `{command}` will be reinvited.").format( _("Users unbanned with {command} will be reinvited.").format(
command=f"{ctx.clean_prefix}unban" command=inline(f"{ctx.clean_prefix}unban")
) )
) )
else: else:
await self.config.guild(guild).reinvite_on_unban.set(False) await self.config.guild(guild).reinvite_on_unban.set(False)
await ctx.send( await ctx.send(
_("Users unbanned with `{command}` will not be reinvited.").format( _("Users unbanned with {command} will not be reinvited.").format(
command=f"{ctx.clean_prefix}unban" command=inline(f"{ctx.clean_prefix}unban")
) )
) )
@ -463,7 +463,7 @@ class ModSettings(MixinMeta):
msg = _( msg = _(
"All name changes will no longer be tracked.\n" "All name changes will no longer be tracked.\n"
"To delete existing name data, use {command}." "To delete existing name data, use {command}."
).format(command=f"`{ctx.clean_prefix}modset deletenames`") ).format(command=inline(f"{ctx.clean_prefix}modset deletenames"))
await self.config.track_all_names.set(enabled) await self.config.track_all_names.set(enabled)
await ctx.send(msg) await ctx.send(msg)

View File

@ -8,7 +8,7 @@ import discord
from redbot.core import checks, commands, modlog from redbot.core import checks, commands, modlog
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils.chat_formatting import box, pagify from redbot.core.utils.chat_formatting import bold, box, pagify
from redbot.core.utils.menus import DEFAULT_CONTROLS, menu from redbot.core.utils.menus import DEFAULT_CONTROLS, menu
from redbot.core.utils.predicates import MessagePredicate from redbot.core.utils.predicates import MessagePredicate
@ -40,10 +40,7 @@ class ModLog(commands.Cog):
if await ctx.embed_requested(): if await ctx.embed_requested():
await ctx.send(embed=await case.message_content(embed=True)) await ctx.send(embed=await case.message_content(embed=True))
else: else:
message = _("{case}\n**Timestamp:** {timestamp}").format( message = f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} <t:{int(case.created_at)}>"
case=await case.message_content(embed=False),
timestamp=f"<t:{int(case.created_at)}>",
)
await ctx.send(message) await ctx.send(message)
@commands.command() @commands.command()
@ -76,10 +73,7 @@ class ModLog(commands.Cog):
else: else:
rendered_cases = [] rendered_cases = []
for case in cases: for case in cases:
message = _("{case}\n**Timestamp:** {timestamp}").format( message = f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} <t:{int(case.created_at)}>"
case=await case.message_content(embed=False),
timestamp=f"<t:{int(case.created_at)}>",
)
rendered_cases.append(message) rendered_cases.append(message)
await menu(ctx, rendered_cases, DEFAULT_CONTROLS) await menu(ctx, rendered_cases, DEFAULT_CONTROLS)
@ -110,10 +104,7 @@ class ModLog(commands.Cog):
rendered_cases = [] rendered_cases = []
message = "" message = ""
for case in cases: for case in cases:
message += _("{case}\n**Timestamp:** {timestamp}\n\n").format( message += f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} <t:{int(case.created_at)}>"
case=await case.message_content(embed=False),
timestamp=f"<t:{int(case.created_at)}>",
)
for page in pagify(message, ["\n\n", "\n"], priority=True): for page in pagify(message, ["\n\n", "\n"], priority=True):
rendered_cases.append(page) rendered_cases.append(page)
await menu(ctx, rendered_cases, DEFAULT_CONTROLS) await menu(ctx, rendered_cases, DEFAULT_CONTROLS)

View File

@ -564,19 +564,13 @@ class Mutes(VoiceMutes, commands.Cog, metaclass=CompositeMetaClass):
else: else:
message = f"{title}\n>>> " message = f"{title}\n>>> "
message += reason message += reason
message += (f"\n{bold(_('Moderator:'))} {moderator_str}") if show_mod else ""
message += ( message += (
_("\n**Moderator**: {moderator}").format(moderator=moderator_str) (f"\n{bold(_('Until:'))} {until_str}\n{bold(_('Duration:'))} {duration_str}")
if show_mod
else ""
)
message += (
_("\n**Until**: {until}\n**Duration**: {duration}").format(
until=until_str, duration=duration_str
)
if duration if duration
else "" else ""
) )
message += _("\n**Guild**: {guild_name}").format(guild_name=guild.name) message += f"\n{bold(_('Guild:'))} {guild.name}"
try: try:
await user.send(message) await user.send(message)
except discord.Forbidden: except discord.Forbidden:

View File

@ -3,7 +3,7 @@ from redbot.core.bot import Red
from redbot.core import checks, commands, Config from redbot.core import checks, commands, Config
from redbot.core.i18n import cog_i18n, Translator, set_contextual_locales_from_guild from redbot.core.i18n import cog_i18n, Translator, set_contextual_locales_from_guild
from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced
from redbot.core.utils.chat_formatting import escape, pagify from redbot.core.utils.chat_formatting import escape, inline, pagify
from .streamtypes import ( from .streamtypes import (
PicartoStream, PicartoStream,
@ -143,7 +143,7 @@ class Streams(commands.Cog):
message = _( message = _(
"You need a client secret key if you want to use the Twitch API on this cog.\n" "You need a client secret key if you want to use the Twitch API on this cog.\n"
"Follow these steps:\n" "Follow these steps:\n"
"1. Go to this page: https://dev.twitch.tv/console/apps.\n" "1. Go to this page: {link}.\n"
'2. Click "Manage" on your application.\n' '2. Click "Manage" on your application.\n'
'3. Click on "New secret".\n' '3. Click on "New secret".\n'
"5. Copy your client ID and your client secret into:\n" "5. Copy your client ID and your client secret into:\n"
@ -152,9 +152,12 @@ class Streams(commands.Cog):
"Note: These tokens are sensitive and should only be used in a private channel " "Note: These tokens are sensitive and should only be used in a private channel "
"or in DM with the bot." "or in DM with the bot."
).format( ).format(
command="`[p]set api twitch client_id {} client_secret {}`".format( link="https://dev.twitch.tv/console/apps",
command=inline(
"[p]set api twitch client_id {} client_secret {}".format(
_("<your_client_id_here>"), _("<your_client_secret_here>") _("<your_client_id_here>"), _("<your_client_secret_here>")
) )
),
) )
if notified_owner_missing_twitch_secret is False: if notified_owner_missing_twitch_secret is False:
await send_to_owners_with_prefix_replaced(self.bot, message) await send_to_owners_with_prefix_replaced(self.bot, message)
@ -258,14 +261,14 @@ class Streams(commands.Cog):
except InvalidTwitchCredentials: except InvalidTwitchCredentials:
await ctx.send( await ctx.send(
_("The Twitch token is either invalid or has not been set. See {command}.").format( _("The Twitch token is either invalid or has not been set. See {command}.").format(
command=f"`{ctx.clean_prefix}streamset twitchtoken`" command=inline(f"{ctx.clean_prefix}streamset twitchtoken")
) )
) )
except InvalidYoutubeCredentials: except InvalidYoutubeCredentials:
await ctx.send( await ctx.send(
_( _(
"The YouTube API key is either invalid or has not been set. See {command}." "The YouTube API key is either invalid or has not been set. See {command}."
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`") ).format(command=inline(f"{ctx.clean_prefix}streamset youtubekey"))
) )
except YoutubeQuotaExceeded: except YoutubeQuotaExceeded:
await ctx.send( await ctx.send(
@ -416,7 +419,7 @@ class Streams(commands.Cog):
await ctx.send( await ctx.send(
_( _(
"The Twitch token is either invalid or has not been set. See {command}." "The Twitch token is either invalid or has not been set. See {command}."
).format(command=f"`{ctx.clean_prefix}streamset twitchtoken`") ).format(command=inline(f"{ctx.clean_prefix}streamset twitchtoken"))
) )
return return
except InvalidYoutubeCredentials: except InvalidYoutubeCredentials:
@ -424,7 +427,7 @@ class Streams(commands.Cog):
_( _(
"The YouTube API key is either invalid or has not been set. See " "The YouTube API key is either invalid or has not been set. See "
"{command}." "{command}."
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`") ).format(command=inline(f"{ctx.clean_prefix}streamset youtubekey"))
) )
return return
except YoutubeQuotaExceeded: except YoutubeQuotaExceeded:
@ -475,9 +478,9 @@ class Streams(commands.Cog):
"""Explain how to set the twitch token.""" """Explain how to set the twitch token."""
message = _( message = _(
"To set the twitch API tokens, follow these steps:\n" "To set the twitch API tokens, follow these steps:\n"
"1. Go to this page: https://dev.twitch.tv/dashboard/apps.\n" "1. Go to this page: {link}.\n"
"2. Click *Register Your Application*.\n" "2. Click *Register Your Application*.\n"
"3. Enter a name, set the OAuth Redirect URI to `http://localhost`, and " "3. Enter a name, set the OAuth Redirect URI to {localhost}, and "
"select an Application Category of your choosing.\n" "select an Application Category of your choosing.\n"
"4. Click *Register*.\n" "4. Click *Register*.\n"
"5. Copy your client ID and your client secret into:\n" "5. Copy your client ID and your client secret into:\n"
@ -486,9 +489,11 @@ class Streams(commands.Cog):
"Note: These tokens are sensitive and should only be used in a private channel\n" "Note: These tokens are sensitive and should only be used in a private channel\n"
"or in DM with the bot.\n" "or in DM with the bot.\n"
).format( ).format(
link="https://dev.twitch.tv/dashboard/apps",
localhost=inline("http://localhost"),
command="`{}set api twitch client_id {} client_secret {}`".format( command="`{}set api twitch client_id {} client_secret {}`".format(
ctx.clean_prefix, _("<your_client_id_here>"), _("<your_client_secret_here>") ctx.clean_prefix, _("<your_client_id_here>"), _("<your_client_secret_here>")
) ),
) )
await ctx.maybe_send_embed(message) await ctx.maybe_send_embed(message)
@ -501,19 +506,22 @@ class Streams(commands.Cog):
message = _( message = _(
"To get one, do the following:\n" "To get one, do the following:\n"
"1. Create a project\n" "1. Create a project\n"
"(see https://support.google.com/googleapi/answer/6251787 for details)\n" "(see {link1} for details)\n"
"2. Enable the YouTube Data API v3 \n" "2. Enable the YouTube Data API v3 \n"
"(see https://support.google.com/googleapi/answer/6158841 for instructions)\n" "(see {link2} for instructions)\n"
"3. Set up your API key \n" "3. Set up your API key \n"
"(see https://support.google.com/googleapi/answer/6158862 for instructions)\n" "(see {link3} for instructions)\n"
"4. Copy your API key and run the command " "4. Copy your API key and run the command "
"{command}\n\n" "{command}\n\n"
"Note: These tokens are sensitive and should only be used in a private channel\n" "Note: These tokens are sensitive and should only be used in a private channel\n"
"or in DM with the bot.\n" "or in DM with the bot.\n"
).format( ).format(
link1="https://support.google.com/googleapi/answer/6251787",
link2="https://support.google.com/googleapi/answer/6158841",
link3="https://support.google.com/googleapi/answer/6158862",
command="`{}set api youtube api_key {}`".format( command="`{}set api youtube api_key {}`".format(
ctx.clean_prefix, _("<your_api_key_here>") ctx.clean_prefix, _("<your_api_key_here>")
) ),
) )
await ctx.maybe_send_embed(message) await ctx.maybe_send_embed(message)
@ -576,10 +584,18 @@ class Streams(commands.Cog):
current_setting = await self.config.guild(guild).mention_everyone() current_setting = await self.config.guild(guild).mention_everyone()
if current_setting: if current_setting:
await self.config.guild(guild).mention_everyone.set(False) await self.config.guild(guild).mention_everyone.set(False)
await ctx.send(_("`@\u200beveryone` will no longer be mentioned for stream alerts.")) await ctx.send(
_("{everyone} will no longer be mentioned for stream alerts.").format(
everyone=inline("@\u200beveryone")
)
)
else: else:
await self.config.guild(guild).mention_everyone.set(True) await self.config.guild(guild).mention_everyone.set(True)
await ctx.send(_("When a stream is live, `@\u200beveryone` will be mentioned.")) await ctx.send(
_("When a stream is live, {everyone} will be mentioned.").format(
everyone=inline("@\u200beveryone")
)
)
@mention.command(aliases=["here"]) @mention.command(aliases=["here"])
@commands.guild_only() @commands.guild_only()
@ -589,10 +605,18 @@ class Streams(commands.Cog):
current_setting = await self.config.guild(guild).mention_here() current_setting = await self.config.guild(guild).mention_here()
if current_setting: if current_setting:
await self.config.guild(guild).mention_here.set(False) await self.config.guild(guild).mention_here.set(False)
await ctx.send(_("`@\u200bhere` will no longer be mentioned for stream alerts.")) await ctx.send(
_("{here} will no longer be mentioned for stream alerts.").format(
here=inline("@\u200bhere")
)
)
else: else:
await self.config.guild(guild).mention_here.set(True) await self.config.guild(guild).mention_here.set(True)
await ctx.send(_("When a stream is live, `@\u200bhere` will be mentioned.")) await ctx.send(
_("When a stream is live, {here} will be mentioned.").format(
here=inline("@\u200bhere")
)
)
@mention.command() @mention.command()
@commands.guild_only() @commands.guild_only()
@ -602,15 +626,15 @@ class Streams(commands.Cog):
if current_setting: if current_setting:
await self.config.role(role).mention.set(False) await self.config.role(role).mention.set(False)
await ctx.send( await ctx.send(
_("`@\u200b{role.name}` will no longer be mentioned for stream alerts.").format( _("{role} will no longer be mentioned for stream alerts.").format(
role=role role=inline(f"@\u200b{role.name}")
) )
) )
else: else:
await self.config.role(role).mention.set(True) await self.config.role(role).mention.set(True)
msg = _( msg = _("When a stream or community is live, {role} will be mentioned.").format(
"When a stream or community is live, `@\u200b{role.name}` will be mentioned." role=inline(f"@\u200b{role.name}")
).format(role=role) )
if not role.mentionable: if not role.mentionable:
msg += " " + _( msg += " " + _(
"Since the role is not mentionable, it will be momentarily made mentionable " "Since the role is not mentionable, it will be momentarily made mentionable "

View File

@ -42,7 +42,15 @@ from ..i18n import Translator
from ..utils import menus from ..utils import menus
from ..utils.mod import mass_purge from ..utils.mod import mass_purge
from ..utils._internal_utils import fuzzy_command_search, format_fuzzy_results from ..utils._internal_utils import fuzzy_command_search, format_fuzzy_results
from ..utils.chat_formatting import box, humanize_list, humanize_number, humanize_timedelta, pagify from ..utils.chat_formatting import (
bold,
box,
humanize_list,
humanize_number,
humanize_timedelta,
pagify,
underline,
)
__all__ = ["red_help", "RedHelpFormatter", "HelpSettings", "HelpFormatterABC"] __all__ = ["red_help", "RedHelpFormatter", "HelpSettings", "HelpFormatterABC"]
@ -274,9 +282,12 @@ class RedHelpFormatter(HelpFormatterABC):
@staticmethod @staticmethod
def get_default_tagline(ctx: Context): def get_default_tagline(ctx: Context):
return _( return _(
"Type {ctx.clean_prefix}help <command> for more info on a command. " "Type {command1} for more info on a command. "
"You can also type {ctx.clean_prefix}help <category> for more info on a category." "You can also type {command2} for more info on a category."
).format(ctx=ctx) ).format(
command1=f"{ctx.clean_prefix}help <command>",
command2=f"{ctx.clean_prefix}help <category>",
)
@staticmethod @staticmethod
def get_command_signature(ctx: Context, command: commands.Command) -> str: def get_command_signature(ctx: Context, command: commands.Command) -> str:
@ -390,9 +401,9 @@ class RedHelpFormatter(HelpFormatterABC):
) )
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 = bold(underline(_("Subcommands:")))
else: else:
title = _("**__Subcommands:__** (continued)") title = bold(underline(_("Subcommands: (continued)")))
field = EmbedField(title, page, False) field = EmbedField(title, page, False)
emb["fields"].append(field) emb["fields"].append(field)
@ -560,14 +571,14 @@ class RedHelpFormatter(HelpFormatterABC):
return a_line[:67].rstrip() + "..." return a_line[:67].rstrip() + "..."
command_text = "\n".join( command_text = "\n".join(
shorten_line(f"**{name}** {command.format_shortdoc_for_context(ctx)}") shorten_line(f"{bold(name)} {command.format_shortdoc_for_context(ctx)}")
for name, command in sorted(coms.items()) for name, command in sorted(coms.items())
) )
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 = f"{underline(bold(_('Commands:')))}"
else: else:
title = _("**__Commands:__** (continued)") title = f"{underline(bold(_('Commands: (continued)')))}"
field = EmbedField(title, page, False) field = EmbedField(title, page, False)
emb["fields"].append(field) emb["fields"].append(field)
@ -617,9 +628,9 @@ class RedHelpFormatter(HelpFormatterABC):
for cog_name, data in coms: for cog_name, data in coms:
if cog_name: if cog_name:
title = f"**__{cog_name}:__**" title = f"{underline(bold(cog_name))}:"
else: else:
title = _("**__No Category:__**") title = f"{underline(bold(_('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
@ -736,7 +747,7 @@ class RedHelpFormatter(HelpFormatterABC):
else: else:
await ctx.send(ret) await ctx.send(ret)
elif help_settings.verify_exists: elif help_settings.verify_exists:
ret = _("Help topic for *{command_name}* not found.").format(command_name=help_for) ret = _("Help topic for {command_name} not found.").format(command_name=bold(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( ret.set_author(
@ -753,8 +764,8 @@ class RedHelpFormatter(HelpFormatterABC):
""" """
Sends an error Sends an error
""" """
ret = _("Command *{command_name}* has no subcommand named *{not_found}*.").format( ret = _("Command {command_name} has no subcommand named {not_found}.").format(
command_name=command.qualified_name, not_found=not_found[0] command_name=bold(command.qualified_name), not_found=bold(not_found[0])
) )
if await self.embed_requested(ctx): if await self.embed_requested(ctx):
ret = discord.Embed(color=(await ctx.embed_color()), description=ret) ret = discord.Embed(color=(await ctx.embed_color()), description=ret)

View File

@ -2612,7 +2612,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
status = ctx.bot.guilds[0].me.status if len(ctx.bot.guilds) > 0 else discord.Status.online status = ctx.bot.guilds[0].me.status if len(ctx.bot.guilds) > 0 else discord.Status.online
await ctx.bot.change_presence(status=status, activity=game) await ctx.bot.change_presence(status=status, activity=game)
if game: if game:
await ctx.send(_("Status set to ``Playing {game.name}``.").format(game=game)) await ctx.send(_("Status set to `Playing {game.name}`.").format(game=game))
else: else:
await ctx.send(_("Game cleared.")) await ctx.send(_("Game cleared."))
@ -2646,7 +2646,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
await ctx.bot.change_presence(status=status, activity=activity) await ctx.bot.change_presence(status=status, activity=activity)
if activity: if activity:
await ctx.send( await ctx.send(
_("Status set to ``Listening to {listening}``.").format(listening=listening) _("Status set to `Listening to {listening}`.").format(listening=listening)
) )
else: else:
await ctx.send(_("Listening cleared.")) await ctx.send(_("Listening cleared."))
@ -2678,7 +2678,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
activity = None activity = None
await ctx.bot.change_presence(status=status, activity=activity) await ctx.bot.change_presence(status=status, activity=activity)
if activity: if activity:
await ctx.send(_("Status set to ``Watching {watching}``.").format(watching=watching)) await ctx.send(_("Status set to `Watching {watching}`.").format(watching=watching))
else: else:
await ctx.send(_("Watching cleared.")) await ctx.send(_("Watching cleared."))
@ -2712,7 +2712,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
await ctx.bot.change_presence(status=status, activity=activity) await ctx.bot.change_presence(status=status, activity=activity)
if activity: if activity:
await ctx.send( await ctx.send(
_("Status set to ``Competing in {competing}``.").format(competing=competing) _("Status set to `Competing in {competing}`.").format(competing=competing)
) )
else: else:
await ctx.send(_("Competing cleared.")) await ctx.send(_("Competing cleared."))
@ -3115,7 +3115,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
Secrets are not shown. Secrets are not shown.
**Example:** **Example:**
- `[p]set api list`` - `[p]set api list`
""" """
services: dict = await ctx.bot.get_shared_api_tokens() services: dict = await ctx.bot.get_shared_api_tokens()
@ -3589,7 +3589,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
Warning: These settings may not be accurate if the default formatter is not in use. Warning: These settings may not be accurate if the default formatter is not in use.
**Example:** **Example:**
- `[p]helpset showsettings`` - `[p]helpset showsettings`
""" """
help_settings = await commands.help.HelpSettings.from_context(ctx) help_settings = await commands.help.HelpSettings.from_context(ctx)
@ -3611,7 +3611,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
This resets [botname]'s help formatter to the default formatter. This resets [botname]'s help formatter to the default formatter.
**Example:** **Example:**
- `[p]helpset resetformatter`` - `[p]helpset resetformatter`
""" """
ctx.bot.reset_help_formatter() ctx.bot.reset_help_formatter()
@ -3631,7 +3631,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic):
This may not have an impact when using custom formatters from 3rd party cogs This may not have an impact when using custom formatters from 3rd party cogs
**Example:** **Example:**
- `[p]helpset resetsettings`` - `[p]helpset resetsettings`
""" """
await ctx.bot._config.help.clear() await ctx.bot._config.help.clear()
await ctx.send( await ctx.send(

View File

@ -15,7 +15,7 @@ from .utils.common_filters import (
filter_urls, filter_urls,
escape_spoilers, escape_spoilers,
) )
from .utils.chat_formatting import pagify from .utils.chat_formatting import bold, pagify
from .i18n import Translator, set_contextual_locales_from_guild from .i18n import Translator, set_contextual_locales_from_guild
from .generic_casetypes import all_generics from .generic_casetypes import all_generics
@ -486,7 +486,7 @@ class Case:
if embed: if embed:
if self.reason: if self.reason:
reason = _("**Reason:** {}").format(self.reason) reason = f"{bold(_('Reason:'))} {self.reason}"
if len(reason) > 2048: if len(reason) > 2048:
reason = ( reason = (
next( next(
@ -521,7 +521,7 @@ class Case:
return emb return emb
else: else:
if self.reason: if self.reason:
reason = _("**Reason:** {}").format(self.reason) reason = f"{bold(_('Reason:'))} {self.reason}"
if len(reason) > 1000: if len(reason) > 1000:
reason = ( reason = (
next( next(
@ -536,20 +536,20 @@ class Case:
user = filter_mass_mentions(filter_urls(user)) # Further sanitization outside embeds user = filter_mass_mentions(filter_urls(user)) # Further sanitization outside embeds
case_text = "" case_text = ""
case_text += "{}\n".format(title) case_text += "{}\n".format(title)
case_text += _("**User:** {}\n").format(user) case_text += f"{bold(_('User:'))} {user}\n"
case_text += _("**Moderator:** {}\n").format(moderator) case_text += f"{bold(_('Moderator:'))} {moderator}\n"
case_text += "{}\n".format(reason) case_text += "{}\n".format(reason)
if until and duration: if until and duration:
case_text += _("**Until:** {}\n**Duration:** {}\n").format(until, duration) case_text += f"{bold(_('Until:'))} {until}\n{bold(_('Duration:'))} {duration}\n"
if self.channel: if self.channel:
if isinstance(self.channel, int): if isinstance(self.channel, int):
case_text += _("**Channel**: {} (Deleted)\n").format(self.channel) case_text += f"{bold(_('Channel:'))} {self.channel} {_('(Deleted)')}\n"
else: else:
case_text += _("**Channel**: {}\n").format(self.channel.name) case_text += f"{bold(_('Channel:'))} {self.channel.name}\n"
if amended_by: if amended_by:
case_text += _("**Amended by:** {}\n").format(amended_by) case_text += f"{bold(_('Amended by:'))} {amended_by}\n"
if last_modified: if last_modified:
case_text += _("**Last modified at:** {}\n").format(last_modified) case_text += f"{bold(_('Last modified at:'))} {last_modified}\n"
return case_text.strip() return case_text.strip()
def to_json(self) -> dict: def to_json(self) -> dict: