aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/moderation/management.py7
-rw-r--r--bot/utils/time.py26
2 files changed, 32 insertions, 1 deletions
diff --git a/bot/cogs/moderation/management.py b/bot/cogs/moderation/management.py
index 180d5219f..9605d47b2 100644
--- a/bot/cogs/moderation/management.py
+++ b/bot/cogs/moderation/management.py
@@ -244,6 +244,12 @@ class ModManagement(commands.Cog):
user_id = infraction["user"]
hidden = infraction["hidden"]
created = time.format_infraction(infraction["inserted_at"])
+
+ if active:
+ remaining = time.until_expiration(infraction["expires_at"]) or "Expired"
+ else:
+ remaining = "Inactive"
+
if infraction["expires_at"] is None:
expires = "*Permanent*"
else:
@@ -259,6 +265,7 @@ class ModManagement(commands.Cog):
Reason: {infraction["reason"] or "*None*"}
Created: {created}
Expires: {expires}
+ Remaining: {remaining}
Actor: {actor.mention if actor else actor_id}
ID: `{infraction["id"]}`
{"**===============**" if active else "==============="}
diff --git a/bot/utils/time.py b/bot/utils/time.py
index a024674ac..ac64865d6 100644
--- a/bot/utils/time.py
+++ b/bot/utils/time.py
@@ -113,7 +113,11 @@ def format_infraction(timestamp: str) -> str:
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:
+def format_infraction_with_duration(
+ expiry: Optional[str],
+ date_from: datetime.datetime = None,
+ max_units: int = 2
+) -> Optional[str]:
"""
Format an infraction timestamp to a more readable ISO 8601 format WITH the duration.
@@ -134,3 +138,23 @@ def format_infraction_with_duration(expiry: str, date_from: datetime.datetime =
duration_formatted = f" ({duration})" if duration else ''
return f"{expiry_formatted}{duration_formatted}"
+
+
+def until_expiration(expiry: Optional[str], max_units: int = 2) -> Optional[str]:
+ """
+ Get the remaining time until infraction's expiration, in a human-readable version of the relativedelta.
+
+ 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
+
+ now = datetime.datetime.utcnow()
+ since = dateutil.parser.isoparse(expiry).replace(tzinfo=None, microsecond=0)
+
+ if since < now:
+ return None
+
+ return humanize_delta(relativedelta(since, now), max_units=max_units)