From 273404a61542935a852232c2296aff31d50c9f55 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Sun, 17 Mar 2024 16:08:14 +0000 Subject: [PATCH 01/22] Allow using proxy in /screenshot --- src/cogs/screenshot.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cogs/screenshot.py b/src/cogs/screenshot.py index b04801a..4b3ca7c 100644 --- a/src/cogs/screenshot.py +++ b/src/cogs/screenshot.py @@ -5,6 +5,7 @@ import logging import os import tempfile import time +import copy from urllib.parse import urlparse import discord @@ -76,7 +77,8 @@ class ScreenshotCog(commands.Cog): load_timeout: int = 10, render_timeout: int = None, eager: bool = None, - resolution: str = "1920x1080" + resolution: str = "1920x1080", + use_proxy: bool = False ): """Screenshots a webpage.""" await ctx.defer() @@ -104,11 +106,14 @@ class ScreenshotCog(commands.Cog): start_init = time.time() try: + options = copy.copy(self.chrome_options) + if use_proxy: + options.add_argument("--proxy-server=http://127.0.0.1:8888") service = await asyncio.to_thread(ChromeService) driver: webdriver.Chrome = await asyncio.to_thread( webdriver.Chrome, service=service, - options=self.chrome_options + options=options ) driver.set_page_load_timeout(load_timeout) if resolution: From 8ef909c33da2f0036ac16b5ca1ef53feece4fba1 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Sun, 17 Mar 2024 16:15:59 +0000 Subject: [PATCH 02/22] Properly allow configuring screenshot proxy --- src/cogs/screenshot.py | 6 ++++-- src/conf.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cogs/screenshot.py b/src/cogs/screenshot.py index 4b3ca7c..0f28b24 100644 --- a/src/cogs/screenshot.py +++ b/src/cogs/screenshot.py @@ -16,6 +16,8 @@ from selenium import webdriver from selenium.webdriver.chrome.options import Options as ChromeOptions from selenium.webdriver.chrome.service import Service as ChromeService +from conf import CONFIG + class ScreenshotCog(commands.Cog): def __init__(self, bot: commands.Bot): @@ -107,8 +109,8 @@ class ScreenshotCog(commands.Cog): start_init = time.time() try: options = copy.copy(self.chrome_options) - if use_proxy: - options.add_argument("--proxy-server=http://127.0.0.1:8888") + if use_proxy and (server := CONFIG["screenshot"].get("proxy")): + options.add_argument("--proxy-server=" + server) service = await asyncio.to_thread(ChromeService) driver: webdriver.Chrome = await asyncio.to_thread( webdriver.Chrome, diff --git a/src/conf.py b/src/conf.py index 88bd862..41ee4c1 100644 --- a/src/conf.py +++ b/src/conf.py @@ -28,6 +28,7 @@ try: CONFIG.setdefault("jimmy", {}) CONFIG.setdefault("ollama", {}) CONFIG.setdefault("rss", {"meta": {"channel": None}}) + CONFIG.setdefault("screenshot", {}) CONFIG.setdefault( "server", { From bc16f3258cbdb0ac722abb70dc7f876bb451ae8a Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Mon, 18 Mar 2024 23:57:13 +0000 Subject: [PATCH 03/22] Add quota cog --- requirements.txt | 1 + src/cogs/quote_quota.py | 118 ++++++++++++++++++++++++++++++++++++++++ src/cogs/screenshot.py | 1 + src/main.py | 2 +- 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/cogs/quote_quota.py diff --git a/requirements.txt b/requirements.txt index da18c0e..0163e13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,3 +18,4 @@ humanize~=4.9 redis~=5.0 beautifulsoup4~=4.12 lxml~=5.1 +matplotlib~=3.8 diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py new file mode 100644 index 0000000..4a3c228 --- /dev/null +++ b/src/cogs/quote_quota.py @@ -0,0 +1,118 @@ +import asyncio +import re + +import discord +import io +import matplotlib.pyplot as plt +from datetime import timedelta +from discord.ext import commands +from typing import Iterable, Annotated + +from conf import CONFIG + + +class QuoteQuota(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.quotes_channel_id = CONFIG["quote_a"].get("channel_id") + + @property + def quotes_channel(self) -> discord.TextChannel | None: + if self.quotes_channel_id: + c = self.bot.get_channel(self.quotes_channel_id) + if c: + return c + + @staticmethod + def generate_pie_chart( + usernames: Iterable[str], + counts: Iterable[int], + ) -> discord.File: + """ + Converts the given username and count tuples into a nice pretty pie chart. + + :param usernames: The usernames + :param counts: The number of times the username appears in the chat + :returns: The pie chart image + """ + fig, ax = plt.subplots() + ax.pie( + counts, + labels=usernames, + autopct='%1.1f%%', + ) + ax.legend(loc="upper right") + fig.tight_layout() + fig.title("Quote Quota") + fio = io.BytesIO() + fig.savefig(fio, format='jpg') + fio.seek(0) + return discord.File(fio, filename="pie.jpeg") + + @commands.slash_command() + async def quota( + self, + ctx: discord.ApplicationContext, + days: Annotated[ + int, + discord.Option( + int, + name="lookback", + description="How many days to look back on. Defaults to 7.", + default=7, + min_value=1, + max_value=365 + ) + ] + ): + """Checks the quote quota for the quotes channel.""" + now = discord.utils.utcnow() + oldest = now - timedelta(days=7) + await ctx.defer() + channel = self.quotes_channel + if not channel: + return await ctx.respond(":x: Cannot find quotes channel.") + + await ctx.respond("Gathering messages, this may take a moment.") + + authors = {} + filtered_messages = 0 + total = 0 + async for message in channel.history( + limit=None, + after=oldest, + oldest_first=False + ): + total += 1 + if not message.content: + filtered_messages += 1 + continue + if message.attachments: + regex = r".*\s*-\s*(\w+)" + else: + regex = r".+\s*-\s*(\w+)" + + if not (m := re.match(regex, message.content)): + filtered_messages += 1 + continue + name = m.group(1) + name = name.strip().title() + authors.setdefault(name, 0) + authors[name] += 1 + + file = await asyncio.to_thread( + self.generate_pie_chart, + list(authors.keys()), + list(authors.values()) + ) + return await ctx.edit( + content="{:,} messages (out of {:,}) were filtered (didn't follow format?)".format( + filtered_messages, + total + ), + file=file + ) + + +def setup(bot): + bot.add_cog(QuoteQuota(bot)) diff --git a/src/cogs/screenshot.py b/src/cogs/screenshot.py index 0f28b24..9b8d518 100644 --- a/src/cogs/screenshot.py +++ b/src/cogs/screenshot.py @@ -168,6 +168,7 @@ class ScreenshotCog(commands.Cog): end_save = time.time() if len(await asyncio.to_thread(file.getvalue)) > 24 * 1024 * 1024: + await ctx.edit(content="Compressing screenshot...") start_compress = time.time() file = await asyncio.to_thread(self.compress_png, file) fn = "screenshot.webp" diff --git a/src/main.py b/src/main.py index 82947c0..ef61146 100644 --- a/src/main.py +++ b/src/main.py @@ -133,7 +133,7 @@ bot = Client( debug_guilds=CONFIG["jimmy"].get("debug_guilds") ) -for ext in ("ytdl", "net", "screenshot", "ollama", "ffmeta"): +for ext in ("ytdl", "net", "screenshot", "ollama", "ffmeta", "quote_quota"): try: bot.load_extension(f"cogs.{ext}") except discord.ExtensionError as e: From b76160d57a2eebb4386d679d100bd14c7ab0b494 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Mon, 18 Mar 2024 23:59:46 +0000 Subject: [PATCH 04/22] Fix quote_a config not being defaulted --- src/cogs/quote_quota.py | 4 ++-- src/conf.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 4a3c228..d61ad50 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -67,9 +67,9 @@ class QuoteQuota(commands.Cog): ): """Checks the quote quota for the quotes channel.""" now = discord.utils.utcnow() - oldest = now - timedelta(days=7) + oldest = now - timedelta(days=days) await ctx.defer() - channel = self.quotes_channel + channel = self.quotes_channel or discord.utils.get(ctx.guild.text_channels, name="quotes") if not channel: return await ctx.respond(":x: Cannot find quotes channel.") diff --git a/src/conf.py b/src/conf.py index 41ee4c1..e260f8d 100644 --- a/src/conf.py +++ b/src/conf.py @@ -29,6 +29,7 @@ try: CONFIG.setdefault("ollama", {}) CONFIG.setdefault("rss", {"meta": {"channel": None}}) CONFIG.setdefault("screenshot", {}) + CONFIG.setdefault("quote_a", {"channel": None}) CONFIG.setdefault( "server", { From 580a6dc30583cd10c015f660e2bab22ff47fca91 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:01:20 +0000 Subject: [PATCH 05/22] I hate MPL --- src/cogs/quote_quota.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index d61ad50..0d3c5e3 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -43,7 +43,6 @@ class QuoteQuota(commands.Cog): ) ax.legend(loc="upper right") fig.tight_layout() - fig.title("Quote Quota") fio = io.BytesIO() fig.savefig(fio, format='jpg') fio.seek(0) From 777669c09b206790beb6f518b5bc1e8566be179a Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:02:41 +0000 Subject: [PATCH 06/22] Forget the tight layout --- src/cogs/quote_quota.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 0d3c5e3..e47a148 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -42,7 +42,6 @@ class QuoteQuota(commands.Cog): autopct='%1.1f%%', ) ax.legend(loc="upper right") - fig.tight_layout() fio = io.BytesIO() fig.savefig(fio, format='jpg') fio.seek(0) From bb71a681c84ca85d6f234fba7a8a16cf668bcf60 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:06:12 +0000 Subject: [PATCH 07/22] Filter out "me" and channel/mentions --- src/cogs/quote_quota.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index e47a148..42240ef 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -86,15 +86,18 @@ class QuoteQuota(commands.Cog): filtered_messages += 1 continue if message.attachments: - regex = r".*\s*-\s*(\w+)" + regex = r".*\s+-\s*@?([\w\s]+)" else: - regex = r".+\s*-\s*(\w+)" + regex = r".+\s*-\s*@?([\w\s]+)" - if not (m := re.match(regex, message.content)): + if not (m := re.match(regex, str(message.clean_content))): filtered_messages += 1 continue name = m.group(1) name = name.strip().title() + if name == "Me": + filtered_messages += 1 + continue authors.setdefault(name, 0) authors[name] += 1 From 834ab86ccacd1a8cd080a5306a996523125b689e Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:13:34 +0000 Subject: [PATCH 08/22] formatting! --- src/cogs/quote_quota.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 42240ef..95541d4 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -39,11 +39,10 @@ class QuoteQuota(commands.Cog): ax.pie( counts, labels=usernames, - autopct='%1.1f%%', + autopct='%1.1f%% (%d)', ) - ax.legend(loc="upper right") fio = io.BytesIO() - fig.savefig(fio, format='jpg') + fig.savefig(fio, format='jpg', bbox_inches='tight') fio.seek(0) return discord.File(fio, filename="pie.jpeg") From 0e5b4914939724e96e194376bfe46977e16c2492 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:14:50 +0000 Subject: [PATCH 09/22] fix formatting! --- src/cogs/quote_quota.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 95541d4..c1e7d44 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -35,11 +35,15 @@ class QuoteQuota(commands.Cog): :param counts: The number of times the username appears in the chat :returns: The pie chart image """ + + def pct(v: int): + return f"{v / sum(counts) * 100:.1f}% ({v})" + fig, ax = plt.subplots() ax.pie( counts, labels=usernames, - autopct='%1.1f%% (%d)', + autopct=pct, ) fio = io.BytesIO() fig.savefig(fio, format='jpg', bbox_inches='tight') From b5d05722d11ff0877c98a436e9a831e3a1a9405c Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:16:19 +0000 Subject: [PATCH 10/22] fix formatting? --- src/cogs/quote_quota.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index c1e7d44..5e01883 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -37,7 +37,7 @@ class QuoteQuota(commands.Cog): """ def pct(v: int): - return f"{v / sum(counts) * 100:.1f}% ({v})" + return f"{v:.1f}% ({(v / 100) * sum(counts):0f})" fig, ax = plt.subplots() ax.pie( From 451d9ba77e369a100ee5795a842ef3b78b7d1e5b Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:20:22 +0000 Subject: [PATCH 11/22] Improve filtering and add "other" --- src/cogs/quote_quota.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 5e01883..d5e14f6 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -12,6 +12,7 @@ from conf import CONFIG class QuoteQuota(commands.Cog): + def __init__(self, bot): self.bot = bot self.quotes_channel_id = CONFIG["quote_a"].get("channel_id") @@ -25,8 +26,8 @@ class QuoteQuota(commands.Cog): @staticmethod def generate_pie_chart( - usernames: Iterable[str], - counts: Iterable[int], + usernames: list[str], + counts: list[int], ) -> discord.File: """ Converts the given username and count tuples into a nice pretty pie chart. @@ -39,6 +40,19 @@ class QuoteQuota(commands.Cog): def pct(v: int): return f"{v:.1f}% ({(v / 100) * sum(counts):0f})" + other = [] + # Any authors with less than 5% of the total count will be grouped into "other" + for i, author in enumerate(usernames.copy()): + if (c := counts[i]) / sum(counts) < 0.05: + other.append(c) + counts[i] = -1 + usernames.remove(author) + if other: + usernames.append("Other") + counts.append(sum(other)) + # And now filter out any -1% counts + counts = [c for c in counts if c != -1] + fig, ax = plt.subplots() ax.pie( counts, @@ -46,7 +60,7 @@ class QuoteQuota(commands.Cog): autopct=pct, ) fio = io.BytesIO() - fig.savefig(fio, format='jpg', bbox_inches='tight') + fig.savefig(fio, format='jpg') fio.seek(0) return discord.File(fio, filename="pie.jpeg") From faf8996a7b31725ff3c51cbde7b06bf7b737388f Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:25:45 +0000 Subject: [PATCH 12/22] Increase pie size, add name mapping --- src/cogs/quote_quota.py | 55 +++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index d5e14f6..b74eb35 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -16,6 +16,7 @@ class QuoteQuota(commands.Cog): def __init__(self, bot): self.bot = bot self.quotes_channel_id = CONFIG["quote_a"].get("channel_id") + self.names = CONFIG["quote_a"].get("names", {}) @property def quotes_channel(self) -> discord.TextChannel | None: @@ -28,36 +29,41 @@ class QuoteQuota(commands.Cog): def generate_pie_chart( usernames: list[str], counts: list[int], + no_other: bool = False ) -> discord.File: """ Converts the given username and count tuples into a nice pretty pie chart. :param usernames: The usernames :param counts: The number of times the username appears in the chat + :param no_other: Disables the "other" grouping :returns: The pie chart image """ def pct(v: int): - return f"{v:.1f}% ({(v / 100) * sum(counts):0f})" + return f"{v:.1f}% ({round((v / 100) * sum(counts))})" - other = [] - # Any authors with less than 5% of the total count will be grouped into "other" - for i, author in enumerate(usernames.copy()): - if (c := counts[i]) / sum(counts) < 0.05: - other.append(c) - counts[i] = -1 - usernames.remove(author) - if other: - usernames.append("Other") - counts.append(sum(other)) - # And now filter out any -1% counts - counts = [c for c in counts if c != -1] + if no_other is False: + other = [] + # Any authors with less than 5% of the total count will be grouped into "other" + for i, author in enumerate(usernames.copy()): + if (c := counts[i]) / sum(counts) < 0.05: + other.append(c) + counts[i] = -1 + usernames.remove(author) + if other: + usernames.append("Other") + counts.append(sum(other)) + # And now filter out any -1% counts + counts = [c for c in counts if c != -1] fig, ax = plt.subplots() ax.pie( counts, labels=usernames, autopct=pct, + startangle=90, + radius=2 ) fio = io.BytesIO() fig.savefig(fio, format='jpg') @@ -78,6 +84,15 @@ class QuoteQuota(commands.Cog): min_value=1, max_value=365 ) + ], + merge_other: Annotated[ + bool, + discord.Option( + bool, + name="merge_other", + description="Whether to merge authors with less than 5% of the total count into 'Other'.", + default=True + ) ] ): """Checks the quote quota for the quotes channel.""" @@ -113,15 +128,23 @@ class QuoteQuota(commands.Cog): name = m.group(1) name = name.strip().title() if name == "Me": - filtered_messages += 1 - continue + name = message.author.name.strip().casefold() + if name in self.names: + name = self.names[name] + else: + filtered_messages += 1 + continue + elif name in self.names: + name = self.names[name] + authors.setdefault(name, 0) authors[name] += 1 file = await asyncio.to_thread( self.generate_pie_chart, list(authors.keys()), - list(authors.values()) + list(authors.values()), + merge_other ) return await ctx.edit( content="{:,} messages (out of {:,}) were filtered (didn't follow format?)".format( From 8f6fd219407cef88a562f20e4211bf90e9109e79 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:29:21 +0000 Subject: [PATCH 13/22] idk AI told me to do this --- src/cogs/quote_quota.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index b74eb35..8977f93 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -66,6 +66,7 @@ class QuoteQuota(commands.Cog): radius=2 ) fio = io.BytesIO() + plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) fig.savefig(fio, format='jpg') fio.seek(0) return discord.File(fio, filename="pie.jpeg") From ca1d531ad6954f789f4ae4533432c71aea7e4cce Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:30:45 +0000 Subject: [PATCH 14/22] again, just fit in the window please --- src/cogs/quote_quota.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 8977f93..7c69e95 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -63,7 +63,8 @@ class QuoteQuota(commands.Cog): labels=usernames, autopct=pct, startangle=90, - radius=2 + radius=1.5, + figsize=(10, 10) ) fio = io.BytesIO() plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) From c53dd9172934d02fb6dc016bda07e041bfeadfe0 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:32:20 +0000 Subject: [PATCH 15/22] again, just fit in the window please please --- src/cogs/quote_quota.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 7c69e95..ff1c184 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -57,20 +57,19 @@ class QuoteQuota(commands.Cog): # And now filter out any -1% counts counts = [c for c in counts if c != -1] - fig, ax = plt.subplots() + fig, ax = plt.subplots(figsize=(10, 10)) ax.pie( counts, labels=usernames, autopct=pct, startangle=90, radius=1.5, - figsize=(10, 10) ) fio = io.BytesIO() plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) - fig.savefig(fio, format='jpg') + fig.savefig(fio, format='png') fio.seek(0) - return discord.File(fio, filename="pie.jpeg") + return discord.File(fio, filename="pie.png") @commands.slash_command() async def quota( From 8519a3278b0259e074850d7e826b6ee8bcc2d362 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:32:50 +0000 Subject: [PATCH 16/22] Too big --- src/cogs/quote_quota.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index ff1c184..d93ade6 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -57,13 +57,13 @@ class QuoteQuota(commands.Cog): # And now filter out any -1% counts counts = [c for c in counts if c != -1] - fig, ax = plt.subplots(figsize=(10, 10)) + fig, ax = plt.subplots(figsize=(7, 7)) ax.pie( counts, labels=usernames, autopct=pct, startangle=90, - radius=1.5, + radius=1.3, ) fio = io.BytesIO() plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) From f226a0ac4105f3023388d3f827a84cbe506b8645 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:37:06 +0000 Subject: [PATCH 17/22] Fix filtering even more --- src/cogs/quote_quota.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index d93ade6..dc28936 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -119,9 +119,9 @@ class QuoteQuota(commands.Cog): filtered_messages += 1 continue if message.attachments: - regex = r".*\s+-\s*@?([\w\s]+)" + regex = r".*\s*-\s*@?([\w\s]+)" else: - regex = r".+\s*-\s*@?([\w\s]+)" + regex = r".+\s+-\s*@?([\w\s]+)" if not (m := re.match(regex, str(message.clean_content))): filtered_messages += 1 @@ -137,6 +137,9 @@ class QuoteQuota(commands.Cog): continue elif name in self.names: name = self.names[name] + elif name.isdigit(): + filtered_messages += 1 + continue authors.setdefault(name, 0) authors[name] += 1 From 17b947f0e50f20be5f012911097d834401b4cc58 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:39:55 +0000 Subject: [PATCH 18/22] honestly what am I even doing with pie charts now --- src/cogs/quote_quota.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index dc28936..80695e8 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -63,10 +63,10 @@ class QuoteQuota(commands.Cog): labels=usernames, autopct=pct, startangle=90, - radius=1.3, + radius=1.2, ) + fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.3, hspace=0.4) fio = io.BytesIO() - plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9) fig.savefig(fio, format='png') fio.seek(0) return discord.File(fio, filename="pie.png") From 13c2acf43fb0b602527d410c8538dea8603a0979 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:42:04 +0000 Subject: [PATCH 19/22] Fix names not properly applying --- src/cogs/quote_quota.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 80695e8..eadbfa9 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -131,12 +131,12 @@ class QuoteQuota(commands.Cog): if name == "Me": name = message.author.name.strip().casefold() if name in self.names: - name = self.names[name] + name = self.names[name].title() else: filtered_messages += 1 continue - elif name in self.names: - name = self.names[name] + elif name.strip().casefold() in self.names: + name = self.names[name].title() elif name.isdigit(): filtered_messages += 1 continue From 328e5d38773703c14cc16051b1fb7f6bfb4f8113 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:43:23 +0000 Subject: [PATCH 20/22] Fix name raising error --- src/cogs/quote_quota.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index eadbfa9..a630ef6 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -127,20 +127,21 @@ class QuoteQuota(commands.Cog): filtered_messages += 1 continue name = m.group(1) - name = name.strip().title() - if name == "Me": + name = name.strip().casefold() + if name == "me": name = message.author.name.strip().casefold() if name in self.names: name = self.names[name].title() else: filtered_messages += 1 continue - elif name.strip().casefold() in self.names: + elif name in self.names: name = self.names[name].title() elif name.isdigit(): filtered_messages += 1 continue + name = name.title() authors.setdefault(name, 0) authors[name] += 1 From 916ba0ab42d5ddb8b6db503aa0433c05110fef75 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:46:10 +0000 Subject: [PATCH 21/22] Handle no messages errors --- src/cogs/quote_quota.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index a630ef6..6d93fbd 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -145,6 +145,18 @@ class QuoteQuota(commands.Cog): authors.setdefault(name, 0) authors[name] += 1 + if not authors: + if total: + return await ctx.edit( + content="No valid messages found in the last {!s} days. " + "Make sure quotes are formatted properly ending with ` - AuthorName`" + " (e.g. `\"This is my quote\" - Jimmy`)".format(days) + ) + else: + return await ctx.edit( + content="No messages found in the last {!s} days.".format(days) + ) + file = await asyncio.to_thread( self.generate_pie_chart, list(authors.keys()), From 4f001c885eb6769e0895ae9c65b58f038ad93d06 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Tue, 19 Mar 2024 00:48:24 +0000 Subject: [PATCH 22/22] Sort pie chart values --- src/cogs/quote_quota.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cogs/quote_quota.py b/src/cogs/quote_quota.py index 6d93fbd..b48cabc 100644 --- a/src/cogs/quote_quota.py +++ b/src/cogs/quote_quota.py @@ -57,6 +57,18 @@ class QuoteQuota(commands.Cog): # And now filter out any -1% counts counts = [c for c in counts if c != -1] + mapping = {} + for i, author in enumerate(usernames): + mapping[author] = counts[i] + + # Sort the authors by count + new_mapping = {} + for author, count in sorted(mapping.items(), key=lambda x: x[1], reverse=True): + new_mapping[author] = count + + usernames = list(new_mapping.keys()) + counts = list(new_mapping.values()) + fig, ax = plt.subplots(figsize=(7, 7)) ax.pie( counts,