#!/usr/bin/env python3 from .config import Config from ircrobots import Bot as BaseBot from ircrobots import ConnectionParams, SASLUserPass from ircrobots import Server as BaseServer from irctokens import build, Line from mastodon import Mastodon import asyncio import emoji import glob import json import os import sys HELP_TEXT = "helo i can send toots from irc: @tildeverse@tilde.zone - from @tildeteam from the #team channel)" masto = {} assigned_channels = {} # load masto creds for cred in glob.glob("tilde*.json"): shortname, _ = os.path.splitext(cred) with open(cred, "r") as f: conf = json.load(f) if "channel" in conf: assigned_channels[conf["channel"]] = shortname masto[shortname] = Mastodon( client_id=conf["client_id"], client_secret=conf["client_secret"], access_token=conf["access_token"], api_base_url=conf["base_url"], ) if "tildeverse" not in masto: print("you must populate tildeverse.json with mastodon credentials") exit(1) # do setup with open("config.json", "r") as f: config = json.load(f) with open("account.json", "r") as f: account = json.load(f) channels = config["channels"] if len(sys.argv) > 1: for c in sys.argv[1:]: channels.append("#" + c) def think(line): chan = line.params[0] cmd, *words = line.params[1].split(" ") cmd = cmd.lower()[1:] if cmd == "source": return "https://tildegit.org/ben/tooter" elif cmd in ["botlist", "toothelp"]: return HELP_TEXT elif cmd == "toot": if len(words) >= 2: status = emoji.emojize(" ".join(words[1:]), use_aliases=True) author = line.tags.get("account", line.hostmask.nickname) res = masto[ assigned_channels[chan] if chan in assigned_channels else "tildeverse" ].toot(f"{status}\n~{author}") return "tooted! {}".format(res["url"]) else: return HELP_TEXT class Server(BaseServer): def __init__(self, bot: BaseBot, name: str, config: Config): super().__init__(bot, name) self._config = config async def line_send(self, line: Line): print(f"{self.name} > {line.format()}") async def line_read(self, line: Line): print(f"{self.name} < {line.format()}") if line.command == "001": await self.send(build("JOIN", [",".join(channels)])) 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(line) if response is not None: await self.send(build("PRIVMSG", [line.params[0], response])) class Bot(BaseBot): def create_server(self, name: str): return Server(self, name) async def main(): params = ConnectionParams( config.get("botnick", "tooter"), config.get("address", "127.0.0.1"), config.get("port", 6667), config.get("tls", False), sasl=SASLUserPass(account["username"], account["password"]), ) bot = Bot() await bot.add_server("tilde", params) await bot.run() if __name__ == "__main__": asyncio.run(main())