From 981e113af8ab01c577780120eb24eaffb8cae322 Mon Sep 17 00:00:00 2001 From: Infinidoge Date: Thu, 19 Dec 2024 01:13:28 -0500 Subject: [PATCH] refactor add_keyword to better account for duplicates --- nomen/notifications.py | 44 ++++++++++++++++++++++++++++++++---------- nomen/utils.py | 7 +++++++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/nomen/notifications.py b/nomen/notifications.py index c7814b3..3513792 100644 --- a/nomen/notifications.py +++ b/nomen/notifications.py @@ -126,32 +126,56 @@ class Notifications(Cog): """ await ctx.send_help(self.keyword) - async def _add_keyword(self, ctx, keyword, regex): + async def _add_keyword(self, ctx, keyword: str, regex: bool): log.debug( f"Adding {'regex' if regex else 'keyword'}: {keyword} of {ctx.author} ({ctx.author.id}) on {ctx.guild} ({ctx.guild.id})" ) + params = { + "keyword": keyword, + "guild_id": ctx.guild.id, + "user_id": ctx.author.id, + "regex": regex, + } + + existing = """ + SELECT keyword FROM keywords + WHERE guild_id=:guild_id + AND user_id=:user_id + AND contains(:keyword, keyword, regex) + """ + redundant = """ + SELECT keyword FROM keywords + WHERE guild_id=:guild_id + AND user_id=:user_id + AND contains(keyword, :keyword, :regex) + """ + if test_keyword(keyword, regex): await ctx.send(f"{'Regex' if regex else 'Keyword'} matches a word that is too common") return - cur = await ctx.bot.db.execute( - "SELECT keyword FROM keywords WHERE guild_id=? AND user_id=? AND contains(?, keyword, regex)", - (ctx.guild.id, ctx.author.id, keyword), - ) - - conflicts = unpack(await cur.fetchall()) + conflicts = await fetch_unpacked(ctx.bot.db, existing, params) if conflicts: - await ctx.send(f"Any instance of keyword `{keyword}` would be matched by existing keywords (check DMs)") + await ctx.send(f"Any instance of `{keyword}` would be matched by existing keywords (check DMs)") await ctx.author.send( f"Conflicts with keyword `{keyword}`:\n" + "\n".join(f"- `{conflict}`" for conflict in conflicts) ) return + conflicts = await fetch_unpacked(ctx.bot.db, redundant, params) + + if conflicts: + await ctx.send(f"Adding `{keyword}` will cause existing keywords to never match (check DMs)") + await ctx.author.send( + f"Keywords redundant from `{keyword}`:\n" + "\n".join(f" - `{conflict}`" for conflict in conflicts) + ) + return + await ctx.bot.db.execute( - "INSERT INTO keywords (guild_id, keyword, user_id, regex) VALUES (?, ?, ?, ?)", - (ctx.guild.id, keyword, ctx.author.id, regex), + "INSERT INTO keywords (guild_id, keyword, user_id, regex) VALUES (:guild_id, :keyword, :user_id, :regex)", + params, ) await ctx.bot.db.commit() await ctx.send(f"Added `{keyword}` to your list of keywords") diff --git a/nomen/utils.py b/nomen/utils.py index 7253e0c..9b5b1ba 100644 --- a/nomen/utils.py +++ b/nomen/utils.py @@ -107,6 +107,13 @@ def unpack(lst_of_tpl): return list(map(first, lst_of_tpl)) +async def fetch_unpacked(db, sql, params=None): + cur = db.cursor() + cur.row_factory = first + cur = await cur.execute(sql, params) + return await cur.fetchall() + + async def in_thread(member, thread): # FIXME: Currently overlooks the situation where a moderator isn't in a thread but has manage threads return any(member.id == thread_member.id for thread_member in await thread.fetch_members())