[i18n] Pass over bank, cleanup, customcom, dataconverter, downloader

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
Toby Harradine 2018-08-16 23:51:45 +10:00
parent 3a20c11331
commit 0c3d8af8f4
9 changed files with 123 additions and 131 deletions

View File

@ -1,11 +1,10 @@
import logging
from typing import Tuple
import discord
from redbot.core import Config, checks, commands
import logging
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils.chat_formatting import box
from .announcer import Announcer
from .converters import MemberDefaultAuthor, SelfRole

View File

@ -67,7 +67,7 @@ class Bank(commands.Cog):
@checks.guildowner_or_permissions(administrator=True)
@commands.group(autohelp=True)
async def bankset(self, ctx: commands.Context):
"""Base command for bank settings"""
"""Base command for bank settings."""
if ctx.invoked_subcommand is None:
if await bank.is_global():
bank_name = await bank._conf.bank_name()
@ -91,9 +91,11 @@ class Bank(commands.Cog):
@bankset.command(name="toggleglobal")
@checks.is_owner()
async def bankset_toggleglobal(self, ctx: commands.Context, confirm: bool = False):
"""Toggles whether the bank is global or not
If the bank is global, it will become per-server
If the bank is per-server, it will become global"""
"""Toggle whether the bank is global or not.
If the bank is global, it will become per-server.
If the bank is per-server, it will become global.
"""
cur_setting = await bank.is_global()
word = _("per-server") if cur_setting else _("global")
@ -111,14 +113,14 @@ class Bank(commands.Cog):
@bankset.command(name="bankname")
@check_global_setting_guildowner()
async def bankset_bankname(self, ctx: commands.Context, *, name: str):
"""Set the bank's name"""
"""Set the bank's name."""
await bank.set_bank_name(name, ctx.guild)
await ctx.send(_("Bank name has been set to: {name}").format(name=name))
@bankset.command(name="creditsname")
@check_global_setting_guildowner()
async def bankset_creditsname(self, ctx: commands.Context, *, name: str):
"""Set the name for the bank's currency"""
"""Set the name for the bank's currency."""
await bank.set_currency_name(name, ctx.guild)
await ctx.send(_("Currency name has been set to: {name}").format(name=name))

View File

