aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/converters.py14
-rw-r--r--bot/errors.py19
-rw-r--r--bot/exts/moderation/infraction/management.py36
-rw-r--r--bot/utils/regex.py3
4 files changed, 52 insertions, 20 deletions
diff --git a/bot/converters.py b/bot/converters.py
index bd4044c7e..18bb6e4e5 100644
--- a/bot/converters.py
+++ b/bot/converters.py
@@ -17,6 +17,7 @@ from discord.utils import DISCORD_EPOCH, escape_markdown, snowflake_time
from bot import exts
from bot.api import ResponseCodeError
from bot.constants import URLs
+from bot.errors import InvalidInfraction
from bot.exts.info.doc import _inventory_parser
from bot.utils.extensions import EXTENSIONS, unqualify
from bot.utils.regex import INVITE_RE
@@ -558,7 +559,7 @@ class Infraction(Converter):
"ordering": "-inserted_at"
}
- infractions = await ctx.bot.api_client.get("bot/infractions", params=params)
+ infractions = await ctx.bot.api_client.get("bot/infractions/expanded", params=params)
if not infractions:
raise BadArgument(
@@ -568,7 +569,16 @@ class Infraction(Converter):
return infractions[0]
else:
- return await ctx.bot.api_client.get(f"bot/infractions/{arg}")
+ try:
+ return await ctx.bot.api_client.get(f"bot/infractions/{arg}/expanded")
+ except ResponseCodeError as e:
+ if e.status == 404:
+ raise InvalidInfraction(
+ converter=Infraction,
+ original=e,
+ infraction_arg=arg
+ )
+ raise e
if t.TYPE_CHECKING:
diff --git a/bot/errors.py b/bot/errors.py
index 2633390a8..078b645f1 100644
--- a/bot/errors.py
+++ b/bot/errors.py
@@ -1,6 +1,9 @@
from __future__ import annotations
-from typing import Hashable, TYPE_CHECKING
+from typing import Hashable, TYPE_CHECKING, Union
+
+from discord.ext.commands import ConversionError, Converter
+
if TYPE_CHECKING:
from bot.converters import MemberOrUser
@@ -40,6 +43,20 @@ class InvalidInfractedUserError(Exception):
super().__init__(reason)
+class InvalidInfraction(ConversionError):
+ """
+ Raised by the Infraction converter when trying to fetch an invalid infraction id.
+
+ Attributes:
+ `infraction_arg` -- the value that we attempted to convert into an Infraction
+ """
+
+ def __init__(self, converter: Converter, original: Exception, infraction_arg: Union[int, str]):
+
+ self.infraction_arg = infraction_arg
+ super().__init__(converter, original)
+
+
class BrandingMisconfiguration(RuntimeError):
"""Raised by the Branding cog when a misconfigured event is encountered."""
diff --git a/bot/exts/moderation/infraction/management.py b/bot/exts/moderation/infraction/management.py
index 223a124d8..d72cf8f89 100644
--- a/bot/exts/moderation/infraction/management.py
+++ b/bot/exts/moderation/infraction/management.py
@@ -11,9 +11,9 @@ from discord.ext.commands import Context
from discord.utils import escape_markdown
from bot import constants
-from bot.api import ResponseCodeError
from bot.bot import Bot
from bot.converters import Expiry, Infraction, MemberOrUser, Snowflake, UnambiguousUser, allowed_strings
+from bot.errors import InvalidInfraction
from bot.exts.moderation.infraction.infractions import Infractions
from bot.exts.moderation.modlog import ModLog
from bot.pagination import LinePaginator
@@ -45,25 +45,22 @@ class ModManagement(commands.Cog):
# region: Edit infraction commands
@commands.group(name='infraction', aliases=('infr', 'infractions', 'inf', 'i'), invoke_without_command=True)
- async def infraction_group(self, ctx: Context, infr_id: int = None) -> None:
- """Infraction manipulation commands. If `infr_id` is passed then this command fetches that infraction."""
- if infr_id is None:
+ async def infraction_group(self, ctx: Context, infraction: Infraction = None) -> None:
+ """
+ Infraction manipulation commands.
+
+ If `infraction` is passed then this command fetches that infraction. The `Infraction` converter
+ supports 'l', 'last' and 'recent' to get the most recent infraction made by `ctx.author`.
+ """
+ if infraction is None:
await ctx.send_help(ctx.command)
return
- try:
- infraction_list = [await self.bot.api_client.get(f"bot/infractions/{infr_id}/expanded")]
- except ResponseCodeError as e:
- if e.status == 404:
- await ctx.send(f":x: No infraction with ID `{infr_id}` could be found.")
- return
- raise e
-
embed = discord.Embed(
- title=f"Infraction #{infr_id}",
+ title=f"Infraction #{infraction['id']}",
colour=discord.Colour.orange()
)
- await self.send_infraction_list(ctx, embed, infraction_list)
+ await self.send_infraction_list(ctx, embed, [infraction])
@infraction_group.command(name="append", aliases=("amend", "add", "a"))
async def infraction_append(
@@ -348,13 +345,20 @@ class ModManagement(commands.Cog):
return all(checks)
# This cannot be static (must have a __func__ attribute).
- async def cog_command_error(self, ctx: Context, error: Exception) -> None:
- """Send a notification to the invoking context on a Union failure."""
+ async def cog_command_error(self, ctx: Context, error: commands.CommandError) -> None:
+ """Handles errors for commands within this cog."""
if isinstance(error, commands.BadUnionArgument):
if discord.User in error.converters:
await ctx.send(str(error.errors[0]))
error.handled = True
+ elif isinstance(error, InvalidInfraction):
+ if error.infraction_arg.isdigit():
+ await ctx.send(f":x: Could not find an infraction with id `{error.infraction_arg}`.")
+ else:
+ await ctx.send(f":x: `{error.infraction_arg}` is not a valid integer infraction id.")
+ error.handled = True
+
def setup(bot: Bot) -> None:
"""Load the ModManagement cog."""
diff --git a/bot/utils/regex.py b/bot/utils/regex.py
index a8efe1446..7bad1e627 100644
--- a/bot/utils/regex.py
+++ b/bot/utils/regex.py
@@ -6,7 +6,8 @@ INVITE_RE = re.compile(
r"discordapp(?:[\.,]|dot)com(?:\/|slash)invite|" # or discordapp.com/invite/
r"discord(?:[\.,]|dot)me|" # or discord.me
r"discord(?:[\.,]|dot)li|" # or discord.li
- r"discord(?:[\.,]|dot)io" # or discord.io.
+ r"discord(?:[\.,]|dot)io|" # or discord.io.
+ r"(?:[\.,]|dot)gg" # or .gg/
r")(?:[\/]|slash)" # / or 'slash'
r"([a-zA-Z0-9\-]+)", # the invite code itself
flags=re.IGNORECASE