diff options
Diffstat (limited to '')
| -rw-r--r-- | bot/converters.py | 35 | 
1 files changed, 35 insertions, 0 deletions
| diff --git a/bot/converters.py b/bot/converters.py index 7386187ab..b7340982b 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -1,4 +1,5 @@  import logging +import re  from datetime import datetime  from ssl import CertificateError  from typing import Union @@ -6,6 +7,7 @@ from typing import Union  import dateparser  import discord  from aiohttp import ClientConnectorError +from dateutil.relativedelta import relativedelta  from discord.ext.commands import BadArgument, Context, Converter @@ -197,3 +199,36 @@ class ExpirationDate(Converter):              expiry = now + (now - expiry)          return expiry + + +class Duration(Converter): +    """Convert duration strings into UTC datetime.datetime objects.""" + +    duration_parser = re.compile( +        r"((?P<years>\d+?)(years|year|Y|y))?" +        r"((?P<months>\d+?)(months|month|m))?" +        r"((?P<weeks>\d+?)(weeks|week|W|w))?" +        r"((?P<days>\d+?)(days|day|D|d))?" +        r"((?P<hours>\d+?)(hours|hour|H|h))?" +        r"((?P<minutes>\d+?)(minutes|minute|M))?" +        r"((?P<seconds>\d+?)(seconds|second|S|s))?" +    ) + +    async def convert(self, ctx: Context, duration: str) -> datetime: +        """ +        Converts a `duration` string to a datetime object that's `duration` in the future. + +        The converter supports years (symbols: `years`, `year, `Y`, `y`), months (`months`, `month`, +        `m`), weeks (`weeks`, `week`, `W`, `w`), days (`days`, `day`, `D`, `d`), hours (`hours`, +        `hour`, `H`, `h`), minutes (`minutes`, `minute`, `M`), and seconds (`seconds`, `second`, +        `S`, `s`), The units must be provided in descending order of magnitude. +        """ +        match = self.duration_parser.fullmatch(duration) +        if not match: +            raise BadArgument(f"`{duration}` is not a valid duration string.") + +        duration_dict = {unit: int(amount) for unit, amount in match.groupdict().items() if amount} +        delta = relativedelta(**duration_dict) +        now = datetime.utcnow() + +        return now + delta | 
