From 2b2dc95f2aa2ac6606b51be183861f2663be3b3e Mon Sep 17 00:00:00 2001 From: mbaruh Date: Fri, 22 Apr 2022 03:05:39 +0300 Subject: Make modpings rescheduling robust to unfilled cache Additionally, this adds a check which will remove entries in the redis cache of former moderators. --- bot/exts/moderation/modpings.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/bot/exts/moderation/modpings.py b/bot/exts/moderation/modpings.py index e82099c88..bdefea91b 100644 --- a/bot/exts/moderation/modpings.py +++ b/bot/exts/moderation/modpings.py @@ -13,6 +13,7 @@ from bot.constants import Colours, Emojis, Guild, Icons, MODERATION_ROLES, Roles from bot.converters import Expiry from bot.log import get_logger from bot.utils import time +from bot.utils.members import get_or_fetch_member log = get_logger(__name__) @@ -57,18 +58,29 @@ class ModPings(Cog): log.trace("Applying the moderators role to the mod team where necessary.") for mod in mod_team.members: - if mod in pings_on: # Make sure that on-duty mods aren't in the cache. + if mod in pings_on: # Make sure that on-duty mods aren't in the redis cache. if mod.id in pings_off: await self.pings_off_mods.delete(mod.id) continue - # Keep the role off only for those in the cache. + # Keep the role off only for those in the redis cache. if mod.id not in pings_off: await self.reapply_role(mod) else: expiry = isoparse(pings_off[mod.id]) self._role_scheduler.schedule_at(expiry, mod.id, self.reapply_role(mod)) + # At this stage every entry in `pings_off` is expected to have a scheduled task, but that might not be the case + # if the discord.py cache is missing members, or if the ID belongs to a former moderator. + for mod_id, expiry_iso in pings_off.items(): + if mod_id not in self._role_scheduler: + mod = await get_or_fetch_member(self.guild, mod_id) + # Make sure the member is still a moderator and doesn't have the pingable role. + if mod is None or mod.get_role(Roles.mod_team) is None or mod.get_role(Roles.moderators) is not None: + await self.pings_off_mods.delete(mod_id) + else: + self._role_scheduler.schedule_at(isoparse(expiry_iso), mod_id, self.reapply_role(mod)) + async def reschedule_modpings_schedule(self) -> None: """Reschedule moderators schedule ping.""" await self.bot.wait_until_guild_available() -- cgit v1.2.3