aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2018-07-02 19:42:20 +0000
committerGravatar Gareth Coles <[email protected]>2018-07-02 19:42:20 +0000
commitbe19e55ae459e1013b9d7ea5cf38bfa2aa13f552 (patch)
treef8dcc4b276f0f54ef321b5013d48e607daf89ea9
parent[Snekbox] Fix failure to send string errors (diff)
parentAdd a simple OffTopicNames cog. (diff)
Merge branch 'add-off-topic-name-rotation' into 'master'
Add a simple OffTopicNames cog. See merge request python-discord/projects/bot!6
-rw-r--r--bot/__main__.py3
-rw-r--r--bot/cogs/off_topic_names.py114
-rw-r--r--config-default.yml4
3 files changed, 120 insertions, 1 deletions
diff --git a/bot/__main__.py b/bot/__main__.py
index 42ab0f224..8eb40757d 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -66,11 +66,12 @@ bot.load_extension("bot.cogs.doc")
bot.load_extension("bot.cogs.eval")
bot.load_extension("bot.cogs.fun")
bot.load_extension("bot.cogs.hiphopify")
+bot.load_extension("bot.cogs.off_topic_names")
bot.load_extension("bot.cogs.snakes")
bot.load_extension("bot.cogs.snekbox")
bot.load_extension("bot.cogs.tags")
-bot.load_extension("bot.cogs.verification")
bot.load_extension("bot.cogs.utils")
+bot.load_extension("bot.cogs.verification")
if has_rmq:
bot.load_extension("bot.cogs.rmq")
diff --git a/bot/cogs/off_topic_names.py b/bot/cogs/off_topic_names.py
new file mode 100644
index 000000000..3b07a227d
--- /dev/null
+++ b/bot/cogs/off_topic_names.py
@@ -0,0 +1,114 @@
+import asyncio
+import logging
+from datetime import datetime, timedelta
+
+from discord.ext.commands import BadArgument, Bot, Context, Converter, group
+
+from bot.constants import Channels, Keys, Roles, URLs
+from bot.decorators import with_role
+
+
+CHANNELS = (Channels.off_topic_0, Channels.off_topic_1, Channels.off_topic_2)
+log = logging.getLogger(__name__)
+
+
+class OffTopicName(Converter):
+ """A converter that ensures an added off-topic name is valid."""
+
+ @staticmethod
+ async def convert(ctx: Context, argument: str):
+ if not (2 <= len(argument) <= 96):
+ raise BadArgument("Channel name must be between 2 and 96 chars long")
+
+ elif not all(c.isalpha() or c == '-' for c in argument):
+ raise BadArgument(
+ "Channel name must only consist of"
+ " alphabetic characters or minus signs"
+ )
+
+ elif not argument.islower():
+ raise BadArgument("Channel name must be lowercase")
+
+ return argument
+
+
+async def update_names(bot: Bot, headers: dict):
+ """
+ The background updater task that performs a channel name update daily.
+
+ Args:
+ bot (Bot):
+ The running bot instance, used for fetching data from the
+ website via the bot's `http_session`.
+ """
+
+ while True:
+ today_at_midnight = datetime.utcnow().replace(microsecond=0, second=0, minute=0, hour=0)
+ next_midnight = today_at_midnight + timedelta(days=1)
+ seconds_to_sleep = (next_midnight - datetime.utcnow()).seconds
+ await asyncio.sleep(seconds_to_sleep)
+
+ response = await bot.http_session.get(
+ f'{URLs.site_off_topic_names_api}?random_items=3',
+ headers=headers
+ )
+ channel_0_name, channel_1_name, channel_2_name = await response.json()
+ channel_0, channel_1, channel_2 = (bot.get_channel(channel_id) for channel_id in CHANNELS)
+
+ await channel_0.edit(name=f'ot0-{channel_0_name}')
+ await channel_1.edit(name=f'ot1-{channel_1_name}')
+ await channel_2.edit(name=f'ot2-{channel_2_name}')
+ log.debug(
+ "Updated off-topic channel names to"
+ f" {channel_0_name}, {channel_1_name} and {channel_2_name}"
+ )
+
+
+class OffTopicNames:
+ """Commands related to managing the off-topic category channel names."""
+
+ def __init__(self, bot: Bot):
+ self.bot = bot
+ self.headers = {"X-API-KEY": Keys.site_api}
+ self.updater_task = None
+
+ def __cleanup(self):
+ if self.updater_task is not None:
+ self.updater_task.cancel()
+
+ async def on_ready(self):
+ if self.updater_task is None:
+ coro = update_names(self.bot, self.headers)
+ self.updater_task = await self.bot.loop.create_task(coro)
+
+ @group(name='otname')
+ async def otname_group(self, ctx: Context):
+ """Contains subcommands to manage the off-topic category names."""
+
+ @with_role(Roles.owner, Roles.owner, Roles.moderator)
+ @otname_group.command(name='add')
+ async def otname_add(self, ctx, name: OffTopicName):
+ """Adds a new off-topic name to the rotation."""
+
+ result = await self.bot.http_session.post(
+ URLs.site_off_topic_names_api,
+ headers=self.headers,
+ params={'name': name}
+ )
+
+ response = await result.json()
+
+ if result.status == 200:
+ log.info(
+ f"{ctx.author.name}#{ctx.author.discriminator}"
+ f" added the off-topic channel name '{name}"
+ )
+ await ctx.send(":ok_hand:")
+ else:
+ error_reason = response.get('message', "No reason provided.")
+ await ctx.send(f":warning: got non-200 from the API: {error_reason}")
+
+
+def setup(bot: Bot):
+ bot.add_cog(OffTopicNames(bot))
+ log.info("Cog loaded: OffTopicNames")
diff --git a/config-default.yml b/config-default.yml
index c22b622c0..147c2f7a6 100644
--- a/config-default.yml
+++ b/config-default.yml
@@ -29,6 +29,9 @@ guild:
modlog: 282638479504965634
python: 267624335836053506
verification: 352442727016693763
+ off_topic_0: 291284109232308226
+ off_topic_1: 463035241142026251
+ off_topic_2: 463035268514185226
roles:
admin: 267628507062992896
@@ -73,6 +76,7 @@ urls:
site_hiphopify_api: 'https://api.pythondiscord.com/bot/hiphopify'
site_idioms_api: 'https://api.pythondiscord.com/bot/snake_idioms'
site_names_api: 'https://api.pythondiscord.com/bot/snake_names'
+ site_off_topic_names_api: 'https://api.pythondiscord.com/bot/off-topic-names'
site_quiz_api: 'https://api.pythondiscord.com/bot/snake_quiz'
site_special_api: 'https://api.pythondiscord.com/bot/special_snakes'
site_tags_api: 'https://api.pythondiscord.com/bot/tags'