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 # PyBuilder
target/ target/
tildeclub.json
tildeteam.json tildeteam.json
tildeverse.json tildeverse.json
config.json config.json

View File

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

View File

@ -1,3 +1,3 @@
Mastodon.py==1.5.0 Mastodon.py==1.5.0
emoji==0.5.4 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 #!/usr/bin/env python3
from mastodon import Mastodon 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 emoji
import irctokens import glob
import json import json
import os import os
import re import re
import socket
import sys import sys
HELPTEXT = "helo i can send toots from irc: @tildeverse@tilde.zone - from @tildeteam from the #team channel)" HELPTEXT = "helo i can send toots from irc: @tildeverse@tilde.zone - from @tildeteam from the #team channel)"
def masto_from_json(conf): def masto_from_json(conf):
conf = json.load(conf) conf = json.load(conf)
return Mastodon( return Mastodon(
@ -21,39 +26,12 @@ def masto_from_json(conf):
) )
def _send(line): masto = {}
print(f"> {line.format()}") # load masto creds
e.push(line) for cred in glob.glob("tilde*.json"):
while e.pending(): shortname, _ = os.path.splitext(cred)
e.pop(s.send(e.pending())) with open(cred, "r") as f:
masto[shortname] = masto_from_json(f)
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)
# do setup # do setup
path = os.path.dirname(os.path.abspath(__file__)) path = os.path.dirname(os.path.abspath(__file__))
@ -70,53 +48,79 @@ if len(sys.argv) > 1:
for c in sys.argv[1:]: for c in sys.argv[1:]:
channels.append("#" + c) 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: def think(line):
tildeteam = masto_from_json(f) 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__": if __name__ == "__main__":
d = irctokens.StatefulDecoder() asyncio.run(main())
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)