nonsensebot/app/main.py

117 lines
3.4 KiB
Python
Raw Permalink Normal View History

# import sys
2024-09-15 23:10:27 +01:00
import asyncio
2024-09-15 23:03:24 +01:00
import hashlib
2024-09-15 20:25:42 +01:00
import sys
2024-07-28 03:59:19 +01:00
import niobot
import tomllib
import platform
import logging
from pathlib import Path
2024-07-28 23:33:15 +01:00
2024-09-15 23:03:24 +01:00
import redis.asyncio as redis
2024-07-28 03:59:19 +01:00
log = logging.getLogger(__name__)
2024-07-31 23:17:09 +01:00
logging.getLogger("nio.rooms").setLevel(logging.WARNING)
logging.getLogger("nio.crypto.log").setLevel(logging.WARNING)
logging.getLogger("peewee").setLevel(logging.WARNING)
logging.getLogger("nio.responses").setLevel(logging.WARNING)
2024-07-28 03:59:19 +01:00
with open("config.toml", "rb") as fd:
config = tomllib.load(fd)
(store := (Path.cwd() / "store")).mkdir(parents=True, exist_ok=True)
2024-09-15 23:03:24 +01:00
class NonsenseBot(niobot.NioBot):
2024-07-28 23:33:15 +01:00
cfg: dict
2024-09-15 23:03:24 +01:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.redis: redis.Redis | None = None
@staticmethod
def redis_key(*parts: str) -> str:
"""Returns a redis key for the given info"""
h = hashlib.md5()
for part in parts:
h.update(part.encode())
return h.hexdigest()
async def close(self):
await self.redis.aclose()
2024-07-28 03:59:19 +01:00
async def start(self, **kwargs):
2024-09-15 20:25:42 +01:00
url = config["database"].get("uri")
2024-09-15 23:03:24 +01:00
if url:
self.redis = redis.Redis.from_url(url)
assert await self.redis.ping()
2024-09-15 20:25:42 +01:00
sys.path.extend(("..", "."))
2024-07-28 03:59:19 +01:00
for file in (Path(__file__).parent / "./modules").glob("*.py"):
if file.name.startswith("__"):
log.warning("Skipping loading %s - dunder file.", file)
name = "app.modules." + file.name[:-3]
try:
log.info("Loading %s...", name)
bot.mount_module(name)
except Exception:
log.error("Failed to load %s!", name, exc_info=True)
else:
log.info("Loaded %s.", name)
await super().start(**kwargs)
2024-09-18 21:03:25 +01:00
async def process_message(self, room, message):
if self.redis:
room_banned = await self.redis.get(self.redis_key("botban", room.room_id))
user_banned = await self.redis.get(self.redis_key("botban", message.sender))
if room_banned or user_banned:
self.log.debug("Ignoring banned room/user: %r - %r", room, message)
return
return await super().process_message(room, message)
2024-07-28 03:59:19 +01:00
2024-09-15 23:03:24 +01:00
bot = NonsenseBot(
2024-07-28 03:59:19 +01:00
homeserver=config["bot"]["homeserver"],
user_id=config["bot"]["user_id"],
device_id=config["bot"].get("device_id", platform.node()),
store_path=str(store.resolve()),
2024-09-15 20:25:42 +01:00
command_prefix=config["bot"].get("prefix", "h!"),
2024-07-28 23:33:15 +01:00
owner_id=config["bot"].get("owner_id") or "@nex:nexy7574.co.uk",
2024-09-18 18:06:31 +01:00
auto_read_messages=False,
2024-07-28 03:59:19 +01:00
)
bot.cfg = config
@bot.on_event("ready")
async def on_ready(_):
log.info("Bot has logged in.")
2024-07-28 23:33:15 +01:00
@bot.on_event("command")
async def on_command(ctx: niobot.Context):
log.info("Command %s invoked by %s.", ctx.command, ctx.message.sender)
@bot.on_event("command_error")
async def on_command_error(ctx: niobot.Context, exc: Exception):
2024-09-08 02:25:12 +01:00
exc = getattr(exc, "original", exc) or exc
2024-07-28 23:33:15 +01:00
log.error("Command %s failed.", ctx.command, exc_info=exc)
2024-09-15 23:03:24 +01:00
text = "\N{WARNING SIGN} Command failed: `%s`" % exc
text = text.replace(bot.access_token, "REDACTED")
2024-09-15 23:03:24 +01:00
await ctx.respond(text)
2024-07-28 23:33:15 +01:00
@bot.on_event("command_complete")
async def on_command_complete(ctx: niobot.Context, _):
log.info("Command %s completed.", ctx.command)
2024-07-31 23:17:09 +01:00
if __name__ == "__main__":
2024-09-15 23:10:27 +01:00
asyncio.run(bot.start(access_token=bot.cfg["bot"]["access_token"]))