diff options
author | 2019-12-03 18:16:13 -0800 | |
---|---|---|
committer | 2019-12-03 18:16:13 -0800 | |
commit | 7af35113e06628d1edb36b98639b0d41903e2f39 (patch) | |
tree | ddadf95d3ecbf12cb9a1ce3f2613ea24f2d9d8e3 | |
parent | Allow snekbox in esoteric-python channel (#675) (diff) | |
parent | Renamed function and improved its docstring to better reflect its purposes. (diff) |
Merge pull request #672 from python-discord/enhance-timedelta-for-infraction-expiration
Enhance timedelta for infraction expiration
-rw-r--r-- | bot/cogs/moderation/management.py | 6 | ||||
-rw-r--r-- | bot/cogs/moderation/scheduler.py | 5 | ||||
-rw-r--r-- | bot/utils/time.py | 23 |
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}" |