[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 import logging
from typing import Tuple from typing import Tuple
@ -72,15 +73,45 @@ class Admin(commands.Cog):
def __init__(self): def __init__(self):
self.config = Config.get_conf(self, 8237492837454039, force_registration=True) 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( self.config.register_guild(
announce_ignore=False, announce_channel=None, selfroles=[], # Integer ID # List of integer ID's
announce_channel=None, # Integer ID
selfroles=[], # List of integer ID's
) )
self.__current_announcer = None 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): def cog_unload(self):
try: try:
@ -320,7 +351,7 @@ class Admin(commands.Cog):
async def announceset_channel(self, ctx, *, channel: discord.TextChannel = None): async def announceset_channel(self, ctx, *, channel: discord.TextChannel = None):
""" """
Change the channel where the bot will send announcements. Change the channel where the bot will send announcements.
If channel is left blank it defaults to the current channel. If channel is left blank it defaults to the current channel.
""" """
if channel is None: if channel is None:
@ -330,21 +361,11 @@ class Admin(commands.Cog):
_("The announcement channel has been set to {channel.mention}").format(channel=channel) _("The announcement channel has been set to {channel.mention}").format(channel=channel)
) )
@announceset.command(name="ignore") @announceset.command(name="clearchannel")
async def announceset_ignore(self, ctx): async def announceset_clear_channel(self, ctx):
"""Toggle announcements being enabled this server.""" """Unsets the channel for announcements."""
ignored = await self.config.guild(ctx.guild).announce_ignore() await self.config.guild(ctx.guild).announce_channel.clear()
await self.config.guild(ctx.guild).announce_ignore.set(not ignored) await ctx.tick()
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
)
)
async def _valid_selfroles(self, guild: discord.Guild) -> Tuple[discord.Role]: async def _valid_selfroles(self, guild: discord.Guild) -> Tuple[discord.Role]:
""" """

View File

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