aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/constants.py3
-rw-r--r--bot/exts/evergreen/branding.py7
-rw-r--r--bot/utils/__init__.py7
-rw-r--r--bot/utils/decorators.py19
4 files changed, 21 insertions, 15 deletions
diff --git a/bot/constants.py b/bot/constants.py
index 22ea9177..638448ea 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -149,6 +149,9 @@ class Month(enum.IntEnum):
NOVEMBER = 11
DECEMBER = 12
+ def __str__(self) -> str:
+ return self.name.title()
+
# If a month override was configured, check that it's a valid Month
# Prevents delaying an exception after the bot starts
diff --git a/bot/exts/evergreen/branding.py b/bot/exts/evergreen/branding.py
index 140613e9..96acd587 100644
--- a/bot/exts/evergreen/branding.py
+++ b/bot/exts/evergreen/branding.py
@@ -15,6 +15,7 @@ from discord.ext import commands
from bot.bot import SeasonalBot
from bot.constants import Branding, Colours, Emojis, MODERATION_ROLES, Tokens
from bot.seasons import SeasonBase, get_all_seasons, get_current_season, get_season
+from bot.utils import human_months
from bot.utils.decorators import with_role
from bot.utils.exceptions import BrandingError
from bot.utils.persist import make_persistent
@@ -219,8 +220,7 @@ class BrandingManager(commands.Cog):
# If we're in a non-evergreen season, also show active months
if self.current_season is not SeasonBase:
- active_months = ", ".join(m.name.title() for m in self.current_season.months)
- title = f"{self.current_season.season_name} ({active_months})"
+ title = f"{self.current_season.season_name} ({human_months(self.current_season.months)})"
else:
title = self.current_season.season_name
@@ -406,8 +406,7 @@ class BrandingManager(commands.Cog):
if season is SeasonBase:
active_when = "always"
else:
- months = ", ".join(m.name.title() for m in season.months)
- active_when = f"in {months}"
+ active_when = f"in {human_months(season.months)}"
description = (
f"Active {active_when}\n"
diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py
index 69bff4de..35ef0a7b 100644
--- a/bot/utils/__init__.py
+++ b/bot/utils/__init__.py
@@ -3,7 +3,7 @@ import contextlib
import re
import string
from datetime import datetime
-from typing import List
+from typing import Iterable, List
import discord
from discord.ext.commands import BadArgument, Context
@@ -12,6 +12,11 @@ from bot.constants import Client, Month
from bot.utils.pagination import LinePaginator
+def human_months(months: Iterable[Month]) -> str:
+ """Build a comma separated list of `months`."""
+ return ", ".join(str(m) for m in months)
+
+
def resolve_current_month() -> Month:
"""
Determine current month w.r.t. `Client.month_override` env var.
diff --git a/bot/utils/decorators.py b/bot/utils/decorators.py
index 1e0a1715..519e61a9 100644
--- a/bot/utils/decorators.py
+++ b/bot/utils/decorators.py
@@ -12,7 +12,7 @@ from discord.ext import commands
from discord.ext.commands import CheckFailure, Command, Context
from bot.constants import Client, ERROR_REPLIES, Month
-from bot.utils import resolve_current_month
+from bot.utils import human_months, resolve_current_month
ONE_DAY = 24 * 60 * 60
@@ -47,7 +47,7 @@ def seasonal_task(*allowed_months: Month, sleep_time: t.Union[float, int] = ONE_
@functools.wraps(task_body)
async def decorated_task(*args, **kwargs) -> None:
"""Call `task_body` once every `sleep_time` seconds in `allowed_months`."""
- log.info(f"Starting seasonal task {task_body.__qualname__} ({allowed_months})")
+ log.info(f"Starting seasonal task {task_body.__qualname__} ({human_months(allowed_months)})")
while True:
current_month = resolve_current_month()
@@ -55,7 +55,7 @@ def seasonal_task(*allowed_months: Month, sleep_time: t.Union[float, int] = ONE_
if current_month in allowed_months:
await task_body(*args, **kwargs)
else:
- log.debug(f"Seasonal task {task_body.__qualname__} sleeps in {current_month.name}")
+ log.debug(f"Seasonal task {task_body.__qualname__} sleeps in {current_month!s}")
await asyncio.sleep(sleep_time)
return decorated_task
@@ -78,7 +78,7 @@ def in_month_listener(*allowed_months: Month) -> t.Callable:
# Propagate return value although it should always be None
return await listener(*args, **kwargs)
else:
- log.debug(f"Guarded {listener.__qualname__} from invoking in {current_month.name}")
+ log.debug(f"Guarded {listener.__qualname__} from invoking in {current_month!s}")
return guarded_listener
return decorator
@@ -93,15 +93,14 @@ def in_month_command(*allowed_months: Month) -> t.Callable:
current_month = resolve_current_month()
can_run = current_month in allowed_months
- human_months = ", ".join(m.name for m in allowed_months)
log.debug(
- f"Command '{ctx.command}' is locked to months {human_months}. "
- f"Invoking it in month {current_month} is {'allowed' if can_run else 'disallowed'}."
+ f"Command '{ctx.command}' is locked to months {human_months(allowed_months)}. "
+ f"Invoking it in month {current_month!s} is {'allowed' if can_run else 'disallowed'}."
)
if can_run:
return True
else:
- raise InMonthCheckFailure(f"Command can only be used in {human_months}")
+ raise InMonthCheckFailure(f"Command can only be used in {human_months(allowed_months)}")
return commands.check(predicate)
@@ -127,12 +126,12 @@ def in_month(*allowed_months: Month) -> t.Callable:
def decorator(callable_: t.Callable) -> t.Callable:
# Functions decorated as commands are turned into instances of `Command`
if isinstance(callable_, Command):
- logging.debug(f"Command {callable_.qualified_name} will be locked to {allowed_months}")
+ logging.debug(f"Command {callable_.qualified_name} will be locked to {human_months(allowed_months)}")
actual_deco = in_month_command(*allowed_months)
# D.py will assign this attribute when `callable_` is registered as a listener
elif hasattr(callable_, "__cog_listener__"):
- logging.debug(f"Listener {callable_.__qualname__} will be locked to {allowed_months}")
+ logging.debug(f"Listener {callable_.__qualname__} will be locked to {human_months(allowed_months)}")
actual_deco = in_month_listener(*allowed_months)
# Otherwise we're unsure exactly what has been decorated