diff options
author | 2018-12-02 03:21:27 +1000 | |
---|---|---|
committer | 2018-12-03 09:18:50 +1000 | |
commit | 08e63544f25a77a6a024c436daa86f997b85f6f9 (patch) | |
tree | 253cef91647bdff51023a1b7c309e142edd9af21 | |
parent | Add season element set methods, add server icon change support (diff) |
Add season announcement support
-rw-r--r-- | bot/constants.py | 4 | ||||
-rw-r--r-- | bot/seasons/christmas/__init__.py | 9 | ||||
-rw-r--r-- | bot/seasons/christmas/adventofcode.py | 5 | ||||
-rw-r--r-- | bot/seasons/halloween/__init__.py | 1 | ||||
-rw-r--r-- | bot/seasons/season.py | 95 |
5 files changed, 97 insertions, 17 deletions
diff --git a/bot/constants.py b/bot/constants.py index 52da161e..02bc5a38 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -4,14 +4,14 @@ from typing import NamedTuple from bot.bot import SeasonalBot -__all__ = ('Client', 'Roles', 'bot') +__all__ = ("Channels", "Client", "Roles", "bot") log = logging.getLogger(__name__) class Channels(NamedTuple): admins = 365960823622991872 - announcements = 354619224620138496 + announcements = int(environ.get('CHANNEL_ANNOUNCEMENTS', 354619224620138496)) big_brother_logs = 468507907357409333 bot = 267659945086812160 checkpoint_test = 422077681434099723 diff --git a/bot/seasons/christmas/__init__.py b/bot/seasons/christmas/__init__.py index 796dd895..d0702100 100644 --- a/bot/seasons/christmas/__init__.py +++ b/bot/seasons/christmas/__init__.py @@ -2,7 +2,16 @@ from bot.seasons import SeasonBase class Christmas(SeasonBase): + """ + We are getting into the festive spirit with a new server icon, new + bot name and avatar, and some new commands for you to check out! + + No matter who you are, where you are or what beliefs you may follow, + we hope every one of you enjoy this festive season! + """ name = "christmas" + greeting = "Happy Holidays!" + colour = 0x1f8b4c start_date = "01/12" end_date = "31/12" bot_name = "Merrybot" diff --git a/bot/seasons/christmas/adventofcode.py b/bot/seasons/christmas/adventofcode.py index 4c766703..5a34d608 100644 --- a/bot/seasons/christmas/adventofcode.py +++ b/bot/seasons/christmas/adventofcode.py @@ -100,6 +100,9 @@ async def day_countdown(bot: commands.Bot): class AdventOfCode: + """ + Advent of Code festivities! Ho Ho Ho! + """ def __init__(self, bot: commands.Bot): self.bot = bot @@ -125,7 +128,7 @@ class AdventOfCode: @commands.group(name="adventofcode", aliases=("aoc",), invoke_without_command=True) async def adventofcode_group(self, ctx: commands.Context): """ - Advent of Code festivities! Ho Ho Ho! + All of the Advent of Code commands """ await ctx.invoke(self.bot.get_command("help"), "adventofcode") diff --git a/bot/seasons/halloween/__init__.py b/bot/seasons/halloween/__init__.py index 1f776c03..53920689 100644 --- a/bot/seasons/halloween/__init__.py +++ b/bot/seasons/halloween/__init__.py @@ -3,6 +3,7 @@ from bot.seasons import SeasonBase class Halloween(SeasonBase): name = "halloween" + greeting = "Happy Halloween!" start_date = "01/10" end_date = "31/10" bot_name = "Spookybot" diff --git a/bot/seasons/season.py b/bot/seasons/season.py index 95367fd2..c971284f 100644 --- a/bot/seasons/season.py +++ b/bot/seasons/season.py @@ -1,14 +1,16 @@ import asyncio import datetime import importlib +import inspect import logging import pkgutil +import typing from pathlib import Path import discord from discord.ext import commands -from bot.constants import Client, Roles, bot +from bot.constants import Channels, Client, Roles, bot from bot.decorators import with_role log = logging.getLogger(__name__) @@ -69,10 +71,11 @@ def get_season(season_name: str = None, date: datetime.datetime = None): class SeasonBase: - name = None + name: typing.Optional[str] = "evergreen" + start_date: typing.Optional[str] = None + end_date: typing.Optional[str] = None + colour: typing.Optional[int] = None date_format = "%d/%m/%Y" - start_date = None - end_date = None bot_name: str = "SeasonalBot" icon: str = "/logos/logo_full/logo_full.png" @@ -96,6 +99,11 @@ class SeasonBase: def is_between_dates(cls, date): return cls.start() <= date <= cls.end() + @property + def greeting(self): + season_name = " ".join(self.name.split("_")).title() + return f"New Season, {season_name}!" + async def get_icon(self): base_url = "https://raw.githubusercontent.com/python-discord/branding/master" async with bot.http_session.get(base_url + self.icon) as resp: @@ -180,17 +188,58 @@ class SeasonBase: log.debug(f"Changing server icon failed: {self.icon}") return False + async def announce_season(self): + # don't actually announce if reverting to normal season + if self.name == "evergreen": + log.debug(f"Season Changed: {self.icon}") + return + + guild = bot.get_guild(Client.guild) + + channel = guild.get_channel(Channels.announcements) + mention = f"<@&{Roles.announcements}>" + + # collect seasonal cogs + cogs = [] + for cog in bot.cogs.values(): + if "evergreen" in cog.__module__: + continue + cog_name = type(cog).__name__ + if cog_name != "SeasonManager": + cogs.append(cog_name) + + # no cogs, so no seasonal commands + if not cogs: + return + + # build cog info output + doc = inspect.getdoc(self) + announce_text = doc + "\n\n" if doc else "" + + def cog_name(cog): + return type(cog).__name__ + + cog_info = [] + for cog in sorted(cogs, key=cog_name): + doc = inspect.getdoc(bot.get_cog(cog)) + if doc: + cog_info.append(f"**{cog}**\n*{doc}*") + else: + cog_info.append(f"**{cog}**") + + embed = discord.Embed(description=announce_text, colour=self.colour or guild.me.colour) + embed.set_author(name=self.greeting) + cogs_text = "\n".join(cog_info) + embed.add_field(name="New Command Categories", value=cogs_text) + embed.set_footer(text="To see the new commands, use .help Category") + + await channel.send(mention, embed=embed) + async def load(self): """ - Loads in the bot name, the bot avatar, and the extensions that are relevant to that season. + Loads extensions, bot name and avatar, server icon and announces new season. """ - await self.apply_username(debug=Client.debug) - await self.apply_avatar() - - if not Client.debug: - await self.apply_server_icon() - # Prepare all the seasonal cogs, and then the evergreen ones. extensions = [] for ext_folder in {self.name, "evergreen"}: @@ -203,6 +252,15 @@ class SeasonBase: # Finally we can load all the cogs we've prepared. bot.load_extensions(extensions) + # Apply seasonal elements after extensions successfully load + await self.apply_username(debug=Client.debug) + + # Avoid heavy API ratelimited elements when debugging + if not Client.debug: + await self.apply_avatar() + await self.apply_server_icon() + await self.announce_season() + class SeasonManager: """ @@ -240,7 +298,7 @@ class SeasonManager: await self.season.load() @with_role(Roles.moderator, Roles.admin, Roles.owner) - @commands.command(name='season') + @commands.command(name="season") async def change_season(self, ctx, new_season: str): """ Changes the currently active season on the bot. @@ -263,6 +321,8 @@ class SeasonManager: current_season = self.season.name + forced_space = "\u200b " + entries = [] seasons = [get_season_class(s) for s in get_seasons()] for season in sorted(seasons, key=season_key): @@ -285,7 +345,6 @@ class SeasonManager: is_active = current_season == season.name sdec = "__" if is_active else "" - forced_space = "\u200b " entries.append( f"**{sdec}{season.__name__}:{sdec}**\n" f"{forced_space*3}{pdec}{period}{pdec}" @@ -353,7 +412,7 @@ class SeasonManager: colour=colour ) embed.set_author(name=title) - embed.set_thumbnail(url=bot.get_guild(Client.guild).icon_url_as(format='png')) + embed.set_thumbnail(url=bot.get_guild(Client.guild).icon_url_as(format="png")) await ctx.send(embed=embed) @refresh.command(name="username", aliases=("name",)) @@ -397,5 +456,13 @@ class SeasonManager: embed.set_author(name=title) await ctx.send(embed=embed) + @with_role(Roles.moderator, Roles.admin, Roles.owner) + @commands.command() + async def announce(self, ctx): + """ + Announces the currently loaded season. + """ + await self.season.announce_season() + def __unload(self): self.season_task.cancel() |