aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/moderation/management.py6
-rw-r--r--bot/cogs/moderation/scheduler.py5
-rw-r--r--bot/utils/time.py23
3 files changed, 28 insertions, 6 deletions
diff --git a/bot/cogs/moderation/management.py b/bot/cogs/moderation/management.py
index 44a508436..abfe5c2b3 100644
--- a/bot/cogs/moderation/management.py
+++ b/bot/cogs/moderation/management.py
@@ -2,6 +2,7 @@ import asyncio
import logging
import textwrap
import typing as t
+from datetime import datetime
import discord
from discord.ext import commands
@@ -96,7 +97,7 @@ class ModManagement(commands.Cog):
confirm_messages.append("marked as permanent")
elif duration is not None:
request_data['expires_at'] = duration.isoformat()
- expiry = duration.strftime(time.INFRACTION_FORMAT)
+ expiry = time.format_infraction_with_duration(request_data['expires_at'])
confirm_messages.append(f"set to expire on {expiry}")
else:
confirm_messages.append("expiry unchanged")
@@ -234,7 +235,8 @@ class ModManagement(commands.Cog):
if infraction["expires_at"] is None:
expires = "*Permanent*"
else:
- expires = time.format_infraction(infraction["expires_at"])
+ date_from = datetime.strptime(created, time.INFRACTION_FORMAT)
+ expires = time.format_infraction_with_duration(infraction["expires_at"], date_from)
lines = textwrap.dedent(f"""
{"**===============**" if active else "==============="}
diff --git a/bot/cogs/moderation/scheduler.py b/bot/cogs/moderation/scheduler.py
index 49b61f35e..3e0968121 100644
--- a/bot/cogs/moderation/scheduler.py
+++ b/bot/cogs/moderation/scheduler.py
@@ -83,14 +83,11 @@ class InfractionScheduler(Scheduler):
infr_type = infraction["type"]
icon = utils.INFRACTION_ICONS[infr_type][0]
reason = infraction["reason"]
- expiry = infraction["expires_at"]
+ expiry = time.format_infraction_with_duration(infraction["expires_at"])
id_ = infraction['id']
log.trace(f"Applying {infr_type} infraction #{id_} to {user}.")
- if expiry:
- expiry = time.format_infraction(expiry)
-
# Default values for the confirmation message and mod log.
confirm_msg = f":ok_hand: applied"
diff --git a/bot/utils/time.py b/bot/utils/time.py
index 2aea2c099..a024674ac 100644
--- a/bot/utils/time.py
+++ b/bot/utils/time.py
@@ -111,3 +111,26 @@ async def wait_until(time: datetime.datetime, start: Optional[datetime.datetime]
def format_infraction(timestamp: str) -> str:
"""Format an infraction timestamp to a more readable ISO 8601 format."""
return dateutil.parser.isoparse(timestamp).strftime(INFRACTION_FORMAT)
+
+
+def format_infraction_with_duration(expiry: str, date_from: datetime.datetime = None, max_units: int = 2) -> str:
+ """
+ Format an infraction timestamp to a more readable ISO 8601 format WITH the duration.
+
+ Returns a human-readable version of the duration between datetime.utcnow() and an expiry.
+ Unlike `humanize_delta`, this function will force the `precision` to be `seconds` by not passing it.
+ `max_units` specifies the maximum number of units of time to include (e.g. 1 may include days but not hours).
+ By default, max_units is 2.
+ """
+ if not expiry:
+ return None
+
+ date_from = date_from or datetime.datetime.utcnow()
+ date_to = dateutil.parser.isoparse(expiry).replace(tzinfo=None, microsecond=0)
+
+ expiry_formatted = format_infraction(expiry)
+
+ duration = humanize_delta(relativedelta(date_to, date_from), max_units=max_units)
+ duration_formatted = f" ({duration})" if duration else ''
+
+ return f"{expiry_formatted}{duration_formatted}"