diff options
| author | 2018-07-23 22:20:40 -0400 | |
|---|---|---|
| committer | 2018-07-23 22:20:40 -0400 | |
| commit | ef1fc0e923ed0d9e730bcda20c4f5adfd3b46241 (patch) | |
| tree | 1a3294c0129701bfae4271bb90a3cec4d79546f2 | |
| parent | Add tempban, add function to cancel active expiration tasks (diff) | |
Unmute and unban commands
| -rw-r--r-- | bot/cogs/moderation.py | 91 | ||||
| -rw-r--r-- | bot/constants.py | 3 | ||||
| -rw-r--r-- | config-default.yml | 1 |
3 files changed, 91 insertions, 4 deletions
diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py index f2ab64850..8829c595d 100644 --- a/bot/cogs/moderation.py +++ b/bot/cogs/moderation.py @@ -248,14 +248,91 @@ class Moderation: await ctx.send(result_message) + @with_role(Roles.admin, Roles.owner, Roles.moderator) + @command(name="moderation.unmute") + async def unmute(self, ctx, user: Member): + """ + Deactivates the active mute infraction for a user. + :param user: Accepts user mention, ID, etc. + """ + try: + # check the current active infraction + response = await self.bot.http_session.get( + URLs.site_infractions_user_type_current.format( + user_id=user.id, + infraction_type="mute" + ), + headers=self.headers + ) + response_object = await response.json() + if "error_code" in response_object: + # something went wrong + await ctx.send(f":x: There was an error removing the infraction: {response_object['error_message']}") + return + + infraction_object = response_object["infraction"] + if infraction_object is None: + # no active infraction + await ctx.send(f":x: There is no active mute infraction for user {user.mention}.") + return + + await self._deactivate_infraction(infraction_object) + if infraction_object["expires_at"] is not None: + self.cancel_expiration(infraction_object["id"]) + + await ctx.send(f":ok_hand: Un-muted {user.mention}.") + except Exception: + log.exception("There was an error removing an infraction.") + await ctx.send(":x: There was an error removing the infraction.") + return + + @with_role(Roles.admin, Roles.owner, Roles.moderator) + @command(name="moderation.unban") + async def unban(self, ctx, user: User): + """ + Deactivates the active ban infraction for a user. + :param user: Accepts user mention, ID, etc. + """ + try: + # check the current active infraction + response = await self.bot.http_session.get( + URLs.site_infractions_user_type_current.format( + user_id=user.id, + infraction_type="ban" + ), + headers=self.headers + ) + response_object = await response.json() + if "error_code" in response_object: + # something went wrong + await ctx.send(f":x: There was an error removing the infraction: {response_object['error_message']}") + return + + infraction_object = response_object["infraction"] + if infraction_object is None: + # no active infraction + await ctx.send(f":x: There is no active ban infraction for user {user.mention}.") + return + + await self._deactivate_infraction(infraction_object, user=user) + if infraction_object["expires_at"] is not None: + self.cancel_expiration(infraction_object["id"]) + + await ctx.send(f":ok_hand: Un-banned {user.mention}.") + except Exception: + log.exception("There was an error removing an infraction.") + await ctx.send(":x: There was an error removing the infraction.") + return + def schedule_expiration(self, loop: asyncio.AbstractEventLoop, infraction_object: dict): infraction_id = infraction_object["id"] if infraction_id in self.expiration_tasks: return task: asyncio.Task = asyncio.ensure_future(self._scheduled_expiration(infraction_object), loop=loop) + # Silently ignore exceptions in a callback (handles the CancelledError nonsense) - task.add_done_callback(lambda future: future.exception()) + task.add_done_callback(_silent_exception) self.expiration_tasks[infraction_id] = task @@ -285,7 +362,7 @@ class Moderation: self.cancel_expiration(infraction_object["id"]) - async def _deactivate_infraction(self, infraction_object): + async def _deactivate_infraction(self, infraction_object, user: User = None): guild: Guild = self.bot.get_guild(constants.Guild.id) user_id = infraction_object["user"]["user_id"] infraction_type = infraction_object["type"] @@ -295,7 +372,8 @@ class Moderation: if member: await member.edit(mute=False) elif infraction_type == "ban": - user: User = self.bot.get_user(user_id) + if user is None: + user: User = self.bot.get_user(user_id) await guild.unban(user) await self.bot.http_session.patch( @@ -315,6 +393,13 @@ def parse_rfc1123(time_str): return datetime.datetime.strptime(time_str, RFC1123_FORMAT).replace(tzinfo=datetime.timezone.utc) +def _silent_exception(future): + try: + future.exception() + except Exception: + pass + + def setup(bot): bot.add_cog(Moderation(bot)) # Here we'll need to call a command I haven't made yet diff --git a/bot/constants.py b/bot/constants.py index c435fbad9..915373add 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -265,7 +265,8 @@ class URLs(metaclass=YAMLGetter): site_infractions: str site_infractions_user: str site_infractions_type: str - site_infractions_by_id: str + site_infractions_user_type_current: str + site_infractions_user_type: str status: str paste_service: str diff --git a/config-default.yml b/config-default.yml index 8f0c32af9..15cdd948c 100644 --- a/config-default.yml +++ b/config-default.yml @@ -89,5 +89,6 @@ urls: site_infractions_user: 'https://api.pythondiscord.com/bot/infractions/user/{user_id}' site_infractions_type: 'https://api.pythondiscord.com/bot/infractions/type/{infraction_type}' site_infractions_by_id: 'https://api.pythondiscord.com/bot/infractions/id/{infraction_id}' + site_infractions_user_type_current: 'https://api.pythondiscord.com/bot/infractions/user/{user_id}/{infraction_type}/current' status: !ENV 'STATUS_URL' paste_service: 'https://paste.pydis.com/{key}' |