diff options
author | 2018-11-15 20:44:39 +0000 | |
---|---|---|
committer | 2018-11-15 20:44:39 +0000 | |
commit | 3c58924312c4b50843855621fa460f0baa348e44 (patch) | |
tree | 91cf34925e5c9fbd4e8fb0b29c6c694158df1b33 | |
parent | Merge branch 'issue/75-help-menu-for-aliases' into 'master' (diff) | |
parent | Hemlock/moderation hidden param (diff) |
Merge branch 'hemlock/moderation_hidden_param' into 'master'
Hemlock/moderation hidden param
See merge request python-discord/projects/bot!76
-rw-r--r-- | bot/cogs/information.py | 11 | ||||
-rw-r--r-- | bot/cogs/moderation.py | 343 |
2 files changed, 351 insertions, 3 deletions
diff --git a/bot/cogs/information.py b/bot/cogs/information.py index a313d2379..0f1aa75c5 100644 --- a/bot/cogs/information.py +++ b/bot/cogs/information.py @@ -10,6 +10,8 @@ from bot.utils.time import time_since log = logging.getLogger(__name__) +MODERATION_ROLES = Roles.owner, Roles.admin, Roles.moderator + class Information: """ @@ -22,7 +24,7 @@ class Information: self.bot = bot self.headers = {"X-API-Key": Keys.site_api} - @with_role(Roles.owner, Roles.admin, Roles.moderator) + @with_role(*MODERATION_ROLES) @command(name="roles") async def roles_info(self, ctx: Context): """ @@ -119,12 +121,16 @@ class Information: await ctx.send(embed=embed) + @with_role(*MODERATION_ROLES) @command(name="user", aliases=["user_info", "member", "member_info"]) - async def user_info(self, ctx: Context, user: Member = None): + async def user_info(self, ctx: Context, user: Member = None, hidden: bool = False): """ Returns info about a user. """ + # Validates hidden input + hidden = str(hidden) + if user is None: user = ctx.author @@ -146,6 +152,7 @@ class Information: # Infractions api_response = await self.bot.http_session.get( url=URLs.site_infractions_user.format(user_id=user.id), + params={"hidden": hidden}, headers=self.headers ) diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py index 9165fe654..987f5fa5b 100644 --- a/bot/cogs/moderation.py +++ b/bot/cogs/moderation.py @@ -380,6 +380,344 @@ class Moderation(Scheduler): ) # endregion + # region: Permanent shadow infractions + + @with_role(*MODERATION_ROLES) + @command(name="shadow_warn", hidden=True, aliases=['shadowwarn', 'swarn', 'note']) + async def shadow_warn(self, ctx: Context, user: User, *, reason: str = None): + """ + Create a warning infraction in the database for a user. + :param user: accepts user mention, ID, etc. + :param reason: The reason for the warning. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "warning", + "reason": reason, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + if reason is None: + result_message = f":ok_hand: warned {user.mention}." + else: + result_message = f":ok_hand: warned {user.mention} ({reason})." + + await ctx.send(result_message) + + @with_role(*MODERATION_ROLES) + @command(name="shadow_kick", hidden=True, aliases=['shadowkick', 'skick']) + async def shadow_kick(self, ctx: Context, user: Member, *, reason: str = None): + """ + Kicks a user. + :param user: accepts user mention, ID, etc. + :param reason: The reason for the kick. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "kick", + "reason": reason, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + self.mod_log.ignore(Event.member_remove, user.id) + await user.kick(reason=reason) + + if reason is None: + result_message = f":ok_hand: kicked {user.mention}." + else: + result_message = f":ok_hand: kicked {user.mention} ({reason})." + + await ctx.send(result_message) + + # Send a log message to the mod log + await self.mod_log.send_log_message( + icon_url=Icons.sign_out, + colour=Colour(Colours.soft_red), + title="Member shadow kicked", + thumbnail=user.avatar_url_as(static_format="png"), + text=textwrap.dedent(f""" + Member: {user.mention} (`{user.id}`) + Actor: {ctx.message.author} + Reason: {reason} + """) + ) + + @with_role(*MODERATION_ROLES) + @command(name="shadow_ban", hidden=True, aliases=['shadowban', 'sban']) + async def shadow_ban(self, ctx: Context, user: User, *, reason: str = None): + """ + Create a permanent ban infraction in the database for a user. + :param user: Accepts user mention, ID, etc. + :param reason: The reason for the ban. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "ban", + "reason": reason, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + self.mod_log.ignore(Event.member_ban, user.id) + self.mod_log.ignore(Event.member_remove, user.id) + await ctx.guild.ban(user, reason=reason, delete_message_days=0) + + if reason is None: + result_message = f":ok_hand: permanently banned {user.mention}." + else: + result_message = f":ok_hand: permanently banned {user.mention} ({reason})." + + await ctx.send(result_message) + + # Send a log message to the mod log + await self.mod_log.send_log_message( + icon_url=Icons.user_ban, + colour=Colour(Colours.soft_red), + title="Member permanently banned", + thumbnail=user.avatar_url_as(static_format="png"), + text=textwrap.dedent(f""" + Member: {user.mention} (`{user.id}`) + Actor: {ctx.message.author} + Reason: {reason} + """) + ) + + @with_role(*MODERATION_ROLES) + @command(name="shadow_mute", hidden=True, aliases=['shadowmute', 'smute']) + async def shadow_mute(self, ctx: Context, user: Member, *, reason: str = None): + """ + Create a permanent mute infraction in the database for a user. + :param user: Accepts user mention, ID, etc. + :param reason: The reason for the mute. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "mute", + "reason": reason, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + # add the mute role + self.mod_log.ignore(Event.member_update, user.id) + await user.add_roles(self._muted_role, reason=reason) + + if reason is None: + result_message = f":ok_hand: permanently muted {user.mention}." + else: + result_message = f":ok_hand: permanently muted {user.mention} ({reason})." + + await ctx.send(result_message) + + # Send a log message to the mod log + await self.mod_log.send_log_message( + icon_url=Icons.user_mute, + colour=Colour(Colours.soft_red), + title="Member permanently muted", + thumbnail=user.avatar_url_as(static_format="png"), + text=textwrap.dedent(f""" + Member: {user.mention} (`{user.id}`) + Actor: {ctx.message.author} + Reason: {reason} + """) + ) + + # endregion + # region: Temporary shadow infractions + + @with_role(*MODERATION_ROLES) + @command(name="shadow_tempmute", hidden=True, aliases=["shadowtempmute, stempmute"]) + async def shadow_tempmute(self, ctx: Context, user: Member, duration: str, *, reason: str = None): + """ + Create a temporary mute infraction in the database for a user. + :param user: Accepts user mention, ID, etc. + :param duration: The duration for the temporary mute infraction + :param reason: The reason for the temporary mute. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "mute", + "reason": reason, + "duration": duration, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + self.mod_log.ignore(Event.member_update, user.id) + await user.add_roles(self._muted_role, reason=reason) + + infraction_object = response_object["infraction"] + infraction_expiration = infraction_object["expires_at"] + + loop = asyncio.get_event_loop() + self.schedule_expiration(loop, infraction_object) + + if reason is None: + result_message = f":ok_hand: muted {user.mention} until {infraction_expiration}." + else: + result_message = f":ok_hand: muted {user.mention} until {infraction_expiration} ({reason})." + + await ctx.send(result_message) + + # Send a log message to the mod log + await self.mod_log.send_log_message( + icon_url=Icons.user_mute, + colour=Colour(Colours.soft_red), + title="Member temporarily muted", + thumbnail=user.avatar_url_as(static_format="png"), + text=textwrap.dedent(f""" + Member: {user.mention} (`{user.id}`) + Actor: {ctx.message.author} + Reason: {reason} + Duration: {duration} + Expires: {infraction_expiration} + """) + ) + + @with_role(*MODERATION_ROLES) + @command(name="shadow_tempban", hidden=True, aliases=["shadowtempban, stempban"]) + async def shadow_tempban(self, ctx, user: User, duration: str, *, reason: str = None): + """ + Create a temporary ban infraction in the database for a user. + :param user: Accepts user mention, ID, etc. + :param duration: The duration for the temporary ban infraction + :param reason: The reason for the temporary ban. + """ + + try: + response = await self.bot.http_session.post( + URLs.site_infractions, + headers=self.headers, + json={ + "type": "ban", + "reason": reason, + "duration": duration, + "user_id": str(user.id), + "actor_id": str(ctx.message.author.id), + "hidden": True + } + ) + except ClientError: + log.exception("There was an error adding an infraction.") + await ctx.send(":x: There was an error adding the infraction.") + return + + response_object = await response.json() + if "error_code" in response_object: + await ctx.send(f":x: There was an error adding the infraction: {response_object['error_message']}") + return + + self.mod_log.ignore(Event.member_ban, user.id) + self.mod_log.ignore(Event.member_remove, user.id) + guild: Guild = ctx.guild + await guild.ban(user, reason=reason, delete_message_days=0) + + infraction_object = response_object["infraction"] + infraction_expiration = infraction_object["expires_at"] + + loop = asyncio.get_event_loop() + self.schedule_expiration(loop, infraction_object) + + if reason is None: + result_message = f":ok_hand: banned {user.mention} until {infraction_expiration}." + else: + result_message = f":ok_hand: banned {user.mention} until {infraction_expiration} ({reason})." + + await ctx.send(result_message) + + # Send a log message to the mod log + await self.mod_log.send_log_message( + icon_url=Icons.user_ban, + colour=Colour(Colours.soft_red), + thumbnail=user.avatar_url_as(static_format="png"), + title="Member temporarily banned", + text=textwrap.dedent(f""" + Member: {user.mention} (`{user.id}`) + Actor: {ctx.message.author} + Reason: {reason} + Duration: {duration} + Expires: {infraction_expiration} + """) + ) + + # endregion # region: Remove infractions (un- commands) @with_role(*MODERATION_ROLES) @@ -682,6 +1020,7 @@ class Moderation(Scheduler): URLs.site_infractions_user.format( user_id=user.id ), + params={"hidden": "True"}, headers=self.headers ) infraction_list = await response.json() @@ -707,7 +1046,7 @@ class Moderation(Scheduler): try: response = await self.bot.http_session.get( URLs.site_infractions, - params={"search": reason}, + params={"search": reason, "hidden": "True"}, headers=self.headers ) infraction_list = await response.json() @@ -803,12 +1142,14 @@ class Moderation(Scheduler): actor = guild.get_member(actor_id) active = infraction_object["active"] is True user_id = int(infraction_object["user"]["user_id"]) + hidden = infraction_object.get("hidden", False) is True lines = textwrap.dedent(f""" {"**===============**" if active else "==============="} Status: {"__**Active**__" if active else "Inactive"} User: {self.bot.get_user(user_id)} (`{user_id}`) Type: **{infraction_object["type"]}** + Shadow: {hidden} Reason: {infraction_object["reason"] or "*None*"} Created: {infraction_object["inserted_at"]} Expires: {infraction_object["expires_at"] or "*Permanent*"} |