rewrite with ircrobots

This commit is contained in:
Ben Harris 2021-02-18 15:41:58 -05:00
parent 7ee1f9a7aa
commit d0ce776572
4 changed files with 89 additions and 83 deletions

1
.gitignore vendored
View File

@ -58,6 +58,7 @@ docs/_build/
# PyBuilder
target/
tildeclub.json
tildeteam.json
tildeverse.json
config.json

View File

@ -2,6 +2,7 @@
"channels": [],
"address": "127.0.0.1",
"port": 6667,
"tls": false,
"botnick", "tooter"
}

View File

@ -1,3 +1,3 @@
Mastodon.py==1.5.0
emoji==0.5.4
irctokens==1.0.0
ircrobots==0.3.7

168
tooter.py
View File

@ -1,16 +1,21 @@
#!/usr/bin/env python3
from mastodon import Mastodon
from irctokens import build, Line
from ircrobots import Bot as BaseBot
from ircrobots import Server as BaseServer
from ircrobots import ConnectionParams, SASLUserPass
import asyncio
import emoji
import irctokens
import glob
import json
import os
import re
import socket
import sys
HELPTEXT = "helo i can send toots from irc: @tildeverse@tilde.zone - from @tildeteam from the #team channel)"
def masto_from_json(conf):
conf = json.load(conf)
return Mastodon(
@ -21,39 +26,12 @@ def masto_from_json(conf):
)
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":
if len(words) >= 2:
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"]))
else:
send(chan, HELPTEXT)
elif cmd == "!source":
send(chan, "https://tildegit.org/ben/tooter")
elif cmd in ["!botlist", "!toothelp"]:
send(chan, HELPTEXT)
masto = {}
# load masto creds
for cred in glob.glob("tilde*.json"):
shortname, _ = os.path.splitext(cred)
with open(cred, "r") as f:
masto[shortname] = masto_from_json(f)
# do setup
path = os.path.dirname(os.path.abspath(__file__))
@ -70,53 +48,79 @@ 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)
def think(line):
chan = line.params[0]
words = line.params[1].split(" ")
if len(words) > 0:
cmd = words[0].lower()
if cmd == "!toot":
if len(words) >= 2:
status = emoji.emojize(" ".join(words[1:]), use_aliases=True)
if chan == "#team":
res = masto["tildeteam"].toot(status)
elif chan == "#club":
res = masto["tildeclub"].toot(status)
else:
res = masto["tildeverse"].toot(status)
print(res)
return "tooted! {}".format(res["url"])
else:
return HELPTEXT
elif cmd == "!source":
return "https://tildegit.org/ben/tooter"
elif cmd in ["!botlist", "!toothelp"]:
return HELPTEXT
class Server(BaseServer):
async def line_send(self, line: Line):
print(f"{self.name} > {line.format()}")
async def line_read(self, line: Line):
print(f"{self.name} < {line.format()}")
if line.command == "001":
print(f"connected to {self.isupport.network}")
await self.send(build("JOIN", [",".join(channels)]))
await self.send(build("MODE", [self.nickname, "+B"]))
if line.command == "INVITE":
print(f"received invite to {line.params[1:]}")
await self.send(build("JOIN", line.params[1:]))
if (
line.command == "PRIVMSG"
and self.has_channel(line.params[0])
and not line.hostmask is None
and not self.casefold(line.hostmask.nickname) == self.nickname_lower
and not ("batch" in line.tags and line.tags["batch"] == "1")
and self.has_user(line.hostmask.nickname)
):
response = think(line)
if response is not None:
await self.send(build("PRIVMSG", [line.params[0], response]))
class Bot(BaseBot):
def create_server(self, name: str):
return Server(self, name)
async def main():
bot = Bot()
params = ConnectionParams(
config["botnick"],
host=config["address"],
port=config["port"],
tls=config["tls"],
sasl=SASLUserPass(account["username"], account["password"]),
)
await bot.add_server("tilde", params)
await bot.run()
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)
asyncio.run(main())