From 6748274cc97ca6fff676470dc4caba60ee9d7699 Mon Sep 17 00:00:00 2001 From: Corban-Lee Jones Date: Sun, 18 Aug 2024 23:09:20 +0100 Subject: [PATCH] guild settings checks --- src/extensions/tasks.py | 62 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/extensions/tasks.py b/src/extensions/tasks.py index b3e0cea..5a0bf54 100644 --- a/src/extensions/tasks.py +++ b/src/extensions/tasks.py @@ -83,14 +83,50 @@ class TaskCog(commands.Cog): async with aiohttp.ClientSession() as session: self.api = API(self.bot.api_token, session) - subscriptions = await self.get_subscriptions() - await self.process_subscriptions(subscriptions) + await self.execute_task() end_time = perf_counter() log.debug(f"task completed in {end_time - start_time:.4f} seconds") - async def get_subscriptions(self) -> list[Subscription]: + async def execute_task(self): + guild_ids = await self.get_guild_ids() + subscriptions = await self.get_subscriptions(guild_ids) + await self.process_subscriptions(subscriptions) + + async def get_guild_ids(self): guild_ids = [guild.id for guild in self.bot.guilds] + guild_settings = [] + + for page, _ in enumerate(iter(int, 1)): + data = await self.get_guild_settings(guild_ids, page) + if not data: + break + + guild_settings.extend(data[0]) + + return [ + settings["guild_id"] for settings in guild_settings + if settings["active"] and settings["guild_id"] in guild_ids + ] + + async def get_guild_settings(self, guild_ids: list[int], page: int) -> list[dict]: + try: + return await self.api.get_guild_settings(guild_id__in=guild_ids, page=page+1) + except aiohttp.ClientResponseError as error: + self.handle_pagination_error(error) + return [] + + def handle_pagination_error(self, error: aiohttp.ClientResponseError): + match error.status: + case 404: + log.debug("final page reached") + case 403: + log.critical("[403] Bot likely lacks permissions: %s", error, exc_info=True) + self.subscription_task.cancel() + case _: + log.debug(error) + + async def get_subscriptions(self, guild_ids: list[int]) -> list[Subscription]: sub_data = [] for page, _ in enumerate(iter(int, 1)): @@ -105,7 +141,7 @@ class TaskCog(commands.Cog): log.debug("final page reached '%s'", page) break case 403: - log.critical(error) + log.error("Cannot continue task due to error: %s", error, exc_info=True) self.subscription_task.cancel() return [] # returning an empty list should gracefully end the task case _: @@ -143,7 +179,7 @@ class TaskCog(commands.Cog): async def process_items(self, sub: Subscription, feed: RSSFeed): log.debug("processing items") - channels = [self.bot.get_channel(channel.channel_id) for channel in await sub.get_channels(self.api)] + channels = await self.fetch_or_get_channels(await sub.get_channels(self.api)) filters = [await self.api.get_filter(filter_id) for filter_id in sub.filters] for item in feed.items: @@ -159,6 +195,18 @@ class TaskCog(commands.Cog): for channel in channels: await self.track_and_send(sub, feed, item, mutated_item, channel, blocked) + async def fetch_or_get_channels(self, channels_data: list[dict]): + channels = [] + + for data in channels_data: + try: + channel = self.bot.get_channel(data.channel_id) + channels.append(channel or await self.bot.fetch_channel(data.channel_id)) + except Forbidden: + log.error(f"Forbidden Channel '{data.channel_id}'") + + return channels + def filter_item(self, _filter: dict, item: RSSItem) -> bool: """ Returns `True` if item should be ignored due to filters. @@ -188,8 +236,8 @@ class TaskCog(commands.Cog): log.debug("sending '%s', exists '%s'", item.guid, result[1]) message = await channel.send(embed=await mutated_item.to_embed(sub, feed, self.api.session)) message_id = message.id - except Forbidden as error: - log.error(error) + except Forbidden: + log.error(f"Forbidden to send to channel {channel.id}") await self.mark_tracked_item(sub, item, channel.id, message_id, blocked)