fix new ircrobots stuff

This commit is contained in:
Ben Harris 2022-05-09 16:42:31 -04:00
parent 570dba09a6
commit 8c2197a0d7
5 changed files with 78 additions and 77 deletions

View File

@ -11,6 +11,6 @@ mastodon:
client_id: 1234566 client_id: 1234566
client_secret: beeeep client_secret: beeeep
access_token: you do not want to know access_token: you do not want to know
base_url: https://tilde.zone api_base_url: https://tilde.zone
channels: channels:
- '#club' - '#club'

View File

@ -1,20 +1,22 @@
from dataclasses import dataclass from dataclasses import dataclass
from os.path import expanduser from mastodon import Mastodon
from re import compile as re_compile from typing import Tuple, Dict
from typing import List, Pattern, Tuple
import yaml import yaml
@dataclass @dataclass
class Config(object): class Config(object):
server: Tuple[str, int, bool] server: Tuple[str, int, bool]
nickname: str nickname: str
username: str username: str
realname: str realname: str
password: str channel: str
channel: str
sasl: Tuple[str, str] sasl: Tuple[str, str]
mastodon_accounts: Dict[str, Mastodon]
assigned_channels: Dict[str, str]
def load(filepath: str): def load(filepath: str):
with open(filepath) as file: with open(filepath) as file:
@ -22,22 +24,34 @@ def load(filepath: str):
nickname = config_yaml["nickname"] nickname = config_yaml["nickname"]
server = config_yaml["server"] server = config_yaml["server"]
hostname, port_s = server.split(":", 1) hostname, port_s = server.split(":", 1)
tls = False tls = False
if port_s.startswith("+"): if port_s.startswith("+"):
tls = True tls = True
port_s = port_s.lstrip("+") port_s = port_s.lstrip("+")
port = int(port_s) 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( return Config(
(hostname, port, tls), (hostname, port, tls),
nickname, nickname,
config_yaml.get("username", nickname), config_yaml.get("username", nickname),
config_yaml.get("realname", nickname), config_yaml.get("realname", nickname),
config_yaml["password"],
config_yaml["channel"], config_yaml["channel"],
(config_yaml["sasl"]["username"], config_yaml["sasl"]["password"]), (config_yaml["sasl"]["username"], config_yaml["sasl"]["password"]),
mastodon_accounts=accounts,
assigned_channels=channels,
) )

View File

@ -1,3 +1,4 @@
Mastodon.py==1.5.1 Mastodon.py==1.5.1
emoji==1.7.0 emoji==1.7.0
ircrobots==0.6.1 ircrobots==0.6.1
PyYAML==6.0

115
tooter.py
View File

@ -1,89 +1,61 @@
#!/usr/bin/env python3 #!/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 Bot as BaseBot
from ircrobots import ConnectionParams, SASLUserPass from ircrobots import ConnectionParams, SASLUserPass
from ircrobots import Server as BaseServer from ircrobots import Server as BaseServer
from irctokens import build, Line from irctokens import build, Line
from mastodon import Mastodon
import asyncio import asyncio
import emoji 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)" HELP_TEXT = "helo i can send toots from irc"
SOURCE_URL = "https://tildegit.org/ben/tooter"
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): def think(self, line):
chan = line.params[0] chan = line.params[0]
cmd, *words = line.params[1].split(" ") cmd, *words = line.params[1].split(" ")
cmd = cmd.lower()[1:] cmd = cmd.lower()[1:]
if cmd == "source": if cmd == "source":
return "https://tildegit.org/ben/tooter" return SOURCE_URL
elif cmd in ["botlist", "toothelp"]: elif cmd in ["botlist", "toothelp"]:
return HELP_TEXT return HELP_TEXT
elif cmd == "toot": elif cmd == "toot":
if len(words) >= 2: 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) author = line.tags.get("account", line.hostmask.nickname)
res = masto[
assigned_channels[chan] if chan in assigned_channels else "tildeverse" if chan in self._config.assigned_channels:
].toot(f"{status}\n~{author}") account = self._config.mastodon_accounts[self._config.assigned_channels[chan]]
return "tooted! {}".format(res["url"]) 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: else:
return HELP_TEXT return HELP_TEXT
class Server(BaseServer): class Server(BaseServer):
def __init__(self, def __init__(self,
bot: BaseBot, bot: BaseBot,
name: str, name: str,
config: Config): cfg: Config):
super().__init__(bot, name) super().__init__(bot, name)
self._config = config self._config = cfg
async def line_send(self, line: Line): async def line_send(self, line: Line):
print(f"{self.name} > {line.format()}") print(f"> {line.format()}")
async def line_read(self, line: Line): async def line_read(self, line: Line):
print(f"{self.name} < {line.format()}") print(f"< {line.format()}")
if line.command == "001": 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"])) await self.send(build("MODE", [self.nickname, "+B"]))
if line.command == "INVITE": if line.command == "INVITE":
@ -99,29 +71,44 @@ class Server(BaseServer):
and not ("batch" in line.tags and line.tags["batch"] == "1") and not ("batch" in line.tags and line.tags["batch"] == "1")
and line.params[1].startswith("!") and line.params[1].startswith("!")
): ):
response = think(line) response = think(self, line)
if response is not None: if response is not None:
await self.send(build("PRIVMSG", [line.params[0], response])) await self.send(build("PRIVMSG", [line.params[0], response]))
class Bot(BaseBot): class Bot(BaseBot):
def __init__(self, cfg: Config):
super().__init__()
self._config = cfg
def create_server(self, name: str): 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( params = ConnectionParams(
config.get("botnick", "tooter"), cfg.nickname,
config.get("address", "127.0.0.1"), host,
config.get("port", 6667), port,
config.get("tls", False), tls,
sasl=SASLUserPass(account["username"], account["password"]), username=cfg.username,
realname=cfg.realname,
sasl=SASLUserPass(sasl_user, sasl_pass),
autojoin=[cfg.channel]
) )
await bot.add_server(host, params)
bot = Bot()
await bot.add_server("tilde", params)
await bot.run() await bot.run()
if __name__ == "__main__": 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))

View File

@ -13,4 +13,3 @@ StartLimitBurst=3
[Install] [Install]
WantedBy=default.target WantedBy=default.target