diff options
| -rw-r--r-- | bot/exts/evergreen/branding.py | 36 | 
1 files changed, 31 insertions, 5 deletions
| diff --git a/bot/exts/evergreen/branding.py b/bot/exts/evergreen/branding.py index c674699e..8fd8d6eb 100644 --- a/bot/exts/evergreen/branding.py +++ b/bot/exts/evergreen/branding.py @@ -1,9 +1,11 @@  import asyncio  import itertools +import json  import logging  import random  import typing as t  from datetime import datetime, time, timedelta +from pathlib import Path  import arrow  import discord @@ -15,6 +17,7 @@ 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.decorators import with_role  from bot.utils.exceptions import BrandingError +from bot.utils.persist import make_persistent  log = logging.getLogger(__name__)  log.setLevel(logging.DEBUG) @@ -77,10 +80,11 @@ class BrandingManager(commands.Cog):      via Github's API, resolving download urls for them, and delegating      to the `bot` instance to upload them to the guild. -    The cog is designed to be entirely autonomous. The `daemon` background task awakens once -    a day (see `time_until_midnight`) to detect new seasons, or to cycle icons within a single -    season. If the `Branding.autostart` constant is True, the `daemon` will launch on start-up, -    otherwise it can be controlled via the `daemon` cmd group. +    BrandingManager is designed to be entirely autonomous. Its `daemon` background task awakens +    once a day (see `time_until_midnight`) to detect new seasons, or to cycle icons within a single +    season. The daemon can be turned on and off via the `daemon` cmd group. The value set via +    its `start` and `stop` commands is persisted across sessions. If turned on, the daemon will +    automatically start on the next bot start-up. Otherwise, it will wait to be started manually.      All supported operations, e.g. setting seasons, applying the branding, or cycling icons, can      also be invoked manually, via the following API: @@ -129,6 +133,8 @@ class BrandingManager(commands.Cog):      should_cycle: t.Iterator +    config_file: Path +      daemon: t.Optional[asyncio.Task]      def __init__(self, bot: SeasonalBot) -> None: @@ -150,7 +156,10 @@ class BrandingManager(commands.Cog):          self.available_icons = []          self.remaining_icons = [] -        if Branding.autostart: +        self.config_file = make_persistent(Path("bot", "resources", "evergreen", "branding.json")) +        should_run = self._read_config()["daemon_active"] + +        if should_run:              self.daemon = self.bot.loop.create_task(self._daemon_func())          else:              self.daemon = None @@ -160,6 +169,19 @@ class BrandingManager(commands.Cog):          """True if the daemon is currently active, False otherwise."""          return self.daemon is not None and not self.daemon.done() +    def _read_config(self) -> t.Dict[str, bool]: +        """Read and return persistent config file.""" +        with self.config_file.open("r") as persistent_file: +            return json.load(persistent_file) + +    def _write_config(self, key: str, value: bool) -> None: +        """Write a `key`, `value` pair to persistent config file.""" +        current_config = self._read_config() +        current_config[key] = value + +        with self.config_file.open("w") as persistent_file: +            json.dump(current_config, persistent_file) +      async def _daemon_func(self) -> None:          """          Manage all automated behaviour of the BrandingManager cog. @@ -507,6 +529,8 @@ class BrandingManager(commands.Cog):              raise BrandingError("Daemon already running!")          self.daemon = self.bot.loop.create_task(self._daemon_func()) +        self._write_config("daemon_active", True) +          response = discord.Embed(description=f"Daemon started {Emojis.ok_hand}", colour=Colours.soft_green)          await ctx.send(embed=response) @@ -517,6 +541,8 @@ class BrandingManager(commands.Cog):              raise BrandingError("Daemon not running!")          self.daemon.cancel() +        self._write_config("daemon_active", False) +          response = discord.Embed(description=f"Daemon stopped {Emojis.ok_hand}", colour=Colours.soft_green)          await ctx.send(embed=response) | 
