aboutsummaryrefslogtreecommitdiffstats
path: root/bot/cogs/moderation/scheduler.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/cogs/moderation/scheduler.py')
-rw-r--r--bot/cogs/moderation/scheduler.py61
1 files changed, 38 insertions, 23 deletions
diff --git a/bot/cogs/moderation/scheduler.py b/bot/cogs/moderation/scheduler.py
index dc42bee2e..b65048f4c 100644
--- a/bot/cogs/moderation/scheduler.py
+++ b/bot/cogs/moderation/scheduler.py
@@ -84,6 +84,7 @@ class InfractionScheduler(Scheduler):
"""Apply an infraction to the user, log the infraction, and optionally notify the user."""
infr_type = infraction["type"]
icon = utils.INFRACTION_ICONS[infr_type][0]
+ # Truncate reason when it's too long to avoid raising error on sending ModLog entry
reason = infraction["reason"]
expiry = time.format_infraction_with_duration(infraction["expires_at"])
id_ = infraction['id']
@@ -101,33 +102,17 @@ class InfractionScheduler(Scheduler):
dm_result = ""
dm_log_text = ""
- expiry_log_text = f"Expires: {expiry}" if expiry else ""
+ expiry_log_text = f"\nExpires: {expiry}" if expiry else ""
log_title = "applied"
log_content = None
-
- # DM the user about the infraction if it's not a shadow/hidden infraction.
- if not infraction["hidden"]:
- dm_result = f"{constants.Emojis.failmail} "
- dm_log_text = "\nDM: **Failed**"
-
- # Sometimes user is a discord.Object; make it a proper user.
- try:
- if not isinstance(user, (discord.Member, discord.User)):
- user = await self.bot.fetch_user(user.id)
- except discord.HTTPException as e:
- log.error(f"Failed to DM {user.id}: could not fetch user (status {e.status})")
- else:
- # Accordingly display whether the user was successfully notified via DM.
- if await utils.notify_infraction(user, infr_type, expiry, reason, icon):
- dm_result = ":incoming_envelope: "
- dm_log_text = "\nDM: Sent"
+ failed = False
if infraction["actor"] == self.bot.user.id:
log.trace(
f"Infraction #{id_} actor is bot; including the reason in the confirmation message."
)
- end_msg = f" (reason: {infraction['reason']})"
+ end_msg = f" (reason: {textwrap.shorten(reason, width=1500, placeholder='...')})"
elif ctx.channel.id not in STAFF_CHANNELS:
log.trace(
f"Infraction #{id_} context is not in a staff channel; omitting infraction count."
@@ -164,11 +149,37 @@ class InfractionScheduler(Scheduler):
log.warning(f"{log_msg}: bot lacks permissions.")
else:
log.exception(log_msg)
+ failed = True
+
+ # DM the user about the infraction if it's not a shadow/hidden infraction.
+ # Don't send DM when applying failed.
+ if not infraction["hidden"] and not failed:
+ dm_result = f"{constants.Emojis.failmail} "
+ dm_log_text = "\nDM: **Failed**"
+
+ # Sometimes user is a discord.Object; make it a proper user.
+ try:
+ if not isinstance(user, (discord.Member, discord.User)):
+ user = await self.bot.fetch_user(user.id)
+ except discord.HTTPException as e:
+ log.error(f"Failed to DM {user.id}: could not fetch user (status {e.status})")
+ else:
+ # Accordingly display whether the user was successfully notified via DM.
+ if await utils.notify_infraction(user, infr_type, expiry, reason, icon):
+ dm_result = ":incoming_envelope: "
+ dm_log_text = "\nDM: Sent"
+
+ if failed:
+ dm_log_text = "\nDM: **Canceled**"
+ dm_result = f"{constants.Emojis.failmail} "
+ log.trace(f"Deleted infraction {infraction['id']} from database because applying infraction failed.")
+ await self.bot.api_client.delete(f"bot/infractions/{infraction['id']}")
# Send a confirmation message to the invoking context.
log.trace(f"Sending infraction #{id_} confirmation message.")
await ctx.send(
- f"{dm_result}{confirm_msg} **{infr_type}** to {user.mention}{expiry_msg}{end_msg}."
+ f"{dm_result}{confirm_msg} "
+ f"{f'**{infr_type}** to {user.mention}{expiry_msg}{end_msg}' if not failed else ''}."
)
# Send a log message to the mod log.
@@ -180,9 +191,8 @@ class InfractionScheduler(Scheduler):
thumbnail=user.avatar_url_as(static_format="png"),
text=textwrap.dedent(f"""
Member: {user.mention} (`{user.id}`)
- Actor: {ctx.message.author}{dm_log_text}
+ Actor: {ctx.message.author}{dm_log_text} {expiry_log_text}
Reason: {reason}
- {expiry_log_text}
"""),
content=log_content,
footer=f"ID {infraction['id']}"
@@ -294,6 +304,9 @@ class InfractionScheduler(Scheduler):
f"{log_text.get('Failure', '')}"
)
+ # Move reason to end of entry to avoid cutting out some keys
+ log_text["Reason"] = log_text.pop("Reason")
+
# Send a log message to the mod log.
await self.mod_log.send_log_message(
icon_url=utils.INFRACTION_ICONS[infr_type][1],
@@ -407,6 +420,9 @@ class InfractionScheduler(Scheduler):
user = self.bot.get_user(user_id)
avatar = user.avatar_url_as(static_format="png") if user else None
+ # Move reason to end so when reason is too long, this is not gonna cut out required items.
+ log_text["Reason"] = log_text.pop("Reason")
+
log.trace(f"Sending deactivation mod log for infraction #{id_}.")
await self.mod_log.send_log_message(
icon_url=utils.INFRACTION_ICONS[type_][1],
@@ -416,7 +432,6 @@ class InfractionScheduler(Scheduler):
text="\n".join(f"{k}: {v}" for k, v in log_text.items()),
footer=f"ID: {id_}",
content=log_content,
-
)
return log_text