aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/evergreen/branding.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/evergreen/branding.py')
-rw-r--r--bot/exts/evergreen/branding.py36
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)