diff options
Diffstat (limited to '')
| -rw-r--r-- | bot/exts/evergreen/emojis.py | 39 | ||||
| -rw-r--r-- | bot/utils/time.py | 84 | 
2 files changed, 123 insertions, 0 deletions
| diff --git a/bot/exts/evergreen/emojis.py b/bot/exts/evergreen/emojis.py new file mode 100644 index 00000000..9f825e6d --- /dev/null +++ b/bot/exts/evergreen/emojis.py @@ -0,0 +1,39 @@ +import textwrap + +from discord import Color, Embed, Emoji +from discord.ext import commands + +from bot.utils.time import time_since + + +class Emojis(commands.Cog): +    """Has commands related to emojis.""" + +    @commands.group(name="emoji", invoke_without_command=True) +    async def emojis_group(self, ctx: commands.Context, emoji: Emoji) -> None: +        """A group of commands related to emojis.""" +        # No parameters = same as invoking info subcommand +        await ctx.invoke(self.info_command, emoji) + +    @emojis_group.command(name="info") +    async def info_command(self, ctx: commands.Context, emoji: Emoji) -> None: +        """Returns relevant information about a Discord Emoji.""" +        emoji_information = Embed( +            title=f'Information about "{emoji.name}"', +            description=textwrap.dedent(f""" +                Name: {emoji.name} +                Created: {time_since(emoji.created_at, precision="hours")} +                ID: {emoji.id} +                [Emoji source image]({emoji.url}) +            """), +            color=Color.blurple() +        ) +        emoji_information.set_thumbnail( +            url=emoji.url +        ) +        await ctx.send(embed=emoji_information) + + +def setup(bot: commands.Bot) -> None: +    """Add the Emojis cog into the bot.""" +    bot.add_cog(Emojis()) diff --git a/bot/utils/time.py b/bot/utils/time.py new file mode 100644 index 00000000..3c57e126 --- /dev/null +++ b/bot/utils/time.py @@ -0,0 +1,84 @@ +import datetime + +from dateutil.relativedelta import relativedelta + + +# All these functions are from https://github.com/python-discord/bot/blob/master/bot/utils/time.py +def _stringify_time_unit(value: int, unit: str) -> str: +    """ +    Returns a string to represent a value and time unit, ensuring that it uses the right plural form of the unit. + +    >>> _stringify_time_unit(1, "seconds") +    "1 second" +    >>> _stringify_time_unit(24, "hours") +    "24 hours" +    >>> _stringify_time_unit(0, "minutes") +    "less than a minute" +    """ +    if unit == "seconds" and value == 0: +        return "0 seconds" +    elif value == 1: +        return f"{value} {unit[:-1]}" +    elif value == 0: +        return f"less than a {unit[:-1]}" +    else: +        return f"{value} {unit}" + + +def humanize_delta(delta: relativedelta, precision: str = "seconds", max_units: int = 6) -> str: +    """ +    Returns a human-readable version of the relativedelta. + +    precision specifies the smallest unit of time to include (e.g. "seconds", "minutes"). +    max_units specifies the maximum number of units of time to include (e.g. 1 may include days but not hours). +    """ +    if max_units <= 0: +        raise ValueError("max_units must be positive") + +    units = ( +        ("years", delta.years), +        ("months", delta.months), +        ("days", delta.days), +        ("hours", delta.hours), +        ("minutes", delta.minutes), +        ("seconds", delta.seconds), +    ) + +    # Add the time units that are >0, but stop at accuracy or max_units. +    time_strings = [] +    unit_count = 0 +    for unit, value in units: +        if value: +            time_strings.append(_stringify_time_unit(value, unit)) +            unit_count += 1 + +        if unit == precision or unit_count >= max_units: +            break + +    # Add the 'and' between the last two units, if necessary +    if len(time_strings) > 1: +        time_strings[-1] = f"{time_strings[-2]} and {time_strings[-1]}" +        del time_strings[-2] + +    # If nothing has been found, just make the value 0 precision, e.g. `0 days`. +    if not time_strings: +        humanized = _stringify_time_unit(0, precision) +    else: +        humanized = ", ".join(time_strings) + +    return humanized + + +def time_since(past_datetime: datetime.datetime, precision: str = "seconds", max_units: int = 6) -> str: +    """ +    Takes a datetime and returns a human-readable string that describes how long ago that datetime was. + +    precision specifies the smallest unit of time to include (e.g. "seconds", "minutes"). +    max_units specifies the maximum number of units of time to include (e.g. 1 may include days but not hours). +    """ +    now = datetime.datetime.utcnow() +    delta = abs(relativedelta(now, past_datetime)) + +    humanized = humanize_delta(delta, precision, max_units) + +    return f"{humanized} ago" | 
