#!/usr/bin/env python3
from mastodon import Mastodon
import emoji
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 rawsend(msg):
print(msg)
ircsock.send(f"{msg}\r\n".encode())
def send(chan, msg):
rawsend(f"PRIVMSG #{chan} :{msg}")
def eventloop(chan, nick, msg):
words = re.split("[ \t\s]+", msg)
if len(words) > 0 and nick != botnick:
if words[0] == "!toot":
status = emoji.emojize(" ".join(words[1:]), use_aliases=True)
print(f"{status} posted by {nick}")
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)
botnick = config["botnick"]
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__":
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ircsock.connect((config["address"], config["port"]))
rawsend(f"NICK {botnick}")
rawsend(f"USER {botnick} 0 * :mastodon tooter")
while 1:
for msg in ircsock.recv(2048).decode().split("\r\n"):
print(msg)
if "PING" in msg:
rawsend(msg.replace("I", "O", 1))
if "INVITE" in msg:
chan = msg.split(":")[-1]
rawsend(f"JOIN {chan}")
if "001" in msg:
for c in channels:
rawsend(f"JOIN {c}")
rawsend(f"MODE {botnick} +B")
if account is not None:
rawsend("SQUERY NickServ IDENTIFY %s %s" % (account["username"], account["password"]))
m = re.match(":(?P<nick>[^ ]+)!.*PRIVMSG #(?P<chan>\w+) :(?P<msg>.*)", msg)
if m and m.groupdict():
m = m.groupdict()
eventloop(m["chan"], m["nick"], m["msg"])