#!/usr/bin/env python3 from mastodon import Mastodon import emoji import irctokens import json import os import re import socket import sys def masto_from_json(conf): conf = json.load(conf) return Mastodon( client_id=conf["client_id"], client_secret=conf["client_secret"], access_token=conf["access_token"], api_base_url=conf["base_url"], ) def _send(line): print(f"> {line.format()}") e.push(line) while e.pending(): e.pop(s.send(e.pending())) def send(chan, msg): _send(irctokens.build("PRIVMSG", [chan, msg])) def think(line): chan = line.params.pop(0) words = line.params[0].split(" ") if len(words) > 0 and line.hostmask.nickname != config["botnick"]: if words[0] == "!toot": status = emoji.emojize(" ".join(words[1:]), use_aliases=True) if chan == "#team": res = tildeteam.toot(status) else: res = tildeverse.toot(status) print(res) send(chan, "tooted! {}".format(res["url"])) elif words[0] == "!source": send(chan, "https://tildegit.org/ben/tooter") elif words[0] == "!botlist" or words[0] == "!toothelp": send( chan, "helo i can send toots from irc: @tildeverse@tilde.zone - from @tildeteam from the #team channel)", ) # do setup path = os.path.dirname(os.path.abspath(__file__)) with open(os.path.join(path, "config.json"), "r") as f: config = json.load(f) if os.path.isfile(os.path.join(path, "account.json")): with open(os.path.join(path, "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) # read masto creds with open(os.path.join(path, "tildeverse.json"), "r") as f: tildeverse = masto_from_json(f) with open(os.path.join(path, "tildeteam.json"), "r") as f: tildeteam = masto_from_json(f) if __name__ == "__main__": d = irctokens.StatefulDecoder() e = irctokens.StatefulEncoder() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((config["address"], config["port"])) _send(irctokens.build("USER", [config["botnick"], "0", "*", "mastodon tooter"])) _send(irctokens.build("NICK", [config["botnick"]])) while True: lines = d.push(s.recv(1024)) if lines == None: print("! disconnected") break for line in lines: print(f"< {line.format()}") if line.command == "PING": _send(irctokens.build("PONG", line.params)) elif line.command == "001": _send(irctokens.build("MODE", [config["botnick"], "+B"])) if account is not None: _send( irctokens.build( "SQUERY", [ "NickServ", "IDENTIFY", account["username"], account["password"], ], ) ) _send(irctokens.build("JOIN", [",".join(channels)])) elif line.command == "INVITE": _send(irctokens.build("JOIN", line.params)) elif line.command == "PRIVMSG": think(line)