oirc/bot.py

143 lines
3.9 KiB
Python
Raw Permalink Normal View History

2020-11-21 20:17:09 +00:00
#!/usr/bin/env python3
import asyncio, os, importlib, inspect
2020-11-21 20:17:09 +00:00
from irctokens import build, Line
from ircrobots import Bot as BaseBot
from ircrobots import Server as BaseServer
from ircrobots import ConnectionParams, SASLUserPass, SASLSCRAM
from auth import username, password
2020-11-22 02:36:20 +00:00
import shared
2020-11-22 01:49:04 +00:00
2022-01-27 02:22:42 +00:00
2020-11-22 01:49:04 +00:00
def is_admin(func):
2022-01-27 02:22:42 +00:00
async def decorator(self, channel, nick, msg):
if (
nick.lower() in self.users
and self.users[nick.lower()].account in self.admins
):
await func(self, channel, nick, msg)
2020-11-22 01:49:04 +00:00
else:
2022-01-27 02:22:42 +00:00
await message(self, channel, "you do not have permission to do that")
2020-11-22 01:49:04 +00:00
return decorator
2022-01-27 02:22:42 +00:00
# def is_chanop(func):
2020-11-22 01:49:04 +00:00
def command(commandname):
def decorator(func):
2020-11-22 02:36:20 +00:00
shared.commands[commandname] = func
2020-11-22 01:49:04 +00:00
return func
2022-01-27 02:22:42 +00:00
2020-11-22 01:49:04 +00:00
return decorator
2022-01-27 02:22:42 +00:00
def listener(listenername):
def decorator(func):
shared.listeners.append((listenername, func))
return func
2022-01-27 02:22:42 +00:00
return decorator
2022-01-27 02:22:42 +00:00
def rawm(rname):
def decorator(func):
shared.rawm[rname] = func
return func
2022-01-27 02:22:42 +00:00
return decorator
2020-11-22 01:49:04 +00:00
2022-01-27 02:22:42 +00:00
async def message(self, channel, msg):
modname = os.path.splitext(os.path.basename(inspect.stack()[:2][-1].filename))[0]
2022-01-27 02:22:42 +00:00
await self.send(build("PRIVMSG", [channel, f"[\x036{modname}\x0f] {msg}"]))
2020-11-22 02:04:11 +00:00
2020-11-22 01:49:04 +00:00
2020-11-21 20:17:09 +00:00
class Server(BaseServer):
async def line_read(self, line: Line):
2022-01-27 02:22:42 +00:00
if "on_" + line.command.lower() in dir(self):
asyncio.create_task(
self.__getattribute__("on_" + line.command.lower())(line)
)
2020-11-22 02:36:20 +00:00
for listener in shared.listeners:
2020-11-22 01:49:04 +00:00
if listener[0] == line.command:
2022-01-27 02:22:42 +00:00
asyncio.create_task(listener[1](self, line))
async def line_preread(self, line: Line):
print(f"{self.name} < {line.format()}")
2022-01-27 02:22:42 +00:00
async def line_presend(self, line: Line):
2020-11-21 20:17:09 +00:00
print(f"{self.name} > {line.format()}")
2020-11-21 22:29:12 +00:00
async def on_001(self, line):
asyncio.create_task(self.load_modules())
async def load_modules(self):
2022-01-27 02:22:42 +00:00
for i in [s for s in os.listdir("modules") if ".py" in s and ".swp" not in s]:
2020-11-21 22:29:12 +00:00
i = i[:-3]
2022-01-27 02:22:42 +00:00
m = importlib.import_module("modules." + i)
2020-11-21 22:29:12 +00:00
asyncio.create_task(m.init(self))
2020-11-22 02:36:20 +00:00
shared.modules[i] = m
2020-11-22 01:49:04 +00:00
2022-01-27 02:22:42 +00:00
async def message(self, channel, msg):
modname = os.path.splitext(os.path.basename(inspect.stack()[:2][-1].filename))[0]
await self.send(build("PRIVMSG", [channel, f"[\x036{modname}\x0f] {msg}"]))
2020-11-22 01:49:04 +00:00
async def on_privmsg(self, line):
2022-01-27 02:22:42 +00:00
if line.tags and "batch" in line.tags and line.tags["batch"] == "1":
return
2020-11-22 01:49:04 +00:00
channel = line.params[0]
2022-01-27 02:22:42 +00:00
nick = line.source.split("!")[0]
2020-11-22 01:49:04 +00:00
msg = line.params[1]
if channel == self.nickname:
channel = nick
2022-01-27 02:22:42 +00:00
await self.handle_rawm(channel, nick, msg)
await self.handle_command(channel, nick, msg)
async def handle_rawm(self, channel, nick, msg):
2020-11-22 02:36:20 +00:00
for i in shared.rawm:
2022-01-27 02:22:42 +00:00
await shared.rawm[i](self, channel, nick, msg)
async def handle_command(self, channel, nick, msg):
if msg[: len(shared.prefix)] == shared.prefix:
msg = msg[len(shared.prefix) :]
cmd = msg.split(" ")[0]
msg = msg[len(cmd) + 1 :]
2020-11-22 01:49:04 +00:00
if len(cmd) < 1:
return
2020-11-22 02:36:20 +00:00
if cmd in shared.commands:
2022-01-27 02:22:42 +00:00
await shared.commands[cmd](self, channel, nick, msg)
2020-11-22 01:49:04 +00:00
return
2020-11-22 02:36:20 +00:00
results = [i for i in shared.commands if i.startswith(cmd)]
2020-11-22 01:49:04 +00:00
if len(results) == 1:
2022-01-27 02:22:42 +00:00
await shared.commands[results[0]](self, channel, nick, msg)
2020-11-21 22:29:12 +00:00
2020-11-21 20:17:09 +00:00
class Bot(BaseBot):
def create_server(self, name: str):
return Server(self, name)
2020-11-21 22:29:12 +00:00
2020-11-21 20:17:09 +00:00
async def main():
bot = Bot()
sasl_params = SASLUserPass(username, password)
2022-01-27 02:22:42 +00:00
params = ConnectionParams(
"balun", host="irc.tilde.chat", port=6697, tls=True, sasl=sasl_params
)
2020-11-21 20:17:09 +00:00
await bot.add_server("tilde", params)
await bot.run()
2022-01-27 02:22:42 +00:00
2020-11-21 20:17:09 +00:00
if __name__ == "__main__":
asyncio.run(main())