diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index d333219..bf56c9b 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -173,7 +173,7 @@ class QuoteQuota(commands.Cog): def _metacounter( self, messages: list[discord.Message], filter_func: Callable[[discord.Message], bool], *, now: datetime = None - ) -> dict[str, float | int]: + ) -> dict[str, float | int | dict[str, int]]: def _is_today(date: datetime) -> bool: return date.date() == now.date() @@ -187,7 +187,10 @@ class QuoteQuota(commands.Cog): "per_minute": 0.0, "per_hour": 0.0, "per_day": 0.0, + "hours": {} } + for i in range(24): + counts["hours"][str(i)] = 0 for message in messages: if filter_func(message): age = now - message.created_at @@ -201,6 +204,7 @@ class QuoteQuota(commands.Cog): counts["day"] += 1 if message.created_at > now - timedelta(days=7): counts["week"] += 1 + counts["hours"][str(message.created_at.hour)] += 1 counts["per_minute"] = counts["hour"] / 60 counts["per_hour"] = counts["day"] / 24 @@ -208,7 +212,7 @@ class QuoteQuota(commands.Cog): self.log.info("Total truth counts: %r", counts) return counts - async def _process_trump_truths(self, messages: list[discord.Message]) -> dict[str, int]: + async def _process_trump_truths(self, messages: list[discord.Message]): """ Processes the given messages to count the number of posts by Donald Trump. @@ -232,7 +236,7 @@ class QuoteQuota(commands.Cog): return self._metacounter(messages, is_truth) - async def _process_tate_truths(self, messages: list[discord.Message]) -> dict[str, int]: + async def _process_tate_truths(self, messages: list[discord.Message]): """ Processes the given messages to count the number of posts by Andrew Tate. @@ -251,7 +255,26 @@ class QuoteQuota(commands.Cog): return self._metacounter(messages, is_truth) - async def _process_all_messages(self, channel: discord.TextChannel) -> discord.Embed: + @staticmethod + def _generate_truth_frequency_graph(hours: dict[str, int]) -> discord.File: + """ + Generates a bar chart representing the most truthed times. + + :param hours: A dictionary of {"hour": count} + :return: A discord.File with the rendered graph + """ + hrs = [x.zfill(2) for x in hours.keys()] + plt.title("Truth times") + plt.xlabel("Hour") + plt.ylabel("Truths") + plt.bar(hrs, list(hours.values()), color="#5448EE") + + file = io.BytesIO() + plt.savefig(file, format="jpg") + file.seek(0) + return discord.File(file, "truths.jpg") + + async def _process_all_messages(self, channel: discord.TextChannel) -> tuple[discord.Embed, discord.File]: """ Processes all the messages in the given channel. @@ -285,7 +308,12 @@ class QuoteQuota(commands.Cog): f"**Last Hour:** {tate_stats['hour']:,} ({tate_stats['per_minute']:.1f}/min)" ), ) - return embed + hours = trump_stats["hours"].copy() + for stat_k, stat_v in tate_stats["hours"].items(): + hours[stat_k] += stat_v + graph = await asyncio.to_thread(self._generate_truth_frequency_graph, hours) + embed.set_image(url="attachment://truths.jpg") + return embed, graph @commands.slash_command(name="truths") async def truths_counter(self, ctx: discord.ApplicationContext): @@ -304,8 +332,8 @@ class QuoteQuota(commands.Cog): timestamp=now, ) await ctx.respond(embed=embed) - embed = await self._process_all_messages(channel) - await ctx.edit(embed=embed) + embed, file = await self._process_all_messages(channel) + await ctx.edit(embed=embed, file=file) def setup(bot):