refactor add_keyword to better account for duplicates

This commit is contained in:
Infinidoge 2024-12-19 01:13:28 -05:00
parent 110b8f2d91
commit 981e113af8
Signed by: Infinidoge
SSH key fingerprint: SHA256:oAMyvotlNFraMmZmr+p6AxnNfW/GioTs1pOn3V4tQ7A
2 changed files with 41 additions and 10 deletions

View file

@ -126,32 +126,56 @@ class Notifications(Cog):
""" """
await ctx.send_help(self.keyword) 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( log.debug(
f"Adding {'regex' if regex else 'keyword'}: {keyword} of {ctx.author} ({ctx.author.id}) on {ctx.guild} ({ctx.guild.id})" 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): if test_keyword(keyword, regex):
await ctx.send(f"{'Regex' if regex else 'Keyword'} matches a word that is too common") await ctx.send(f"{'Regex' if regex else 'Keyword'} matches a word that is too common")
return return
cur = await ctx.bot.db.execute( conflicts = await fetch_unpacked(ctx.bot.db, existing, params)
"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())
if conflicts: 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( await ctx.author.send(
f"Conflicts with keyword `{keyword}`:\n" + "\n".join(f"- `{conflict}`" for conflict in conflicts) f"Conflicts with keyword `{keyword}`:\n" + "\n".join(f"- `{conflict}`" for conflict in conflicts)
) )
return 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( await ctx.bot.db.execute(
"INSERT INTO keywords (guild_id, keyword, user_id, regex) VALUES (?, ?, ?, ?)", "INSERT INTO keywords (guild_id, keyword, user_id, regex) VALUES (:guild_id, :keyword, :user_id, :regex)",
(ctx.guild.id, keyword, ctx.author.id, regex), params,
) )
await ctx.bot.db.commit() await ctx.bot.db.commit()
await ctx.send(f"Added `{keyword}` to your list of keywords") await ctx.send(f"Added `{keyword}` to your list of keywords")

View file

@ -107,6 +107,13 @@ def unpack(lst_of_tpl):
return list(map(first, 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): async def in_thread(member, thread):
# FIXME: Currently overlooks the situation where a moderator isn't in a thread but has manage threads # 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()) return any(member.id == thread_member.id for thread_member in await thread.fetch_members())