diff options
author | 2020-10-01 16:48:47 +0800 | |
---|---|---|
committer | 2020-10-01 16:54:26 +0800 | |
commit | 7d9cb7a7d7b42d1abb9cf42e8066994c9f979eb9 (patch) | |
tree | 4ca3cfc7ad5c9c37209cfab3d39e2707764639eb | |
parent | Merge pull request #1200 from python-discord/bug/mod/1182/deleted-msg-null-char (diff) |
Modify `!superstar` to use `apply_infraction`.
Using `apply_infraction` from `InfractionScheduler` rather than doing it
manually allows us to handle HTTP errors while reducing code
duplication.
Specifically, discord.Forbidden is handled when the bot tries to
superstar someone they do not have permissions to.
Resolves BOT-5Q.
-rw-r--r-- | bot/exts/moderation/infraction/_scheduler.py | 24 | ||||
-rw-r--r-- | bot/exts/moderation/infraction/superstarify.py | 77 |
2 files changed, 52 insertions, 49 deletions
diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index 814b17830..b66fdc850 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -81,15 +81,29 @@ class InfractionScheduler: ctx: Context, infraction: _utils.Infraction, user: UserSnowflake, - action_coro: t.Optional[t.Awaitable] = None - ) -> None: - """Apply an infraction to the user, log the infraction, and optionally notify the user.""" + action_coro: t.Optional[t.Awaitable] = None, + reason_override: t.Optional[str] = None, + additional_info: t.Optional[str] = None, + ) -> bool: + """ + Apply an infraction to the user, log the infraction, and optionally notify the user. + + `reason_override`, if provided, will be sent to the user in place of the infraction reason. + `additional_info` will be attached to the text field in the mod-log embed. + Returns whether or not the infraction succeeded. + """ infr_type = infraction["type"] icon = _utils.INFRACTION_ICONS[infr_type][0] reason = infraction["reason"] expiry = time.format_infraction_with_duration(infraction["expires_at"]) id_ = infraction['id'] + if reason_override is not None: + reason_override = reason + + if additional_info is not None: + additional_info = "" + log.trace(f"Applying {infr_type} infraction #{id_} to {user}.") # Default values for the confirmation message and mod log. @@ -125,7 +139,7 @@ class InfractionScheduler: log.error(f"Failed to DM {user.id}: could not fetch user (status {e.status})") else: # Accordingly display whether the user was successfully notified via DM. - if await _utils.notify_infraction(user, infr_type, expiry, reason, icon): + if await _utils.notify_infraction(user, infr_type, expiry, reason_override, icon): dm_result = ":incoming_envelope: " dm_log_text = "\nDM: Sent" @@ -201,12 +215,14 @@ class InfractionScheduler: Member: {messages.format_user(user)} Actor: {ctx.author.mention}{dm_log_text}{expiry_log_text} Reason: {reason} + {additional_info} """), content=log_content, footer=f"ID {infraction['id']}" ) log.info(f"Applied {infr_type} infraction #{id_} to {user}.") + return not failed async def pardon_infraction( self, diff --git a/bot/exts/moderation/infraction/superstarify.py b/bot/exts/moderation/infraction/superstarify.py index eec63f5b3..3c96f7317 100644 --- a/bot/exts/moderation/infraction/superstarify.py +++ b/bot/exts/moderation/infraction/superstarify.py @@ -5,7 +5,7 @@ import textwrap import typing as t from pathlib import Path -from discord import Colour, Embed, Member +from discord import Embed, Member from discord.ext.commands import Cog, Context, command, has_any_role from discord.utils import escape_markdown @@ -142,57 +142,44 @@ class Superstarify(InfractionScheduler, Cog): forced_nick = self.get_nick(id_, member.id) expiry_str = format_infraction(infraction["expires_at"]) - # Apply the infraction and schedule the expiration task. - log.debug(f"Changing nickname of {member} to {forced_nick}.") - self.mod_log.ignore(constants.Event.member_update, member.id) - await member.edit(nick=forced_nick, reason=reason) - self.schedule_expiration(infraction) + # Apply the infraction + async def action() -> None: + log.debug(f"Changing nickname of {member} to {forced_nick}.") + self.mod_log.ignore(constants.Event.member_update, member.id) + await member.edit(nick=forced_nick, reason=reason) old_nick = escape_markdown(member.display_name) forced_nick = escape_markdown(forced_nick) - # Send a DM to the user to notify them of their new infraction. - await _utils.notify_infraction( - user=member, - infr_type="Superstarify", - expires_at=expiry_str, - icon_url=_utils.INFRACTION_ICONS["superstar"][0], - reason=f"Your nickname didn't comply with our [nickname policy]({NICKNAME_POLICY_URL})." + superstar_reason = f"Your nickname didn't comply with our [nickname policy]({NICKNAME_POLICY_URL})." + nickname_info = textwrap.dedent(f""" + Old nickname: `{old_nick}` + New nickname: `{forced_nick}` + """).strip() + + successful = await self.apply_infraction( + ctx, infraction, member, action(), + reason_override=superstar_reason, + additional_info=nickname_info ) - # Send an embed with the infraction information to the invoking context. - log.trace(f"Sending superstar #{id_} embed.") - embed = Embed( - title="Congratulations!", - colour=constants.Colours.soft_orange, - description=( - f"Your previous nickname, **{old_nick}**, " - f"was so bad that we have decided to change it. " - f"Your new nickname will be **{forced_nick}**.\n\n" - f"You will be unable to change your nickname until **{expiry_str}**.\n\n" - "If you're confused by this, please read our " - f"[official nickname policy]({NICKNAME_POLICY_URL})." + # Send an embed with the infraction information to the invoking context if + # superstar was successful. + if successful: + log.trace(f"Sending superstar #{id_} embed.") + embed = Embed( + title="Congratulations!", + colour=constants.Colours.soft_orange, + description=( + f"Your previous nickname, **{old_nick}**, " + f"was so bad that we have decided to change it. " + f"Your new nickname will be **{forced_nick}**.\n\n" + f"You will be unable to change your nickname until **{expiry_str}**.\n\n" + "If you're confused by this, please read our " + f"[official nickname policy]({NICKNAME_POLICY_URL})." + ) ) - ) - await ctx.send(embed=embed) - - # Log to the mod log channel. - log.trace(f"Sending apply mod log for superstar #{id_}.") - await self.mod_log.send_log_message( - icon_url=_utils.INFRACTION_ICONS["superstar"][0], - colour=Colour.gold(), - title="Member achieved superstardom", - thumbnail=member.avatar_url_as(static_format="png"), - text=textwrap.dedent(f""" - Member: {member.mention} - Actor: {ctx.message.author.mention} - Expires: {expiry_str} - Old nickname: `{old_nick}` - New nickname: `{forced_nick}` - Reason: {reason} - """), - footer=f"ID {id_}" - ) + await ctx.send(embed=embed) @command(name="unsuperstarify", aliases=("release_nick", "unstar")) async def unsuperstarify(self, ctx: Context, member: Member) -> None: |