diff options
| -rw-r--r-- | bot/cogs/moderation/infractions.py | 30 | ||||
| -rw-r--r-- | bot/cogs/moderation/scheduler.py | 20 | ||||
| -rw-r--r-- | bot/cogs/moderation/superstarify.py | 57 | 
3 files changed, 39 insertions, 68 deletions
| diff --git a/bot/cogs/moderation/infractions.py b/bot/cogs/moderation/infractions.py index fbfcb8ae3..7e8d58144 100644 --- a/bot/cogs/moderation/infractions.py +++ b/bot/cogs/moderation/infractions.py @@ -1,8 +1,6 @@  import logging  import typing as t -from datetime import datetime -import dateutil.parser  import discord  from discord import Member  from discord.ext import commands @@ -37,31 +35,19 @@ class Infractions(InfractionScheduler, commands.Cog):      async def on_member_join(self, member: Member) -> None:          """Reapply active mute infractions for returning members."""          active_mutes = await self.bot.api_client.get( -            'bot/infractions', +            "bot/infractions",              params={ -                'user__id': str(member.id), -                'type': 'mute', -                'active': 'true' +                "active": "true", +                "type": "mute", +                "user__id": member.id              }          ) -        if not active_mutes: -            return - -        # Assume a single mute because of restrictions elsewhere. -        mute = active_mutes[0] -        # Calculate the time remaining, in seconds, for the mute. -        expiry = dateutil.parser.isoparse(mute["expires_at"]).replace(tzinfo=None) -        delta = (expiry - datetime.utcnow()).total_seconds() - -        # Mark as inactive if less than a minute remains. -        if delta < 60: -            await self.deactivate_infraction(mute) -            return +        if active_mutes: +            reason = f"Re-applying active mute: {active_mutes[0]['id']}" +            action = member.add_roles(self._muted_role, reason=reason) -        # Allowing mod log since this is a passive action that should be logged. -        await member.add_roles(self._muted_role, reason=f"Re-applying active mute: {mute['id']}") -        log.debug(f"User {member.id} has been re-muted on rejoin.") +            await self.reapply_infraction(active_mutes[0], action)      # region: Permanent infractions diff --git a/bot/cogs/moderation/scheduler.py b/bot/cogs/moderation/scheduler.py index cef96de99..fe8e43fbe 100644 --- a/bot/cogs/moderation/scheduler.py +++ b/bot/cogs/moderation/scheduler.py @@ -2,6 +2,7 @@ import logging  import textwrap  import typing as t  from abc import abstractmethod +from datetime import datetime  from gettext import ngettext  import dateutil.parser @@ -46,6 +47,25 @@ class InfractionScheduler(Scheduler):              if infraction["expires_at"] is not None:                  self.schedule_task(self.bot.loop, infraction["id"], infraction) +    async def reapply_infraction( +        self, +        infraction: utils.Infraction, +        apply_coro: t.Optional[t.Awaitable] +    ) -> None: +        """Reapply an infraction if it's still active or deactivate it if less than 60 sec left.""" +        # Calculate the time remaining, in seconds, for the mute. +        expiry = dateutil.parser.isoparse(infraction["expires_at"]).replace(tzinfo=None) +        delta = (expiry - datetime.utcnow()).total_seconds() + +        # Mark as inactive if less than a minute remains. +        if delta < 60: +            await self.deactivate_infraction(infraction) +            return + +        # Allowing mod log since this is a passive action that should be logged. +        await apply_coro +        log.info(f"Re-applied {infraction['type']} to user {infraction['user']} upon rejoining.") +      async def apply_infraction(          self,          ctx: Context, diff --git a/bot/cogs/moderation/superstarify.py b/bot/cogs/moderation/superstarify.py index 051eaf6b5..3200087ae 100644 --- a/bot/cogs/moderation/superstarify.py +++ b/bot/cogs/moderation/superstarify.py @@ -82,60 +82,25 @@ class Superstarify(InfractionScheduler, Cog):      @Cog.listener()      async def on_member_join(self, member: Member) -> None: -        """ -        This event will trigger when someone (re)joins the server. - -        At this point we will look up the user in our database and check whether they are in -        superstar-prison. If so, we will change their name back to the forced nickname. -        """ +        """Reapply active superstar infractions for returning members."""          active_superstarifies = await self.bot.api_client.get( -            'bot/infractions', +            "bot/infractions",              params={ -                'active': 'true', -                'type': 'superstar', -                'user__id': member.id +                "active": "true", +                "type": "superstar", +                "user__id": member.id              }          )          if active_superstarifies: -            [infraction] = active_superstarifies -            forced_nick = self.get_nick(infraction['id'], member.id) -            await member.edit(nick=forced_nick) -            end_timestamp_human = format_infraction(infraction['expires_at']) - -            try: -                await member.send( -                    "You have left and rejoined the **Python Discord** server, effectively resetting " -                    f"your nickname from **{forced_nick}** to **{member.name}**, " -                    "but as you are currently in superstar-prison, you do not have permission to do so. " -                    "Therefore your nickname was automatically changed back. You will be allowed to " -                    "change your nickname again at the following time:\n\n" -                    f"**{end_timestamp_human}**." -                ) -            except Forbidden: -                log.warning( -                    "The user left and rejoined the server while in superstar-prison. " -                    "This led to the bot trying to DM the user to let them know their name was restored, " -                    "but the user had either blocked the bot or disabled DMs, so it was not possible " -                    "to DM them, and a discord.errors.Forbidden error was incurred." -                ) - -            # Log to the mod_log channel -            log.trace("Logging to the #mod-log channel. This could fail because of channel permissions.") -            mod_log_message = ( -                f"**{member}** (`{member.id}`)\n\n" -                f"Superstarified member potentially tried to escape the prison.\n" -                f"Restored enforced nickname: `{forced_nick}`\n" -                f"Superstardom ends: **{end_timestamp_human}**" -            ) -            await self.modlog.send_log_message( -                icon_url=constants.Icons.user_update, -                colour=Colour.gold(), -                title="Superstar member rejoined server", -                text=mod_log_message, -                thumbnail=member.avatar_url_as(static_format="png") +            infraction = active_superstarifies[0] +            action = member.edit( +                nick=self.get_nick(infraction["id"], member.id), +                reason=f"Superstarified member tried to escape the prison: {infraction['id']}"              ) +            await self.reapply_infraction(infraction, action) +      @command(name='superstarify', aliases=('force_nick', 'star'))      async def superstarify(self, ctx: Context, member: Member, duration: utils.Expiry, reason: str = None) -> None:          """ | 
