diff options
| author | 2021-07-15 15:25:12 -0700 | |
|---|---|---|
| committer | 2021-07-15 15:25:12 -0700 | |
| commit | af3c1459ba491e748339545687a8939b4dd70e43 (patch) | |
| tree | f83116fd6804c8f5e2e5d1e6f50122bd6f6bd572 | |
| parent | Remove unnecessary config constant (diff) | |
Add util function to send an infraction using an Infraction dict
There was some redundant pre-processing of arguments happening before
calling `notify_infraction`.
Diffstat (limited to '')
| -rw-r--r-- | bot/exts/moderation/infraction/_scheduler.py | 18 | ||||
| -rw-r--r-- | bot/exts/moderation/infraction/_utils.py | 38 | ||||
| -rw-r--r-- | bot/exts/moderation/infraction/superstarify.py | 4 | ||||
| -rw-r--r-- | tests/bot/exts/moderation/infraction/test_utils.py | 4 | 
4 files changed, 45 insertions, 19 deletions
| diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index 8286d3635..19402d01d 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -162,20 +162,12 @@ class InfractionScheduler:          # apply kick/ban infractions first, this would mean that we'd make it          # impossible for us to deliver a DM. See python-discord/bot#982.          if not infraction["hidden"]: -            dm_result = f"{constants.Emojis.failmail} " -            dm_log_text = "\nDM: **Failed**" - -            # Sometimes user is a discord.Object; make it a proper user. -            try: -                if not isinstance(user, (discord.Member, discord.User)): -                    user = await self.bot.fetch_user(user.id) -            except discord.HTTPException as e: -                log.error(f"Failed to DM {user.id}: could not fetch user (status {e.status})") +            if await _utils.notify_infraction(infraction, user, user_reason): +                dm_result = ":incoming_envelope: " +                dm_log_text = "\nDM: Sent"              else: -                # Accordingly display whether the user was successfully notified via DM. -                if await _utils.notify_infraction(user, infr_type.replace("_", " ").title(), expiry, user_reason, icon): -                    dm_result = ":incoming_envelope: " -                    dm_log_text = "\nDM: Sent" +                dm_result = f"{constants.Emojis.failmail} " +                dm_log_text = "\nDM: **Failed**"          end_msg = ""          if infraction["actor"] == self.bot.user.id: diff --git a/bot/exts/moderation/infraction/_utils.py b/bot/exts/moderation/infraction/_utils.py index adbc641fa..a6f180c8c 100644 --- a/bot/exts/moderation/infraction/_utils.py +++ b/bot/exts/moderation/infraction/_utils.py @@ -5,9 +5,11 @@ from datetime import datetime  import discord  from discord.ext.commands import Context +import bot  from bot.api import ResponseCodeError  from bot.constants import Colours, Icons  from bot.errors import InvalidInfractedUserError +from bot.utils import time  log = logging.getLogger(__name__) @@ -152,7 +154,7 @@ async def get_active_infraction(          log.trace(f"{user} does not have active infractions of type {infr_type}.") -async def notify_infraction( +async def send_infraction_embed(          user: UserObject,          infr_type: str,          expires_at: t.Optional[str] = None, @@ -188,6 +190,40 @@ async def notify_infraction(      return await send_private_embed(user, embed) +async def notify_infraction( +        infraction: Infraction, +        user: t.Optional[UserSnowflake] = None, +        reason: t.Optional[str] = None +) -> bool: +    """ +    DM a user about their new infraction and return True if the DM is successful. + +    `user` and `reason` can be used to override what is in `infraction`. Otherwise, this data will +    be retrieved from `infraction`. + +    Also return False if the user needs to be fetched but fails to be fetched. +    """ +    if user is None: +        user = discord.Object(infraction["user"]) + +    # Sometimes user is a discord.Object; make it a proper user. +    try: +        if not isinstance(user, (discord.Member, discord.User)): +            user = await bot.instance.fetch_user(user.id) +    except discord.HTTPException as e: +        log.error(f"Failed to DM {user.id}: could not fetch user (status {e.status})") +        return False + +    type_ = infraction["type"].replace("_", " ").title() +    icon = INFRACTION_ICONS[infraction["type"]][0] +    expiry = time.format_infraction_with_duration(infraction["expires_at"]) + +    if reason is None: +        reason = infraction["reason"] + +    return await send_infraction_embed(user, type_, expiry, reason, icon) + +  async def notify_pardon(          user: UserObject,          title: str, diff --git a/bot/exts/moderation/infraction/superstarify.py b/bot/exts/moderation/infraction/superstarify.py index 07e79b9fe..6dd9924ad 100644 --- a/bot/exts/moderation/infraction/superstarify.py +++ b/bot/exts/moderation/infraction/superstarify.py @@ -70,15 +70,13 @@ class Superstarify(InfractionScheduler, Cog):          )          notified = await _utils.notify_infraction( +            infraction=infraction,              user=after, -            infr_type="Superstarify", -            expires_at=format_infraction(infraction["expires_at"]),              reason=(                  "You have tried to change your nickname on the **Python Discord** server "                  f"from **{before.display_name}** to **{after.display_name}**, but as you "                  "are currently in superstar-prison, you do not have permission to do so."              ), -            icon_url=_utils.INFRACTION_ICONS["superstar"][0]          )          if not notified: diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index 50a717bb5..d35120992 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -124,7 +124,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                      self.ctx.send.assert_not_awaited()      @patch("bot.exts.moderation.infraction._utils.send_private_embed") -    async def test_notify_infraction(self, send_private_embed_mock): +    async def test_send_infraction_embed(self, send_private_embed_mock):          """          Should send an embed of a certain format as a DM and return `True` if DM successful. @@ -230,7 +230,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                  send_private_embed_mock.reset_mock()                  send_private_embed_mock.return_value = case["send_result"] -                result = await utils.notify_infraction(*case["args"]) +                result = await utils.send_infraction_embed(*case["args"])                  self.assertEqual(case["send_result"], result) | 