@ -16,7 +16,7 @@ _ = Translator("Cleanup", __file__)
@cog_i18n(_)
class Cleanup(commands.Cog):
"""Commands for cleaning messages"""
"""Commands for cleaning messages."""
def __init__(self, bot: Red):
super().__init__()
@ -104,7 +104,7 @@ class Cleanup(commands.Cog):
@commands.group()
@checks.mod_or_permissions(manage_messages=True)
async def cleanup(self, ctx: commands.Context):
"""Deletes messages."""
"""Delete messages."""
pass
@cleanup.command()
@ -112,16 +112,17 @@ class Cleanup(commands.Cog):
async def text(
self, ctx: commands.Context, text: str, number: int, delete_pinned: bool = False
):
"""Deletes last X messages matching the specified text.
"""Delete the last X messages matching the specified text.
Example:
cleanup text \"test\" 5
`[p]cleanup text "test" 5`
Remember to use double quotes."""
Remember to use double quotes.
"""
channel = ctx.channel
if not channel.permissions_for(ctx.guild.me).manage_messages:
await ctx.send("I need the Manage Messages permission to do this.")
await ctx.send(_("I need the Manage Messages permission to do this."))
return
author = ctx.author
@ -159,14 +160,15 @@ class Cleanup(commands.Cog):
async def user(
self, ctx: commands.Context, user: str, number: int, delete_pinned: bool = False
):
"""Deletes last X messages from specified user.
"""Delete the last X messages from a specified user.
Examples:
cleanup user @\u200bTwentysix 2
cleanup user Red 6"""
`[p]cleanup user @\u200bTwentysix 2`
`[p]cleanup user Red 6`
"""
channel = ctx.channel
if not channel.permissions_for(ctx.guild.me).manage_messages:
await ctx.send("I need the Manage Messages permission to do this.")
await ctx.send(_("I need the Manage Messages permission to do this."))
return
member = None
@ -214,7 +216,7 @@ class Cleanup(commands.Cog):
@cleanup.command()
@commands.guild_only()
async def after(self, ctx: commands.Context, message_id: int, delete_pinned: bool = False):
"""Deletes all messages after specified message.
"""Delete all messages after a specified message.
To get a message id, enable developer mode in Discord's
settings, 'appearance' tab. Then right click a message
@ -223,7 +225,7 @@ class Cleanup(commands.Cog):
channel = ctx.channel
if not channel.permissions_for(ctx.guild.me).manage_messages:
await ctx.send("I need the Manage Messages permission to do this.")
await ctx.send(_("I need the Manage Messages permission to do this."))
return
author = ctx.author
@ -280,14 +282,15 @@ class Cleanup(commands.Cog):
@cleanup.command()
@commands.guild_only()
async def messages(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
"""Deletes last X messages.
"""Delete the last X messages.
Example:
cleanup messages 26"""
`[p]cleanup messages 26`
"""
channel = ctx.channel
if not channel.permissions_for(ctx.guild.me).manage_messages:
await ctx.send("I need the Manage Messages permission to do this.")
await ctx.send(_("I need the Manage Messages permission to do this."))
return
author = ctx.author
@ -311,11 +314,11 @@ class Cleanup(commands.Cog):
@cleanup.command(name="bot")
@commands.guild_only()
async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
"""Cleans up command messages and messages from the bot."""
"""Clean up command messages and messages from the bot."""
channel = ctx.channel
if not channel.permissions_for(ctx.guild.me).manage_messages:
await ctx.send("I need the Manage Messages permission to do this.")
await ctx.send(_("I need the Manage Messages permission to do this."))
return
author = ctx.message.author
@ -369,7 +372,7 @@ class Cleanup(commands.Cog):
match_pattern: str = None,
delete_pinned: bool = False,
):
"""Cleans up messages owned by the bot.
"""Clean up messages owned by the bot.
By default, all messages are cleaned. If a third argument is specified,
it is used for pattern matching: If it begins with r( and ends with ),

View File

