diff --git a/nomen/notifications.py b/nomen/notifications.py index 704964d..93bc234 100644 --- a/nomen/notifications.py +++ b/nomen/notifications.py @@ -3,7 +3,8 @@ from asyncio import TaskGroup from textwrap import indent from typing import Union -from disnake import Embed, Member, TextChannel +from disnake import Embed, Member, Thread, User +from disnake.abc import GuildChannel from disnake.ext.commands import Cog, group, guild_only from .utils import can_view, confirm, test_keyword @@ -68,11 +69,16 @@ async def handle_triggers(ctx, message): params = { "author": ctx.author.id, "channel": ctx.channel.id, + "category": ctx.channel.category_id, "guild": ctx.guild.id, "content": message.content, "is_bot": ctx.author.bot, + "parent": 0, } + if isinstance(ctx.channel, Thread) and ctx.channel.parent: + params["parent"] = ctx.channel.parent.id + disabled = await ctx.bot.db.fetch_exists( "SELECT * FROM users WHERE user_id=:author AND unlikely(disabled IS 1)", params ) @@ -94,11 +100,12 @@ async def handle_triggers(ctx, message): AND (unlikely(bots_notify IS 1) OR :is_bot IS NOT 1) -- Don't notify from bots unless wanted AND likely(NOT EXISTS(SELECT * FROM ( -- Don't notify if... SELECT target FROM user_ignores -- Author or channel is ignored in this guild - WHERE user_id=user_id AND guild_id=guild_id + WHERE user_id=user_id AND guild_id=:guild UNION SELECT target FROM user_blocks -- Author is blocked WHERE user_id=user_id - ) WHERE target IN (:author, :channel))) + ) WHERE target IN (:author, :channel, :category, :parent))) + AND likely(NOT EXISTS(SELECT * FROM user_pauses WHERE user_id=user_id AND guild_id=:guild)) AND guild_id=:guild AND unlikely(contains(:content, keyword, regex)) ) WHERE n=1 @@ -303,32 +310,110 @@ class Notifications(Cog): @keyword.command() @guild_only() async def pause(self, ctx): - params = (ctx.author.id, ctx.guild_id) + """ + Pause notifications in this guild + """ + + params = (ctx.author.id, ctx.guild.id) if await ctx.bot.db.fetch_exists("SELECT * FROM user_pauses WHERE user_id=? AND guild_id=?", params): - await ctx.bot.db.execute("DELETE FROM user_pauses WHERE user_id=? AND guild_id=?", params) - await ctx.bot.send(f"Resumed notifications in {ctx.guild}") + await ctx.send(f"Notifications in {ctx.guild} are already paused") else: await ctx.bot.db.execute("INSERT INTO user_pauses VALUES(?, ?)", params) - await ctx.bot.send(f"Paused notifications in {ctx.guild}") - # TODO: Pause guild notifications in handler - - @keyword.group(invoke_without_command=True) - @guild_only() - async def ignore(self, ctx, target: Union[TextChannel, Member]): - await ctx.bot.db.execute("INSERT INTO user_ignores VALUES(?, ?, ?)", (ctx.author.id, ctx.guild.id, target.id)) - await ctx.bot.db.commit() - await ctx.send(f"Now ignoring {target}") + await ctx.bot.db.commit() + await ctx.send(f"Paused notifications in {ctx.guild}") @keyword.command() @guild_only() - async def uningnore(self, ctx, target: Union[TextChannel, Member]): - pass - # TODO: Unignore + async def resume(self, ctx): + """ + Resume notifications in this guild + """ - @ignore.command() + params = (ctx.author.id, ctx.guild_id) + if await ctx.bot.db.fetch_exists("SELECT * FROM user_pauses WHERE user_id=? AND guild_id=?", params): + await ctx.bot.db.execute("DELETE FROM user_pauses WHERE user_id=? AND guild_id=?", params) + await ctx.bot.db.commit() + await ctx.send(f"Resumed notifications in {ctx.guild}") + else: + await ctx.send(f"Notifications in {ctx.guild} aren't paused") + + @keyword.command() @guild_only() - async def active(self, ctx): - await ctx.bot.user_toggle(ctx.author.id, "ignore_active") - await ctx.bot.send("Toggled ignore active channel") # TODO: Send current state + async def ignore(self, ctx, target: Union[GuildChannel, Member]): + """ + Ignore a channel or member in this guild - # TODO: Ignore active channel in handler + This prevents you from receiving any notifications from that channel or user in this guild + """ + + params = (ctx.author.id, ctx.guild.id, target.id) + if await ctx.bot.db.fetch_exists( + "SELECT * FROM user_ignores WHERE user_id=? AND guild_id=? AND target=?", params + ): + await ctx.send(f"Target `{repr(target)}` already ignored") + return + + await ctx.bot.db.execute("INSERT INTO user_ignores VALUES(?, ?, ?)", params) + await ctx.bot.db.commit() + await ctx.send(f"Now ignoring `{repr(target)}`") + + @keyword.command() + @guild_only() + async def unignore(self, ctx, target: Union[GuildChannel, Member]): + """ + Unignore a channel or member in this guild + + This allows you to receive notifications from that channel or user again + """ + + params = (ctx.author.id, ctx.guild.id, target.id) + if not await ctx.bot.db.fetch_exists( + "SELECT * FROM user_ignores WHERE user_id=? AND guild_id=? AND target=?", params + ): + await ctx.send(f"Target `{repr(target)}` is not currently being ignored") + return + + await ctx.bot.db.execute("DELETE FROM user_ignores WHERE user_id=? AND guild_id=? AND target=?", params) + await ctx.bot.db.commit() + await ctx.send(f"No longer ignoring `{repr(target)}`") + + @keyword.command() + async def block(self, ctx, target: User): + """ + Block a user from triggering your notifications + + This prevents you from receiving notifications from that user in any guild + NOTE: They will still receive notifications from you + """ + await ctx.message.delete(delay=0) # Delete invoking message if able to + + params = (ctx.author.id, ctx.target.id) + if await ctx.bot.db.fetch_exists("SELECT * FROM user_blocks WHERE user_id=? AND target=?", params): + await ctx.author.send(f"Target {target} already blocked") + return + + await ctx.bot.db.execute( + "INSERT INTO user_blocks VALUES(?, ?)", + (ctx.author.id, target.id), + ) + await ctx.bot.db.commit() + await ctx.author.send(f"Blocked {target}") + + @keyword.command() + async def unblock(self, ctx, target: User): + """ + Unblock a user + + This allows you to receive notifications from that user again + """ + + await ctx.message.delete(delay=0) # Delete invoking message if able to + + params = (ctx.author.id, ctx.target.id) + if await ctx.bot.db.fetch_exists("SELECT * FROM user_blocks WHERE user_id=? AND target=?", params): + await ctx.author.send(f"Target {target} already blocked") + return + + await ctx.bot.db.execute("DELETE FROM user_ignores WHERE user_id=? AND target=?", params) + await ctx.bot.db.commit() + await ctx.author.send(f"Unblocked {target}")