about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2021-02-18 23:13:16 -0500
committerBen Harris <ben@tilde.team>2021-02-18 23:15:22 -0500
commitb140c7e5391fcbd594e293dcb688b4b561ceae2d (patch)
treedd38bedc19572a785535deb18aa8fb81043776db
parentb973b31c9785356d399187ae80ca18801c053e1f (diff)
rewrite with ircrobots
-rw-r--r--config.ini1
-rw-r--r--requirements.txt2
-rw-r--r--tracer.py152
3 files changed, 73 insertions, 82 deletions
diff --git a/config.ini b/config.ini
index e17bb24..d4386bb 100644
--- a/config.ini
+++ b/config.ini
@@ -3,4 +3,5 @@ server = 127.0.0.1
 channels = #bots, #meta, #team
 nick = tracer
 port = 6667
+tls = false
 
diff --git a/requirements.txt b/requirements.txt
index f245902..7776149 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
 tracery==0.1.1
-irctokens==1.0.0
+ircrobots==0.3.7
diff --git a/tracer.py b/tracer.py
index 8a4e430..4b1ddfe 100644
--- a/tracer.py
+++ b/tracer.py
@@ -1,18 +1,17 @@
 #!/usr/bin/env python3
 
+from irctokens import build, Line
+from ircrobots import Bot as BaseBot
+from ircrobots import Server as BaseServer
+from ircrobots import ConnectionParams, SASLUserPass
 from random import randint, choice
 from tracery.modifiers import base_english
+import asyncio
 import configparser
 import glob
-import irctokens
 import json
 import os
 import random
-import re
-import socket
-import subprocess
-import sys
-import time
 import traceback
 import tracery
 
@@ -49,7 +48,7 @@ def load_rules(path):
 
 def populate():
     global DB
-    DB = {}
+    # DB = {}
     for p in glob.glob("/home/*/.tracery/*"):
         name, ext = os.path.splitext(p)
         name = os.path.basename(name)
@@ -103,103 +102,94 @@ def fuse(argv):
     return grammar(raw).flatten("#origin#")
 
 
-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(" ")
+    chan = line.params[0]
+    words = line.params[1].split(" ")
 
-    if len(words) > 0 and line.hostmask.nickname != bot["nick"]:
+    if len(words) > 0:
         if words[0] == "!!list":
             res = ""
             for k in DB:
                 res += k + " "
-            send(chan, res[:475])
+            return res
         elif words[0] == "!!fuse":
             if "|" in words:
                 res = fuse(words[1 : words.index("|")])
                 if res:
-                    send(chan, " ".join(words[words.index("|") + 1 :]) + " " + res)
+                    return " ".join(words[words.index("|") + 1 :]) + " " + res
             else:
                 res = fuse(words[1:])
                 if res:
-                    send(chan, res[0:475])
+                    return res
         elif words[0] == "!!source":
-            send(chan, "https://tildegit.org/ben/tracer")
+            return "https://tildegit.org/ben/tracer"
         elif words[0] == "!botlist" or words[0] == "!!help":
-            send(
-                chan,
-                "helo i'm a tracery bot that makes cool things from tracery grammars in your ~/.tracery. see http://tracery.io for more info",
-            )
+            return "helo i'm a tracery bot that makes cool things from tracery grammars in your ~/.tracery. see http://tracery.io for more info"
         elif words[0][0:2] == "!!":
             print(words)
             res = generate(words[0][2:])
             if res:
                 if len(words) >= 3:
                     if words[1] == "|":
-                        send(chan, " ".join(words[2:]) + " " + res)
+                        return " ".join(words[2:]) + " " + res
                     else:
-                        send(chan, res)
+                        return res
                 else:
-                    send(chan, res)
+                    return res
+
+
+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":
+            await self.send(build("JOIN", [",".join(bot.getlist("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 not "inspircd.org/bot" in line.tags
+            and self.has_user(line.hostmask.nickname)
+        ):
+            try:
+                response = think(line)
+                if response is not None:
+                    await self.send(build("PRIVMSG", [line.params[0], response]))
+            except Exception as e:
+                print("ERROR", line)
+                print(e)
+                traceback.print_exc()
+
+
+class Bot(BaseBot):
+    def create_server(self, name: str):
+        return Server(self, name)
+
+
+async def main():
+    ircrobot = Bot()
+
+    params = ConnectionParams(
+        bot["nick"],
+        host=bot["server"],
+        port=int(bot["port"]),
+        tls=bool(bot["tls"]),
+        sasl=SASLUserPass(account["username"], account["password"]),
+    )
+
+    await ircrobot.add_server("tilde", params)
+    await ircrobot.run()
 
 
 if __name__ == "__main__":
-    d = irctokens.StatefulDecoder()
-    e = irctokens.StatefulEncoder()
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    s.connect((bot["server"], int(bot["port"])))
-
-    _send(irctokens.build("USER", [bot["nick"], "0", "*", "tracery bot"]))
-    _send(irctokens.build("NICK", [bot["nick"]]))
-
-    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[0]]))
-
-            elif line.command == "001":
-                _send(irctokens.build("MODE", [bot["nick"], "+B"]))
-                if account is not None:
-                    _send(
-                        irctokens.build(
-                            "SQUERY",
-                            [
-                                "NickServ",
-                                "IDENTIFY",
-                                account["username"],
-                                account["password"],
-                            ],
-                        )
-                    )
-
-                _send(irctokens.build("JOIN", [",".join(bot.getlist("channels"))]))
-
-            elif line.command == "INVITE":
-                _send(irctokens.build("JOIN", [line.params[1]]))
-
-            elif line.command == "PRIVMSG":
-                try:
-                    think(line)
-                except Exception as e:
-                    print("ERROR", line)
-                    print(e)
-                    traceback.print_exc()
-
+    asyncio.run(main())