Tobotimus 15ea5440a3 [V3 i18n] Internationalise help for commands and cogs (#1143)
* Framework for internationalised command help

* Translator for class docstring of cog

* Remove references to old context module

* Use CogManagerUI as PoC

* Replace all references to RedContext

* Rename CogI18n object to avoid confusion

* Update docs

* Update i18n docs.

* Store translators in list instead of dict

* Change commands module to package, updated refs in cogs

* Updated docs and more references in cogs

* Resolve syntax error

* Update from merge
2018-05-12 01:47:49 +02:00

142 lines
5.1 KiB
Python

from copy import copy
import asyncio
import inspect
import discord
from redbot.core import Config, checks, commands
from redbot.core.i18n import Translator
_ = Translator("Warnings", __file__)
async def warning_points_add_check(config: Config, ctx: commands.Context, user: discord.Member, points: int):
"""Handles any action that needs to be taken or not based on the points"""
guild = ctx.guild
guild_settings = config.guild(guild)
act = {}
async with guild_settings.actions() as registered_actions:
for a in registered_actions:
if points >= a["points"]:
act = a
else:
break
if act: # some action needs to be taken
await create_and_invoke_context(ctx, act["exceed_command"], user)
async def warning_points_remove_check(config: Config, ctx: commands.Context, user: discord.Member, points: int):
guild = ctx.guild
guild_settings = config.guild(guild)
act = {}
async with guild_settings.actions() as registered_actions:
for a in registered_actions:
if points >= a["points"]:
act = a
else:
break
if act: # some action needs to be taken
await create_and_invoke_context(ctx, act["drop_command"], user)
async def create_and_invoke_context(realctx: commands.Context, command_str: str, user: discord.Member):
m = copy(realctx.message)
m.content = command_str.format(user=user.mention, prefix=realctx.prefix)
fctx = await realctx.bot.get_context(m, cls=commands.Context)
try:
await realctx.bot.invoke(fctx)
except (commands.CheckFailure, commands.CommandOnCooldown):
await fctx.reinvoke()
def get_command_from_input(bot, userinput: str):
com = None
orig = userinput
while com is None:
com = bot.get_command(userinput)
if com is None:
userinput = ' '.join(userinput.split(' ')[:-1])
if len(userinput) == 0:
break
if com is None:
return None, _("I could not find a command from that input!")
check_str = inspect.getsource(checks.is_owner)
if any(inspect.getsource(x) in check_str for x in com.checks):
# command the user specified has the is_owner check
return None, _("That command requires bot owner. I can't "
"allow you to use that for an action")
return "{prefix}" + orig, None
async def get_command_for_exceeded_points(ctx: commands.Context):
"""Gets the command to be executed when the user is at or exceeding
the points threshold for the action"""
await ctx.send(
_("Enter the command to be run when the user exceeds the points for "
"this action to occur.\nEnter it exactly as you would if you were "
"actually trying to run the command, except don't put a prefix and "
"use {user} in place of any user/member arguments\n\n"
"WARNING: The command entered will be run without regard to checks or cooldowns. "
"Commands requiring bot owner are not allowed for security reasons.\n\n"
"Please wait 15 seconds before entering your response.")
)
await asyncio.sleep(15)
await ctx.send(_("You may enter your response now."))
def same_author_check(m):
return m.author == ctx.author
try:
msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30)
except asyncio.TimeoutError:
await ctx.send(_("Ok then."))
return None
command, m = get_command_from_input(ctx.bot, msg.content)
if command is None:
await ctx.send(m)
return None
return command
async def get_command_for_dropping_points(ctx: commands.Context):
"""
Gets the command to be executed when the user drops below the points
threshold
This is intended to be used for reversal of the action that was executed
when the user exceeded the threshold
"""
await ctx.send(
_("Enter the command to be run when the user returns to a value below "
"the points for this action to occur. Please note that this is "
"intended to be used for reversal of the action taken when the user "
"exceeded the action's point value\nEnter it exactly as you would "
"if you were actually trying to run the command, except don't put a prefix "
"and use {user} in place of any user/member arguments\n\n"
"WARNING: The command entered will be run without regard to checks or cooldowns. "
"Commands requiring bot owner are not allowed for security reasons.\n\n"
"Please wait 15 seconds before entering your response.")
)
await asyncio.sleep(15)
await ctx.send(_("You may enter your response now."))
def same_author_check(m):
return m.author == ctx.author
try:
msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30)
except asyncio.TimeoutError:
await ctx.send(_("Ok then."))
return None
command, m = get_command_from_input(ctx.bot, msg.content)
if command is None:
await ctx.send(m)
return None
return command