@ -54,7 +54,7 @@ class CommandObj:
intro = _(
"Welcome to the interactive random {cc} maker!\n"
"Every message you send will be added as one of the random "
"responses to choose from once this {} is "
"responses to choose from once this {cc} is "
"triggered. To exit this interactive menu, type `{quit}`"
).format(cc="customcommand", quit="exit()")
await ctx.send(intro)
@ -196,30 +196,26 @@ class CustomCommands(commands.Cog):
@commands.group(aliases=["cc"])
@commands.guild_only()
async def customcom(self, ctx: commands.Context):
"""Custom commands management"""
"""Custom commands management."""
pass
@customcom.group(name="add")
@customcom.group(name="create", aliases=["add"])
@checks.mod_or_permissions(administrator=True)
async def cc_add(self, ctx: commands.Context):
"""
Adds a new custom command
async def cc_create(self, ctx: commands.Context):
"""Create custom commands.
CCs can be enhanced with arguments:
https://red-discordbot.readthedocs.io/en/v3-develop/cog_customcom.html
CCs can be enhanced with arguments, see the guide
[here](https://red-discordbot.readthedocs.io/en/v3-develop/cog_customcom.html).
"""
pass
@cc_add.command(name="random")
@cc_create.command(name="random")
@checks.mod_or_permissions(administrator=True)
async def cc_add_random(self, ctx: commands.Context, command: str.lower):
"""
Create a CC where it will randomly choose a response!
async def cc_create_random(self, ctx: commands.Context, command: str.lower):
"""Create a CC where it will randomly choose a response!
Note: This is interactive
Note: This command is interactive.
"""
responses = []
responses = await self.commandobj.get_responses(ctx=ctx)
try:
await self.commandobj.create(ctx=ctx, command=command, response=responses)
@ -233,16 +229,16 @@ class CustomCommands(commands.Cog):
# await ctx.send(str(responses))
@cc_add.command(name="simple")
@cc_create.command(name="simple")
@checks.mod_or_permissions(administrator=True)
async def cc_add_simple(self, ctx, command: str.lower, *, text: str):
"""Adds a simple custom command
async def cc_create_simple(self, ctx, command: str.lower, *, text: str):
"""Add a simple custom command.
Example:
[p]customcom add simple yourcommand Text you want
- `[p]customcom create simple yourcommand Text you want`
"""
if command in self.bot.all_commands:
await ctx.send(_("That command is already a standard command."))
await ctx.send(_("There already exists a bot command with the same name."))
return
try:
await self.commandobj.create(ctx=ctx, command=command, response=text)
@ -261,13 +257,14 @@ class CustomCommands(commands.Cog):
async def cc_cooldown(
self, ctx, command: str.lower, cooldown: int = None, *, per: str.lower = "member"
):
"""
Sets, edits, or views cooldowns for a custom command
"""Set, edit, or view the cooldown for a custom command.
You may set cooldowns per member, channel, or guild. Multiple
cooldowns may be set. All cooldowns must be cooled to call the
custom command.
You may set cooldowns per member, channel, or guild.
Multiple cooldowns may be set. All cooldowns must be cooled to call the custom command.
Example:
[p]customcom cooldown yourcommand 30
- `[p]customcom cooldown yourcommand 30`
"""
if cooldown is None:
try:
@ -294,17 +291,18 @@ class CustomCommands(commands.Cog):
except NotFound:
await ctx.send(
_("That command doesn't exist. Use `{command}` to add it.").format(
command="{}customcom add".format(ctx.prefix)
command="{}customcom create".format(ctx.prefix)
)
)
@customcom.command(name="delete")
@checks.mod_or_permissions(administrator=True)
async def cc_delete(self, ctx, command: str.lower):
"""Deletes a custom command
"""Delete a custom command
.
Example:
[p]customcom delete yourcommand"""
- `[p]customcom delete yourcommand`
"""
try:
await self.commandobj.delete(ctx=ctx, command=command)
await ctx.send(_("Custom command successfully deleted."))
@ -314,18 +312,20 @@ class CustomCommands(commands.Cog):
@customcom.command(name="edit")
@checks.mod_or_permissions(administrator=True)
async def cc_edit(self, ctx, command: str.lower, *, text: str = None):
"""Edits a custom command's response
"""Edit a custom command.
Example:
[p]customcom edit yourcommand Text you want
- `[p]customcom edit yourcommand Text you want`
"""
command = command.lower()
try:
await self.commandobj.edit(ctx=ctx, command=command, response=text)
await ctx.send(_("Custom command successfully edited."))
except NotFound:
await ctx.send(
_("That command doesn't exist. Use `{}` to add it.").format(
"{}customcom add".format(ctx.prefix)
_("That command doesn't exist. Use `{command}` to add it.").format(
command="{}customcom create".format(ctx.prefix)
)
)
except ArgParseError as e:
@ -333,7 +333,7 @@ class CustomCommands(commands.Cog):
@customcom.command(name="list")
async def cc_list(self, ctx):
"""Shows custom commands list"""
"""List all available custom commands."""
response = await CommandObj.get_commands(self.config.guild(ctx.guild))
@ -342,7 +342,7 @@ class CustomCommands(commands.Cog):
_(
"There are no custom commands in this server."
" Use `{command}` to start adding some."
).format(command="{}customcom add".format(ctx.prefix))
).format(command="{}customcom create".format(ctx.prefix))
)
return

View File

@ -13,9 +13,7 @@ _ = Translator("DataConverter", __file__)
@cog_i18n(_)
class DataConverter(commands.Cog):
"""
Cog for importing Red v2 Data
"""
"""Import Red V2 data to your V3 instance."""
def __init__(self, bot: Red):
super().__init__()
@ -24,13 +22,10 @@ class DataConverter(commands.Cog):
@checks.is_owner()
@commands.command(name="convertdata")
async def dataconversioncommand(self, ctx: commands.Context, v2path: str):
"""
Interactive prompt for importing data from Red v2
"""Interactive prompt for importing data from Red V2.
Takes the path where the v2 install is
Overwrites values which have entries in both v2 and v3,
use with caution.
Takes the path where the V2 install is, and overwrites
values which have entries in both V2 and v3; use with caution.
"""
resolver = SpecResolver(Path(v2path.strip()))
@ -54,7 +49,7 @@ class DataConverter(commands.Cog):
"message", check=MessagePredicate.same_context(ctx), timeout=60
)
except asyncio.TimeoutError:
return await ctx.send(_("Try this again when you are more ready"))
return await ctx.send(_("Try this again when you are ready."))
else:
if message.content.strip().lower() in ["quit", "exit", "-1", "q", "cancel"]:
return await ctx.tick()
@ -72,7 +67,7 @@ class DataConverter(commands.Cog):
else:
return await ctx.send(
_(
"There isn't anything else I know how to convert here."
"\nThere might be more things I can convert in the future."
"There isn't anything else I know how to convert here.\n"
"There might be more things I can convert in the future."
)
)

