[Core] Add Red.wait_until_red_ready() function to wait until post connection startup is done (#3273)

* enhance: add `Red.wait_until_red_ready()` for post connection startup

* enhance: fill `bot.owner_id` in our `on_ready`

* enhance: log missing destinations in `get_owner_notification_destinations`

* chore(changelog): add towncrier entries

* chore(changelog): use past form of verb "add"
This commit is contained in:
jack1142 2020-01-06 00:38:59 +01:00 committed by Michael H
parent 9ec78d1455
commit b0f840c273
6 changed files with 34 additions and 8 deletions

View File

@ -0,0 +1 @@
:attr:`redbot.core.bot.Bot.owner_id` is now set in our post connection startup.

View File

@ -0,0 +1 @@
:meth:`redbot.core.bot.Bot.send_to_owners()` and :meth:`redbot.core.bot.Bot.get_owner_notification_destinations()` now wait until Red is done with post connection startup to ensure owner ID is available.

View File

@ -0,0 +1 @@
:meth:`redbot.core.bot.Bot.send_to_owners()` and :meth:`redbot.core.bot.Bot.get_owner_notification_destinations()` now log that they weren't able to find owner notification destination.

View File

@ -0,0 +1 @@
Added :meth:`redbot.core.bot.Bot.wait_until_red_ready()` method that waits until our post connection startup is done.

View File

@ -146,6 +146,7 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d
self.add_command(commands.help.red_help)
self._permissions_hooks: List[commands.CheckPredicate] = []
self._red_ready = asyncio.Event()
@property
def cog_mgr(self) -> NoReturn:
@ -942,6 +943,7 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d
"""
Gets the users and channels to send to
"""
await self.wait_until_red_ready()
destinations = []
opt_outs = await self._config.owner_opt_out_list()
for user_id in (self.owner_id, *self._co_owners):
@ -949,12 +951,24 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d
user = self.get_user(user_id)
if user:
destinations.append(user)
else:
log.warning(
"Owner with ID %s is missing in user cache,"
" ignoring owner notification destination.",
user_id,
)
channel_ids = await self._config.extra_owner_destinations()
for channel_id in channel_ids:
channel = self.get_channel(channel_id)
if channel:
destinations.append(channel)
else:
log.warning(
"Channel with ID %s is not available,"
" ignoring owner notification destination.",
channel_id,
)
return destinations
@ -979,6 +993,10 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d
sends = [wrapped_send(d, content, **kwargs) for d in destinations]
await asyncio.gather(*sends)
async def wait_until_red_ready(self):
"""Wait until our post connection startup is done."""
await self._red_ready.wait()
class Red(RedBase, discord.AutoShardedClient):
"""

View File

@ -48,9 +48,12 @@ def init_events(bot, cli_flags):
guilds = len(bot.guilds)
users = len(set([m for m in bot.get_all_members()]))
app_info = await bot.application_info()
if bot.owner_id is None:
bot.owner_id = app_info.owner.id
try:
data = await bot.application_info()
invite_url = discord.utils.oauth_url(data.id)
invite_url = discord.utils.oauth_url(app_info.id)
except:
invite_url = "Could not fetch invite url"
@ -75,6 +78,7 @@ def init_events(bot, cli_flags):
INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
outdated_red_message = ""
with contextlib.suppress(aiohttp.ClientError, discord.HTTPException):
async with aiohttp.ClientSession() as session:
async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
@ -84,13 +88,10 @@ def init_events(bot, cli_flags):
"Outdated version! {} is available "
"but you're using {}".format(data["info"]["version"], red_version)
)
await bot.send_to_owners(
outdated_red_message = (
"Your Red instance is out of date! {} is the current "
"version, however you are using {}!".format(
data["info"]["version"], red_version
)
)
"version, however you are using {}!"
).format(data["info"]["version"], red_version)
INFO2 = []
reqs_installed = {"docs": None, "test": None}
@ -123,6 +124,9 @@ def init_events(bot, cli_flags):
print("\nInvite URL: {}\n".format(invite_url))
bot._color = discord.Colour(await bot._config.color())
bot._red_ready.set()
if outdated_red_message:
await bot.send_to_owners(outdated_red_message)
@bot.event
async def on_command_error(ctx, error, unhandled_by_cog=False):