From 9966668307d28145f64d2843869544ff8f21879c Mon Sep 17 00:00:00 2001 From: DiscordLiz <47602820+DiscordLiz@users.noreply.github.com> Date: Thu, 21 Feb 2019 21:31:37 -0500 Subject: [PATCH] adds function to modlg API to get cases by member (#2453) adds command using this to view all of a member's cases demonstrating this closes #2266 --- redbot/cogs/modlog/modlog.py | 35 ++++++++++++++- redbot/core/modlog.py | 87 ++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/redbot/cogs/modlog/modlog.py b/redbot/cogs/modlog/modlog.py index aa0b40b8c..0c7bbd9fb 100644 --- a/redbot/cogs/modlog/modlog.py +++ b/redbot/cogs/modlog/modlog.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Union import discord @@ -6,6 +6,8 @@ from redbot.core import checks, modlog, commands from redbot.core.bot import Red from redbot.core.i18n import Translator, cog_i18n from redbot.core.utils.chat_formatting import box +from redbot.core.utils.menus import menu, DEFAULT_CONTROLS + _ = Translator("ModLog", __file__) @@ -105,6 +107,37 @@ class ModLog(commands.Cog): else: await ctx.send(await case.message_content(embed=False)) + @commands.command() + @commands.guild_only() + async def casesfor(self, ctx: commands.Context, member: Union[discord.Member, int]): + """ + Displays the cases for the specified member + """ + try: + if isinstance(member, int): + cases = await modlog.get_cases_for_member( + bot=ctx.bot, guild=ctx.guild, member_id=member + ) + else: + cases = await modlog.get_cases_for_member( + bot=ctx.bot, guild=ctx.guild, member=member + ) + except discord.NotFound: + return await ctx.send(_("That user does not exist.")) + except discord.HTTPException: + return await ctx.send( + _("Something unexpected went wrong while fetching that user by ID.") + ) + + if not cases: + return await ctx.send(_("That user does not have any cases.")) + + embed_requested = await ctx.embed_requested() + + rendered_cases = [await case.message_content(embed=embed_requested) for case in cases] + + await menu(ctx, rendered_cases, DEFAULT_CONTROLS) + @commands.command() @commands.guild_only() async def reason(self, ctx: commands.Context, case: Optional[int], *, reason: str): diff --git a/redbot/core/modlog.py b/redbot/core/modlog.py index 6a3b4dc4d..e44364034 100644 --- a/redbot/core/modlog.py +++ b/redbot/core/modlog.py @@ -19,6 +19,7 @@ __all__ = [ "get_next_case_number", "get_case", "get_all_cases", + "get_cases_for_member", "create_case", "get_casetype", "get_all_casetypes", @@ -431,6 +432,92 @@ async def get_all_cases(guild: discord.Guild, bot: Red) -> List[Case]: return case_list +async def get_cases_for_member( + guild: discord.Guild, bot: Red, *, member: discord.Member = None, member_id: int = None +) -> List[Case]: + """ + Gets all cases for the specified member or member id in a guild. + + Parameters + ---------- + guild: `discord.Guild` + The guild to get the cases from + bot: Red + The bot's instance + member: `discord.Member` + The member to get cases about + member_id: int + The id of the member to get cases about + + Returns + ------- + list + A list of all matching cases. + + Raises + ------ + ValueError + If at least one of member or member_id is not provided + `discord.NotFound` + A user with this ID does not exist. + `discord.Forbidden` + The bot does not have permission to fetch the modlog message which was sent. + `discord.HTTPException` + Fetching the user failed. + """ + + cases = await _conf.guild(guild).get_raw("cases") + + if not (member_id or member): + raise ValueError("Expected a member or a member id to be provided.") from None + + if not member_id: + member_id = member.id + + if not member: + member = guild.get_member(member_id) + if not member: + member = await bot.get_user_info(member_id) + + try: + mod_channel = await get_modlog_channel(guild) + except RuntimeError: + mod_channel = None + + async def make_case(data: dict) -> Case: + + message = None + if data["message"] and mod_channel: + try: + message = await mod_channel.get_message(data["message"]) + except discord.NotFound: + pass + + return Case( + bot=bot, + guild=bot.get_guild(data["guild"]), + created_at=data["created_at"], + action_type=data["action_type"], + user=member, + moderator=guild.get_member(data["moderator"]), + case_number=data["case_number"], + reason=data["reason"], + until=data["until"], + channel=guild.get_channel(data["channel"]), + amended_by=guild.get_member(data["amended_by"]), + modified_at=data["modified_at"], + message=message, + ) + + cases = [ + await make_case(case_data) + for case_data in cases.values() + if case_data["user"] == member_id + ] + + return cases + + async def create_case( bot: Red, guild: discord.Guild,