From 8c2197a0d7b74cd8ffe761670aca4213039a7aff Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Mon, 9 May 2022 16:42:31 -0400 Subject: [PATCH] fix new ircrobots stuff --- config.example.yaml | 2 +- config.py | 36 +++++++++----- requirements.txt | 1 + tooter.py | 115 ++++++++++++++++++++------------------------ tooter.service | 1 - 5 files changed, 78 insertions(+), 77 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index ab54cb4..6c62e98 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -11,6 +11,6 @@ mastodon: client_id: 1234566 client_secret: beeeep access_token: you do not want to know - base_url: https://tilde.zone + api_base_url: https://tilde.zone channels: - '#club' diff --git a/config.py b/config.py index 958c095..e69528d 100644 --- a/config.py +++ b/config.py @@ -1,20 +1,22 @@ from dataclasses import dataclass -from os.path import expanduser -from re import compile as re_compile -from typing import List, Pattern, Tuple +from mastodon import Mastodon +from typing import Tuple, Dict import yaml + @dataclass class Config(object): - server: Tuple[str, int, bool] + server: Tuple[str, int, bool] nickname: str username: str realname: str - password: str - channel: str + channel: str sasl: Tuple[str, str] + mastodon_accounts: Dict[str, Mastodon] + assigned_channels: Dict[str, str] + def load(filepath: str): with open(filepath) as file: @@ -22,22 +24,34 @@ def load(filepath: str): nickname = config_yaml["nickname"] - server = config_yaml["server"] + server = config_yaml["server"] hostname, port_s = server.split(":", 1) - tls = False + tls = False if port_s.startswith("+"): - tls = True + tls = True port_s = port_s.lstrip("+") port = int(port_s) + accounts = {} + channels = {} + for acct in config_yaml["mastodon"]: + accounts[acct["name"]] = Mastodon( + client_id=acct["client_id"], + client_secret=acct["client_secret"], + access_token=acct["access_token"], + api_base_url=acct["api_base_url"], + ) + if "channel" in acct: + channels[acct["channel"]] = acct["name"] + return Config( (hostname, port, tls), nickname, config_yaml.get("username", nickname), config_yaml.get("realname", nickname), - config_yaml["password"], config_yaml["channel"], (config_yaml["sasl"]["username"], config_yaml["sasl"]["password"]), + mastodon_accounts=accounts, + assigned_channels=channels, ) - diff --git a/requirements.txt b/requirements.txt index 7fac7b7..d790193 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ Mastodon.py==1.5.1 emoji==1.7.0 ircrobots==0.6.1 +PyYAML==6.0 \ No newline at end of file diff --git a/tooter.py b/tooter.py index 6447801..9c16e71 100644 --- a/tooter.py +++ b/tooter.py @@ -1,89 +1,61 @@ #!/usr/bin/env python3 +from argparse import ArgumentParser -from .config import Config +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 -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) +HELP_TEXT = "helo i can send toots from irc" +SOURCE_URL = "https://tildegit.org/ben/tooter" -def think(line): +def think(self, line): chan = line.params[0] cmd, *words = line.params[1].split(" ") cmd = cmd.lower()[1:] if cmd == "source": - return "https://tildegit.org/ben/tooter" + return SOURCE_URL elif cmd in ["botlist", "toothelp"]: return HELP_TEXT elif cmd == "toot": if len(words) >= 2: - status = emoji.emojize(" ".join(words[1:]), use_aliases=True) + status = emoji.emojize(" ".join(words), 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"]) + + 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 HELP_TEXT class Server(BaseServer): def __init__(self, - bot: BaseBot, - name: str, - config: Config): + bot: BaseBot, + name: str, + cfg: Config): super().__init__(bot, name) - self._config = config + self._config = cfg async def line_send(self, line: Line): - print(f"{self.name} > {line.format()}") + print(f"> {line.format()}") async def line_read(self, line: Line): - print(f"{self.name} < {line.format()}") + print(f"< {line.format()}") if line.command == "001": - await self.send(build("JOIN", [",".join(channels)])) + await self.send(build("JOIN", [",".join(self._config.channel)])) await self.send(build("MODE", [self.nickname, "+B"])) if line.command == "INVITE": @@ -99,29 +71,44 @@ class Server(BaseServer): and not ("batch" in line.tags and line.tags["batch"] == "1") and line.params[1].startswith("!") ): - response = think(line) + 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) + return Server(self, name, self._config) -async def main(): +async def main(cfg: Config): + bot = Bot(cfg) + + host, port, tls = cfg.server + sasl_user, sasl_pass = cfg.sasl + 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"]), + cfg.nickname, + host, + port, + tls, + username=cfg.username, + realname=cfg.realname, + sasl=SASLUserPass(sasl_user, sasl_pass), + autojoin=[cfg.channel] ) - - bot = Bot() - await bot.add_server("tilde", params) + await bot.add_server(host, params) await bot.run() if __name__ == "__main__": - asyncio.run(main()) + parser = ArgumentParser() + parser.add_argument("config") + args = parser.parse_args() + config = config_load(args.config) + + asyncio.run(main(config)) diff --git a/tooter.service b/tooter.service index 5aa430d..02b1044 100644 --- a/tooter.service +++ b/tooter.service @@ -13,4 +13,3 @@ StartLimitBurst=3 [Install] WantedBy=default.target -