[i18n] User-facing string pass over admin, alias and audio

This commit is contained in:
Toby Harradine 2018-08-16 10:10:03 +10:00
parent aa8c9c350e
commit 3a20c11331
5 changed files with 439 additions and 366 deletions

View File

@ -14,26 +14,30 @@ log = logging.getLogger("red.admin")
_ = Translator("Admin", __file__) _ = Translator("Admin", __file__)
GENERIC_FORBIDDEN = _( # The following are all lambdas to allow us to fetch the translation
# during runtime, without having to copy the large strings everywhere
# in the code.
generic_forbidden = lambda: _(
"I attempted to do something that Discord denied me permissions for." "I attempted to do something that Discord denied me permissions for."
" Your command failed to successfully complete." " Your command failed to successfully complete."
) )
HIERARCHY_ISSUE = _( hierarchy_issue = lambda: _(
"I tried to add {role.name} to {member.display_name} but that role" "I tried to add {role.name} to {member.display_name} but that role"
" is higher than my highest role in the Discord hierarchy so I was" " is higher than my highest role in the Discord hierarchy so I was"
" unable to successfully add it. Please give me a higher role and " " unable to successfully add it. Please give me a higher role and "
"try again." "try again."
) )
USER_HIERARCHY_ISSUE = _( user_hierarchy_issue = lambda: _(
"I tried to add {role.name} to {member.display_name} but that role" "I tried to add {role.name} to {member.display_name} but that role"
" is higher than your highest role in the Discord hierarchy so I was" " is higher than your highest role in the Discord hierarchy so I was"
" unable to successfully add it. Please get a higher role and " " unable to successfully add it. Please get a higher role and "
"try again." "try again."
) )
RUNNING_ANNOUNCEMENT = _( running_announcement = lambda: _(
"I am already announcing something. If you would like to make a" "I am already announcing something. If you would like to make a"
" different announcement please use `{prefix}announce cancel`" " different announcement please use `{prefix}announce cancel`"
" first." " first."
@ -42,6 +46,7 @@ RUNNING_ANNOUNCEMENT = _(
@cog_i18n(_) @cog_i18n(_)
class Admin(commands.Cog): class Admin(commands.Cog):
"""A collection of server administration utilities."""
def __init__(self, config=Config): def __init__(self, config=Config):
super().__init__() super().__init__()
self.conf = config.get_conf(self, 8237492837454039, force_registration=True) self.conf = config.get_conf(self, 8237492837454039, force_registration=True)
@ -101,9 +106,9 @@ class Admin(commands.Cog):
await member.add_roles(role) await member.add_roles(role)
except discord.Forbidden: except discord.Forbidden:
if not self.pass_hierarchy_check(ctx, role): if not self.pass_hierarchy_check(ctx, role):
await self.complain(ctx, HIERARCHY_ISSUE, role=role, member=member) await self.complain(ctx, hierarchy_issue(), role=role, member=member)
else: else:
await self.complain(ctx, GENERIC_FORBIDDEN) await self.complain(ctx, generic_forbidden())
else: else:
await ctx.send( await ctx.send(
_("I successfully added {role.name} to {member.display_name}").format( _("I successfully added {role.name} to {member.display_name}").format(
@ -116,9 +121,9 @@ class Admin(commands.Cog):
await member.remove_roles(role) await member.remove_roles(role)
except discord.Forbidden: except discord.Forbidden:
if not self.pass_hierarchy_check(ctx, role): if not self.pass_hierarchy_check(ctx, role):
await self.complain(ctx, HIERARCHY_ISSUE, role=role, member=member) await self.complain(ctx, hierarchy_issue(), role=role, member=member)
else: else:
await self.complain(ctx, GENERIC_FORBIDDEN) await self.complain(ctx, generic_forbidden())
else: else:
await ctx.send( await ctx.send(
_("I successfully removed {role.name} from {member.display_name}").format( _("I successfully removed {role.name} from {member.display_name}").format(
@ -132,8 +137,8 @@ class Admin(commands.Cog):
async def addrole( async def addrole(
self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None
): ):
""" """Add a role to a user.
Adds a role to a user.
If user is left blank it defaults to the author of the command. If user is left blank it defaults to the author of the command.
""" """
if user is None: if user is None:
@ -142,7 +147,7 @@ class Admin(commands.Cog):
# noinspection PyTypeChecker # noinspection PyTypeChecker
await self._addrole(ctx, user, rolename) await self._addrole(ctx, user, rolename)
else: else:
await self.complain(ctx, USER_HIERARCHY_ISSUE, member=ctx.author, role=rolename) await self.complain(ctx, user_hierarchy_issue(), member=ctx.author, role=rolename)
@commands.command() @commands.command()
@commands.guild_only() @commands.guild_only()
@ -150,8 +155,8 @@ class Admin(commands.Cog):
async def removerole( async def removerole(
self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None
): ):
""" """Remove a role from a user.
Removes a role from a user.
If user is left blank it defaults to the author of the command. If user is left blank it defaults to the author of the command.
""" """
if user is None: if user is None:
@ -160,38 +165,40 @@ class Admin(commands.Cog):
# noinspection PyTypeChecker # noinspection PyTypeChecker
await self._removerole(ctx, user, rolename) await self._removerole(ctx, user, rolename)
else: else:
await self.complain(ctx, USER_HIERARCHY_ISSUE) await self.complain(ctx, user_hierarchy_issue())
@commands.group() @commands.group()
@commands.guild_only() @commands.guild_only()
@checks.admin_or_permissions(manage_roles=True) @checks.admin_or_permissions(manage_roles=True)
async def editrole(self, ctx: commands.Context): async def editrole(self, ctx: commands.Context):
"""Edits roles settings""" """Edit role settings."""
pass pass
@editrole.command(name="colour", aliases=["color"]) @editrole.command(name="colour", aliases=["color"])
async def editrole_colour( async def editrole_colour(
self, ctx: commands.Context, role: discord.Role, value: discord.Colour self, ctx: commands.Context, role: discord.Role, value: discord.Colour
): ):
"""Edits a role's colour """Edit a role's colour.
Use double quotes if the role contains spaces. Use double quotes if the role contains spaces.
Colour must be in hexadecimal format. Colour must be in hexadecimal format.
\"http://www.w3schools.com/colors/colors_picker.asp\" [Online colour picker](http://www.w3schools.com/colors/colors_picker.asp)
Examples: Examples:
!editrole colour \"The Transistor\" #ff0000 `[p]editrole colour "The Transistor" #ff0000`
!editrole colour Test #ff9900""" `[p]editrole colour Test #ff9900`
"""
author = ctx.author author = ctx.author
reason = "{}({}) changed the colour of role '{}'".format(author.name, author.id, role.name) reason = "{}({}) changed the colour of role '{}'".format(author.name, author.id, role.name)
if not self.pass_user_hierarchy_check(ctx, role): if not self.pass_user_hierarchy_check(ctx, role):
await self.complain(ctx, USER_HIERARCHY_ISSUE) await self.complain(ctx, user_hierarchy_issue())
return return
try: try:
await role.edit(reason=reason, color=value) await role.edit(reason=reason, color=value)
except discord.Forbidden: except discord.Forbidden:
await self.complain(ctx, GENERIC_FORBIDDEN) await self.complain(ctx, generic_forbidden())
else: else:
log.info(reason) log.info(reason)
await ctx.send(_("Done.")) await ctx.send(_("Done."))
@ -199,11 +206,13 @@ class Admin(commands.Cog):
@editrole.command(name="name") @editrole.command(name="name")
@checks.admin_or_permissions(administrator=True) @checks.admin_or_permissions(administrator=True)
async def edit_role_name(self, ctx: commands.Context, role: discord.Role, *, name: str): async def edit_role_name(self, ctx: commands.Context, role: discord.Role, *, name: str):
"""Edits a role's name """Edit a role's name.
Use double quotes if the role or the name contain spaces. Use double quotes if the role or the name contain spaces.
Examples: Examples:
!editrole name \"The Transistor\" Test""" `[p]editrole name \"The Transistor\" Test`
"""
author = ctx.message.author author = ctx.message.author
old_name = role.name old_name = role.name
reason = "{}({}) changed the name of role '{}' to '{}'".format( reason = "{}({}) changed the name of role '{}' to '{}'".format(
@ -211,13 +220,13 @@ class Admin(commands.Cog):
) )
if not self.pass_user_hierarchy_check(ctx, role): if not self.pass_user_hierarchy_check(ctx, role):
await self.complain(ctx, USER_HIERARCHY_ISSUE) await self.complain(ctx, user_hierarchy_issue())
return return
try: try:
await role.edit(reason=reason, name=name) await role.edit(reason=reason, name=name)
except discord.Forbidden: except discord.Forbidden:
await self.complain(ctx, GENERIC_FORBIDDEN) await self.complain(ctx, generic_forbidden())
else: else:
log.info(reason) log.info(reason)
await ctx.send(_("Done.")) await ctx.send(_("Done."))
@ -225,9 +234,7 @@ class Admin(commands.Cog):
@commands.group(invoke_without_command=True) @commands.group(invoke_without_command=True)
@checks.is_owner() @checks.is_owner()
async def announce(self, ctx: commands.Context, *, message: str): async def announce(self, ctx: commands.Context, *, message: str):
""" """Announce a message to all servers the bot is in."""
Announces a message to all servers the bot is in.
"""
if not self.is_announcing(): if not self.is_announcing():
announcer = Announcer(ctx, message, config=self.conf) announcer = Announcer(ctx, message, config=self.conf)
announcer.start() announcer.start()
@ -237,14 +244,12 @@ class Admin(commands.Cog):
await ctx.send(_("The announcement has begun.")) await ctx.send(_("The announcement has begun."))
else: else:
prefix = ctx.prefix prefix = ctx.prefix
await self.complain(ctx, RUNNING_ANNOUNCEMENT, prefix=prefix) await self.complain(ctx, running_announcement(), prefix=prefix)
@announce.command(name="cancel") @announce.command(name="cancel")
@checks.is_owner() @checks.is_owner()
async def announce_cancel(self, ctx): async def announce_cancel(self, ctx):
""" """Cancel a running announce."""
Cancels a running announce.
"""
try: try:
self.__current_announcer.cancel() self.__current_announcer.cancel()
except AttributeError: except AttributeError:
@ -256,9 +261,7 @@ class Admin(commands.Cog):
@commands.guild_only() @commands.guild_only()
@checks.guildowner_or_permissions(administrator=True) @checks.guildowner_or_permissions(administrator=True)
async def announce_channel(self, ctx, *, channel: discord.TextChannel = None): async def announce_channel(self, ctx, *, channel: discord.TextChannel = None):
""" """Change the channel to which the bot makes announcements."""
Changes the channel on which the bot makes announcements.
"""
if channel is None: if channel is None:
channel = ctx.channel channel = ctx.channel
await self.conf.guild(ctx.guild).announce_channel.set(channel.id) await self.conf.guild(ctx.guild).announce_channel.set(channel.id)
@ -271,9 +274,7 @@ class Admin(commands.Cog):
@commands.guild_only() @commands.guild_only()
@checks.guildowner_or_permissions(administrator=True) @checks.guildowner_or_permissions(administrator=True)
async def announce_ignore(self, ctx): async def announce_ignore(self, ctx):
""" """Toggle announcements being enabled this server."""
Toggles whether the announcements will ignore the current server.
"""
ignored = await self.conf.guild(ctx.guild).announce_ignore() ignored = await self.conf.guild(ctx.guild).announce_ignore()
await self.conf.guild(ctx.guild).announce_ignore.set(not ignored) await self.conf.guild(ctx.guild).announce_ignore.set(not ignored)
@ -309,8 +310,9 @@ class Admin(commands.Cog):
@commands.guild_only() @commands.guild_only()
@commands.group(invoke_without_command=True) @commands.group(invoke_without_command=True)
async def selfrole(self, ctx: commands.Context, *, selfrole: SelfRole): async def selfrole(self, ctx: commands.Context, *, selfrole: SelfRole):
""" """Add a role to yourself.
Add a role to yourself that server admins have configured as user settable.
Server admins must have configured the role as user settable.
NOTE: The role is case sensitive! NOTE: The role is case sensitive!
""" """
@ -319,8 +321,7 @@ class Admin(commands.Cog):
@selfrole.command(name="remove") @selfrole.command(name="remove")
async def selfrole_remove(self, ctx: commands.Context, *, selfrole: SelfRole): async def selfrole_remove(self, ctx: commands.Context, *, selfrole: SelfRole):
""" """Remove a selfrole from yourself.
Removes a selfrole from yourself.
NOTE: The role is case sensitive! NOTE: The role is case sensitive!
""" """
@ -330,8 +331,7 @@ class Admin(commands.Cog):
@selfrole.command(name="add") @selfrole.command(name="add")
@checks.admin_or_permissions(manage_roles=True) @checks.admin_or_permissions(manage_roles=True)
async def selfrole_add(self, ctx: commands.Context, *, role: discord.Role): async def selfrole_add(self, ctx: commands.Context, *, role: discord.Role):
""" """Add a role to the list of available selfroles.
Add a role to the list of available selfroles.
NOTE: The role is case sensitive! NOTE: The role is case sensitive!
""" """
@ -344,8 +344,7 @@ class Admin(commands.Cog):
@selfrole.command(name="delete") @selfrole.command(name="delete")
@checks.admin_or_permissions(manage_roles=True) @checks.admin_or_permissions(manage_roles=True)
async def selfrole_delete(self, ctx: commands.Context, *, role: SelfRole): async def selfrole_delete(self, ctx: commands.Context, *, role: SelfRole):
""" """Remove a role from the list of available selfroles.
Removes a role from the list of available selfroles.
NOTE: The role is case sensitive! NOTE: The role is case sensitive!
""" """
@ -362,7 +361,7 @@ class Admin(commands.Cog):
selfroles = await self._valid_selfroles(ctx.guild) selfroles = await self._valid_selfroles(ctx.guild)
fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles]) fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles])
msg = _("Available Selfroles:\n{selfroles}").format(selfroles=fmt_selfroles) msg = _("Available Selfroles: {selfroles}").format(selfroles=fmt_selfroles)
await ctx.send(box(msg, "diff")) await ctx.send(box(msg, "diff"))
async def _serverlock_check(self, guild: discord.Guild) -> bool: async def _serverlock_check(self, guild: discord.Guild) -> bool:
@ -379,9 +378,7 @@ class Admin(commands.Cog):
@commands.command() @commands.command()
@checks.is_owner() @checks.is_owner()
async def serverlock(self, ctx: commands.Context): async def serverlock(self, ctx: commands.Context):
""" """Lock a bot to its current servers only."""
Locks a bot to its current servers only.
"""
serverlocked = await self.conf.serverlocked() serverlocked = await self.conf.serverlocked()
await self.conf.serverlocked.set(not serverlocked) await self.conf.serverlocked.set(not serverlocked)

View File

@ -2,6 +2,9 @@ import asyncio
import discord import discord
from redbot.core import commands from redbot.core import commands
from redbot.core.i18n import Translator
_ = Translator("Announcer", __file__)
class Announcer: class Announcer:
@ -63,7 +66,9 @@ class Announcer:
try: try:
await channel.send(self.message) await channel.send(self.message)
except discord.Forbidden: except discord.Forbidden:
await bot_owner.send("I could not announce to server: {}".format(g.id)) await bot_owner.send(
_("I could not announce to server: {server.id}").format(server=g)
)
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
self.active = False self.active = False

View File

@ -1,5 +1,8 @@
import discord import discord
from redbot.core import commands from redbot.core import commands
from redbot.core.i18n import Translator
_ = Translator("AdminConverters", __file__)
class MemberDefaultAuthor(commands.Converter): class MemberDefaultAuthor(commands.Converter):
@ -19,7 +22,7 @@ class SelfRole(commands.Converter):
async def convert(self, ctx: commands.Context, arg: str) -> discord.Role: async def convert(self, ctx: commands.Context, arg: str) -> discord.Role:
admin = ctx.command.instance admin = ctx.command.instance
if admin is None: if admin is None:
raise commands.BadArgument("Admin is not loaded.") raise commands.BadArgument(_("The Admin cog is not loaded."))
conf = admin.conf conf = admin.conf
selfroles = await conf.guild(ctx.guild).selfroles() selfroles = await conf.guild(ctx.guild).selfroles()
@ -28,5 +31,5 @@ class SelfRole(commands.Converter):
role = await role_converter.convert(ctx, arg) role = await role_converter.convert(ctx, arg)
if role.id not in selfroles: if role.id not in selfroles:
raise commands.BadArgument("The provided role is not a valid selfrole.") raise commands.BadArgument(_("The provided role is not a valid selfrole."))
return role return role

View File

@ -15,15 +15,14 @@ _ = Translator("Alias", __file__)
@cog_i18n(_) @cog_i18n(_)
class Alias(commands.Cog): class Alias(commands.Cog):
""" """Create aliases for commands.
Alias
Aliases are alternative names shortcuts for commands. They
Aliases are per server shortcuts for commands. They can act as both a lambda (storing arguments for repeated use)
can act as both a lambda (storing arguments for repeated use) or as simply a shortcut to saying "x y z".
or as simply a shortcut to saying "x y z".
When run, aliases will accept any additional arguments When run, aliases will accept any additional arguments
and append them to the stored alias and append them to the stored alias.
""" """
default_global_settings = {"entries": []} default_global_settings = {"entries": []}
@ -114,9 +113,8 @@ class Alias(commands.Cog):
return False return False
async def get_prefix(self, message: discord.Message) -> str: async def get_prefix(self, message: discord.Message) -> str:
""" """Tries to determine what prefix is used in a message object.
Tries to determine what prefix is used in a message object. Looks to identify from longest prefix to smallest.
Looks to identify from longest prefix to smallest.
Will raise ValueError if no prefix is found. Will raise ValueError if no prefix is found.
:param message: Message object :param message: Message object
@ -177,23 +175,19 @@ class Alias(commands.Cog):
@commands.group() @commands.group()
@commands.guild_only() @commands.guild_only()
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."""
pass pass
@alias.group(name="global") @alias.group(name="global")
async def global_(self, ctx: commands.Context): async def global_(self, ctx: commands.Context):
""" """Manage global aliases."""
Manage global aliases.
"""
pass pass
@checks.mod_or_permissions(manage_guild=True) @checks.mod_or_permissions(manage_guild=True)
@alias.command(name="add") @alias.command(name="add")
@commands.guild_only() @commands.guild_only()
async def _add_alias(self, ctx: commands.Context, alias_name: str, *, command): async def _add_alias(self, ctx: commands.Context, alias_name: str, *, command):
""" """Add an alias for a command."""
Add an alias for a command.
"""
# region Alias Add Validity Checking # region Alias Add Validity Checking
is_command = self.is_command(alias_name) is_command = self.is_command(alias_name)
if is_command: if is_command:
@ -242,9 +236,7 @@ class Alias(commands.Cog):
@checks.is_owner() @checks.is_owner()
@global_.command(name="add") @global_.command(name="add")
async def _add_global_alias(self, ctx: commands.Context, alias_name: str, *, command): async def _add_global_alias(self, ctx: commands.Context, alias_name: str, *, command):
""" """Add a global alias for a command."""
Add a global alias for a command.
"""
# region Alias Add Validity Checking # region Alias Add Validity Checking
is_command = self.is_command(alias_name) is_command = self.is_command(alias_name)
if is_command: if is_command:
@ -292,7 +284,7 @@ class Alias(commands.Cog):
@alias.command(name="help") @alias.command(name="help")
@commands.guild_only() @commands.guild_only()
async def _help_alias(self, ctx: commands.Context, alias_name: str): async def _help_alias(self, ctx: commands.Context, alias_name: str):
"""Tries to execute help for the base command of the alias""" """Try to execute help for the base command of the alias."""
is_alias, alias = await self.is_alias(ctx.guild, alias_name=alias_name) is_alias, alias = await self.is_alias(ctx.guild, alias_name=alias_name)
if is_alias: if is_alias:
base_cmd = alias.command[0] base_cmd = alias.command[0]
@ -308,7 +300,7 @@ class Alias(commands.Cog):
@alias.command(name="show") @alias.command(name="show")
@commands.guild_only() @commands.guild_only()
async def _show_alias(self, ctx: commands.Context, alias_name: str): async def _show_alias(self, ctx: commands.Context, alias_name: str):
"""Shows what command the alias executes.""" """Show what command the alias executes."""
is_alias, alias = await self.is_alias(ctx.guild, alias_name) is_alias, alias = await self.is_alias(ctx.guild, alias_name)
if is_alias: if is_alias:
@ -324,14 +316,12 @@ class Alias(commands.Cog):
@alias.command(name="del") @alias.command(name="del")
@commands.guild_only() @commands.guild_only()
async def _del_alias(self, ctx: commands.Context, alias_name: str): async def _del_alias(self, ctx: commands.Context, alias_name: str):
""" """Delete an existing alias on this server."""
Deletes an existing alias on this server.
"""
aliases = await self.unloaded_aliases(ctx.guild) aliases = await self.unloaded_aliases(ctx.guild)
try: try:
next(aliases) next(aliases)
except StopIteration: except StopIteration:
await ctx.send(_("There are no aliases on this guild.")) await ctx.send(_("There are no aliases on this server."))
return return
if await self.delete_alias(ctx, alias_name): if await self.delete_alias(ctx, alias_name):
@ -344,9 +334,7 @@ class Alias(commands.Cog):
@checks.is_owner() @checks.is_owner()
@global_.command(name="del") @global_.command(name="del")
async def _del_global_alias(self, ctx: commands.Context, alias_name: str): async def _del_global_alias(self, ctx: commands.Context, alias_name: str):
""" """Delete an existing global alias."""
Deletes an existing global alias.
"""
aliases = await self.unloaded_global_aliases() aliases = await self.unloaded_global_aliases()
try: try:
next(aliases) next(aliases)
@ -364,9 +352,7 @@ class Alias(commands.Cog):
@alias.command(name="list") @alias.command(name="list")
@commands.guild_only() @commands.guild_only()
async def _list_alias(self, ctx: commands.Context): async def _list_alias(self, ctx: commands.Context):
""" """List the available aliases on this server."""
Lists the available aliases on this server.
"""
names = [_("Aliases:")] + sorted( names = [_("Aliases:")] + sorted(
["+ " + a.name for a in (await self.unloaded_aliases(ctx.guild))] ["+ " + a.name for a in (await self.unloaded_aliases(ctx.guild))]
) )
@ -377,9 +363,7 @@ class Alias(commands.Cog):
@global_.command(name="list") @global_.command(name="list")
async def _list_global_alias(self, ctx: commands.Context): async def _list_global_alias(self, ctx: commands.Context):
""" """List the available global aliases on this bot."""
Lists the available global aliases on this bot.
"""
names = [_("Aliases:")] + sorted( names = [_("Aliases:")] + sorted(
["+ " + a.name for a in await self.unloaded_global_aliases()] ["+ " + a.name for a in await self.unloaded_global_aliases()]
) )

File diff suppressed because it is too large Load Diff