[Announcer] Don't die with a lack of channels (#4089)

This commit is contained in:
Michael H 2020-07-20 13:51:27 -04:00 committed by GitHub
parent 5507816c42
commit ec262d4c30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 40 deletions

View File

@ -1,3 +1,4 @@
import asyncio
import logging
from typing import Tuple
@ -72,15 +73,45 @@ class Admin(commands.Cog):
def __init__(self):
self.config = Config.get_conf(self, 8237492837454039, force_registration=True)
self.config.register_global(serverlocked=False)
self.config.register_global(serverlocked=False, schema_version=0)
self.config.register_guild(
announce_ignore=False,
announce_channel=None, # Integer ID
selfroles=[], # List of integer ID's
announce_channel=None, selfroles=[], # Integer ID # List of integer ID's
)
self.__current_announcer = None
self._ready = asyncio.Event()
asyncio.create_task(self.handle_migrations())
# As this is a data migration, don't store this for cancelation.
async def cog_before_invoke(self):
await self._ready.wait()
async def handle_migrations(self):
lock = self.config.get_guilds_lock()
async with lock:
# This prevents the edge case of someone loading admin,
# unloading it, loading it again during a migration
current_schema = await self.config.schema_version()
if current_schema == 0:
await self.migrate_config_from_0_to_1()
await self.config.schema_version.set(1)
await self._ready.set()
async def migrate_config_from_0_to_1(self):
all_guilds = await self.config.all_guilds()
for guild_id, guild_data in all_guilds.items():
if guild_data.get("announce_ignore", False):
async with self.config.guild_from_id(guild_id).all(
acquire_lock=False
) as guild_config:
guild_config.pop("announce_channel", None)
guild_config.pop("announce_ignore", None)
def cog_unload(self):
try:
@ -330,21 +361,11 @@ class Admin(commands.Cog):
_("The announcement channel has been set to {channel.mention}").format(channel=channel)
)
@announceset.command(name="ignore")
async def announceset_ignore(self, ctx):
"""Toggle announcements being enabled this server."""
ignored = await self.config.guild(ctx.guild).announce_ignore()
await self.config.guild(ctx.guild).announce_ignore.set(not ignored)
if ignored:
await ctx.send(
_("The server {guild.name} will receive announcements.").format(guild=ctx.guild)
)
else:
await ctx.send(
_("The server {guild.name} will not receive announcements.").format(
guild=ctx.guild
)
)
@announceset.command(name="clearchannel")
async def announceset_clear_channel(self, ctx):
"""Unsets the channel for announcements."""
await self.config.guild(ctx.guild).announce_channel.clear()
await ctx.tick()
async def _valid_selfroles(self, guild: discord.Guild) -> Tuple[discord.Role]:
"""

View File

@ -1,4 +1,5 @@
import asyncio
from typing import Optional
import discord
from redbot.core import commands
@ -38,20 +39,9 @@ class Announcer:
"""
self.active = False
async def _get_announce_channel(self, guild: discord.Guild) -> discord.TextChannel:
async def _get_announce_channel(self, guild: discord.Guild) -> Optional[discord.TextChannel]:
channel_id = await self.config.guild(guild).announce_channel()
channel = None
if channel_id is not None:
channel = guild.get_channel(channel_id)
if channel is None:
channel = guild.system_channel
if channel is None:
channel = guild.text_channels[0]
return channel
return guild.get_channel(channel_id)
async def announcer(self):
guild_list = self.ctx.bot.guilds
@ -60,15 +50,16 @@ class Announcer:
if not self.active:
return
if await self.config.guild(g).announce_ignore():
continue
channel = await self._get_announce_channel(g)
if channel:
if channel.permissions_for(g.me).send_messages:
try:
await channel.send(self.message)
except discord.Forbidden:
failed.append(str(g.id))
else:
failed.append(str(g.id))
if failed:
msg = (