diff options
Diffstat (limited to '')
| -rw-r--r-- | bot/exts/moderation/infraction/_scheduler.py | 4 | ||||
| -rw-r--r-- | bot/exts/moderation/infraction/_utils.py | 19 | ||||
| -rw-r--r-- | bot/exts/moderation/infraction/management.py | 8 | ||||
| -rw-r--r-- | tests/bot/exts/moderation/infraction/test_utils.py | 26 | 
4 files changed, 45 insertions, 12 deletions
| diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index 762eb6afa..52dd79791 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -238,7 +238,9 @@ class InfractionScheduler:                  dm_log_text = "\nDM: **Failed**"                  # Accordingly update whether the user was successfully notified via DM. -                if await _utils.notify_infraction(user, infr_type.replace("_", " ").title(), expiry, user_reason, icon): +                if await _utils.notify_infraction( +                        ctx.bot, user, infraction["id"], infr_type.replace("_", " ").title(), expiry, user_reason, icon +                ):                      dm_result = ":incoming_envelope: "                      dm_log_text = "\nDM: Sent" diff --git a/bot/exts/moderation/infraction/_utils.py b/bot/exts/moderation/infraction/_utils.py index bb3cc5380..e683c9db4 100644 --- a/bot/exts/moderation/infraction/_utils.py +++ b/bot/exts/moderation/infraction/_utils.py @@ -5,6 +5,7 @@ import discord  from discord.ext.commands import Context  from bot.api import ResponseCodeError +from bot.bot import Bot  from bot.constants import Colours, Icons  from bot.converters import MemberOrUser  from bot.errors import InvalidInfractedUserError @@ -78,7 +79,8 @@ async def post_infraction(          reason: str,          expires_at: datetime = None,          hidden: bool = False, -        active: bool = True +        active: bool = True, +        dm_sent: bool = False,  ) -> t.Optional[dict]:      """Posts an infraction to the API."""      if isinstance(user, (discord.Member, discord.User)) and user.bot: @@ -93,7 +95,8 @@ async def post_infraction(          "reason": reason,          "type": infr_type,          "user": user.id, -        "active": active +        "active": active, +        "dm_sent": dm_sent      }      if expires_at:          payload['expires_at'] = expires_at.isoformat() @@ -156,7 +159,9 @@ async def send_active_infraction_message(ctx: Context, infraction: Infraction) -  async def notify_infraction( +        bot: Bot,          user: MemberOrUser, +        infr_id: id,          infr_type: str,          expires_at: t.Optional[str] = None,          reason: t.Optional[str] = None, @@ -186,7 +191,15 @@ async def notify_infraction(      embed.title = INFRACTION_TITLE      embed.url = RULES_URL -    return await send_private_embed(user, embed) +    dm_sent = await send_private_embed(user, embed) +    if dm_sent: +        await bot.api_client.patch( +            f"bot/infractions/{infr_id}", +            json={"dm_sent": True} +        ) +        log.debug(f"Update infraction #{infr_id} dm_sent field to true.") + +    return dm_sent  async def notify_pardon( diff --git a/bot/exts/moderation/infraction/management.py b/bot/exts/moderation/infraction/management.py index a833eb227..b77c20434 100644 --- a/bot/exts/moderation/infraction/management.py +++ b/bot/exts/moderation/infraction/management.py @@ -352,6 +352,7 @@ class ModManagement(commands.Cog):          user = infraction["user"]          expires_at = infraction["expires_at"]          created = time.format_infraction(infraction["inserted_at"]) +        dm_sent = infraction["dm_sent"]          # Format the user string.          if user_obj := self.bot.get_user(user["id"]): @@ -377,11 +378,18 @@ class ModManagement(commands.Cog):              date_to = dateutil.parser.isoparse(expires_at)              duration = humanize_delta(relativedelta(date_to, date_from)) +        # Format `dm_sent` +        if dm_sent is None: +            dm_sent_text = "N/A" +        else: +            dm_sent_text = "Yes" if dm_sent else "No" +          lines = textwrap.dedent(f"""              {"**===============**" if active else "==============="}              Status: {"__**Active**__" if active else "Inactive"}              User: {user_str}              Type: **{infraction["type"]}** +            DM Sent: {dm_sent_text}              Shadow: {infraction["hidden"]}              Created: {created}              Expires: {remaining} diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index 72eebb254..350274ecd 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -132,7 +132,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):          """          test_cases = [              { -                "args": (self.user, "ban", "2020-02-26 09:20 (23 hours and 59 minutes)"), +                "args": (self.bot, self.user, 0, "ban", "2020-02-26 09:20 (23 hours and 59 minutes)"),                  "expected_output": Embed(                      title=utils.INFRACTION_TITLE,                      description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format( @@ -150,7 +150,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                  "send_result": True              },              { -                "args": (self.user, "warning", None, "Test reason."), +                "args": (self.bot, self.user, 0, "warning", None, "Test reason."),                  "expected_output": Embed(                      title=utils.INFRACTION_TITLE,                      description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format( @@ -170,7 +170,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):              # Note that this test case asserts that the DM that *would* get sent to the user is formatted              # correctly, even though that message is deliberately never sent.              { -                "args": (self.user, "note", None, None, Icons.defcon_denied), +                "args": (self.bot, self.user, 0, "note", None, None, Icons.defcon_denied),                  "expected_output": Embed(                      title=utils.INFRACTION_TITLE,                      description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format( @@ -188,7 +188,15 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                  "send_result": False              },              { -                "args": (self.user, "mute", "2020-02-26 09:20 (23 hours and 59 minutes)", "Test", Icons.defcon_denied), +                "args": ( +                    self.bot, +                    self.user, +                    0, +                    "mute", +                    "2020-02-26 09:20 (23 hours and 59 minutes)", +                    "Test", +                    Icons.defcon_denied +                ),                  "expected_output": Embed(                      title=utils.INFRACTION_TITLE,                      description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format( @@ -206,7 +214,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                  "send_result": False              },              { -                "args": (self.user, "mute", None, "foo bar" * 4000, Icons.defcon_denied), +                "args": (self.bot, self.user, 0, "mute", None, "foo bar" * 4000, Icons.defcon_denied),                  "expected_output": Embed(                      title=utils.INFRACTION_TITLE,                      description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format( @@ -238,7 +246,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):                  self.assertEqual(embed.to_dict(), case["expected_output"].to_dict()) -                send_private_embed_mock.assert_awaited_once_with(case["args"][0], embed) +                send_private_embed_mock.assert_awaited_once_with(case["args"][1], embed)      @patch("bot.exts.moderation.infraction._utils.send_private_embed")      async def test_notify_pardon(self, send_private_embed_mock): @@ -313,7 +321,8 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase):              "type": "ban",              "user": self.member.id,              "active": False, -            "expires_at": now.isoformat() +            "expires_at": now.isoformat(), +            "dm_sent": False          }          self.ctx.bot.api_client.post.return_value = "foo" @@ -350,7 +359,8 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase):              "reason": "Test reason",              "type": "mute",              "user": self.user.id, -            "active": True +            "active": True, +            "dm_sent": False          }          self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] | 
