tooter/tooter.py

122 lines
3.4 KiB
Python

#!/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"]:
cmd = words[0].lower()
if cmd == "!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 cmd == "!source":
send(chan, "https://tildegit.org/ben/tooter")
elif cmd in ["!botlist", "!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)