aboutsummaryrefslogtreecommitdiffstats
path: root/bot/seasons/season.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/seasons/season.py')
-rw-r--r--bot/seasons/season.py104
1 files changed, 41 insertions, 63 deletions
diff --git a/bot/seasons/season.py b/bot/seasons/season.py
index b7892606..9dac51e2 100644
--- a/bot/seasons/season.py
+++ b/bot/seasons/season.py
@@ -19,9 +19,7 @@ log = logging.getLogger(__name__)
def get_seasons() -> List[str]:
- """
- Returns all the Season objects located in bot/seasons/
- """
+ """Returns all the Season objects located in /bot/seasons/."""
seasons = []
@@ -32,9 +30,7 @@ def get_seasons() -> List[str]:
def get_season_class(season_name: str) -> Type["SeasonBase"]:
- """
- Get's the season class of the season module.
- """
+ """Gets the season class of the season module."""
season_lib = importlib.import_module(f"bot.seasons.{season_name}")
class_name = season_name.replace("_", " ").title().replace(" ", "")
@@ -42,9 +38,7 @@ def get_season_class(season_name: str) -> Type["SeasonBase"]:
def get_season(season_name: str = None, date: datetime.datetime = None) -> "SeasonBase":
- """
- Returns a Season object based on either a string or a date.
- """
+ """Returns a Season object based on either a string or a date."""
# If either both or neither are set, raise an error.
if not bool(season_name) ^ bool(date):
@@ -78,9 +72,7 @@ def get_season(season_name: str = None, date: datetime.datetime = None) -> "Seas
class SeasonBase:
- """
- Base class for Seasonal classes.
- """
+ """Base class for Seasonal classes."""
name: Optional[str] = "evergreen"
bot_name: str = "SeasonalBot"
@@ -96,9 +88,7 @@ class SeasonBase:
@staticmethod
def current_year() -> int:
- """
- Returns the current year.
- """
+ """Returns the current year."""
return datetime.date.today().year
@@ -107,8 +97,7 @@ class SeasonBase:
"""
Returns the start date using current year and start_date attribute.
- If no start_date was defined, returns the minimum datetime to ensure
- it's always below checked dates.
+ If no start_date was defined, returns the minimum datetime to ensure it's always below checked dates.
"""
if not cls.start_date:
@@ -120,8 +109,7 @@ class SeasonBase:
"""
Returns the start date using current year and end_date attribute.
- If no end_date was defined, returns the minimum datetime to ensure
- it's always above checked dates.
+ If no end_date was defined, returns the minimum datetime to ensure it's always above checked dates.
"""
if not cls.end_date:
@@ -130,37 +118,36 @@ class SeasonBase:
@classmethod
def is_between_dates(cls, date: datetime.datetime) -> bool:
- """
- Determines if the given date falls between the season's date range.
- """
+ """Determines if the given date falls between the season's date range."""
return cls.start() <= date <= cls.end()
@property
def name_clean(self) -> str:
+ """Return the Season's name with underscores replaced by whitespace."""
+
return self.name.replace("_", " ").title()
@property
def greeting(self) -> str:
"""
- Provides a default greeting based on the season name if one wasn't
- defined in the season class.
+ Provides a default greeting based on the season name if one wasn't defined in the season class.
- It's recommended to define one in most cases by overwriting this as a
- normal attribute in the inhertiting class.
+ It's recommended to define one in most cases by overwriting this as a normal attribute in the
+ inheriting class.
"""
return f"New Season, {self.name_clean}!"
async def get_icon(self, avatar: bool = False) -> bytes:
"""
- Retrieves the icon image from the branding repository, using the
- defined icon attribute for the season. If `avatar` is True, uses
- optional bot-only avatar icon if present.
+ Retrieve the season's icon from the branding repository using the Season's icon attribute.
+
+ If `avatar` is True, uses optional bot-only avatar icon if present.
- The icon attribute must provide the url path, starting from the master
- branch base url, including the starting slash:
- `https://raw.githubusercontent.com/python-discord/branding/master`
+ The icon attribute must provide the url path, starting from the master branch base url,
+ including the starting slash.
+ e.g. `/logos/logo_seasonal/valentines/loved_up.png`
"""
base_url = "https://raw.githubusercontent.com/python-discord/branding/master"
@@ -175,8 +162,9 @@ class SeasonBase:
async def apply_username(self, *, debug: bool = False) -> Union[bool, None]:
"""
- Applies the username for the current season. Only changes nickname if
- `bool` is False, otherwise only changes the nickname.
+ Applies the username for the current season.
+
+ Only changes nickname if `bool` is False, otherwise only changes the nickname.
Returns True if it successfully changed the username.
Returns False if it failed to change the username, falling back to nick.
@@ -216,7 +204,9 @@ class SeasonBase:
async def apply_avatar(self) -> bool:
"""
- Applies the avatar for the current season. Returns if it was successful.
+ Applies the avatar for the current season.
+
+ Returns True if successful.
"""
# track old avatar hash for later comparison
@@ -238,7 +228,9 @@ class SeasonBase:
async def apply_server_icon(self) -> bool:
"""
- Applies the server icon for the current season. Returns if it was successful.
+ Applies the server icon for the current season.
+
+ Returns True if was successful.
"""
guild = bot.get_guild(Client.guild)
@@ -265,8 +257,7 @@ class SeasonBase:
"""
Announces a change in season in the announcement channel.
- It will skip the announcement if the current active season is the
- "evergreen" default season.
+ It will skip the announcement if the current active season is the "evergreen" default season.
"""
# don't actually announce if reverting to normal season
@@ -352,10 +343,8 @@ class SeasonBase:
await bot.send_log("SeasonalBot Loaded!", f"Active Season: **{self.name_clean}**")
-class SeasonManager(commands.Cog):
- """
- A cog for managing seasons.
- """
+class SeasonManager:
+ """A cog for managing seasons."""
def __init__(self, bot):
self.bot = bot
@@ -375,6 +364,8 @@ class SeasonManager(commands.Cog):
self.sleep_time = (midnight - datetime.datetime.now()).seconds + 60
async def load_seasons(self):
+ """Asynchronous timer loop to check for a new season every midnight."""
+
await self.bot.wait_until_ready()
await self.season.load()
@@ -390,9 +381,7 @@ class SeasonManager(commands.Cog):
@with_role(Roles.moderator, Roles.admin, Roles.owner)
@commands.command(name="season")
async def change_season(self, ctx, new_season: str):
- """
- Changes the currently active season on the bot.
- """
+ """Changes the currently active season on the bot."""
self.season = get_season(season_name=new_season)
await self.season.load()
@@ -401,9 +390,7 @@ class SeasonManager(commands.Cog):
@with_role(Roles.moderator, Roles.admin, Roles.owner)
@commands.command(name="seasons")
async def show_seasons(self, ctx):
- """
- Shows the available seasons and their dates.
- """
+ """Shows the available seasons and their dates."""
# sort by start order, followed by lower duration
def season_key(season_class: Type[SeasonBase]):
@@ -447,17 +434,13 @@ class SeasonManager(commands.Cog):
@with_role(Roles.moderator, Roles.admin, Roles.owner)
@commands.group()
async def refresh(self, ctx):
- """
- Refreshes certain seasonal elements without reloading seasons.
- """
+ """Refreshes certain seasonal elements without reloading seasons."""
if not ctx.invoked_subcommand:
await ctx.invoke(bot.get_command("help"), "refresh")
@refresh.command(name="avatar")
async def refresh_avatar(self, ctx):
- """
- Re-applies the bot avatar for the currently loaded season.
- """
+ """Re-applies the bot avatar for the currently loaded season."""
# attempt the change
is_changed = await self.season.apply_avatar()
@@ -481,9 +464,7 @@ class SeasonManager(commands.Cog):
@refresh.command(name="icon")
async def refresh_server_icon(self, ctx):
- """
- Re-applies the server icon for the currently loaded season.
- """
+ """Re-applies the server icon for the currently loaded season."""
# attempt the change
is_changed = await self.season.apply_server_icon()
@@ -507,9 +488,7 @@ class SeasonManager(commands.Cog):
@refresh.command(name="username", aliases=("name",))
async def refresh_username(self, ctx):
- """
- Re-applies the bot username for the currently loaded season.
- """
+ """Re-applies the bot username for the currently loaded season."""
old_username = str(bot.user)
old_display_name = ctx.guild.me.display_name
@@ -549,9 +528,8 @@ class SeasonManager(commands.Cog):
@with_role(Roles.moderator, Roles.admin, Roles.owner)
@commands.command()
async def announce(self, ctx):
- """
- Announces the currently loaded season.
- """
+ """Announces the currently loaded season."""
+
await self.season.announce_season()
def __unload(self):