View File

@ -1,11 +1,15 @@
import asyncio
from redbot.core import commands
from redbot.core.i18n import Translator
from redbot.core.utils.predicates import MessagePredicate
__all__ = ["do_install_agreement"]
REPO_INSTALL_MSG = (
T_ = Translator("DownloaderChecks", __file__)
_ = lambda s: s
REPO_INSTALL_MSG = _(
"You're about to add a 3rd party repository. The creator of Red"
" and its community have no responsibility for any potential "
"damage that the content of 3rd party repositories might cause."
@ -14,6 +18,7 @@ REPO_INSTALL_MSG = (
"shown again until the next reboot.\n\nYou have **30** seconds"
" to reply to this message."
)
_ = T_
async def do_install_agreement(ctx: commands.Context):
@ -21,14 +26,14 @@ async def do_install_agreement(ctx: commands.Context):
if downloader is None or downloader.already_agreed:
return True
await ctx.send(REPO_INSTALL_MSG)
await ctx.send(T_(REPO_INSTALL_MSG))
try:
await ctx.bot.wait_for(
"message", check=MessagePredicate.lower_equal_to("i agree", ctx), timeout=30
)
except asyncio.TimeoutError:
await ctx.send("Your response has timed out, please try again.")
await ctx.send(_("Your response has timed out, please try again."))
return False
downloader.already_agreed = True

View File

@ -8,10 +8,10 @@ class InstalledCog(Installable):
async def convert(cls, ctx: commands.Context, arg: str) -> Installable:
downloader = ctx.bot.get_cog("Downloader")
if downloader is None:
raise commands.CommandError("Downloader not loaded.")
raise commands.CommandError(_("No Downloader cog found."))
cog = discord.utils.get(await downloader.installed_cogs(), name=arg)
if cog is None:
raise commands.BadArgument("That cog is not installed")
raise commands.BadArgument(_("That cog is not installed"))
return cog

View File

@ -8,7 +8,7 @@ from sys import path as syspath
from typing import Tuple, Union, Iterable
import discord
from redbot.core import checks, commands, Config
from redbot.core import checks, commands, Config, checks, commands
from redbot.core.bot import Red
from redbot.core.data_manager import cog_data_path
from redbot.core.i18n import Translator, cog_i18n
@ -193,9 +193,7 @@ class Downloader(commands.Cog):
@commands.command()
@checks.is_owner()
async def pipinstall(self, ctx, *deps: str):
"""
Installs a group of dependencies using pip.
"""
"""Install a group of dependencies using pip."""
repo = Repo("", "", "", Path.cwd(), loop=ctx.bot.loop)
success = await repo.install_raw_requirements(deps, self.LIB_PATH)
@ -212,18 +210,15 @@ class Downloader(commands.Cog):
@commands.group()
@checks.is_owner()
async def repo(self, ctx):
"""
Command group for managing Downloader repos.
"""
"""Repo management commands."""
pass
@repo.command(name="add")
async def _repo_add(self, ctx, name: str, repo_url: str, branch: str = None):
"""
Add a new repo to Downloader.
"""Add a new repo.
Name can only contain characters A-z, numbers and underscore
Branch will default to master if not specified
The name can only contain characters A-z, numbers and underscores.
The branch will default to master if not specified.
"""
agreed = await do_install_agreement(ctx)
if not agreed:
@ -246,11 +241,9 @@ class Downloader(commands.Cog):
if repo.install_msg is not None:
await ctx.send(repo.install_msg.replace("[p]", ctx.prefix))
@repo.command(name="delete")
@repo.command(name="delete", aliases=["remove"])
async def _repo_del(self, ctx, repo_name: Repo):
"""
Removes a repo from Downloader and its' files.
"""
"""Remove a repo and its files."""
await self._repo_manager.delete_repo(repo_name.name)
await ctx.send(
@ -259,9 +252,7 @@ class Downloader(commands.Cog):
@repo.command(name="list")
async def _repo_list(self, ctx):
"""
Lists all installed repos.
"""
"""List all installed repos."""
repos = self._repo_manager.get_all_repo_names()
repos = sorted(repos, key=str.lower)
joined = _("Installed Repos:\n\n")
@ -274,11 +265,9 @@ class Downloader(commands.Cog):
@repo.command(name="info")
async def _repo_info(self, ctx, repo_name: Repo):
"""
Lists information about a single repo
"""
"""Show information about a repo."""
if repo_name is None:
await ctx.send(_("There is no repo `{repo_name}`").format(repo_name=repo_name.name))
await ctx.send(_("Repo `{repo_name}` not found.").format(repo_name=repo_name.name))
return
msg = _("Information on {repo_name}:\n{description}").format(
@ -289,28 +278,24 @@ class Downloader(commands.Cog):
@commands.group()
@checks.is_owner()
async def cog(self, ctx):
"""
Command group for managing installable Cogs.
"""
"""Cog installation management commands."""
pass
@cog.command(name="install")
async def _cog_install(self, ctx, repo_name: Repo, cog_name: str):
"""
Installs a cog from the given repo.
"""
cog = discord.utils.get(repo_name.available_cogs, name=cog_name) # type: Installable
"""Install a cog from the given repo."""
cog: Installable = discord.utils.get(repo_name.available_cogs, name=cog_name)
if cog is None:
await ctx.send(
_(
"Error, there is no cog by the name of `{cog_name}` in the `{repo_name}` repo."
"Error: there is no cog by the name of `{cog_name}` in the `{repo_name}` repo."
).format(cog_name=cog_name, repo_name=repo_name.name)
)
return
elif cog.min_python_version > sys.version_info:
await ctx.send(
_("This cog requires at least python version {}, aborting install.").format(
".".join([str(n) for n in cog.min_python_version])
_("This cog requires at least python version {version}, aborting install.").format(
version=".".join([str(n) for n in cog.min_python_version])
)
)
return
@ -329,15 +314,16 @@ class Downloader(commands.Cog):
await repo_name.install_libraries(self.SHAREDLIB_PATH)
await ctx.send(_("`{cog_name}` cog successfully installed.").format(cog_name=cog_name))
await ctx.send(_("Cog `{cog_name}` successfully installed.").format(cog_name=cog_name))
if cog.install_msg is not None:
await ctx.send(cog.install_msg.replace("[p]", ctx.prefix))
@cog.command(name="uninstall")
async def _cog_uninstall(self, ctx, cog_name: InstalledCog):
"""
Allows you to uninstall cogs that were previously installed
through Downloader.
"""Uninstall a cog.
You may only uninstall cogs which were previously installed
by Downloader.
"""
# noinspection PyUnresolvedReferences,PyProtectedMember
real_name = cog_name.name
@ -348,7 +334,7 @@ class Downloader(commands.Cog):
# noinspection PyTypeChecker
await self._remove_from_installed(cog_name)
await ctx.send(
_("`{real_name}` was successfully removed.").format(real_name=real_name)
_("Cog `{cog_name}` was successfully uninstalled.").format(cog_name=real_name)
)
else:
await ctx.send(
@ -356,14 +342,14 @@ class Downloader(commands.Cog):
"That cog was installed but can no longer"
" be located. You may need to remove it's"
" files manually if it is still usable."
)
" Also make sure you've unloaded the cog"
" with `{prefix}unload {cog_name}`."
).format(cog_name=real_name)
)
@cog.command(name="update")
async def _cog_update(self, ctx, cog_name: InstalledCog = None):
"""
Updates all cogs or one of your choosing.
"""
"""Update all cogs, or one of your choosing."""
installed_cogs = set(await self.installed_cogs())
async with ctx.typing():
@ -426,9 +412,7 @@ class Downloader(commands.Cog):
@cog.command(name="list")
async def _cog_list(self, ctx, repo_name: Repo):
"""
Lists all available cogs from a single repo.
"""
"""List all available cogs from a single repo."""
installed = await self.installed_cogs()
installed_str = ""
if installed:
@ -453,9 +437,7 @@ class Downloader(commands.Cog):
@cog.command(name="info")
async def _cog_info(self, ctx, repo_name: Repo, cog_name: str):
"""
Lists information about a single cog.
"""
"""List information about a single cog."""
cog = discord.utils.get(repo_name.available_cogs, name=cog_name)
if cog is None:
await ctx.send(
@ -549,9 +531,9 @@ class Downloader(commands.Cog):
@commands.command()
async def findcog(self, ctx: commands.Context, command_name: str):
"""
Figures out which cog a command comes from. Only works with loaded
cogs.
"""Find which cog a command comes from.
This will only work with loaded cogs.
"""
command = ctx.bot.all_commands.get(command_name)

View File

@ -12,11 +12,15 @@ from typing import Tuple, MutableMapping, Union, Optional
from redbot.core import data_manager, commands
from redbot.core.utils import safe_delete
from redbot.core.i18n import Translator
from . import errors
from .installable import Installable, InstallableType
from .json_mixins import RepoJSONMixin
from .log import log
_ = Translator("RepoManager", __file__)
class Repo(RepoJSONMixin):
GIT_CLONE = "git clone --recurse-submodules -b {branch} {url} {folder}"
@ -64,13 +68,15 @@ class Repo(RepoJSONMixin):
async def convert(cls, ctx: commands.Context, argument: str):
downloader_cog = ctx.bot.get_cog("Downloader")
if downloader_cog is None:
raise commands.CommandError("No Downloader cog found.")
raise commands.CommandError(_("No Downloader cog found."))
# noinspection PyProtectedMember
repo_manager = downloader_cog._repo_manager
poss_repo = repo_manager.get_repo(argument)
if poss_repo is None:
raise commands.BadArgument("Repo by the name {} does not exist.".format(argument))
raise commands.BadArgument(
_('Repo by the name "{repo_name}" does not exist.').format(repo_name=argument)
)
return poss_repo
def _existing_git_repo(self) -> (bool, Path):