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: """ |