aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/moderation/infraction/infractions.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/moderation/infraction/infractions.py')
-rw-r--r--bot/exts/moderation/infraction/infractions.py86
1 files changed, 44 insertions, 42 deletions
diff --git a/bot/exts/moderation/infraction/infractions.py b/bot/exts/moderation/infraction/infractions.py
index e785216c9..15d80cd58 100644
--- a/bot/exts/moderation/infraction/infractions.py
+++ b/bot/exts/moderation/infraction/infractions.py
@@ -30,8 +30,9 @@ if t.TYPE_CHECKING:
# Comp ban
-LINK_PASSWORD = "https://support.discord.com/hc/en-us/articles/218410947-I-forgot-my-Password-Where-can-I-set-a-new-one"
-LINK_2FA = "https://support.discord.com/hc/en-us/articles/219576828-Setting-up-Two-Factor-Authentication"
+DISCORD_ARTICLE_URL = "https://support.discord.com/hc/en-us/articles"
+LINK_PASSWORD = DISCORD_ARTICLE_URL + "/218410947-I-forgot-my-Password-Where-can-I-set-a-new-one"
+LINK_2FA = DISCORD_ARTICLE_URL + "/219576828-Setting-up-Two-Factor-Authentication"
COMP_BAN_REASON = (
"Your account has been used to send links to a phishing website. You have been automatically banned. "
"If you are not aware of sending them, that means your account has been compromised.\n\n"
@@ -68,7 +69,7 @@ class Infractions(InfractionScheduler, commands.Cog):
# region: Permanent infractions
@command(aliases=("warning",))
- async def warn(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: t.Optional[str] = None) -> None:
+ async def warn(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: str | None = None) -> None:
"""Warn a user for the given reason."""
if not isinstance(user, Member):
await ctx.send(":x: The user doesn't appear to be on the server.")
@@ -81,7 +82,7 @@ class Infractions(InfractionScheduler, commands.Cog):
await self.apply_infraction(ctx, infraction, user)
@command()
- async def kick(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: t.Optional[str] = None) -> None:
+ async def kick(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: str | None = None) -> None:
"""Kick a user for the given reason."""
if not isinstance(user, Member):
await ctx.send(":x: The user doesn't appear to be on the server.")
@@ -95,9 +96,9 @@ class Infractions(InfractionScheduler, commands.Cog):
self,
ctx: Context,
user: UnambiguousMemberOrUser,
- duration_or_expiry: t.Optional[DurationOrExpiry] = None,
+ duration_or_expiry: DurationOrExpiry | None = None,
*,
- reason: t.Optional[str] = None
+ reason: str | None = None
) -> None:
"""
Permanently ban a `user` for the given `reason` and stop watching them with Big Brother.
@@ -114,16 +115,16 @@ class Infractions(InfractionScheduler, commands.Cog):
self,
ctx: Context,
user: UnambiguousMemberOrUser,
- duration: t.Optional[DurationOrExpiry] = None,
+ duration: DurationOrExpiry | None = None,
*,
- reason: t.Optional[str] = None
+ reason: str | None = None
) -> None:
"""
Same as ban, but also cleans all their messages from the last hour.
If duration is specified, it temporarily bans that user for the given duration.
"""
- clean_cog: t.Optional[Clean] = self.bot.get_cog("Clean")
+ clean_cog: Clean | None = self.bot.get_cog("Clean")
if clean_cog is None:
# If we can't get the clean cog, fall back to native purgeban.
await self.apply_ban(ctx, user, reason, purge_days=1, duration_or_expiry=duration)
@@ -148,7 +149,7 @@ class Infractions(InfractionScheduler, commands.Cog):
# Cleaning failed, or there were no messages to clean, exit early.
return
- infr_manage_cog: t.Optional[ModManagement] = self.bot.get_cog("ModManagement")
+ infr_manage_cog: ModManagement | None = self.bot.get_cog("ModManagement")
if infr_manage_cog is None:
# If we can't get the mod management cog, don't bother appending the log.
return
@@ -182,9 +183,9 @@ class Infractions(InfractionScheduler, commands.Cog):
self,
ctx: Context,
user: UnambiguousMemberOrUser,
- duration: t.Optional[DurationOrExpiry] = None,
+ duration: DurationOrExpiry | None = None,
*,
- reason: t.Optional[str]
+ reason: str | None
) -> None:
"""
Permanently mute user in voice channels.
@@ -201,9 +202,9 @@ class Infractions(InfractionScheduler, commands.Cog):
async def timeout(
self, ctx: Context,
user: UnambiguousMemberOrUser,
- duration: t.Optional[DurationOrExpiry] = None,
+ duration: DurationOrExpiry | None = None,
*,
- reason: t.Optional[str] = None
+ reason: str | None = None
) -> None:
"""
Timeout a user for the given reason and duration.
@@ -221,7 +222,7 @@ class Infractions(InfractionScheduler, commands.Cog):
Alternatively, an ISO 8601 timestamp can be provided for the duration.
If no duration is given, a one-hour duration is used by default.
- """
+ """ # noqa: RUF002
if not isinstance(user, Member):
await ctx.send(":x: The user doesn't appear to be on the server.")
return
@@ -255,7 +256,7 @@ class Infractions(InfractionScheduler, commands.Cog):
user: UnambiguousMemberOrUser,
duration_or_expiry: DurationOrExpiry,
*,
- reason: t.Optional[str] = None
+ reason: str | None = None
) -> None:
"""
Temporarily ban a user for the given reason and duration.
@@ -271,7 +272,7 @@ class Infractions(InfractionScheduler, commands.Cog):
\u2003`s` - seconds
Alternatively, an ISO 8601 timestamp can be provided for the duration.
- """
+ """ # noqa: RUF002
await self.apply_ban(ctx, user, reason, duration_or_expiry=duration_or_expiry)
@command(aliases=("tempvban", "tvban"))
@@ -291,7 +292,7 @@ class Infractions(InfractionScheduler, commands.Cog):
user: UnambiguousMemberOrUser,
duration: DurationOrExpiry,
*,
- reason: t.Optional[str]
+ reason: str | None
) -> None:
"""
Temporarily voice mute a user for the given reason and duration.
@@ -307,14 +308,14 @@ class Infractions(InfractionScheduler, commands.Cog):
\u2003`s` - seconds
Alternatively, an ISO 8601 timestamp can be provided for the duration.
- """
+ """ # noqa: RUF002
await self.apply_voice_mute(ctx, user, reason, duration_or_expiry=duration)
# endregion
# region: Permanent shadow infractions
@command(hidden=True)
- async def note(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: t.Optional[str] = None) -> None:
+ async def note(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: str | None = None) -> None:
"""Create a private note for a user with the given reason without notifying the user."""
infraction = await _utils.post_infraction(ctx, user, "note", reason, hidden=True, active=False)
if infraction is None:
@@ -322,8 +323,8 @@ class Infractions(InfractionScheduler, commands.Cog):
await self.apply_infraction(ctx, infraction, user)
- @command(hidden=True, aliases=['shadowban', 'sban'])
- async def shadow_ban(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: t.Optional[str] = None) -> None:
+ @command(hidden=True, aliases=["shadowban", "sban"])
+ async def shadow_ban(self, ctx: Context, user: UnambiguousMemberOrUser, *, reason: str | None = None) -> None:
"""Permanently ban a user for the given reason without notifying the user."""
await self.apply_ban(ctx, user, reason, hidden=True)
@@ -338,7 +339,7 @@ class Infractions(InfractionScheduler, commands.Cog):
user: UnambiguousMemberOrUser,
duration: DurationOrExpiry,
*,
- reason: t.Optional[str] = None
+ reason: str | None = None
) -> None:
"""
Temporarily ban a user for the given reason and duration without notifying the user.
@@ -354,7 +355,7 @@ class Infractions(InfractionScheduler, commands.Cog):
\u2003`s` - seconds
Alternatively, an ISO 8601 timestamp can be provided for the duration.
- """
+ """ # noqa: RUF002
await self.apply_ban(ctx, user, reason, duration_or_expiry=duration, hidden=True)
# endregion
@@ -366,7 +367,7 @@ class Infractions(InfractionScheduler, commands.Cog):
ctx: Context,
user: UnambiguousMemberOrUser,
*,
- pardon_reason: t.Optional[str] = None
+ pardon_reason: str | None = None
) -> None:
"""Prematurely end the active timeout infraction for the user."""
await self.pardon_infraction(ctx, "timeout", user, pardon_reason)
@@ -391,7 +392,7 @@ class Infractions(InfractionScheduler, commands.Cog):
ctx: Context,
user: UnambiguousMemberOrUser,
*,
- pardon_reason: t.Optional[str] = None
+ pardon_reason: str | None = None
) -> None:
"""Prematurely end the active voice mute infraction for the user."""
await self.pardon_infraction(ctx, "voice_mute", user, pardon_reason)
@@ -400,11 +401,11 @@ class Infractions(InfractionScheduler, commands.Cog):
# region: Base apply functions
@respect_role_hierarchy(member_arg=2)
- async def apply_timeout(self, ctx: Context, user: Member, reason: t.Optional[str], **kwargs) -> None:
+ async def apply_timeout(self, ctx: Context, user: Member, reason: str | None, **kwargs) -> None:
"""Apply a timeout infraction with kwargs passed to `post_infraction`."""
if isinstance(user, Member) and user.top_role >= ctx.me.top_role:
await ctx.send(":x: I can't timeout users above or equal to me in the role hierarchy.")
- return None
+ return
if active := await _utils.get_active_infraction(ctx, user, "timeout", send_msg=False):
if active["actor"] != self.bot.user.id:
@@ -439,7 +440,7 @@ class Infractions(InfractionScheduler, commands.Cog):
await self.apply_infraction(ctx, infraction, user, action)
@respect_role_hierarchy(member_arg=2)
- async def apply_kick(self, ctx: Context, user: Member, reason: t.Optional[str], **kwargs) -> None:
+ async def apply_kick(self, ctx: Context, user: Member, reason: str | None, **kwargs) -> None:
"""Apply a kick infraction with kwargs passed to `post_infraction`."""
if user.top_role >= ctx.me.top_role:
await ctx.send(":x: I can't kick users above or equal to me in the role hierarchy.")
@@ -464,10 +465,10 @@ class Infractions(InfractionScheduler, commands.Cog):
self,
ctx: Context,
user: MemberOrUser,
- reason: t.Optional[str],
- purge_days: t.Optional[int] = 0,
+ reason: str | None,
+ purge_days: int | None = 0,
**kwargs
- ) -> t.Optional[dict]:
+ ) -> dict | None:
"""
Apply a ban infraction with kwargs passed to `post_infraction`.
@@ -510,8 +511,8 @@ class Infractions(InfractionScheduler, commands.Cog):
await self.apply_infraction(ctx, infraction, user, action)
- bb_cog: t.Optional[BigBrother] = self.bot.get_cog("Big Brother")
- if infraction.get('expires_at') is not None:
+ bb_cog: BigBrother | None = self.bot.get_cog("Big Brother")
+ if infraction.get("expires_at") is not None:
log.trace(f"Ban isn't permanent; user {user} won't be unwatched by Big Brother.")
elif not bb_cog:
log.error(f"Big Brother cog not loaded; perma-banned user {user} won't be unwatched.")
@@ -523,7 +524,7 @@ class Infractions(InfractionScheduler, commands.Cog):
return infraction
@respect_role_hierarchy(member_arg=2)
- async def apply_voice_mute(self, ctx: Context, user: MemberOrUser, reason: t.Optional[str], **kwargs) -> None:
+ async def apply_voice_mute(self, ctx: Context, user: MemberOrUser, reason: str | None, **kwargs) -> None:
"""Apply a voice mute infraction with kwargs passed to `post_infraction`."""
if await _utils.get_active_infraction(ctx, user, "voice_mute"):
return
@@ -554,10 +555,10 @@ class Infractions(InfractionScheduler, commands.Cog):
self,
user_id: int,
guild: discord.Guild,
- reason: t.Optional[str],
+ reason: str | None,
*,
notify: bool = True
- ) -> t.Dict[str, str]:
+ ) -> dict[str, str]:
"""Remove a user's timeout, optionally DM them a notification, and return a log dict."""
user = await get_or_fetch_member(guild, user_id)
log_text = {}
@@ -586,7 +587,7 @@ class Infractions(InfractionScheduler, commands.Cog):
return log_text
- async def pardon_ban(self, user_id: int, guild: discord.Guild, reason: t.Optional[str]) -> t.Dict[str, str]:
+ async def pardon_ban(self, user_id: int, guild: discord.Guild, reason: str | None) -> dict[str, str]:
"""Remove a user's ban on the Discord guild and return a log dict."""
user = discord.Object(user_id)
log_text = {}
@@ -607,7 +608,7 @@ class Infractions(InfractionScheduler, commands.Cog):
guild: discord.Guild,
*,
notify: bool = True
- ) -> t.Dict[str, str]:
+ ) -> dict[str, str]:
"""Optionally DM the user a pardon notification and return a log dict."""
user = await get_or_fetch_member(guild, user_id)
log_text = {}
@@ -629,7 +630,7 @@ class Infractions(InfractionScheduler, commands.Cog):
return log_text
- async def _pardon_action(self, infraction: _utils.Infraction, notify: bool) -> t.Optional[t.Dict[str, str]]:
+ async def _pardon_action(self, infraction: _utils.Infraction, notify: bool) -> dict[str, str] | None:
"""
Execute deactivation steps specific to the infraction's type and return a log dict.
@@ -642,10 +643,11 @@ class Infractions(InfractionScheduler, commands.Cog):
if infraction["type"] == "timeout":
return await self.pardon_timeout(user_id, guild, reason, notify=notify)
- elif infraction["type"] == "ban":
+ if infraction["type"] == "ban":
return await self.pardon_ban(user_id, guild, reason)
- elif infraction["type"] == "voice_mute":
+ if infraction["type"] == "voice_mute":
return await self.pardon_voice_mute(user_id, guild, notify=notify)
+ return None
# endregion