Compare commits
No commits in common. "49a7ac9fd7f19f0578ea3fe0dd3fe3f556fd854a" and "38e41dc1b5d6612f4b6f403355cc04aff62abacb" have entirely different histories.
49a7ac9fd7
...
38e41dc1b5
3 changed files with 20 additions and 61 deletions
23
nomen/db.py
23
nomen/db.py
|
@ -13,12 +13,11 @@ schema = """
|
||||||
PRAGMA user_version = 1;
|
PRAGMA user_version = 1;
|
||||||
|
|
||||||
PRAGMA main.synchronous = NORMAL;
|
PRAGMA main.synchronous = NORMAL;
|
||||||
PRAGMA foreign_keys = ON;
|
|
||||||
|
|
||||||
CREATE TABLE keywords (
|
CREATE TABLE keywords (
|
||||||
guild_id INTEGER NOT NULL,
|
guild_id INTEGER NOT NULL,
|
||||||
keyword TEXT NOT NULL,
|
keyword TEXT NOT NULL,
|
||||||
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
|
user_id INTEGER NOT NULL,
|
||||||
regex INTEGER NOT NULL DEFAULT 0 CHECK(regex IN (0, 1)),
|
regex INTEGER NOT NULL DEFAULT 0 CHECK(regex IN (0, 1)),
|
||||||
count INTEGER NOT NULL DEFAULT 0
|
count INTEGER NOT NULL DEFAULT 0
|
||||||
);
|
);
|
||||||
|
@ -34,34 +33,22 @@ CREATE TABLE users (
|
||||||
disabled INTEGER NOT NULL DEFAULT 0 CHECK(disabled IN (0, 1)),
|
disabled INTEGER NOT NULL DEFAULT 0 CHECK(disabled IN (0, 1)),
|
||||||
use_embed INTEGER NOT NULL DEFAULT 1 CHECK(use_embed IN (0, 1)),
|
use_embed INTEGER NOT NULL DEFAULT 1 CHECK(use_embed IN (0, 1)),
|
||||||
notify_self INTEGER NOT NULL DEFAULT 0 CHECK(notify_self IN (0, 1)),
|
notify_self INTEGER NOT NULL DEFAULT 0 CHECK(notify_self IN (0, 1)),
|
||||||
bots_notify INTEGER NOT NULL DEFAULT 0 CHECK(bots_notify IN (0, 1)),
|
bots_notify INTEGER NOT NULL DEFAULT 0 CHECK(bots_notify IN (0, 1))
|
||||||
ignore_active INTEGER NOT NULL DEFAULT 0 CHECK(bots_notify IN (0, 1))
|
|
||||||
)
|
)
|
||||||
WITHOUT ROWID;
|
WITHOUT ROWID;
|
||||||
|
|
||||||
CREATE TABLE user_ignores (
|
CREATE TABLE user_ignores (
|
||||||
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
|
user_id INTEGER NOT NULL,
|
||||||
guild_id INTEGER NOT NULL,
|
guild_id INTEGER NOT NULL,
|
||||||
target INTEGER NOT NULL, -- channel or user id
|
target INTEGER NOT NULL,
|
||||||
PRIMARY KEY (user_id, guild_id, target)
|
PRIMARY KEY (user_id, guild_id, target)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE user_blocks (
|
CREATE TABLE user_blocks (
|
||||||
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
|
user_id INTEGER NOT NULL,
|
||||||
target INTEGER NOT NULL,
|
target INTEGER NOT NULL,
|
||||||
PRIMARY KEY (user_id, target)
|
PRIMARY KEY (user_id, target)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE user_pauses (
|
|
||||||
user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
|
|
||||||
guild_id INTEGER NOT NULL,
|
|
||||||
PRIMARY KEY (user_id, guild_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX keywords_index ON keywords(user_id);
|
|
||||||
CREATE INDEX user_ignores_index ON user_ignores(user_id);
|
|
||||||
CREATE INDEX user_blocks_index ON user_blocks(user_id);
|
|
||||||
CREATE INDEX user_pauses_index ON user_pauses(user_id);
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,13 +89,6 @@ class Nomen(Bot):
|
||||||
await super().close()
|
await super().close()
|
||||||
await self.db.close()
|
await self.db.close()
|
||||||
|
|
||||||
async def user_toggle(self, user_id, item):
|
|
||||||
await self.db.execute(
|
|
||||||
"REPLACE INTO users (user_id, {item}) VALUES(:user_id, iff((SELECT {item} FROM users WHERE user_id=:user_id)), 0, 1)",
|
|
||||||
{"user_id": user_id},
|
|
||||||
)
|
|
||||||
await self.db.commit()
|
|
||||||
|
|
||||||
|
|
||||||
bot = Nomen(
|
bot = Nomen(
|
||||||
description="Keeper of Names",
|
description="Keeper of Names",
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
from asyncio import TaskGroup
|
from asyncio import TaskGroup
|
||||||
from textwrap import indent
|
from textwrap import indent
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from disnake import Embed, Member, TextChannel
|
from disnake import Embed
|
||||||
from disnake.ext.commands import Cog, group, guild_only
|
from disnake.ext.commands import Cog, group, guild_only
|
||||||
|
|
||||||
from .utils import can_view, confirm, fetch_exists, fetch_unpacked, test_keyword
|
from .utils import can_view, confirm, fetch_exists, fetch_unpacked, test_keyword
|
||||||
|
@ -73,9 +72,7 @@ async def handle_triggers(ctx, message):
|
||||||
"is_bot": ctx.author.bot,
|
"is_bot": ctx.author.bot,
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled = await fetch_exists(
|
disabled = await fetch_exists(ctx.bot.db, "SELECT * FROM users WHERE user_id=:author AND disabled IS 1", params)
|
||||||
ctx.bot.db, "SELECT * FROM users WHERE user_id=:author AND unlikely(disabled IS 1)", params
|
|
||||||
)
|
|
||||||
|
|
||||||
if disabled:
|
if disabled:
|
||||||
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
||||||
|
@ -89,17 +86,17 @@ async def handle_triggers(ctx, message):
|
||||||
SELECT keyword, user_id, use_embed, row_number() over (partition by user_id) n
|
SELECT keyword, user_id, use_embed, row_number() over (partition by user_id) n
|
||||||
FROM keywords
|
FROM keywords
|
||||||
LEFT JOIN users USING (user_id)
|
LEFT JOIN users USING (user_id)
|
||||||
WHERE likely(disabled IS NOT 1) -- Don't notify users who opted out
|
WHERE disabled IS NOT 1 -- Don't notify users who opted out
|
||||||
AND (unlikely(notify_self IS 1) OR user_id IS NOT :author) -- Don't notify author unless wanted
|
AND (notify_self IS 1 OR user_id IS NOT :author) -- Don't notify author unless wanted
|
||||||
AND (unlikely(bots_notify IS 1) OR :is_bot IS NOT 1) -- Don't notify from bots unless wanted
|
AND (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...
|
AND :author NOT IN ( -- Don't notify if...
|
||||||
SELECT target FROM user_ignores -- Author or channel is ignored in this guild
|
SELECT target FROM user_ignores -- Author is ignored in this guild
|
||||||
WHERE user_id=user_id AND guild_id=guild_id
|
WHERE user_id=user_id AND guild_id=guild_id
|
||||||
UNION
|
UNION
|
||||||
SELECT target FROM user_blocks -- Author is blocked
|
SELECT target FROM user_blocks -- Author is blocked
|
||||||
WHERE user_id=user_id
|
WHERE user_id=user_id
|
||||||
) WHERE target IN (:author, :channel)))
|
)
|
||||||
AND guild_id=:guild AND unlikely(contains(:content, keyword, regex))
|
AND guild_id=:guild AND contains(:content, keyword, regex)
|
||||||
)
|
)
|
||||||
WHERE n=1
|
WHERE n=1
|
||||||
"""
|
"""
|
||||||
|
@ -138,9 +135,6 @@ class Notifications(Cog):
|
||||||
|
|
||||||
await handle_triggers(ctx, message)
|
await handle_triggers(ctx, message)
|
||||||
|
|
||||||
async def cog_before_invoke(ctx):
|
|
||||||
await ctx.bot.db.execute("INSERT OR IGNORE INTO users (userid) VALUE(?)", (ctx.author.id,))
|
|
||||||
|
|
||||||
@group(
|
@group(
|
||||||
aliases=["kw", "notification", "notifications", "notif", "noti"],
|
aliases=["kw", "notification", "notifications", "notif", "noti"],
|
||||||
invoke_without_command=True,
|
invoke_without_command=True,
|
||||||
|
@ -303,32 +297,17 @@ class Notifications(Cog):
|
||||||
@keyword.command()
|
@keyword.command()
|
||||||
@guild_only()
|
@guild_only()
|
||||||
async def pause(self, ctx):
|
async def pause(self, ctx):
|
||||||
params = (ctx.author.id, ctx.guild_id)
|
pass
|
||||||
if await fetch_exists("SELECT * FROM user_pauses WHERE user_id=? AND guild_id=?"):
|
# TODO: Pause guild notifications
|
||||||
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}")
|
|
||||||
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)
|
@keyword.group(invoke_without_command=True)
|
||||||
@guild_only()
|
@guild_only()
|
||||||
async def ignore(self, ctx, target: Union[TextChannel, Member]):
|
async def ignore(self, ctx, channel):
|
||||||
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}")
|
|
||||||
|
|
||||||
@keyword.command()
|
|
||||||
@guild_only()
|
|
||||||
async def uningnore(self, ctx, target: Union[TextChannel, Member]):
|
|
||||||
pass
|
pass
|
||||||
# TODO: Unignore
|
# TODO: Ignore channels and users
|
||||||
|
|
||||||
@ignore.command()
|
@ignore.command()
|
||||||
@guild_only()
|
@guild_only()
|
||||||
async def active(self, ctx):
|
async def active(self, ctx):
|
||||||
await ctx.bot.user_toggle(ctx.author.id, "ignore_active")
|
pass
|
||||||
await ctx.bot.send("Toggled ignore active channel") # TODO: Send current state
|
# TODO: Ignore active channel
|
||||||
|
|
||||||
# TODO: Ignore active channel in handler
|
|
||||||
|
|
Loading…
Reference in a new issue