tooter/tooter.py

119 lines
3.4 KiB
Python

#!/usr/bin/env python3
from argparse import ArgumentParser
from config import Config, load as config_load
from ircrobots import Bot as BaseBot
from ircrobots import ConnectionParams, SASLUserPass
from ircrobots import Server as BaseServer
from irctokens import build, Line
import asyncio
import emoji
HELP_TEXT = "helo i can send toots from irc"
SOURCE_URL = "https://tildegit.org/ben/tooter"
def think(self, line):
chan = line.params[0]
cmd, *words = line.params[1].split(" ")
cmd = cmd.lower()[1:]
if cmd == "source":
return SOURCE_URL
elif cmd in ["botlist", "toothelp"]:
return HELP_TEXT
elif cmd == "toot":
if len(words) >= 2:
status = emoji.emojize(" ".join(words), use_aliases=True)
author = line.tags.get("account", line.hostmask.nickname)
if chan in self._config.assigned_channels:
account = self._config.mastodon_accounts[self._config.assigned_channels[chan]]
else:
account = self._config.mastodon_accounts.get("tildeverse")
if account:
res = account.toot(f"{status}\n~{author}")
if res:
return "tooted! {}".format(res["url"])
else:
return "tooted failed :("
else:
return "no account :("
else:
return HELP_TEXT
class Server(BaseServer):
def __init__(self,
bot: BaseBot,
name: str,
cfg: Config):
super().__init__(bot, name)
self._config = cfg
async def line_send(self, line: Line):
print(f"> {line.format()}")
async def line_read(self, line: Line):
print(f"< {line.format()}")
if line.command == "001":
await self.send(build("JOIN", [",".join(self._config.channel)]))
await self.send(build("MODE", [self.nickname, "+B"]))
if line.command == "INVITE":
await self.send(build("JOIN", line.params[1:]))
if (
line.command == "PRIVMSG"
and self.has_channel(line.params[0])
and self.has_user(line.hostmask.nickname)
and len(line.params[1].split(" ")) > 0
and line.hostmask is not None
and not self.casefold(line.hostmask.nickname) == self.nickname_lower
and not ("batch" in line.tags and line.tags["batch"] == "1")
and line.params[1].startswith("!")
):
response = think(self, line)
if response is not None:
await self.send(build("PRIVMSG", [line.params[0], response]))
class Bot(BaseBot):
def __init__(self, cfg: Config):
super().__init__()
self._config = cfg
def create_server(self, name: str):
return Server(self, name, self._config)
async def main(cfg: Config):
bot = Bot(cfg)
host, port, tls = cfg.server
sasl_user, sasl_pass = cfg.sasl
params = ConnectionParams(
cfg.nickname,
host,
port,
tls,
username=cfg.username,
realname=cfg.realname,
sasl=SASLUserPass(sasl_user, sasl_pass),
autojoin=[cfg.channel]
)
await bot.add_server(host, params)
await bot.run()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("config")
args = parser.parse_args()
config = config_load(args.config)
asyncio.run(main(config))