[V3 Warnings] changes to the warnings cog (#1867)

* [V3 Warnings] clarify text on entering commands

* Fix up action commands and allow for no command on both add and remove

* Notify warned user when they receive a warning + disallow warning and unwarning self

* Add myself to COOWNERS for the warnings cog
This commit is contained in:
palmtree5 2018-07-11 17:29:22 -08:00 committed by Kowlin
parent 9d0eca1914
commit 77566a887a
3 changed files with 74 additions and 45 deletions

1
.github/CODEOWNERS vendored
View File

@ -45,6 +45,7 @@ redbot/cogs/trivia/* @Tobotimus
redbot/cogs/dataconverter/* @mikeshardmind redbot/cogs/dataconverter/* @mikeshardmind
redbot/cogs/reports/* @mikeshardmind redbot/cogs/reports/* @mikeshardmind
redbot/cogs/permissions/* @mikeshardmind redbot/cogs/permissions/* @mikeshardmind
redbot/cogs/warnings/* @palmtree5
# Docs # Docs
docs/* @tekulvw @palmtree5 docs/* @tekulvw @palmtree5

View File

@ -22,7 +22,7 @@ async def warning_points_add_check(
act = a act = a
else: else:
break break
if act: # some action needs to be taken if act and act["exceed_command"] is not None: # some action needs to be taken
await create_and_invoke_context(ctx, act["exceed_command"], user) await create_and_invoke_context(ctx, act["exceed_command"], user)
@ -38,7 +38,7 @@ async def warning_points_remove_check(
act = a act = a
else: else:
break break
if act: # some action needs to be taken if act and act["drop_command"] is not None: # some action needs to be taken
await create_and_invoke_context(ctx, act["drop_command"], user) await create_and_invoke_context(ctx, act["drop_command"], user)
@ -81,10 +81,11 @@ async def get_command_for_exceeded_points(ctx: commands.Context):
the points threshold for the action""" the points threshold for the action"""
await ctx.send( await ctx.send(
_( _(
"Enter the command to be run when the user exceeds the points for " "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 " "this action to occur.**\n**If you do not wish to have a command run, enter** "
"`none`.\n\nEnter it exactly as you would if you were "
"actually trying to run the command, except don't put a prefix and " "actually trying to run the command, except don't put a prefix and "
"use {user} in place of any user/member arguments\n\n" "use `{user}` in place of any user/member arguments\n\n"
"WARNING: The command entered will be run without regard to checks or cooldowns. " "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" "Commands requiring bot owner are not allowed for security reasons.\n\n"
"Please wait 15 seconds before entering your response." "Please wait 15 seconds before entering your response."
@ -100,7 +101,9 @@ async def get_command_for_exceeded_points(ctx: commands.Context):
try: try:
msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30) msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30)
except asyncio.TimeoutError: except asyncio.TimeoutError:
await ctx.send(_("Ok then.")) return None
else:
if msg.content == "none":
return None return None
command, m = get_command_from_input(ctx.bot, msg.content) command, m = get_command_from_input(ctx.bot, msg.content)
@ -121,12 +124,13 @@ async def get_command_for_dropping_points(ctx: commands.Context):
""" """
await ctx.send( await ctx.send(
_( _(
"Enter the command to be run when the user returns to a value below " "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 " "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 " "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 " "exceeded the action's point value.\n**If you do not wish to have a command run "
"on dropping points, enter** `none`.\n\nEnter it exactly as you would "
"if you were actually trying to run the command, except don't put a prefix " "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" "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. " "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" "Commands requiring bot owner are not allowed for security reasons.\n\n"
"Please wait 15 seconds before entering your response." "Please wait 15 seconds before entering your response."
@ -142,9 +146,10 @@ async def get_command_for_dropping_points(ctx: commands.Context):
try: try:
msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30) msg = await ctx.bot.wait_for("message", check=same_author_check, timeout=30)
except asyncio.TimeoutError: except asyncio.TimeoutError:
await ctx.send(_("Ok then."))
return None return None
else:
if msg.content == "none":
return None
command, m = get_command_from_input(ctx.bot, msg.content) command, m = get_command_from_input(ctx.bot, msg.content)
if command is None: if command is None:
await ctx.send(m) await ctx.send(m)

View File

@ -14,6 +14,7 @@ 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.mod import is_admin_or_superior from redbot.core.utils.mod import is_admin_or_superior
from redbot.core.utils.chat_formatting import warning, pagify from redbot.core.utils.chat_formatting import warning, pagify
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
_ = Translator("Warnings", __file__) _ = Translator("Warnings", __file__)
@ -74,27 +75,9 @@ class Warnings:
""" """
guild = ctx.guild guild = ctx.guild
await ctx.send("Would you like to enter commands to be run? (y/n)")
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
if msg.content.lower() == "y":
exceed_command = await get_command_for_exceeded_points(ctx) exceed_command = await get_command_for_exceeded_points(ctx)
if exceed_command is None:
return
drop_command = await get_command_for_dropping_points(ctx) drop_command = await get_command_for_dropping_points(ctx)
if drop_command is None:
return
else:
exceed_command = None
drop_command = None
to_add = { to_add = {
"action_name": name, "action_name": name,
"points": points, "points": points,
@ -114,7 +97,7 @@ class Warnings:
# Sort in descending order by point count for ease in # Sort in descending order by point count for ease in
# finding the highest possible action to take # finding the highest possible action to take
registered_actions.sort(key=lambda a: a["points"], reverse=True) registered_actions.sort(key=lambda a: a["points"], reverse=True)
await ctx.tick() await ctx.send(_("Action {name} has been added.").format(name=name))
@warnaction.command(name="del") @warnaction.command(name="del")
@commands.guild_only() @commands.guild_only()
@ -182,13 +165,20 @@ class Warnings:
msg_list = [] msg_list = []
async with guild_settings.reasons() as registered_reasons: async with guild_settings.reasons() as registered_reasons:
for r, v in registered_reasons.items(): for r, v in registered_reasons.items():
if ctx.embed_requested():
em = discord.Embed(
title=_("Reason: {name}").format(name=r), description=v["description"]
)
em.add_field(name=_("Points"), value=str(v["points"]))
msg_list.append(em)
else:
msg_list.append( msg_list.append(
"Name: {}\nPoints: {}\nDescription: {}".format( "Name: {}\nPoints: {}\nDescription: {}".format(
r, v["points"], v["description"] r, v["points"], v["description"]
) )
) )
if msg_list: if msg_list:
await ctx.send_interactive(msg_list) await menu(ctx, msg_list, DEFAULT_CONTROLS)
else: else:
await ctx.send(_("There are no reasons configured!")) await ctx.send(_("There are no reasons configured!"))
@ -202,6 +192,13 @@ class Warnings:
msg_list = [] msg_list = []
async with guild_settings.actions() as registered_actions: async with guild_settings.actions() as registered_actions:
for r in registered_actions: for r in registered_actions:
if await ctx.embed_requested():
em = discord.Embed(title=_("Action: {name}").format(name=r["action_name"]))
em.add_field(name=_("Points"), value="{}".format(r["points"]), inline=False)
em.add_field(name=_("Exceed command"), value=r["exceed_command"], inline=False)
em.add_field(name=_("Drop command"), value=r["drop_command"], inline=False)
msg_list.append(em)
else:
msg_list.append( msg_list.append(
"Name: {}\nPoints: {}\nExceed command: {}\n" "Name: {}\nPoints: {}\nExceed command: {}\n"
"Drop command: {}".format( "Drop command: {}".format(
@ -209,7 +206,7 @@ class Warnings:
) )
) )
if msg_list: if msg_list:
await ctx.send_interactive(msg_list) await menu(ctx, msg_list, DEFAULT_CONTROLS)
else: else:
await ctx.send(_("There are no actions configured!")) await ctx.send(_("There are no actions configured!"))
@ -221,6 +218,9 @@ class Warnings:
Reason must be a registered reason, or "custom" if custom reasons are allowed Reason must be a registered reason, or "custom" if custom reasons are allowed
""" """
if user == ctx.author:
await ctx.send(_("You cannot warn yourself."))
return
if reason.lower() == "custom": if reason.lower() == "custom":
custom_allowed = await self.config.guild(ctx.guild).allow_custom_reasons() custom_allowed = await self.config.guild(ctx.guild).allow_custom_reasons()
if not custom_allowed: if not custom_allowed:
@ -256,7 +256,27 @@ class Warnings:
await member_settings.total_points.set(current_point_count) await member_settings.total_points.set(current_point_count)
await warning_points_add_check(self.config, ctx, user, current_point_count) await warning_points_add_check(self.config, ctx, user, current_point_count)
await ctx.tick() try:
em = discord.Embed(
title=_("Warning from {mod_name}#{mod_discrim}").format(
mod_name=ctx.author.display_name, mod_discrim=ctx.author.discriminator
),
description=reason_type["description"],
)
em.add_field(name=_("Points"), value=str(reason_type["points"]))
await user.send(
_("You have received a warning in {guild_name}.").format(
guild_name=ctx.guild.name
),
embed=em,
)
except discord.HTTPException:
pass
await ctx.send(
_("User {user_name}#{user_discrim} has been warned.").format(
user_name=user.display_name, user_discrim=user.discriminator
)
)
@commands.command() @commands.command()
@commands.guild_only() @commands.guild_only()
@ -303,6 +323,9 @@ class Warnings:
@checks.admin_or_permissions(ban_members=True) @checks.admin_or_permissions(ban_members=True)
async def unwarn(self, ctx: commands.Context, user_id: int, warn_id: str): async def unwarn(self, ctx: commands.Context, user_id: int, warn_id: str):
"""Removes the specified warning from the user specified""" """Removes the specified warning from the user specified"""
if user_id == ctx.author.id:
await ctx.send(_("You cannot remove warnings from yourself."))
return
guild = ctx.guild guild = ctx.guild
member = guild.get_member(user_id) member = guild.get_member(user_id)
if member is None: # no longer in guild, but need a "member" object if member is None: # no longer in guild, but need a "member" object