diff --git a/redbot/cogs/mod/mod.py b/redbot/cogs/mod/mod.py index b43764609..8a8bd0555 100644 --- a/redbot/cogs/mod/mod.py +++ b/redbot/cogs/mod/mod.py @@ -12,6 +12,7 @@ from redbot.core import Config, modlog, commands from redbot.core.bot import Red 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.chat_formatting import inline from .events import Events from .kickban import KickBanMixin from .names import ModInfo @@ -141,8 +142,8 @@ class Mod( if e["ignored"] is not False: msg = _( "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)) message_sent = True break @@ -151,8 +152,8 @@ class Mod( if e["ignored"] is not False: msg = _( "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) ) @@ -163,8 +164,8 @@ class Mod( if e["delete_delay"] != -1: msg = _( "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)) break await self.config.version.set("1.2.0") diff --git a/redbot/cogs/mod/settings.py b/redbot/cogs/mod/settings.py index 095df9258..12fb07130 100644 --- a/redbot/cogs/mod/settings.py +++ b/redbot/cogs/mod/settings.py @@ -336,15 +336,15 @@ class ModSettings(MixinMeta): if not cur_setting: await self.config.guild(guild).reinvite_on_unban.set(True) await ctx.send( - _("Users unbanned with `{command}` will be reinvited.").format( - command=f"{ctx.clean_prefix}unban" + _("Users unbanned with {command} will be reinvited.").format( + command=inline(f"{ctx.clean_prefix}unban") ) ) else: await self.config.guild(guild).reinvite_on_unban.set(False) await ctx.send( - _("Users unbanned with `{command}` will not be reinvited.").format( - command=f"{ctx.clean_prefix}unban" + _("Users unbanned with {command} will not be reinvited.").format( + command=inline(f"{ctx.clean_prefix}unban") ) ) @@ -463,7 +463,7 @@ class ModSettings(MixinMeta): msg = _( "All name changes will no longer be tracked.\n" "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 ctx.send(msg) diff --git a/redbot/cogs/modlog/modlog.py b/redbot/cogs/modlog/modlog.py index 7e4f310ab..1d630c84a 100644 --- a/redbot/cogs/modlog/modlog.py +++ b/redbot/cogs/modlog/modlog.py @@ -8,7 +8,7 @@ import discord from redbot.core import checks, commands, modlog from redbot.core.bot import Red 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.predicates import MessagePredicate @@ -40,10 +40,7 @@ class ModLog(commands.Cog): if await ctx.embed_requested(): await ctx.send(embed=await case.message_content(embed=True)) else: - message = _("{case}\n**Timestamp:** {timestamp}").format( - case=await case.message_content(embed=False), - timestamp=f"", - ) + message = f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} " await ctx.send(message) @commands.command() @@ -76,10 +73,7 @@ class ModLog(commands.Cog): else: rendered_cases = [] for case in cases: - message = _("{case}\n**Timestamp:** {timestamp}").format( - case=await case.message_content(embed=False), - timestamp=f"", - ) + message = f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} " rendered_cases.append(message) await menu(ctx, rendered_cases, DEFAULT_CONTROLS) @@ -110,10 +104,7 @@ class ModLog(commands.Cog): rendered_cases = [] message = "" for case in cases: - message += _("{case}\n**Timestamp:** {timestamp}\n\n").format( - case=await case.message_content(embed=False), - timestamp=f"", - ) + message += f"{await case.message_content(embed=False)}\n{bold(_('Timestamp:'))} " for page in pagify(message, ["\n\n", "\n"], priority=True): rendered_cases.append(page) await menu(ctx, rendered_cases, DEFAULT_CONTROLS) diff --git a/redbot/cogs/mutes/mutes.py b/redbot/cogs/mutes/mutes.py index e0ef6e5ed..51d93fb5a 100644 --- a/redbot/cogs/mutes/mutes.py +++ b/redbot/cogs/mutes/mutes.py @@ -564,19 +564,13 @@ class Mutes(VoiceMutes, commands.Cog, metaclass=CompositeMetaClass): else: message = f"{title}\n>>> " message += reason + message += (f"\n{bold(_('Moderator:'))} {moderator_str}") if show_mod else "" message += ( - _("\n**Moderator**: {moderator}").format(moderator=moderator_str) - if show_mod - else "" - ) - message += ( - _("\n**Until**: {until}\n**Duration**: {duration}").format( - until=until_str, duration=duration_str - ) + (f"\n{bold(_('Until:'))} {until_str}\n{bold(_('Duration:'))} {duration_str}") if duration else "" ) - message += _("\n**Guild**: {guild_name}").format(guild_name=guild.name) + message += f"\n{bold(_('Guild:'))} {guild.name}" try: await user.send(message) except discord.Forbidden: diff --git a/redbot/cogs/streams/streams.py b/redbot/cogs/streams/streams.py index 139c4380b..2b5f9b803 100644 --- a/redbot/cogs/streams/streams.py +++ b/redbot/cogs/streams/streams.py @@ -3,7 +3,7 @@ from redbot.core.bot import Red from redbot.core import checks, commands, Config 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.chat_formatting import escape, pagify +from redbot.core.utils.chat_formatting import escape, inline, pagify from .streamtypes import ( PicartoStream, @@ -143,7 +143,7 @@ class Streams(commands.Cog): message = _( "You need a client secret key if you want to use the Twitch API on this cog.\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' '3. Click on "New secret".\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 " "or in DM with the bot." ).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( + _(""), _("") + ) + ), ) if notified_owner_missing_twitch_secret is False: await send_to_owners_with_prefix_replaced(self.bot, message) @@ -258,14 +261,14 @@ class Streams(commands.Cog): except InvalidTwitchCredentials: await ctx.send( _("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: await ctx.send( _( "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: await ctx.send( @@ -416,7 +419,7 @@ class Streams(commands.Cog): await ctx.send( _( "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 except InvalidYoutubeCredentials: @@ -424,7 +427,7 @@ class Streams(commands.Cog): _( "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")) ) return except YoutubeQuotaExceeded: @@ -475,9 +478,9 @@ class Streams(commands.Cog): """Explain how to set the twitch token.""" message = _( "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" - "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" "4. Click *Register*.\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" "or in DM with the bot.\n" ).format( + link="https://dev.twitch.tv/dashboard/apps", + localhost=inline("http://localhost"), command="`{}set api twitch client_id {} client_secret {}`".format( ctx.clean_prefix, _(""), _("") - ) + ), ) await ctx.maybe_send_embed(message) @@ -501,19 +506,22 @@ class Streams(commands.Cog): message = _( "To get one, do the following:\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" - "(see https://support.google.com/googleapi/answer/6158841 for instructions)\n" + "(see {link2} for instructions)\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 " "{command}\n\n" "Note: These tokens are sensitive and should only be used in a private channel\n" "or in DM with the bot.\n" ).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( ctx.clean_prefix, _("") - ) + ), ) await ctx.maybe_send_embed(message) @@ -576,10 +584,18 @@ class Streams(commands.Cog): current_setting = await self.config.guild(guild).mention_everyone() if current_setting: 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: 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"]) @commands.guild_only() @@ -589,10 +605,18 @@ class Streams(commands.Cog): current_setting = await self.config.guild(guild).mention_here() if current_setting: 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: 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() @commands.guild_only() @@ -602,15 +626,15 @@ class Streams(commands.Cog): if current_setting: await self.config.role(role).mention.set(False) await ctx.send( - _("`@\u200b{role.name}` will no longer be mentioned for stream alerts.").format( - role=role + _("{role} will no longer be mentioned for stream alerts.").format( + role=inline(f"@\u200b{role.name}") ) ) else: await self.config.role(role).mention.set(True) - msg = _( - "When a stream or community is live, `@\u200b{role.name}` will be mentioned." - ).format(role=role) + msg = _("When a stream or community is live, {role} will be mentioned.").format( + role=inline(f"@\u200b{role.name}") + ) if not role.mentionable: msg += " " + _( "Since the role is not mentionable, it will be momentarily made mentionable " diff --git a/redbot/core/commands/help.py b/redbot/core/commands/help.py index a4ed41bd7..840e8339c 100644 --- a/redbot/core/commands/help.py +++ b/redbot/core/commands/help.py @@ -42,7 +42,15 @@ from ..i18n import Translator from ..utils import menus from ..utils.mod import mass_purge 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"] @@ -274,9 +282,12 @@ class RedHelpFormatter(HelpFormatterABC): @staticmethod def get_default_tagline(ctx: Context): return _( - "Type {ctx.clean_prefix}help for more info on a command. " - "You can also type {ctx.clean_prefix}help for more info on a category." - ).format(ctx=ctx) + "Type {command1} for more info on a command. " + "You can also type {command2} for more info on a category." + ).format( + command1=f"{ctx.clean_prefix}help ", + command2=f"{ctx.clean_prefix}help ", + ) @staticmethod 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)): if i == 0: - title = _("**__Subcommands:__**") + title = bold(underline(_("Subcommands:"))) else: - title = _("**__Subcommands:__** (continued)") + title = bold(underline(_("Subcommands: (continued)"))) field = EmbedField(title, page, False) emb["fields"].append(field) @@ -560,14 +571,14 @@ class RedHelpFormatter(HelpFormatterABC): return a_line[:67].rstrip() + "..." 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 i, page in enumerate(pagify(command_text, page_length=500, shorten_by=0)): if i == 0: - title = _("**__Commands:__**") + title = f"{underline(bold(_('Commands:')))}" else: - title = _("**__Commands:__** (continued)") + title = f"{underline(bold(_('Commands: (continued)')))}" field = EmbedField(title, page, False) emb["fields"].append(field) @@ -617,9 +628,9 @@ class RedHelpFormatter(HelpFormatterABC): for cog_name, data in coms: if cog_name: - title = f"**__{cog_name}:__**" + title = f"{underline(bold(cog_name))}:" else: - title = _("**__No Category:__**") + title = f"{underline(bold(_('No Category:')))}" def shorten_line(a_line: str) -> str: if len(a_line) < 70: # embed max width needs to be lower @@ -736,7 +747,7 @@ class RedHelpFormatter(HelpFormatterABC): else: await ctx.send(ret) 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: ret = discord.Embed(color=(await ctx.embed_color()), description=ret) ret.set_author( @@ -753,8 +764,8 @@ class RedHelpFormatter(HelpFormatterABC): """ Sends an error """ - ret = _("Command *{command_name}* has no subcommand named *{not_found}*.").format( - command_name=command.qualified_name, not_found=not_found[0] + ret = _("Command {command_name} has no subcommand named {not_found}.").format( + command_name=bold(command.qualified_name), not_found=bold(not_found[0]) ) if await self.embed_requested(ctx): ret = discord.Embed(color=(await ctx.embed_color()), description=ret) diff --git a/redbot/core/core_commands.py b/redbot/core/core_commands.py index 91fe5af0b..010b5a623 100644 --- a/redbot/core/core_commands.py +++ b/redbot/core/core_commands.py @@ -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 await ctx.bot.change_presence(status=status, activity=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: 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) if activity: await ctx.send( - _("Status set to ``Listening to {listening}``.").format(listening=listening) + _("Status set to `Listening to {listening}`.").format(listening=listening) ) else: await ctx.send(_("Listening cleared.")) @@ -2678,7 +2678,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic): activity = None await ctx.bot.change_presence(status=status, activity=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: 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) if activity: await ctx.send( - _("Status set to ``Competing in {competing}``.").format(competing=competing) + _("Status set to `Competing in {competing}`.").format(competing=competing) ) else: await ctx.send(_("Competing cleared.")) @@ -3115,7 +3115,7 @@ class Core(commands.commands._RuleDropper, commands.Cog, CoreLogic): Secrets are not shown. **Example:** - - `[p]set api list`` + - `[p]set api list` """ 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. **Example:** - - `[p]helpset showsettings`` + - `[p]helpset showsettings` """ 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. **Example:** - - `[p]helpset resetformatter`` + - `[p]helpset resetformatter` """ 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 **Example:** - - `[p]helpset resetsettings`` + - `[p]helpset resetsettings` """ await ctx.bot._config.help.clear() await ctx.send( diff --git a/redbot/core/modlog.py b/redbot/core/modlog.py index cff882fce..cc3ea7557 100644 --- a/redbot/core/modlog.py +++ b/redbot/core/modlog.py @@ -15,7 +15,7 @@ from .utils.common_filters import ( filter_urls, 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 .generic_casetypes import all_generics @@ -486,7 +486,7 @@ class Case: if embed: if self.reason: - reason = _("**Reason:** {}").format(self.reason) + reason = f"{bold(_('Reason:'))} {self.reason}" if len(reason) > 2048: reason = ( next( @@ -521,7 +521,7 @@ class Case: return emb else: if self.reason: - reason = _("**Reason:** {}").format(self.reason) + reason = f"{bold(_('Reason:'))} {self.reason}" if len(reason) > 1000: reason = ( next( @@ -536,20 +536,20 @@ class Case: user = filter_mass_mentions(filter_urls(user)) # Further sanitization outside embeds case_text = "" case_text += "{}\n".format(title) - case_text += _("**User:** {}\n").format(user) - case_text += _("**Moderator:** {}\n").format(moderator) + case_text += f"{bold(_('User:'))} {user}\n" + case_text += f"{bold(_('Moderator:'))} {moderator}\n" case_text += "{}\n".format(reason) 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 isinstance(self.channel, int): - case_text += _("**Channel**: {} (Deleted)\n").format(self.channel) + case_text += f"{bold(_('Channel:'))} {self.channel} {_('(Deleted)')}\n" else: - case_text += _("**Channel**: {}\n").format(self.channel.name) + case_text += f"{bold(_('Channel:'))} {self.channel.name}\n" if amended_by: - case_text += _("**Amended by:** {}\n").format(amended_by) + case_text += f"{bold(_('Amended by:'))} {amended_by}\n" 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() def to_json(self) -> dict: