Compare commits
No commits in common. "38e41dc1b5d6612f4b6f403355cc04aff62abacb" and "ec54e31b5c5f480df62ac25fd84af76136ca83aa" have entirely different histories.
38e41dc1b5
...
ec54e31b5c
4 changed files with 33 additions and 59 deletions
|
@ -23,7 +23,7 @@ logger_disnake.setLevel(logging.WARNING)
|
||||||
log = logging.getLogger("nomen")
|
log = logging.getLogger("nomen")
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
formatter = logging.Formatter("{asctime} {levelname:8} {name}: {message}", "%Y-%m-%d %H:%M:%S", "{")
|
formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")
|
||||||
handler = logging.StreamHandler(sys.stdout)
|
handler = logging.StreamHandler(sys.stdout)
|
||||||
handler.setFormatter(formatter)
|
handler.setFormatter(formatter)
|
||||||
logging.getLogger(None).addHandler(handler)
|
logging.getLogger(None).addHandler(handler)
|
||||||
|
@ -78,7 +78,10 @@ class Nomen(Bot):
|
||||||
return prefix
|
return prefix
|
||||||
|
|
||||||
async def set_guild_prefix(self, guild: Guild, prefix):
|
async def set_guild_prefix(self, guild: Guild, prefix):
|
||||||
await self.db.execute("REPLACE INTO guilds (guild_id, prefix) VALUES(?, ?)", (guild.id, prefix))
|
await self.db.execute(
|
||||||
|
"REPLACE INTO guilds VALUES(?, ?)",
|
||||||
|
(guild.id, prefix),
|
||||||
|
)
|
||||||
self.prefixes[guild.id] = prefix
|
self.prefixes[guild.id] = prefix
|
||||||
|
|
||||||
async def start(self, *args, **kwargs):
|
async def start(self, *args, **kwargs):
|
||||||
|
|
|
@ -1,60 +1,42 @@
|
||||||
import logging
|
import logging
|
||||||
from asyncio import TaskGroup
|
from asyncio import TaskGroup
|
||||||
from textwrap import indent
|
|
||||||
|
|
||||||
from disnake import Embed
|
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_unpacked, test_keyword
|
||||||
|
|
||||||
log = logging.getLogger("nomen.notifications")
|
log = logging.getLogger("nomen.notifications")
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.INFO)
|
||||||
log_ = log
|
|
||||||
|
|
||||||
|
|
||||||
class NotifierLogAdapter(logging.LoggerAdapter):
|
async def handle_notification(db_updates, ctx, message, keyword, user_id):
|
||||||
def process(self, msg, kwargs):
|
|
||||||
return (
|
|
||||||
f"[guild: {self.extra["guild"]}, user: {self.extra["user"]}, keyword: {self.extra["keyword"]}] {msg}",
|
|
||||||
kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_notification(db_updates, ctx, message, keyword, user_id, use_embed):
|
|
||||||
"""
|
"""
|
||||||
Async task to dispatch a notification
|
Async task to dispatch a notification
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
log.debug(f"- Handling `{keyword}` for {user_id}")
|
||||||
|
|
||||||
member = await ctx.guild.getch_member(user_id)
|
member = await ctx.guild.getch_member(user_id)
|
||||||
|
|
||||||
log = NotifierLogAdapter(log_.getChild("notifier"), {"guild": ctx.guild, "user": member, "keyword": keyword})
|
|
||||||
|
|
||||||
log.debug("Handling notification")
|
|
||||||
|
|
||||||
if not await can_view(ctx, member):
|
if not await can_view(ctx, member):
|
||||||
log.debug("Missing permission")
|
log.debug(f"- - Missing permission {user_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
log.debug("Notifying")
|
log.debug(f"- - Notifying {user_id}")
|
||||||
db_updates.append((ctx.guild.id, keyword, user_id))
|
db_updates.append((ctx.guild.id, keyword, user_id))
|
||||||
|
|
||||||
header = f"🔔 `{message.author.display_name}` mentioned `{keyword}` on `{ctx.guild}`:"
|
footer = f"\n\n<t:{int(message.created_at.timestamp())}:R> | [Show]({message.jump_url}) | <#{ctx.channel.id}>"
|
||||||
footer = f"\n<t:{int(message.created_at.timestamp())}:R> | [Show]({message.jump_url}) | <#{ctx.channel.id}>"
|
|
||||||
|
|
||||||
if use_embed:
|
embed = Embed(
|
||||||
log.debug("Sending embed")
|
description=message.content + footer,
|
||||||
embed = Embed(description=message.content + "\n" + footer)
|
)
|
||||||
embed.set_author(
|
embed.set_author(name=message.author, icon_url=message.author.display_avatar)
|
||||||
name=f"{message.author.display_name} ({message.author})",
|
|
||||||
icon_url=message.author.display_avatar,
|
|
||||||
)
|
|
||||||
|
|
||||||
await member.send(header, embed=embed)
|
await member.send(
|
||||||
else:
|
f":bell: `{message.author}` mentioned `{keyword}` on `{ctx.guild}`:",
|
||||||
log.debug("Sending plain message")
|
embed=embed,
|
||||||
await member.send("\n".join((header, indent(message.content, "> ", lambda line: True).strip(), footer)))
|
)
|
||||||
|
|
||||||
log.debug("Sent")
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_triggers(ctx, message):
|
async def handle_triggers(ctx, message):
|
||||||
|
@ -62,8 +44,6 @@ async def handle_triggers(ctx, message):
|
||||||
Main function that handles message triggers
|
Main function that handles message triggers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.debug(f"Handling triggers for '{message.content}' from {ctx.author}")
|
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"author": ctx.author.id,
|
"author": ctx.author.id,
|
||||||
"channel": ctx.channel.id,
|
"channel": ctx.channel.id,
|
||||||
|
@ -72,9 +52,11 @@ async def handle_triggers(ctx, message):
|
||||||
"is_bot": ctx.author.bot,
|
"is_bot": ctx.author.bot,
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled = await fetch_exists(ctx.bot.db, "SELECT * FROM users WHERE user_id=:author AND disabled IS 1", params)
|
disabled = await ctx.bot.db.execute_fetchall(
|
||||||
|
"SELECT EXISTS(SELECT * FROM users WHERE user_id=:author AND disabled IS 1)", params
|
||||||
|
)
|
||||||
|
|
||||||
if disabled:
|
if disabled[0][0]:
|
||||||
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
log.debug(f"User {ctx.author} ({ctx.author.id}) opted out")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -90,7 +72,7 @@ async def handle_triggers(ctx, message):
|
||||||
AND (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 (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 :author NOT IN ( -- Don't notify if...
|
AND :author NOT IN ( -- Don't notify if...
|
||||||
SELECT target FROM user_ignores -- Author is ignored in this guild
|
SELECT target FROM user_ignores -- Author is ignored in this guilde
|
||||||
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
|
||||||
|
@ -106,9 +88,8 @@ async def handle_triggers(ctx, message):
|
||||||
async for keyword, user_id, use_embed in cur:
|
async for keyword, user_id, use_embed in cur:
|
||||||
log.debug(f"- Creating notification task: '{keyword}' for {user_id}")
|
log.debug(f"- Creating notification task: '{keyword}' for {user_id}")
|
||||||
|
|
||||||
tg.create_task(handle_notification(db_updates, ctx, message, keyword, user_id, use_embed))
|
tg.create_task(handle_notification(db_updates, ctx, message, keyword, user_id))
|
||||||
|
|
||||||
log.debug("Incrementing notification counts")
|
|
||||||
await ctx.bot.db.executemany(
|
await ctx.bot.db.executemany(
|
||||||
"UPDATE keywords SET count = count + 1 WHERE guild_id=? AND keyword=? AND user_id=?",
|
"UPDATE keywords SET count = count + 1 WHERE guild_id=? AND keyword=? AND user_id=?",
|
||||||
db_updates,
|
db_updates,
|
||||||
|
@ -226,7 +207,7 @@ class Notifications(Cog):
|
||||||
|
|
||||||
await self._add_keyword(ctx, keyword, True)
|
await self._add_keyword(ctx, keyword, True)
|
||||||
|
|
||||||
@keyword.command(aliases=["delete", "del"])
|
@keyword.command()
|
||||||
@guild_only()
|
@guild_only()
|
||||||
async def remove(self, ctx, keyword):
|
async def remove(self, ctx, keyword):
|
||||||
"""
|
"""
|
||||||
|
@ -304,7 +285,7 @@ class Notifications(Cog):
|
||||||
@guild_only()
|
@guild_only()
|
||||||
async def ignore(self, ctx, channel):
|
async def ignore(self, ctx, channel):
|
||||||
pass
|
pass
|
||||||
# TODO: Ignore channels and users
|
# TODO: Ignore channels
|
||||||
|
|
||||||
@ignore.command()
|
@ignore.command()
|
||||||
@guild_only()
|
@guild_only()
|
||||||
|
|
|
@ -91,7 +91,7 @@ You may want to `{ctx.clean_prefix}nomen export` first"""
|
||||||
f"You have now opted-out and will no longer trigger or receive notifications. To opt back in, run `{ctx.clean_prefix}nomen opt-in`"
|
f"You have now opted-out and will no longer trigger or receive notifications. To opt back in, run `{ctx.clean_prefix}nomen opt-in`"
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.bot.db.execute("REPLACE INTO users (user_id, disabled) VALUES(?, 1)", (ctx.author.id,))
|
await self.bot.db.execute("REPLACE INTO users VALUES(?, 1)", (ctx.author.id,))
|
||||||
await self.bot.db.commit()
|
await self.bot.db.commit()
|
||||||
|
|
||||||
@nomen.command(name="opt-in")
|
@nomen.command(name="opt-in")
|
||||||
|
@ -106,5 +106,5 @@ You may want to `{ctx.clean_prefix}nomen export` first"""
|
||||||
f"You have opted back in and will now trigger and receive notifications. To opt out, run `{ctx.clean_prefix}nomen opt-out`"
|
f"You have opted back in and will now trigger and receive notifications. To opt out, run `{ctx.clean_prefix}nomen opt-out`"
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.bot.db.execute("REPLACE INTO users (user_id, disabled) VALUES(?, 0)", (ctx.author.id,))
|
await self.bot.db.execute("REPLACE INTO users VALUES(?, 0)", (ctx.author.id,))
|
||||||
await self.bot.db.commit()
|
await self.bot.db.commit()
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import logging
|
|
||||||
from asyncio import TimeoutError
|
from asyncio import TimeoutError
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
import re2 as re
|
import re2 as re
|
||||||
from disnake import ChannelType
|
from disnake import ChannelType
|
||||||
|
|
||||||
log = logging.getLogger("nomen.utils")
|
|
||||||
|
|
||||||
ALPHABET = list("abcdefghijklmnopqrstuvwxyz ")
|
ALPHABET = list("abcdefghijklmnopqrstuvwxyz ")
|
||||||
|
|
||||||
COMMON_WORDS = [
|
COMMON_WORDS = [
|
||||||
|
@ -112,17 +109,12 @@ def unpack(lst_of_tpl):
|
||||||
|
|
||||||
|
|
||||||
async def fetch_unpacked(db, sql, params=None):
|
async def fetch_unpacked(db, sql, params=None):
|
||||||
cur = await db.cursor()
|
cur = db.cursor()
|
||||||
cur.row_factory = lambda cursor, row: first(row)
|
cur.row_factory = first
|
||||||
cur = await cur.execute(sql, params)
|
cur = await cur.execute(sql, params)
|
||||||
return await cur.fetchall()
|
return await cur.fetchall()
|
||||||
|
|
||||||
|
|
||||||
async def fetch_exists(db, sql, params=None):
|
|
||||||
result = await db.execute_fetchall(f"SELECT EXISTS({sql})", params)
|
|
||||||
return result[0][0]
|
|
||||||
|
|
||||||
|
|
||||||
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())
|
||||||
|
@ -190,7 +182,6 @@ async def confirm(ctx, message, delete_msgs=False, response_check=get_positivity
|
||||||
pass
|
pass
|
||||||
return reply_bool
|
return reply_bool
|
||||||
|
|
||||||
|
|
||||||
def cleanup_code(content):
|
def cleanup_code(content):
|
||||||
"""Automatically removes code blocks from the code."""
|
"""Automatically removes code blocks from the code."""
|
||||||
# remove ```py\n```
|
# remove ```py\n```
|
||||||
|
@ -200,5 +191,4 @@ def cleanup_code(content):
|
||||||
# remove `foo`
|
# remove `foo`
|
||||||
return content.strip("` \n")
|
return content.strip("` \n")
|
||||||
|
|
||||||
|
|
||||||
# ===== End code borrowed from Avrae =====
|
# ===== End code borrowed from Avrae =====
|
||||||
|
|
Loading…
Reference in a new issue